diff --git a/apps/api/package.json b/apps/api/package.json index 1bb3f370..817c64e0 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -4,9 +4,9 @@ "main": "index.js", "license": "MIT", "scripts": { - "build": "tsc --project ./tsconfig.json", + "build": "tsc --project tsconfig.json", "clean": "rm -r dist", - "dev": "nodemon src/server.ts --experimental-global-webcrypto", + "dev": "nodemon src/server.ts", "format": "", "work": "ts-node ./src/workers.ts", "work:order": "ts-node ./src/orders/worker.ts" @@ -24,8 +24,10 @@ "graphql-request": "^6.1.0", "helmet": "^7.1.0", "ioredis": "^5.3.2", + "js-combinatorics": "^2.1.2", "jsonwebtoken": "^9.0.2", "kysely": "^0.27.3", + "libphonenumber-js": "^1.10.60", "morgan": "^1.10.0", "nodemon": "^3.0.2", "oslo": "^1.1.1", @@ -40,10 +42,13 @@ "@types/concurrently": "^7.0.0", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", + "@types/js-combinatorics": "^1.2.0", "@types/node": "^20.10.5", "@types/pg": "^8.11.5", "chalk": "^5.3.0", "concurrently": "^8.2.2", + "otplib": "^12.0.1", + "qrcode": "^1.5.3", "typescript": "^5.3.3" } } diff --git a/apps/api/src/init.ts b/apps/api/src/init.ts index 1f0db144..bc29b624 100644 --- a/apps/api/src/init.ts +++ b/apps/api/src/init.ts @@ -4,6 +4,7 @@ import cors from "cors"; // import compression from "compression"; import * as helmet from "helmet"; import { catchErrors } from "./middleware/errors"; +import { logRequest } from "./middleware/requestLogger"; export function init(app: any) { app.use(cors()); @@ -16,5 +17,6 @@ export function init(app: any) { // app.use(helmet()); // app.use(morganLogger("dev")); app.use(routers); + app.use(logRequest); app.use(catchErrors); } diff --git a/apps/api/src/matcher/sahilScore.ts b/apps/api/src/matcher/sahilScore.ts new file mode 100644 index 00000000..51d1f847 --- /dev/null +++ b/apps/api/src/matcher/sahilScore.ts @@ -0,0 +1,9 @@ +export const calculateSahilScore = (pair: any) => { + const totalQuantity = pair[0].quantity + pair[1].quantity; + const totalDistance = pair[0].distance + pair[1].distance; + const totalPricePerUnit = pair[0].pricePerUnit + pair[1].pricePerUnit; + const distanceCost = totalDistance * 0.5; + const unitCost = totalQuantity * totalPricePerUnit; + return distanceCost + unitCost; + }; + \ No newline at end of file diff --git a/apps/api/src/matcher/setGeofence.ts b/apps/api/src/matcher/setGeofence.ts new file mode 100644 index 00000000..9798079a --- /dev/null +++ b/apps/api/src/matcher/setGeofence.ts @@ -0,0 +1,6 @@ +import { client } from "../lib/graphql-request"; + + +export const setGeofence = async (lat: number, lng: number) => { + // const coords = client.request(); +} \ No newline at end of file diff --git a/apps/api/src/matcher/sumOrderItems.ts b/apps/api/src/matcher/sumOrderItems.ts new file mode 100644 index 00000000..c95f885c --- /dev/null +++ b/apps/api/src/matcher/sumOrderItems.ts @@ -0,0 +1,42 @@ +export const sumOrderItems = (suppliersArray: any, target: number) => { + const map = new Map(); + const pairs = []; + + for (let i = 0; i < suppliersArray.length; i++) { + const complement = target - suppliersArray[i].quantity; + + if (map.has(complement)) { + // If the complement is found, add all pairs that include the current supplier + const indices = map.get(complement); + for (const element of indices) { + pairs.push([suppliersArray[element], suppliersArray[i]]); + } + } + + // Update the map with the current supplier's quantity and its index + if (map.has(suppliersArray[i].quantity)) { + map.get(suppliersArray[i].quantity).push(i); + } else { + map.set(suppliersArray[i].quantity, [i]); + } + } + return pairs; +}; + +export const calculateSahilScore = (pair: any) => { + const totalQuantity = pair[0].quantity + pair[1].quantity; + const totalDistance = pair[0].distance + pair[1].distance; + const totalPricePerUnit = pair[0].pricePerUnit + pair[1].pricePerUnit; + const distanceCost = totalDistance * 0.5; + const unitCost = totalQuantity * totalPricePerUnit; + return distanceCost + unitCost; +}; + + +// Calculate total cost for each pair and rank them +export const rankedSuppliersBasedOnScore = (suppliers: any) => { + return suppliers.map((supplier: any) => ({ + supplier, + totalCost: calculateSahilScore(supplier) + })).sort((a: any, b: any) => a.totalCost - b.totalCost); +} \ No newline at end of file diff --git a/apps/api/src/matcher/supplierCombinations.ts b/apps/api/src/matcher/supplierCombinations.ts new file mode 100644 index 00000000..f8fb3b48 --- /dev/null +++ b/apps/api/src/matcher/supplierCombinations.ts @@ -0,0 +1,34 @@ +import { Combination } from 'js-combinatorics'; + +// we could rank the combinations based on the sum of their quantities +// modulus the number of qunatity to get the combination size +export const calculateCombinationSize = (candidates: { name: string, quantity: number }[], targetQuantity: number) : number => { + let remainingQuantity = targetQuantity; + let combinationSize = 0; + for (const candidate of candidates) { + if (remainingQuantity <= 0) { + break; + } + if (candidate.quantity >= remainingQuantity) { + combinationSize++; + break; + } else { + combinationSize++; + remainingQuantity -= candidate.quantity; + } + } + return combinationSize; + } + +export const generateCombinations = async (suppliers: { name: string; id: string; quantity: number; }[], combinationSize: number = 2) => { + const combinations = new Combination(suppliers, combinationSize); + return [...combinations]; +} + +export const findBestCombination = (suppliers: any, target: number) => { + const combinations = generateCombinations(suppliers, target); + let bestCombination: never[] = []; + let bestCombinationSum = 0; + + return bestCombination; +} \ No newline at end of file diff --git a/apps/api/src/orders/operations/initOrder.ts b/apps/api/src/orders/operations/initOrder.ts index bebda8ae..a5608991 100644 --- a/apps/api/src/orders/operations/initOrder.ts +++ b/apps/api/src/orders/operations/initOrder.ts @@ -9,24 +9,19 @@ export const orderSchema = z .refine((value) => value > new Date()) .optional(), customerId: z.any(), - destination: z.string(), origin: z.string(), processedBy: z.string().optional(), - }) - .refine( - ({ destination, origin }) => { - return origin !== destination; - }, - { message: "Destination is the same as origin" } - ); + orderItems: z.any() + }); export type OrderAttributes = z.infer; export const initOrder = async (order: OrderAttributes): Promise => { - const data = await client.request(INSERT_NEW_ORDER, { - object: { - ...order, - }, - }); - return Promise.resolve(data); + // const data = await client.request(INSERT_NEW_ORDER, { + // object: { + // ...order, + // }, + // }); + // return Promise.resolve(data); + return Promise.resolve(order); }; diff --git a/apps/api/src/orders/operations/updateOrder.ts b/apps/api/src/orders/operations/updateOrder.ts new file mode 100644 index 00000000..6e0303a3 --- /dev/null +++ b/apps/api/src/orders/operations/updateOrder.ts @@ -0,0 +1,25 @@ +import { UPDATE_ORDER_STATUS, FETCH_ORDER_BY_PK } from "@sahil/lib/graphql"; +import { z } from "zod"; +import { client } from "../../lib/graphql-request"; + +export const updateOrder = async (orderId: string, data = { + status: "IN-PROGRESS" +}) => { + // check if the order exists + const order = await client.request(FETCH_ORDER_BY_PK, { + id: orderId + }); + + if(!order) { + throw new Error("Order Not Found"); + } + + const updatedOrder = await client.request(UPDATE_ORDER_STATUS, { + object: { + ...order, + status: "IN_PROGRESS" + } + }); + + return updateOrder; +} \ No newline at end of file diff --git a/apps/api/src/orders/router.ts b/apps/api/src/orders/router.ts index c967beae..1105ee63 100644 --- a/apps/api/src/orders/router.ts +++ b/apps/api/src/orders/router.ts @@ -2,6 +2,7 @@ import { NextFunction, Response, Router, Request } from "express"; import { pushIntoOrders } from "../enqueue"; import { logRequest } from "../middleware/requestLogger"; import { validate } from "../middleware/zodValidate"; +import { updateOrder } from "./operations/updateOrder"; import { initOrder, @@ -16,14 +17,35 @@ ordersRouter.use(logRequest); ordersRouter.post( "/", - validate(orderSchema), + + async (req: Request, res: Response, next: NextFunction) => { + try { + const order = await initOrder(req.body); + // push into Queue + await pushIntoOrders(req.body); + res.status(201).send({ + order: { + name: "hello" + } + }); + } catch (error) { + next(error); + } + } +); + +ordersRouter.put( + "/:orderId", + async (req: Request, res: Response, next: NextFunction) => { try { const order = await initOrder(req.body); // push into Queue await pushIntoOrders(req.body); res.status(201).send({ - order, + order: { + name: "hello" + } }); } catch (error) { next(error); diff --git a/apps/api/src/orders/worker.ts b/apps/api/src/orders/worker.ts index 5cbf1148..4fc58cc6 100644 --- a/apps/api/src/orders/worker.ts +++ b/apps/api/src/orders/worker.ts @@ -2,10 +2,13 @@ import { Worker } from "bullmq"; import { logger } from "../lib/winston"; import { connection } from "../lib/ioredis"; import { Queues } from "../queue"; +import { updateOrder } from "./operations/updateOrder"; const worker = new Worker( Queues.Order, async (job) => { + console.log("yerrrrr", job.data); + const updatedOrder = await updateOrder(job.data.id); logger.info("Processing Job", { world: "hello 0", }); diff --git a/apps/api/src/queue.ts b/apps/api/src/queue.ts index da9024a9..db352960 100644 --- a/apps/api/src/queue.ts +++ b/apps/api/src/queue.ts @@ -3,7 +3,7 @@ import { connection } from "./lib/ioredis"; import { redisHost, redisPort } from "./config"; export enum Queues { - Auth = "Auth", + Auth = "Auth", Client = "Client", Event = "Event", Mail = "Mail", diff --git a/apps/api/src/suppliers/operations/list.ts b/apps/api/src/suppliers/operations/list.ts index 8e02f978..04e5d3d7 100644 --- a/apps/api/src/suppliers/operations/list.ts +++ b/apps/api/src/suppliers/operations/list.ts @@ -1,6 +1,83 @@ import { db } from "../../lib/kysley/databse"; +import { + findBestCombination, + generateCombinations, +} from "../../matcher/supplierCombinations"; + +import { rankedSuppliersBasedOnScore } from "../../matcher/sumOrderItems"; + +import { sumOrderItems } from "../../matcher/sumOrderItems"; + +const candidates = [ + { + name: "Emmanuel Office Solutions", + id: "514f5a78-9f4c-4cde-b6c0-5f7649a28d60", + quantity: 9, + pricePerUnit: 0.95, + distance: 144 + }, + { + name: "Twins Construction", + id: "627460d3-7b29-4bc6-b9ff-3958d6d02fe4", + quantity: 14, + pricePerUnit: 0.9, + distance: 120 + }, + { + name: "Khan Agricultural", + id: "403140dc-1d5d-435f-ba3d-ccc65abb1e5f", + quantity: 7, + pricePerUnit: 0.8, + distance: 111 + }, + { + name: "Energi Dealers", + id: "6f911d9b-580b-4283-bc8b-fbd381d298be", + quantity: 6, + pricePerUnit: 1, + distance: 97 + }, + { + name: "Brown Safety Solutions", + id: "0c8c5d87-b0a3-4409-95ea-d1134e1d72fd", + quantity: 12, + pricePerUnit: 0.85, + distance: 123 + }, + { + name: "Ozone Supermarket", + id: "b5f93ced-ba1f-42cb-bb96-e0d388bb111d", + quantity: 8, + pricePerUnit: 0.95, + distance: 109 + }, + { + name: "Mtn Momo", + id: "64f3bac9-12f7-4821-bd5c-4c48e5afe4fb", + quantity: 10, + pricePerUnit: 0.9, + distance: 119 + }, +]; + export const listRecommendedSuppliers = async () => { + const combinations = await generateCombinations(candidates, 20); + // Print the combinations + console.log("Combinations of suppliers that add up to 20kgs:", combinations); + + + const pairs = sumOrderItems(candidates, 20); + + // console.log("pairs", pairs); + + const rankedSuppliers = rankedSuppliersBasedOnScore(pairs); + + console.log("rankedSuppliers", rankedSuppliers[0]); + console.log("*****************"); + console.log("rankedSuppliers", rankedSuppliers[1]); + + let query = db.selectFrom("suppliers"); const result = await query.selectAll().execute(); return result; diff --git a/apps/api/src/suppliers/operations/supplierProductInfo.ts b/apps/api/src/suppliers/operations/supplierProductInfo.ts new file mode 100644 index 00000000..4d084709 --- /dev/null +++ b/apps/api/src/suppliers/operations/supplierProductInfo.ts @@ -0,0 +1,18 @@ +import { db } from "../../lib/kysley/databse"; +// given a product label and category, this function returns the supplier as well as the product information +// for instance, suppliers could have milk as a label and diary as a category but a unique brand name for the product which +// we need to get the exact product from each supplier for comparison +export const supplierProductInfo = async (supplierId: string, product: any) => { + // Construct the query + const query = db + .selectFrom("products"); + // .where("products.supplier_id", "=", supplierId) + // .andWhere("products.category", "=", product.category) + // .andWhere("products.label", "=", product.label) + + // Execute the query + const result = await query.execute(); + + + return result; +}; \ No newline at end of file diff --git a/apps/api/src/suppliers/router.ts b/apps/api/src/suppliers/router.ts index 2878ebe6..f889ed6c 100644 --- a/apps/api/src/suppliers/router.ts +++ b/apps/api/src/suppliers/router.ts @@ -1,4 +1,6 @@ import { NextFunction, Response, Router, Request } from "express"; +import { logRequest } from "../middleware/requestLogger"; +import { validate } from "../middleware/zodValidate"; import { listRecommendedSuppliers } from "./operations/list"; const suppliersRouter = Router(); @@ -7,7 +9,7 @@ suppliersRouter.get( "/", async (req: Request, res: Response, next: NextFunction) => { try { - const suppliers = await listRecommendedSuppliers(); + const { suppliers } = await listRecommendedSuppliers(); res.status(201).json({ suppliers, }); diff --git a/apps/api/tsconfig.json b/apps/api/tsconfig.json index 144ad424..0e7681f4 100644 --- a/apps/api/tsconfig.json +++ b/apps/api/tsconfig.json @@ -14,7 +14,7 @@ "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ @@ -27,7 +27,7 @@ /* Modules */ "module": "commonjs", /* Specify what module code is generated. */ // "rootDir": "./", /* Specify the root folder within your source files. */ - // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ @@ -35,7 +35,12 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ @@ -48,8 +53,9 @@ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ @@ -57,7 +63,6 @@ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ // "newLine": "crlf", /* Set the newline character for emitting files. */ @@ -70,6 +75,7 @@ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ @@ -100,4 +106,4 @@ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */ } -} +} \ No newline at end of file diff --git a/apps/maps/src/Directions/index.ts b/apps/maps/src/Directions/index.ts index 45b14567..4714ca10 100644 --- a/apps/maps/src/Directions/index.ts +++ b/apps/maps/src/Directions/index.ts @@ -3,6 +3,7 @@ export class GoogleDirectionsAPI { private client; private _key; + // @ts-ignore constructor({ key }) { this.client = new Client({}); this._key = key; diff --git a/apps/maps/src/Geolocation/index.ts b/apps/maps/src/Geolocation/index.ts index e6b70199..3de2f97d 100644 --- a/apps/maps/src/Geolocation/index.ts +++ b/apps/maps/src/Geolocation/index.ts @@ -4,12 +4,12 @@ import type { GeocodeResult } from "@googlemaps/google-maps-services-js"; export class GoogleGeocodingAPI { private client; private _key; - +// @ts-ignore constructor({ key }) { this.client = new Client({}); this._key = key; } - +// @ts-ignore async geocode({ address }): Promise< Pick & { location: Record; @@ -23,6 +23,7 @@ export class GoogleGeocodingAPI { }, }); return { + // @ts-ignore location: { ...data.results[0]?.geometry?.location }, placeId: data.results[0]?.place_id, types: data.results[0]?.types, @@ -33,6 +34,7 @@ export class GoogleGeocodingAPI { const { data } = await this.client.geocode({ params: { key: this._key, + // @ts-ignore latlng: `${lat},${lng}`, }, }); diff --git a/apps/maps/src/Places/index.ts b/apps/maps/src/Places/index.ts index 09fe2060..2f4c6951 100644 --- a/apps/maps/src/Places/index.ts +++ b/apps/maps/src/Places/index.ts @@ -2,7 +2,7 @@ import { Client } from "@googlemaps/google-maps-services-js"; export class GooglePlacesAPI { private client; private _key; - +// @ts-ignore constructor({ key }) { this.client = new Client({}); this._key = key; @@ -20,12 +20,15 @@ export class GooglePlacesAPI { }); console.log("response", response?.data?.results); console.log("************"); + // @ts-ignore console.log("response", response?.data?.results?.geometry); return response?.data?.results?.map((place) => { return { name: place.name, - lat: place.geometry.location.lat, - lng: place.geometry.location.lng, + // @ts-ignore + lat: place?.geometry?.location?.lat, + // @ts-ignore + lng: place?.geometry?.location?.lng, address: "String", location: "String", }; diff --git a/packages/lib/google-maps/directions/getDirections.ts b/packages/lib/google-maps/directions/getDirections.ts new file mode 100644 index 00000000..4714ca10 --- /dev/null +++ b/packages/lib/google-maps/directions/getDirections.ts @@ -0,0 +1,42 @@ +import { Client } from "@googlemaps/google-maps-services-js"; +export class GoogleDirectionsAPI { + private client; + private _key; + + // @ts-ignore + constructor({ key }) { + this.client = new Client({}); + this._key = key; + } + async getDirections(origin: string, destination: string): Promise { + const { data } = await this.client.directions({ + params: { + origin, + destination, + key: this._key, + }, + }); + + return { + routes: { + name: "Route", + legs: [ + { + distance: { + ...data.routes?.[0]?.legs[0]?.distance, + }, + duration: { + ...data.routes?.[0]?.legs[0]?.duration, + }, + }, + ], + }, + startLocation: { + ...data.routes?.[0]?.legs[0]?.start_location, + }, + endLocation: { + ...data.routes?.[0]?.legs[0]?.end_location, + }, + }; + } +} diff --git a/packages/lib/graphql/mutations/orders.ts b/packages/lib/graphql/mutations/orders.ts index 54dddf1d..019c2dc4 100644 --- a/packages/lib/graphql/mutations/orders.ts +++ b/packages/lib/graphql/mutations/orders.ts @@ -8,6 +8,16 @@ export const INSERT_NEW_ORDER = gql` } `; + +export const UPDATE_ORDER_STATUS = gql` + mutation insertBusinessOrder($orderId: uuid!) { + update_order_status(where: {orders: {id: {_eq: $orderId}}}) { + affected_rows + } + } +`; + + export const INIT_ORDER_ACTION = gql` mutation insertBusinessOrderAction( $object: InsertBusinessOrderOrdersInsertInput = {} diff --git a/packages/lib/hooks/businesses.tsx b/packages/lib/hooks/businesses.tsx index 66469f56..96385905 100644 --- a/packages/lib/hooks/businesses.tsx +++ b/packages/lib/hooks/businesses.tsx @@ -16,7 +16,6 @@ import { BUSINESS_VALIDATED } from "@sahil/lib/graphql/subscriptions/businesses" import { GetBusinessesQuery, GetBusinessesQueryVariables, - GetBusinessesDocument, GetBusinessByPkQuery, GetBusinessByPkQueryVariables, GetBusinessOrdersQuery, diff --git a/packages/lib/kysley/database.ts b/packages/lib/kysley/database.ts new file mode 100644 index 00000000..9629f26e --- /dev/null +++ b/packages/lib/kysley/database.ts @@ -0,0 +1,2 @@ +import { Pool } from "pg"; +import { Kysely, PostgresDialect } from "kysely"; diff --git a/yarn.lock b/yarn.lock index ee2318cf..522edc01 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1902,6 +1902,44 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@otplib/core@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/core/-/core-12.0.1.tgz#73720a8cedce211fe5b3f683cd5a9c098eaf0f8d" + integrity sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA== + +"@otplib/plugin-crypto@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/plugin-crypto/-/plugin-crypto-12.0.1.tgz#2b42c624227f4f9303c1c041fca399eddcbae25e" + integrity sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g== + dependencies: + "@otplib/core" "^12.0.1" + +"@otplib/plugin-thirty-two@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/plugin-thirty-two/-/plugin-thirty-two-12.0.1.tgz#5cc9b56e6e89f2a1fe4a2b38900ca4e11c87aa9e" + integrity sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA== + dependencies: + "@otplib/core" "^12.0.1" + thirty-two "^1.0.2" + +"@otplib/preset-default@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/preset-default/-/preset-default-12.0.1.tgz#cb596553c08251e71b187ada4a2246ad2a3165ba" + integrity sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ== + dependencies: + "@otplib/core" "^12.0.1" + "@otplib/plugin-crypto" "^12.0.1" + "@otplib/plugin-thirty-two" "^12.0.1" + +"@otplib/preset-v11@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/preset-v11/-/preset-v11-12.0.1.tgz#4c7266712e7230500b421ba89252963c838fc96d" + integrity sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg== + dependencies: + "@otplib/core" "^12.0.1" + "@otplib/plugin-crypto" "^12.0.1" + "@otplib/plugin-thirty-two" "^12.0.1" + "@panva/hkdf@^1.0.2": version "1.1.1" resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d" @@ -2334,6 +2372,13 @@ "@types/through" "*" rxjs "^6.4.0" +"@types/js-combinatorics@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/js-combinatorics/-/js-combinatorics-1.2.0.tgz#81c753702bf9c826297abe85d179f803dc51ada1" + integrity sha512-c8JDKRYrLjJUD77htINkEXTZ4bq5MaJNTRYnFLMoeXviSWQkdHYZ3wUfT2YGuB+pizDmQTsaXCMQOntMdS9kvQ== + dependencies: + js-combinatorics "*" + "@types/js-yaml@^4.0.0": version "4.0.9" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2" @@ -4167,6 +4212,11 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dijkstrajs@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz#4c8dbdea1f0f6478bff94d9c49c784d623e4fc23" + integrity sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -4280,6 +4330,11 @@ enabled@2.0.x: resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== +encode-utf8@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -6051,6 +6106,11 @@ jose@^5.0.0: resolved "https://registry.yarnpkg.com/jose/-/jose-5.2.0.tgz#d0ffd7f7e31253f633eefb190a930cd14a916995" integrity sha512-oW3PCnvyrcm1HMvGTzqjxxfnEs9EoFOFWi2HsEGhlFVOXxTE3K9GKWVMFoFw06yPUqwpvEWic1BmtUZBI/tIjw== +js-combinatorics@*, js-combinatorics@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/js-combinatorics/-/js-combinatorics-2.1.2.tgz#1434bce70c6e3b46f01c6b214626e95ff7905f81" + integrity sha512-/1AY2bYwxajoaKjPzvgQ80U7lcucU71ubzFPVgZGmzbDGn3R18ZQUZfD69+4Idg4JfNcq6trwD6I+dRfVnr/tg== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -6254,6 +6314,11 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +libphonenumber-js@^1.10.60: + version "1.10.60" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.60.tgz#1160ec5b390d46345032aa52be7ffa7a1950214b" + integrity sha512-Ctgq2lXUpEJo5j1762NOzl2xo7z7pqmVWYai0p07LvAkQ32tbPv3wb+tcUeHEiXhKU5buM4H9MXsXo6OlM6C2g== + lilconfig@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" @@ -7147,6 +7212,15 @@ oslo@^1.1.1: "@node-rs/bcrypt" "1.9.0" auri "1.0.2" +otplib@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/otplib/-/otplib-12.0.1.tgz#c1d3060ab7aadf041ed2960302f27095777d1f73" + integrity sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg== + dependencies: + "@otplib/core" "^12.0.1" + "@otplib/preset-default" "^12.0.1" + "@otplib/preset-v11" "^12.0.1" + p-limit@3.1.0, p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" @@ -7450,6 +7524,11 @@ pirates@^4.0.1: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== +pngjs@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" + integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== + postcss-import@^15.1.0: version "15.1.0" resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" @@ -7679,6 +7758,16 @@ pvutils@^1.1.3: resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3" integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ== +qrcode@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.3.tgz#03afa80912c0dccf12bc93f615a535aad1066170" + integrity sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg== + dependencies: + dijkstrajs "^1.0.1" + encode-utf8 "^1.0.3" + pngjs "^5.0.0" + yargs "^15.3.1" + qs@6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" @@ -8659,6 +8748,11 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +thirty-two@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/thirty-two/-/thirty-two-1.0.2.tgz#4ca2fffc02a51290d2744b9e3f557693ca6b627a" + integrity sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA== + through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"