From a2a8e5a161aeccbe88be03ba0379b70506faa6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giosu=C3=A8=20Delgado?= <11545723+giosueDelgado@users.noreply.github.com> Date: Mon, 22 Apr 2024 21:25:56 +0200 Subject: [PATCH] feat: add @nestjs-cls/transactional-adapter-typeorm (#141) * feat(transactional-adapter-typeorm): :sparkles: add new transactional-adapter-typeorm --- .vscode/settings.json | 2 +- .../01-transactional/05-typeorm-adapter.md | 50 +++ .../transactional-adapter-typeorm/CHANGES.md | 1 + .../transactional-adapter-typeorm/README.md | 5 + .../jest.config.js | 17 + .../package.json | 67 ++++ .../src/index.ts | 1 + .../src/lib/transactional-adapter-typeorm.ts | 35 ++ .../src/lib/transactional-options.ts | 12 + .../test/docker-compose.yml | 14 + .../transactional-adapter-typeorm.spec.ts | 209 ++++++++++++ .../tsconfig.json | 8 + yarn.lock | 314 +++++++++++++++++- 13 files changed, 729 insertions(+), 6 deletions(-) create mode 100644 docs/docs/06_plugins/01_available-plugins/01-transactional/05-typeorm-adapter.md create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/CHANGES.md create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/README.md create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/jest.config.js create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/package.json create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/src/index.ts create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/src/lib/transactional-adapter-typeorm.ts create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/src/lib/transactional-options.ts create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/test/docker-compose.yml create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/test/transactional-adapter-typeorm.spec.ts create mode 100644 packages/transactional-adapters/transactional-adapter-typeorm/tsconfig.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 3d2cbf7e..62120f87 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,4 +2,4 @@ "editor.formatOnSave": true, "typescript.preferences.importModuleSpecifier": "relative", "typescript.tsdk": "node_modules/typescript/lib" -} +} \ No newline at end of file diff --git a/docs/docs/06_plugins/01_available-plugins/01-transactional/05-typeorm-adapter.md b/docs/docs/06_plugins/01_available-plugins/01-transactional/05-typeorm-adapter.md new file mode 100644 index 00000000..9c633f97 --- /dev/null +++ b/docs/docs/06_plugins/01_available-plugins/01-transactional/05-typeorm-adapter.md @@ -0,0 +1,50 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# TypeOrm adapter + +## Installation + + + + +```bash +npm install @nestjs-cls/transactional-adapter-typeorm +``` + + + + +```bash +yarn add @nestjs-cls/transactional-adapter-typeorm +``` + + + + +```bash +pnpm add @nestjs-cls/transactional-adapter-typeorm +``` + + + + +## Registration + +```ts + +ClsModule.forRoot({ + plugins: [ + new ClsPluginTransactional({ + imports: [ + // module in which the database instance is provided + TypeOrmModule + ], + adapter: new TransactionalAdapterTypeOrm({ + // the injection token of the database instance + dataSourceToken: DataSource, + }), + }), + ], +}), +``` diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/CHANGES.md b/packages/transactional-adapters/transactional-adapter-typeorm/CHANGES.md new file mode 100644 index 00000000..825c32f0 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/CHANGES.md @@ -0,0 +1 @@ +# Changelog diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/README.md b/packages/transactional-adapters/transactional-adapter-typeorm/README.md new file mode 100644 index 00000000..83e7131b --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/README.md @@ -0,0 +1,5 @@ +# @nestjs-cls/transactional-adapter-typeorm + +`typeorm` adapter for the `@nestjs-cls/transactional` plugin. + +### ➡️ [Go to the documentation website](https://papooch.github.io/nestjs-cls/plugins/available-plugins/transactional) 📖 diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/jest.config.js b/packages/transactional-adapters/transactional-adapter-typeorm/jest.config.js new file mode 100644 index 00000000..14ae88e3 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/jest.config.js @@ -0,0 +1,17 @@ +module.exports = { + moduleFileExtensions: ['js', 'json', 'ts'], + rootDir: '.', + testRegex: '.*\\.spec\\.ts$', + transform: { + '^.+\\.ts$': [ + 'ts-jest', + { + isolatedModules: true, + maxWorkers: 1, + }, + ], + }, + collectCoverageFrom: ['src/**/*.ts'], + coverageDirectory: '../coverage', + testEnvironment: 'node', +}; diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/package.json b/packages/transactional-adapters/transactional-adapter-typeorm/package.json new file mode 100644 index 00000000..e74a5d0f --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/package.json @@ -0,0 +1,67 @@ +{ + "name": "@nestjs-cls/transactional-adapter-typeorm", + "version": "1.2.0", + "description": "A typeorm adapter for @nestjs-cls/transactional", + "author": "Giosuè Delgado S.Z. - Relybytes Srl ", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Papooch/nestjs-cls.git" + }, + "homepage": "https://papooch.github.io/nestjs-cls/", + "keywords": [ + "nest", + "nestjs", + "cls", + "continuation-local-storage", + "als", + "AsyncLocalStorage", + "async_hooks", + "request context", + "async context", + "typeorm" + ], + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "files": [ + "dist/src/**/!(*.spec).d.ts", + "dist/src/**/!(*.spec).js" + ], + "scripts": { + "prepack": "cp ../../../LICENSE ./LICENSE", + "prebuild": "rimraf dist", + "build": "tsc", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage" + }, + "peerDependencies": { + "@nestjs-cls/transactional": "workspace:^2.2.2", + "nestjs-cls": "workspace:^4.3.0", + "typeorm": "0.3.20" + }, + "devDependencies": { + "@nestjs/cli": "^10.0.2", + "@nestjs/common": "^10.3.7", + "@nestjs/core": "^10.3.7", + "@nestjs/testing": "^10.3.7", + "@types/jest": "^28.1.2", + "@types/node": "^18.0.0", + "jest": "^29.7.0", + "reflect-metadata": "^0.1.13", + "rimraf": "^3.0.2", + "rxjs": "^7.5.5", + "ts-jest": "^29.1.2", + "ts-loader": "^9.3.0", + "ts-node": "^10.8.1", + "tsconfig-paths": "^4.0.0", + "typeorm": "0.3.20", + "typescript": "5.0" + } +} \ No newline at end of file diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/src/index.ts b/packages/transactional-adapters/transactional-adapter-typeorm/src/index.ts new file mode 100644 index 00000000..9682f717 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/src/index.ts @@ -0,0 +1 @@ +export * from './lib/transactional-adapter-typeorm'; diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/src/lib/transactional-adapter-typeorm.ts b/packages/transactional-adapters/transactional-adapter-typeorm/src/lib/transactional-adapter-typeorm.ts new file mode 100644 index 00000000..01a4901f --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/src/lib/transactional-adapter-typeorm.ts @@ -0,0 +1,35 @@ +import { DataSource, EntityManager } from 'typeorm'; +import { + TypeOrmTransactionOptions, + TypeOrmTransactionalAdapterOptions, +} from './transactional-options'; +import { TransactionalAdapter } from '@nestjs-cls/transactional'; + +export class TransactionalAdapterTypeOrm + implements + TransactionalAdapter< + DataSource, + EntityManager, + TypeOrmTransactionOptions + > +{ + connectionToken: any; + + constructor(options: TypeOrmTransactionalAdapterOptions) { + this.connectionToken = options.dataSourceToken; + } + + optionsFactory = (dataSource: DataSource) => ({ + wrapWithTransaction: async ( + options: TypeOrmTransactionOptions, + fn: (...args: any[]) => Promise, + setClient: (client?: EntityManager) => void, + ) => { + return dataSource.transaction(options?.isolationLevel, (trx) => { + setClient(trx); + return fn(); + }); + }, + getFallbackInstance: () => dataSource.manager, + }); +} diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/src/lib/transactional-options.ts b/packages/transactional-adapters/transactional-adapter-typeorm/src/lib/transactional-options.ts new file mode 100644 index 00000000..db62b871 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/src/lib/transactional-options.ts @@ -0,0 +1,12 @@ +import { IsolationLevel } from 'typeorm/driver/types/IsolationLevel'; + +export interface TypeOrmTransactionalAdapterOptions { + /** + * The injection token for the typeOrm instance. + */ + dataSourceToken: any; +} + +export interface TypeOrmTransactionOptions { + isolationLevel: IsolationLevel; +} diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/test/docker-compose.yml b/packages/transactional-adapters/transactional-adapter-typeorm/test/docker-compose.yml new file mode 100644 index 00000000..c4cacdd9 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/test/docker-compose.yml @@ -0,0 +1,14 @@ +services: + db: + image: postgres:15 + ports: + - 5444:5432 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U postgres'] + interval: 1s + timeout: 1s + retries: 5 diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/test/transactional-adapter-typeorm.spec.ts b/packages/transactional-adapters/transactional-adapter-typeorm/test/transactional-adapter-typeorm.spec.ts new file mode 100644 index 00000000..653b1956 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/test/transactional-adapter-typeorm.spec.ts @@ -0,0 +1,209 @@ +import { + ClsPluginTransactional, + Transactional, + TransactionHost, +} from '@nestjs-cls/transactional'; +import { Injectable, Module } from '@nestjs/common'; +import { Test, TestingModule } from '@nestjs/testing'; +import { ClsModule } from 'nestjs-cls'; +import { execSync } from 'node:child_process'; +import { DataSource, Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; +import { TransactionalAdapterTypeOrm } from '../src'; + +@Entity() +class User { + @PrimaryGeneratedColumn() + id!: number; + + @Column() + name?: string; + + @Column() + email?: string; +} + +const dataSource = new DataSource({ + type: 'postgres', + host: 'localhost', + port: 5444, + username: 'postgres', + password: 'postgres', + database: 'postgres', + entities: [User], + synchronize: true, +}); + +@Injectable() +class UserRepository { + constructor( + private readonly transactionHost: TransactionHost, + ) {} + + async getUserById(id: number) { + return await this.transactionHost.tx + .getRepository(User) + .findOneBy({ id }); + } + + async createUser(name: string) { + return await this.transactionHost.tx.getRepository(User).save({ + name, + email: `${name}@email.com`, + }); + } +} + +@Injectable() +class UserService { + constructor( + private readonly userRepository: UserRepository, + private readonly transactionHost: TransactionHost, + + private datasource: DataSource, + ) {} + + @Transactional() + async transactionWithDecorator() { + const r1 = await this.userRepository.createUser('John'); + const r2 = await this.userRepository.getUserById(r1.id); + return { r1, r2 }; + } + + @Transactional({ + isolationLevel: 'SERIALIZABLE', + }) + async transactionWithDecoratorWithOptions() { + const r1 = await this.userRepository.createUser('James'); + const r2 = await this.datasource + .getRepository(User) + .createQueryBuilder('user') + .where('user.id = :id', { id: r1.id }) + .getOne(); + const r3 = await this.userRepository.getUserById(r1.id); + return { r1, r2, r3 }; + } + + async transactionWithFunctionWrapper() { + return this.transactionHost.withTransaction( + { isolationLevel: 'SERIALIZABLE' }, + async () => { + const r1 = await this.userRepository.createUser('Joe'); + const r2 = await this.datasource + .getRepository(User) + .createQueryBuilder('user') + .where('user.id = :id', { id: r1.id }) + .getOne(); + const r3 = await this.userRepository.getUserById(r1.id); + return { r1, r2, r3 }; + }, + ); + } + + @Transactional() + async transactionWithDecoratorError() { + await this.userRepository.createUser('Nobody'); + throw new Error('Rollback'); + } +} + +@Module({ + providers: [ + { + provide: DataSource, + useValue: dataSource, + }, + UserRepository, + UserService, + ], + exports: [DataSource], +}) +class TypeOrmModule {} + +@Module({ + imports: [ + TypeOrmModule, + ClsModule.forRoot({ + plugins: [ + new ClsPluginTransactional({ + imports: [TypeOrmModule], + adapter: new TransactionalAdapterTypeOrm({ + dataSourceToken: DataSource, + }), + }), + ], + }), + ], + providers: [UserRepository, UserService], +}) +class AppModule {} + +describe('Transactional', () => { + let module: TestingModule; + let callingService: UserService; + + beforeAll(async () => { + execSync( + 'docker compose -f test/docker-compose.yml up -d --quiet-pull --wait', + { + stdio: 'inherit', + cwd: process.cwd(), + }, + ); + await dataSource.initialize(); + + await dataSource.query('DROP TABLE IF EXISTS "User"'); + await dataSource.synchronize(); + }, 60_000); + + beforeEach(async () => { + module = await Test.createTestingModule({ + imports: [AppModule], + }).compile(); + await module.init(); + callingService = module.get(UserService); + }); + + afterAll(async () => { + await dataSource.destroy(); + execSync('docker compose -f test/docker-compose.yml down', { + stdio: 'inherit', + }); + }, 60_000); + + describe('TransactionalAdapterTypeOrmPromise', () => { + it('should run a transaction with the default options with a decorator', async () => { + const { r1, r2 } = await callingService.transactionWithDecorator(); + expect(r1).toEqual(r2); + const users = await dataSource.manager.find(User); + expect(users).toEqual(expect.arrayContaining([r1])); + }); + + it('should run a transaction with the specified options with a decorator', async () => { + const { r1, r2, r3 } = + await callingService.transactionWithDecoratorWithOptions(); + expect(r1).toEqual(r3); + expect(r2).toBeNull(); + const users = await dataSource.manager.find(User); + expect(users).toEqual(expect.arrayContaining([r1])); + }); + + it('should run a transaction with the specified options with a function wrapper', async () => { + const { r1, r2, r3 } = + await callingService.transactionWithFunctionWrapper(); + expect(r1).toEqual(r3); + expect(r2).toBeNull(); + const users = await dataSource.manager.find(User); + expect(users).toEqual(expect.arrayContaining([r1])); + }); + + it('should rollback a transaction on error', async () => { + await expect( + callingService.transactionWithDecoratorError(), + ).rejects.toThrow(new Error('Rollback')); + const users = await dataSource.manager.find(User); + expect(users).toEqual( + expect.not.arrayContaining([{ name: 'Nobody' }]), + ); + }); + }); +}); diff --git a/packages/transactional-adapters/transactional-adapter-typeorm/tsconfig.json b/packages/transactional-adapters/transactional-adapter-typeorm/tsconfig.json new file mode 100644 index 00000000..bbc28fb3 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-typeorm/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "." + }, + "include": ["src/**/*.ts", "test/**/*.ts"] +} diff --git a/yarn.lock b/yarn.lock index 863c8f6c..3ccfc363 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4991,6 +4991,33 @@ __metadata: languageName: unknown linkType: soft +"@nestjs-cls/transactional-adapter-typeorm@workspace:packages/transactional-adapters/transactional-adapter-typeorm": + version: 0.0.0-use.local + resolution: "@nestjs-cls/transactional-adapter-typeorm@workspace:packages/transactional-adapters/transactional-adapter-typeorm" + dependencies: + "@nestjs/cli": "npm:^10.0.2" + "@nestjs/common": "npm:^10.3.7" + "@nestjs/core": "npm:^10.3.7" + "@nestjs/testing": "npm:^10.3.7" + "@types/jest": "npm:^28.1.2" + "@types/node": "npm:^18.0.0" + jest: "npm:^29.7.0" + reflect-metadata: "npm:^0.1.13" + rimraf: "npm:^3.0.2" + rxjs: "npm:^7.5.5" + ts-jest: "npm:^29.1.2" + ts-loader: "npm:^9.3.0" + ts-node: "npm:^10.8.1" + tsconfig-paths: "npm:^4.0.0" + typeorm: "npm:0.3.20" + typescript: "npm:5.0" + peerDependencies: + "@nestjs-cls/transactional": "workspace:^2.2.2" + nestjs-cls: "workspace:^4.3.0" + typeorm: 0.3.20 + languageName: unknown + linkType: soft + "@nestjs-cls/transactional@workspace:packages/transactional": version: 0.0.0-use.local resolution: "@nestjs-cls/transactional@workspace:packages/transactional" @@ -5729,6 +5756,13 @@ __metadata: languageName: node linkType: hard +"@sqltools/formatter@npm:^1.2.5": + version: 1.2.5 + resolution: "@sqltools/formatter@npm:1.2.5" + checksum: 4b4fa62b8cd4880784b71cc5edd4a13da04fda0a915c14282765a8ec1a900a495e69b322704413e2052d221b5646d9fb0e20e87911f9a8f438f33180eecb11a4 + languageName: node + linkType: hard + "@svgr/babel-plugin-add-jsx-attribute@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:6.5.1" @@ -7873,6 +7907,13 @@ __metadata: languageName: node linkType: hard +"any-promise@npm:^1.0.0": + version: 1.3.0 + resolution: "any-promise@npm:1.3.0" + checksum: 60f0298ed34c74fef50daab88e8dab786036ed5a7fad02e012ab57e376e0a0b4b29e83b95ea9b5e7d89df762f5f25119b83e00706ecaccb22cfbacee98d74889 + languageName: node + linkType: hard + "anymatch@npm:^3.0.3, anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" @@ -7883,6 +7924,13 @@ __metadata: languageName: node linkType: hard +"app-root-path@npm:^3.1.0": + version: 3.1.0 + resolution: "app-root-path@npm:3.1.0" + checksum: 4a0fd976de1bffcdb18a5e1f8050091f15d0780e0582bca99aaa9d52de71f0e08e5185355fcffc781180bfb898499e787a2f5ed79b9c448b942b31dc947acaa9 + languageName: node + linkType: hard + "append-field@npm:^1.0.0": version: 1.0.0 resolution: "append-field@npm:1.0.0" @@ -9018,6 +9066,22 @@ __metadata: languageName: node linkType: hard +"cli-highlight@npm:^2.1.11": + version: 2.1.11 + resolution: "cli-highlight@npm:2.1.11" + dependencies: + chalk: "npm:^4.0.0" + highlight.js: "npm:^10.7.1" + mz: "npm:^2.4.0" + parse5: "npm:^5.1.1" + parse5-htmlparser2-tree-adapter: "npm:^6.0.0" + yargs: "npm:^16.0.0" + bin: + highlight: bin/highlight + checksum: b5b4af3b968aa9df77eee449a400fbb659cf47c4b03a395370bd98d5554a00afaa5819b41a9a8a1ca0d37b0b896a94e57c65289b37359a25b700b1f56eb04852 + languageName: node + linkType: hard + "cli-spinners@npm:^2.5.0": version: 2.9.0 resolution: "cli-spinners@npm:2.9.0" @@ -9077,6 +9141,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^7.0.2": + version: 7.0.4 + resolution: "cliui@npm:7.0.4" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.0" + wrap-ansi: "npm:^7.0.0" + checksum: 6035f5daf7383470cef82b3d3db00bec70afb3423538c50394386ffbbab135e26c3689c41791f911fa71b62d13d3863c712fdd70f0fbdffd938a1e6fd09aac00 + languageName: node + linkType: hard + "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -9939,6 +10014,13 @@ __metadata: languageName: node linkType: hard +"dayjs@npm:^1.11.9": + version: 1.11.10 + resolution: "dayjs@npm:1.11.10" + checksum: 4de9af50639d47df87f2e15fa36bb07e0f9ed1e9c52c6caa1482788ee9a384d668f1dbd00c54f82aaab163db07d61d2899384b8254da3a9184fc6deca080e2fe + languageName: node + linkType: hard + "debounce@npm:^1.2.1": version: 1.2.1 resolution: "debounce@npm:1.2.1" @@ -10453,6 +10535,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.0.3": + version: 16.4.5 + resolution: "dotenv@npm:16.4.5" + checksum: 48d92870076832af0418b13acd6e5a5a3e83bb00df690d9812e94b24aff62b88ade955ac99a05501305b8dc8f1b0ee7638b18493deb6fe93d680e5220936292f + languageName: node + linkType: hard + "dotenv@npm:^16.3.1": version: 16.3.2 resolution: "dotenv@npm:16.3.2" @@ -12011,6 +12100,21 @@ __metadata: languageName: node linkType: hard +"glob@npm:^10.3.10": + version: 10.3.12 + resolution: "glob@npm:10.3.12" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^2.3.6" + minimatch: "npm:^9.0.1" + minipass: "npm:^7.0.4" + path-scurry: "npm:^1.10.2" + bin: + glob: dist/esm/bin.mjs + checksum: f60cefdc1cf3f958b2bb5823e1b233727f04916d489dc4641d76914f016e6704421e06a83cbb68b0cb1cb9382298b7a88075b844ad2127fc9727ea22b18b0711 + languageName: node + linkType: hard + "glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -12624,6 +12728,13 @@ __metadata: languageName: node linkType: hard +"highlight.js@npm:^10.7.1": + version: 10.7.3 + resolution: "highlight.js@npm:10.7.3" + checksum: 073837eaf816922427a9005c56c42ad8786473dc042332dfe7901aa065e92bc3d94ebf704975257526482066abb2c8677cc0326559bb8621e046c21c5991c434 + languageName: node + linkType: hard + "history@npm:^4.9.0": version: 4.10.1 resolution: "history@npm:4.10.1" @@ -13730,6 +13841,19 @@ __metadata: languageName: node linkType: hard +"jackspeak@npm:^2.3.6": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 + languageName: node + linkType: hard + "jest-changed-files@npm:^29.7.0": version: 29.7.0 resolution: "jest-changed-files@npm:29.7.0" @@ -14756,6 +14880,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^10.2.0": + version: 10.2.0 + resolution: "lru-cache@npm:10.2.0" + checksum: c9847612aa2daaef102d30542a8d6d9b2c2bb36581c1bf0dc3ebf5e5f3352c772a749e604afae2e46873b930a9e9523743faac4e5b937c576ab29196774712ee + languageName: node + linkType: hard + "lru-cache@npm:^5.1.1": version: 5.1.1 resolution: "lru-cache@npm:5.1.1" @@ -16049,6 +16180,13 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^7.0.4": + version: 7.0.4 + resolution: "minipass@npm:7.0.4" + checksum: 6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5 + languageName: node + linkType: hard + "minizlib@npm:^2.0.0, minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": version: 2.1.2 resolution: "minizlib@npm:2.1.2" @@ -16093,6 +16231,15 @@ __metadata: languageName: node linkType: hard +"mkdirp@npm:^2.1.3": + version: 2.1.6 + resolution: "mkdirp@npm:2.1.6" + bin: + mkdirp: dist/cjs/src/bin.js + checksum: 96f551c651dd8f5f9435d53df1a7b9bfc553be769ee6da5192c37c1f303a376ef1c6996f96913d4a8d357060451d4526a346031d1919f92c58806a5fa3cd8dfe + languageName: node + linkType: hard + "mnemonist@npm:0.39.6": version: 0.39.6 resolution: "mnemonist@npm:0.39.6" @@ -16192,6 +16339,17 @@ __metadata: languageName: node linkType: hard +"mz@npm:^2.4.0": + version: 2.7.0 + resolution: "mz@npm:2.7.0" + dependencies: + any-promise: "npm:^1.0.0" + object-assign: "npm:^4.0.1" + thenify-all: "npm:^1.0.0" + checksum: 103114e93f87362f0b56ab5b2e7245051ad0276b646e3902c98397d18bb8f4a77f2ea4a2c9d3ad516034ea3a56553b60d3f5f78220001ca4c404bd711bd0af39 + languageName: node + linkType: hard + "nanoid@npm:^3.3.6": version: 3.3.6 resolution: "nanoid@npm:3.3.6" @@ -16596,7 +16754,7 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4, object-assign@npm:^4.1.1": +"object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 @@ -16946,6 +17104,15 @@ __metadata: languageName: node linkType: hard +"parse5-htmlparser2-tree-adapter@npm:^6.0.0": + version: 6.0.1 + resolution: "parse5-htmlparser2-tree-adapter@npm:6.0.1" + dependencies: + parse5: "npm:^6.0.1" + checksum: dfa5960e2aaf125707e19a4b1bc333de49232eba5a6ffffb95d313a7d6087c3b7a274b58bee8d3bd41bdf150638815d1d601a42bbf2a0345208c3c35b1279556 + languageName: node + linkType: hard + "parse5-htmlparser2-tree-adapter@npm:^7.0.0": version: 7.0.0 resolution: "parse5-htmlparser2-tree-adapter@npm:7.0.0" @@ -16956,7 +17123,14 @@ __metadata: languageName: node linkType: hard -"parse5@npm:^6.0.0": +"parse5@npm:^5.1.1": + version: 5.1.1 + resolution: "parse5@npm:5.1.1" + checksum: b0f87a77a7fea5f242e3d76917c983bbea47703b9371801d51536b78942db6441cbda174bf84eb30e47315ddc6f8a0b57d68e562c790154430270acd76c1fa03 + languageName: node + linkType: hard + +"parse5@npm:^6.0.0, parse5@npm:^6.0.1": version: 6.0.1 resolution: "parse5@npm:6.0.1" checksum: 595821edc094ecbcfb9ddcb46a3e1fe3a718540f8320eff08b8cf6742a5114cce2d46d45f95c26191c11b184dcaf4e2960abcd9c5ed9eb9393ac9a37efcfdecb @@ -17055,6 +17229,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^1.10.2": + version: 1.10.2 + resolution: "path-scurry@npm:1.10.2" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: d723777fbf9627f201e64656680f66ebd940957eebacf780e6cce1c2919c29c116678b2d7dbf8821b3a2caa758d125f4444005ccec886a25c8f324504e48e601 + languageName: node + linkType: hard + "path-to-regexp@npm:0.1.7": version: 0.1.7 resolution: "path-to-regexp@npm:0.1.7" @@ -18580,6 +18764,13 @@ __metadata: languageName: node linkType: hard +"reflect-metadata@npm:^0.2.1": + version: 0.2.2 + resolution: "reflect-metadata@npm:0.2.2" + checksum: 1cd93a15ea291e420204955544637c264c216e7aac527470e393d54b4bb075f10a17e60d8168ec96600c7e0b9fcc0cb0bb6e91c3fbf5b0d8c9056f04e6ac1ec2 + languageName: node + linkType: hard + "regenerate-unicode-properties@npm:^10.1.0": version: 10.1.0 resolution: "regenerate-unicode-properties@npm:10.1.0" @@ -20351,6 +20542,24 @@ __metadata: languageName: node linkType: hard +"thenify-all@npm:^1.0.0": + version: 1.6.0 + resolution: "thenify-all@npm:1.6.0" + dependencies: + thenify: "npm:>= 3.1.0 < 4" + checksum: 9b896a22735e8122754fe70f1d65f7ee691c1d70b1f116fda04fea103d0f9b356e3676cb789506e3909ae0486a79a476e4914b0f92472c2e093d206aed4b7d6b + languageName: node + linkType: hard + +"thenify@npm:>= 3.1.0 < 4": + version: 3.3.1 + resolution: "thenify@npm:3.3.1" + dependencies: + any-promise: "npm:^1.0.0" + checksum: f375aeb2b05c100a456a30bc3ed07ef03a39cbdefe02e0403fb714b8c7e57eeaad1a2f5c4ecfb9ce554ce3db9c2b024eba144843cd9e344566d9fcee73b04767 + languageName: node + linkType: hard + "thread-stream@npm:^2.0.0": version: 2.3.0 resolution: "thread-stream@npm:2.3.0" @@ -20661,7 +20870,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.6.2, tslib@npm:^2.6.0": +"tslib@npm:2.6.2, tslib@npm:^2.5.0, tslib@npm:^2.6.0": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb @@ -20821,6 +21030,86 @@ __metadata: languageName: node linkType: hard +"typeorm@npm:0.3.20": + version: 0.3.20 + resolution: "typeorm@npm:0.3.20" + dependencies: + "@sqltools/formatter": "npm:^1.2.5" + app-root-path: "npm:^3.1.0" + buffer: "npm:^6.0.3" + chalk: "npm:^4.1.2" + cli-highlight: "npm:^2.1.11" + dayjs: "npm:^1.11.9" + debug: "npm:^4.3.4" + dotenv: "npm:^16.0.3" + glob: "npm:^10.3.10" + mkdirp: "npm:^2.1.3" + reflect-metadata: "npm:^0.2.1" + sha.js: "npm:^2.4.11" + tslib: "npm:^2.5.0" + uuid: "npm:^9.0.0" + yargs: "npm:^17.6.2" + peerDependencies: + "@google-cloud/spanner": ^5.18.0 + "@sap/hana-client": ^2.12.25 + better-sqlite3: ^7.1.2 || ^8.0.0 || ^9.0.0 + hdb-pool: ^0.1.6 + ioredis: ^5.0.4 + mongodb: ^5.8.0 + mssql: ^9.1.1 || ^10.0.1 + mysql2: ^2.2.5 || ^3.0.1 + oracledb: ^6.3.0 + pg: ^8.5.1 + pg-native: ^3.0.0 + pg-query-stream: ^4.0.0 + redis: ^3.1.1 || ^4.0.0 + sql.js: ^1.4.0 + sqlite3: ^5.0.3 + ts-node: ^10.7.0 + typeorm-aurora-data-api-driver: ^2.0.0 + peerDependenciesMeta: + "@google-cloud/spanner": + optional: true + "@sap/hana-client": + optional: true + better-sqlite3: + optional: true + hdb-pool: + optional: true + ioredis: + optional: true + mongodb: + optional: true + mssql: + optional: true + mysql2: + optional: true + oracledb: + optional: true + pg: + optional: true + pg-native: + optional: true + pg-query-stream: + optional: true + redis: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + ts-node: + optional: true + typeorm-aurora-data-api-driver: + optional: true + bin: + typeorm: cli.js + typeorm-ts-node-commonjs: cli-ts-node-commonjs.js + typeorm-ts-node-esm: cli-ts-node-esm.js + checksum: 7e4be724641beef86ae36289c87b6e66bfaf19a4313f089926d36d2d6f0d67f9314d942711c9d83ab8a174b8622148c2f7e83e6c1448d638ee3ab24469257814 + languageName: node + linkType: hard + "typescript@npm:5.0": version: 5.0.4 resolution: "typescript@npm:5.0.4" @@ -21934,14 +22223,29 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^20.2.3": +"yargs-parser@npm:^20.2.2, yargs-parser@npm:^20.2.3": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" checksum: 0685a8e58bbfb57fab6aefe03c6da904a59769bd803a722bb098bd5b0f29d274a1357762c7258fb487512811b8063fb5d2824a3415a0a4540598335b3b086c72 languageName: node linkType: hard -"yargs@npm:^17.3.1, yargs@npm:^17.5.1": +"yargs@npm:^16.0.0": + version: 16.2.0 + resolution: "yargs@npm:16.2.0" + dependencies: + cliui: "npm:^7.0.2" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.0" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^20.2.2" + checksum: b1dbfefa679848442454b60053a6c95d62f2d2e21dd28def92b647587f415969173c6e99a0f3bab4f1b67ee8283bf735ebe3544013f09491186ba9e8a9a2b651 + languageName: node + linkType: hard + +"yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: