From 6050d9d3a3f80ffb32dcdf81827a16b7d167b60d Mon Sep 17 00:00:00 2001 From: Paul Coral Date: Fri, 1 Aug 2025 23:18:04 +0200 Subject: [PATCH] improve .env parsing --- apps/backend/.gitignore | 1 + apps/backend/package.json | 5 +- apps/backend/src/app.controller.spec.ts | 22 -- apps/backend/src/app.controller.ts | 12 - apps/backend/src/app.module.ts | 12 +- apps/backend/src/app.service.ts | 8 - .../auth/auth.controller.spec.ts | 0 apps/backend/src/app/auth/auth.controller.ts | 14 ++ .../backend/src/app/auth/auth.service.spec.ts | 18 ++ apps/backend/src/app/auth/auth.service.ts | 17 ++ .../app/users/user-registry.service.spec.ts | 18 ++ .../src/app/users/user-registry.service.ts | 18 ++ .../src/controllers/auth/auth.controller.ts | 12 - .../src/database/database.service.spec.ts | 18 ++ apps/backend/src/database/database.service.ts | 33 +++ apps/backend/src/database/db.d.ts | 29 +++ apps/backend/src/database/kysely-config.ts | 22 -- apps/backend/src/env/env.service.spec.ts | 18 ++ apps/backend/src/env/env.service.ts | 27 +++ .../bruno-rest-api/LocalAPI/asdf.bru | 15 ++ package.json | 2 +- .../src/api-services/auth/auth-api-service.ts | 10 - .../common/src/api-services/auth/index.ts | 1 - packages/common/src/api-services/index.ts | 1 - packages/common/src/index.ts | 2 +- packages/common/src/utils/common.ts | 3 + packages/common/src/utils/index.ts | 1 + pnpm-lock.yaml | 207 ++++++++++++++++++ pnpm-workspace.yaml | 7 +- 29 files changed, 455 insertions(+), 98 deletions(-) delete mode 100644 apps/backend/src/app.controller.spec.ts delete mode 100644 apps/backend/src/app.controller.ts delete mode 100644 apps/backend/src/app.service.ts rename apps/backend/src/{controllers => app}/auth/auth.controller.spec.ts (100%) create mode 100644 apps/backend/src/app/auth/auth.controller.ts create mode 100644 apps/backend/src/app/auth/auth.service.spec.ts create mode 100644 apps/backend/src/app/auth/auth.service.ts create mode 100644 apps/backend/src/app/users/user-registry.service.spec.ts create mode 100644 apps/backend/src/app/users/user-registry.service.ts delete mode 100644 apps/backend/src/controllers/auth/auth.controller.ts create mode 100644 apps/backend/src/database/database.service.spec.ts create mode 100644 apps/backend/src/database/database.service.ts create mode 100644 apps/backend/src/database/db.d.ts delete mode 100644 apps/backend/src/database/kysely-config.ts create mode 100644 apps/backend/src/env/env.service.spec.ts create mode 100644 apps/backend/src/env/env.service.ts create mode 100644 documentation/bruno-rest-api/LocalAPI/asdf.bru delete mode 100644 packages/common/src/api-services/auth/auth-api-service.ts delete mode 100644 packages/common/src/api-services/auth/index.ts delete mode 100644 packages/common/src/api-services/index.ts create mode 100644 packages/common/src/utils/common.ts create mode 100644 packages/common/src/utils/index.ts diff --git a/apps/backend/.gitignore b/apps/backend/.gitignore index 4b56acf..b6e8eef 100644 --- a/apps/backend/.gitignore +++ b/apps/backend/.gitignore @@ -54,3 +54,4 @@ pids # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + diff --git a/apps/backend/package.json b/apps/backend/package.json index c673a2d..b31c411 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -18,13 +18,15 @@ "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json", - "migrate:latest": "ts-node src/migrate.ts" + "migrate:latest": "ts-node src/migrate.ts", + "kysely:codegen": "kysely-codegen --out-file ./src/database/db.d.ts" }, "dependencies": { "@my-monorepo/common": "workspace:*", "@nestjs/common": "^11.0.1", "@nestjs/core": "^11.0.1", "@nestjs/platform-express": "^11.0.1", + "dotenv": "^17.2.1", "kysely": "^0.28.3", "pg": "^8.16.3", "reflect-metadata": "^0.2.2", @@ -49,6 +51,7 @@ "eslint-plugin-prettier": "^5.2.2", "globals": "^16.0.0", "jest": "^29.7.0", + "kysely-codegen": "^0.18.5", "prettier": "^3.4.2", "source-map-support": "^0.5.21", "supertest": "^7.0.0", diff --git a/apps/backend/src/app.controller.spec.ts b/apps/backend/src/app.controller.spec.ts deleted file mode 100644 index d22f389..0000000 --- a/apps/backend/src/app.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; - -describe('AppController', () => { - let appController: AppController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [AppController], - providers: [AppService], - }).compile(); - - appController = app.get(AppController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(appController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/apps/backend/src/app.controller.ts b/apps/backend/src/app.controller.ts deleted file mode 100644 index 70a8b55..0000000 --- a/apps/backend/src/app.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { AppService } from './app.service'; - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get('hello') - getHello(): string { - return this.appService.getHello(); - } -} diff --git a/apps/backend/src/app.module.ts b/apps/backend/src/app.module.ts index 81a90d3..5aa3c94 100644 --- a/apps/backend/src/app.module.ts +++ b/apps/backend/src/app.module.ts @@ -1,11 +1,13 @@ import { Module } from '@nestjs/common'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; -import { AuthController } from './controllers/auth/auth.controller'; +import { AuthController } from './app/auth/auth.controller'; +import { DatabaseService } from './database/database.service'; +import { AuthService } from './app/auth/auth.service'; +import { UserRegistryService } from './app/users/user-registry.service'; +import { EnvService } from './env/env.service'; @Module({ imports: [], - controllers: [AppController, AuthController], - providers: [AppService], + controllers: [AuthController], + providers: [DatabaseService, AuthService, UserRegistryService, EnvService], }) export class AppModule {} diff --git a/apps/backend/src/app.service.ts b/apps/backend/src/app.service.ts deleted file mode 100644 index 927d7cc..0000000 --- a/apps/backend/src/app.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class AppService { - getHello(): string { - return 'Hello World!'; - } -} diff --git a/apps/backend/src/controllers/auth/auth.controller.spec.ts b/apps/backend/src/app/auth/auth.controller.spec.ts similarity index 100% rename from apps/backend/src/controllers/auth/auth.controller.spec.ts rename to apps/backend/src/app/auth/auth.controller.spec.ts diff --git a/apps/backend/src/app/auth/auth.controller.ts b/apps/backend/src/app/auth/auth.controller.ts new file mode 100644 index 0000000..6cae994 --- /dev/null +++ b/apps/backend/src/app/auth/auth.controller.ts @@ -0,0 +1,14 @@ +import { Controller, Post } from '@nestjs/common'; +import { AuthService } from './auth.service'; + +@Controller('auth') +export class AuthController { + constructor(private authService: AuthService) {} + + // eslint-disable-next-line @typescript-eslint/no-misused-promises + @Post('credentials') + // eslint-disable-next-line @typescript-eslint/require-await + async postCredentials() { + return this.authService.verifyCredentials(); + } +} diff --git a/apps/backend/src/app/auth/auth.service.spec.ts b/apps/backend/src/app/auth/auth.service.spec.ts new file mode 100644 index 0000000..800ab66 --- /dev/null +++ b/apps/backend/src/app/auth/auth.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AuthService } from './auth.service'; + +describe('AuthService', () => { + let service: AuthService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AuthService], + }).compile(); + + service = module.get(AuthService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/backend/src/app/auth/auth.service.ts b/apps/backend/src/app/auth/auth.service.ts new file mode 100644 index 0000000..21e5365 --- /dev/null +++ b/apps/backend/src/app/auth/auth.service.ts @@ -0,0 +1,17 @@ +import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { UserRegistryService } from '../users/user-registry.service'; + +@Injectable() +export class AuthService { + constructor(private userRegistry: UserRegistryService) {} + + async verifyCredentials() { + const isValidCredential = await this.userRegistry.existsEmailPassword( + '', + '', + ); + if (!isValidCredential) { + throw new UnauthorizedException('invalid credentials'); + } + } +} diff --git a/apps/backend/src/app/users/user-registry.service.spec.ts b/apps/backend/src/app/users/user-registry.service.spec.ts new file mode 100644 index 0000000..d18db6e --- /dev/null +++ b/apps/backend/src/app/users/user-registry.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { UserRegistryService } from './user-registry.service'; + +describe('UserRegistryService', () => { + let service: UserRegistryService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [UserRegistryService], + }).compile(); + + service = module.get(UserRegistryService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/backend/src/app/users/user-registry.service.ts b/apps/backend/src/app/users/user-registry.service.ts new file mode 100644 index 0000000..88aa160 --- /dev/null +++ b/apps/backend/src/app/users/user-registry.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common'; +import { DatabaseService } from '../../database/database.service'; +import { isDefined } from '@my-monorepo/common'; + +@Injectable() +export class UserRegistryService { + constructor(private databaseService: DatabaseService) {} + + async existsEmailPassword(email: string, hashedPassword: string) { + const id = await this.databaseService.database + .selectFrom('users') + .select('id') + .where((eb) => eb('email', '=', email).and('hash', '=', hashedPassword)) + .executeTakeFirst(); + + return isDefined(id); + } +} diff --git a/apps/backend/src/controllers/auth/auth.controller.ts b/apps/backend/src/controllers/auth/auth.controller.ts deleted file mode 100644 index 6e0461b..0000000 --- a/apps/backend/src/controllers/auth/auth.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { AuthApiService } from '@my-monorepo/common'; -import { Controller, Post } from '@nestjs/common'; - -@Controller(AuthApiService.baseUrl) -export class AuthController implements AuthApiService { - // eslint-disable-next-line @typescript-eslint/no-misused-promises - @Post(AuthApiService.postCredentials) - // eslint-disable-next-line @typescript-eslint/require-await - async postCredentials() { - return 'hello'; - } -} diff --git a/apps/backend/src/database/database.service.spec.ts b/apps/backend/src/database/database.service.spec.ts new file mode 100644 index 0000000..b806f31 --- /dev/null +++ b/apps/backend/src/database/database.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { DatabaseService } from './database.service'; + +describe('DatabaseService', () => { + let service: DatabaseService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [DatabaseService], + }).compile(); + + service = module.get(DatabaseService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/backend/src/database/database.service.ts b/apps/backend/src/database/database.service.ts new file mode 100644 index 0000000..ec6b38c --- /dev/null +++ b/apps/backend/src/database/database.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@nestjs/common'; + +import { Pool } from 'pg'; +import { Kysely, PostgresDialect } from 'kysely'; +import { DB } from './db'; +import { EnvService } from '../env/env.service'; + +@Injectable() +export class DatabaseService { + database: Kysely; + + constructor(envService: EnvService) { + const config = envService.config; + const dialect = new PostgresDialect({ + pool: new Pool({ + database: config.DATABASE, + host: config.DATABASE_HOST, + user: config.DATABASE_USER, + password: config.DATABASE_PASSWORD, + port: config.DATABASE_PORT, + max: 10, + }), + }); + + // Database interface is passed to Kysely's constructor, and from now on, Kysely + // knows your database structure. + // Dialect is passed to Kysely's constructor, and from now on, Kysely knows how + // to communicate with your database. + this.database = new Kysely({ + dialect, + }); + } +} diff --git a/apps/backend/src/database/db.d.ts b/apps/backend/src/database/db.d.ts new file mode 100644 index 0000000..8693c2e --- /dev/null +++ b/apps/backend/src/database/db.d.ts @@ -0,0 +1,29 @@ +/** + * This file was generated by kysely-codegen. + * Please do not edit it manually. + */ + +import type { ColumnType } from "kysely"; + +export type Generated = T extends ColumnType + ? ColumnType + : ColumnType; + +export type Int8 = ColumnType; + +export type Timestamp = ColumnType; + +export interface Users { + created_at: Generated; + deleted_at: Timestamp | null; + email: string; + first_name: string; + hash: string | null; + id: Generated; + last_name: string; + updated_at: Generated; +} + +export interface DB { + users: Users; +} diff --git a/apps/backend/src/database/kysely-config.ts b/apps/backend/src/database/kysely-config.ts deleted file mode 100644 index 886bf48..0000000 --- a/apps/backend/src/database/kysely-config.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Pool } from 'pg'; -import { Kysely, PostgresDialect } from 'kysely'; - -const dialect = new PostgresDialect({ - // TODO : temporary data, make to .env - pool: new Pool({ - database: 'cowsi', - host: 'localhost', - user: 'postgres', - password: 'postgres', - port: 5432, - max: 10, - }), -}); - -// Database interface is passed to Kysely's constructor, and from now on, Kysely -// knows your database structure. -// Dialect is passed to Kysely's constructor, and from now on, Kysely knows how -// to communicate with your database. -export const db = new Kysely({ - dialect, -}); diff --git a/apps/backend/src/env/env.service.spec.ts b/apps/backend/src/env/env.service.spec.ts new file mode 100644 index 0000000..73aab30 --- /dev/null +++ b/apps/backend/src/env/env.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { EnvService } from './env.service'; + +describe('EnvService', () => { + let service: EnvService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [EnvService], + }).compile(); + + service = module.get(EnvService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/backend/src/env/env.service.ts b/apps/backend/src/env/env.service.ts new file mode 100644 index 0000000..4b09fd0 --- /dev/null +++ b/apps/backend/src/env/env.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@nestjs/common'; +import z from 'zod'; +import * as dotenv from 'dotenv'; + +const envParser = z.object({ + DATABASE: z.string(), + DATABASE_USER: z.string(), + DATABASE_PASSWORD: z.string(), + DATABASE_HOST: z.string(), + DATABASE_PORT: z.coerce.number(), +}); + +export type EnvConfig = Readonly>; + +@Injectable() +export class EnvService { + readonly config: EnvConfig; + + constructor() { + console.log('paul-debug', dotenv); + const res = dotenv.config(); + if (res.error) { + throw res.error; + } + this.config = envParser.parse(res.parsed); + } +} diff --git a/documentation/bruno-rest-api/LocalAPI/asdf.bru b/documentation/bruno-rest-api/LocalAPI/asdf.bru new file mode 100644 index 0000000..24d76b6 --- /dev/null +++ b/documentation/bruno-rest-api/LocalAPI/asdf.bru @@ -0,0 +1,15 @@ +meta { + name: asdf + type: http + seq: 3 +} + +get { + url: localhost:5047 + body: none + auth: inherit +} + +settings { + encodeUrl: true +} diff --git a/package.json b/package.json index 391887a..097ef72 100644 --- a/package.json +++ b/package.json @@ -10,5 +10,5 @@ "keywords": [], "author": "", "license": "ISC", - "packageManager": "pnpm@10.13.1" + "packageManager": "pnpm@10.14.0" } diff --git a/packages/common/src/api-services/auth/auth-api-service.ts b/packages/common/src/api-services/auth/auth-api-service.ts deleted file mode 100644 index 0e54765..0000000 --- a/packages/common/src/api-services/auth/auth-api-service.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface AuthApiService { - postCredentials(): Promise; -} - -export const AuthApiService: Record & { - baseUrl: string; -} = { - baseUrl: "auth", - postCredentials: "credentials", -}; diff --git a/packages/common/src/api-services/auth/index.ts b/packages/common/src/api-services/auth/index.ts deleted file mode 100644 index 107910a..0000000 --- a/packages/common/src/api-services/auth/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./auth-api-service"; diff --git a/packages/common/src/api-services/index.ts b/packages/common/src/api-services/index.ts deleted file mode 100644 index 97ccf76..0000000 --- a/packages/common/src/api-services/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./auth"; diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index ec3cb0f..aa7832e 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -1,2 +1,2 @@ -export * from "./api-services"; export * from "./models"; +export * from "./utils"; diff --git a/packages/common/src/utils/common.ts b/packages/common/src/utils/common.ts new file mode 100644 index 0000000..c715936 --- /dev/null +++ b/packages/common/src/utils/common.ts @@ -0,0 +1,3 @@ +export function isDefined(obj: T): obj is NonNullable { + return obj !== undefined && obj !== null; +} diff --git a/packages/common/src/utils/index.ts b/packages/common/src/utils/index.ts new file mode 100644 index 0000000..6b57160 --- /dev/null +++ b/packages/common/src/utils/index.ts @@ -0,0 +1 @@ +export * from "./common"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c625af3..096ac2c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,9 @@ importers: '@nestjs/platform-express': specifier: ^11.0.1 version: 11.1.3(@nestjs/common@11.1.3(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3) + dotenv: + specifier: ^17.2.1 + version: 17.2.1 kysely: specifier: ^0.28.3 version: 0.28.3 @@ -89,6 +92,9 @@ importers: jest: specifier: ^29.7.0 version: 29.7.0(@types/node@22.16.3)(ts-node@10.9.2(@swc/core@1.12.11)(@types/node@22.16.3)(typescript@5.7.3)) + kysely-codegen: + specifier: ^0.18.5 + version: 0.18.5(kysely@0.28.3)(pg@8.16.3)(typescript@5.7.3) prettier: specifier: ^3.4.2 version: 3.6.2 @@ -1274,6 +1280,10 @@ packages: resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -1443,6 +1453,10 @@ packages: caniuse-lite@1.0.30001727: resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -1500,10 +1514,16 @@ packages: collect-v8-coverage@1.0.2: resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} @@ -1586,6 +1606,15 @@ packages: typescript: optional: true + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + create-jest@29.7.0: resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1656,10 +1685,26 @@ packages: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + diff@3.5.0: + resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} + engines: {node: '>=0.3.1'} + diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + dotenv-expand@12.0.2: + resolution: {integrity: sha512-lXpXz2ZE1cea1gL4sz2Ipj8y4PiVjytYr3Ij0SWoms1PGxIv7m2CRKuRuCRtHdVuvM/hNJPMxt5PbhboNC4dPQ==} + engines: {node: '>=12'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dotenv@17.2.1: + resolution: {integrity: sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==} + engines: {node: '>=12'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -1696,6 +1741,10 @@ packages: resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} engines: {node: '>=10.13.0'} + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -1725,6 +1774,10 @@ packages: escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} @@ -2005,6 +2058,10 @@ packages: resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} engines: {node: '>=18'} + git-diff@2.0.6: + resolution: {integrity: sha512-/Iu4prUrydE3Pb3lCBMbcSNIf81tgGt0W1ZwknnyF62t3tHmtiJTRj0f+1ZIhp3+Rh0ktz1pJVoa7ZXUCskivA==} + engines: {node: '>= 4.8.0'} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2047,6 +2104,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -2127,6 +2188,10 @@ packages: inspect-with-kind@1.0.5: resolution: {integrity: sha512-MAQUJuIo7Xqk8EVNP+6d3CKq9c80hi4tjIbIAT6lmGW9W6WzlHiu9PS8uSuUYU+Do+j1baiFp3H25XEVxDIG2g==} + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -2411,6 +2476,41 @@ packages: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} + kysely-codegen@0.18.5: + resolution: {integrity: sha512-bj6DMsXcKo0PrrXUk/fdjFgNC6Pwq+HPBCqhNGuD57gwUJZdci2s2OqhNneQeYpAIWGot7/481WdzTyXrClY2Q==} + engines: {node: '>=20.0.0'} + hasBin: true + peerDependencies: + '@libsql/kysely-libsql': '>=0.3.0 <0.5.0' + '@tediousjs/connection-string': '>=0.5.0 <0.6.0' + better-sqlite3: '>=7.6.2 <8.0.0' + kysely: '>=0.27.0 <1.0.0' + kysely-bun-sqlite: '>=0.3.2 <1.0.0' + kysely-bun-worker: '>=1.2.0 <2.0.0' + mysql2: '>=2.3.3 <4.0.0' + pg: '>=8.8.0 <9.0.0' + tarn: '>=3.0.0 <4.0.0' + tedious: '>=18.0.0 <20.0.0' + peerDependenciesMeta: + '@libsql/kysely-libsql': + optional: true + '@tediousjs/connection-string': + optional: true + better-sqlite3: + optional: true + kysely-bun-sqlite: + optional: true + kysely-bun-worker: + optional: true + mysql2: + optional: true + pg: + optional: true + tarn: + optional: true + tedious: + optional: true + kysely@0.28.3: resolution: {integrity: sha512-svKnkSH72APRdjfVCCOknxaC9Eb3nA2StHG9d5/sKOqRvHRp2Dtf1XwDvc92b4B5v6LV+EAGWXQbZ5jMOvHaDw==} engines: {node: '>=20.0.0'} @@ -2455,6 +2555,10 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} + engines: {node: '>= 0.6.0'} + lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2863,6 +2967,10 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} @@ -2989,6 +3097,15 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shelljs.exec@1.1.8: + resolution: {integrity: sha512-vFILCw+lzUtiwBAHV8/Ex8JsFjelFMdhONIsgKNLgTzeRckp2AOYRQtHJE/9LhNvdMmE27AGtzWx0+DHpwIwSw==} + engines: {node: '>= 4.0.0'} + + shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -3125,6 +3242,10 @@ packages: resolution: {integrity: sha512-ORY0gPa6ojmg/C74P/bDoS21WL6FMXq5I8mawkEz30/zkwdu0gOeqstFy316vHG6OKxqQ+IbGneRemHI8WraEw==} engines: {node: '>=14.18.0'} + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -4959,6 +5080,10 @@ snapshots: ansi-regex@6.1.0: {} + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -5203,6 +5328,12 @@ snapshots: caniuse-lite@1.0.30001727: {} + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -5248,10 +5379,16 @@ snapshots: collect-v8-coverage@1.0.2: {} + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + color-convert@2.0.1: dependencies: color-name: 1.1.4 + color-name@1.1.3: {} + color-name@1.1.4: {} combined-stream@1.0.8: @@ -5321,6 +5458,15 @@ snapshots: optionalDependencies: typescript: 5.8.3 + cosmiconfig@9.0.0(typescript@5.7.3): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.7.3 + create-jest@29.7.0(@types/node@22.16.3)(ts-node@10.9.2(@swc/core@1.12.11)(@types/node@22.16.3)(typescript@5.7.3)): dependencies: '@jest/types': 29.6.3 @@ -5379,8 +5525,18 @@ snapshots: diff-sequences@29.6.3: {} + diff@3.5.0: {} + diff@4.0.2: {} + dotenv-expand@12.0.2: + dependencies: + dotenv: 16.6.1 + + dotenv@16.6.1: {} + + dotenv@17.2.1: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -5410,6 +5566,8 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.2 + env-paths@2.2.1: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -5435,6 +5593,8 @@ snapshots: escape-html@1.0.3: {} + escape-string-regexp@1.0.5: {} + escape-string-regexp@2.0.0: {} escape-string-regexp@4.0.0: {} @@ -5790,6 +5950,14 @@ snapshots: '@sec-ant/readable-stream': 0.4.1 is-stream: 4.0.1 + git-diff@2.0.6: + dependencies: + chalk: 2.4.2 + diff: 3.5.0 + loglevel: 1.9.2 + shelljs: 0.8.5 + shelljs.exec: 1.1.8 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -5842,6 +6010,8 @@ snapshots: graphemer@1.4.0: {} + has-flag@3.0.0: {} + has-flag@4.0.0: {} has-own-prop@2.0.0: {} @@ -5912,6 +6082,8 @@ snapshots: dependencies: kind-of: 6.0.3 + interpret@1.4.0: {} + ipaddr.js@1.9.1: {} is-arrayish@0.2.1: {} @@ -6359,6 +6531,23 @@ snapshots: kleur@3.0.3: {} + kysely-codegen@0.18.5(kysely@0.28.3)(pg@8.16.3)(typescript@5.7.3): + dependencies: + chalk: 4.1.2 + cosmiconfig: 9.0.0(typescript@5.7.3) + dotenv: 16.6.1 + dotenv-expand: 12.0.2 + git-diff: 2.0.6 + kysely: 0.28.3 + micromatch: 4.0.8 + minimist: 1.2.8 + pluralize: 8.0.0 + zod: 3.25.76 + optionalDependencies: + pg: 8.16.3 + transitivePeerDependencies: + - typescript + kysely@0.28.3: {} leven@3.1.0: {} @@ -6393,6 +6582,8 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + loglevel@1.9.2: {} + lowercase-keys@3.0.0: {} lru-cache@11.1.0: {} @@ -6737,6 +6928,10 @@ snapshots: readdirp@4.1.2: {} + rechoir@0.6.2: + dependencies: + resolve: 1.22.10 + reflect-metadata@0.2.2: {} repeat-string@1.6.1: {} @@ -6866,6 +7061,14 @@ snapshots: shebang-regex@3.0.0: {} + shelljs.exec@1.1.8: {} + + shelljs@0.8.5: + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -7017,6 +7220,10 @@ snapshots: transitivePeerDependencies: - supports-color + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3ff5faa..2556687 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,6 @@ packages: - - "apps/*" - - "packages/*" + - apps/* + - packages/* + +ignoredBuiltDependencies: + - '@nestjs/core'