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: