diff --git a/packages/transactional-adapters/transactional-adapter-drizzle/.gitignore b/packages/transactional-adapters/transactional-adapter-drizzle/.gitignore new file mode 100644 index 0000000..884e3de --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-drizzle/.gitignore @@ -0,0 +1 @@ +test.db \ No newline at end of file diff --git a/packages/transactional-adapters/transactional-adapter-drizzle/CHANGES.md b/packages/transactional-adapters/transactional-adapter-drizzle/CHANGES.md new file mode 100644 index 0000000..cd3a2c2 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-drizzle/CHANGES.md @@ -0,0 +1,3 @@ +# Changelog + + diff --git a/packages/transactional-adapters/transactional-adapter-drizzle/README.md b/packages/transactional-adapters/transactional-adapter-drizzle/README.md new file mode 100644 index 0000000..3f48ec3 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-drizzle/README.md @@ -0,0 +1,5 @@ +# @nestjs-cls/transactional-adapter-drizzle-postgres + +Drizzle-orm (postgres) adapter for the `@nestjs-cls/transactional` plugin. + +### ➡️ [Go to the documentation website](https://papooch.github.io/nestjs-cls/plugins/available-plugins/transactional/knex-adapter) 📖 diff --git a/packages/transactional-adapters/transactional-adapter-drizzle/jest.config.js b/packages/transactional-adapters/transactional-adapter-drizzle/jest.config.js new file mode 100644 index 0000000..14ae88e --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-drizzle/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-drizzle/package.json b/packages/transactional-adapters/transactional-adapter-drizzle/package.json new file mode 100644 index 0000000..1608fa3 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-drizzle/package.json @@ -0,0 +1,73 @@ +{ + "name": "@nestjs-cls/transactional-adapter-drizzle", + "version": "1.2.4", + "description": "A drizzle-orm adapter for @nestjs-cls/transactional", + "author": "papooch", + "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", + "transaction", + "transactional", + "transactional decorator", + "aop", + "drizzle-orm", + "drizzle" + ], + "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.4.2", + "drizzle-orm": "*", + "nestjs-cls": "workspace:^4.4.1" + }, + "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", + "drizzle-orm": "^0.34.1", + "jest": "^29.7.0", + "reflect-metadata": "^0.1.13", + "rimraf": "^3.0.2", + "rxjs": "^7.5.5", + "sqlite3": "^5.1.7", + "ts-jest": "^29.1.2", + "ts-loader": "^9.3.0", + "ts-node": "^10.8.1", + "tsconfig-paths": "^4.0.0", + "typescript": "5.0" + } +} diff --git a/packages/transactional-adapters/transactional-adapter-drizzle/src/index.ts b/packages/transactional-adapters/transactional-adapter-drizzle/src/index.ts new file mode 100644 index 0000000..4d65fe5 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-drizzle/src/index.ts @@ -0,0 +1 @@ +export * from './lib/transactional-adapter-drizzle'; diff --git a/packages/transactional-adapters/transactional-adapter-drizzle/src/lib/transactional-adapter-drizzle.ts b/packages/transactional-adapters/transactional-adapter-drizzle/src/lib/transactional-adapter-drizzle.ts new file mode 100644 index 0000000..941a390 --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-drizzle/src/lib/transactional-adapter-drizzle.ts @@ -0,0 +1,48 @@ +import { TransactionalAdapter } from "@nestjs-cls/transactional"; +import type { PgTransactionConfig } from "drizzle-orm/pg-core"; +import { PostgresJsDatabase } from "drizzle-orm/postgres-js"; + +export interface DrizzleOrmTransactionalAdapterOptions { + /** + * The injection token for the Drizzle instance. + */ + drizzleInstanceToken: any; + + /** + * Default options for the transaction. These will be merged with any transaction-specific options + * passed to the `@Transactional` decorator or the `TransactionHost#withTransaction` method. + */ + defaultTxOptions?: Partial; +} + +export class TransactionalAdapterDrizzleOrm + implements + TransactionalAdapter< + PostgresJsDatabase, + PostgresJsDatabase, + PgTransactionConfig + > +{ + connectionToken: any; + + defaultTxOptions?: Partial; + + constructor(options: DrizzleOrmTransactionalAdapterOptions) { + this.connectionToken = options.drizzleInstanceToken; + this.defaultTxOptions = options.defaultTxOptions; + } + + optionsFactory = (drizzleInstance: PostgresJsDatabase) => ({ + wrapWithTransaction: async ( + options: PgTransactionConfig, + fn: (...args: any[]) => Promise, + setClient: (client?: PostgresJsDatabase) => void + ) => { + return drizzleInstance.transaction(async (trx) => { + setClient(trx); + return fn(); + }, options); + }, + getFallbackInstance: () => drizzleInstance + }); +} diff --git a/packages/transactional-adapters/transactional-adapter-drizzle/test/transactional-adapter-drizzle.spec.ts b/packages/transactional-adapters/transactional-adapter-drizzle/test/transactional-adapter-drizzle.spec.ts new file mode 100644 index 0000000..2b07f5e --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-drizzle/test/transactional-adapter-drizzle.spec.ts @@ -0,0 +1,7 @@ +const DRIZZLE_TOKEN = 'DRIZZLE'; + +describe('TransactionalAdapter Drizzle', () => { + it('Should be able to create a transactional adapter', async () => { + return true; + }); +}); diff --git a/packages/transactional-adapters/transactional-adapter-drizzle/tsconfig.json b/packages/transactional-adapters/transactional-adapter-drizzle/tsconfig.json new file mode 100644 index 0000000..bbc28fb --- /dev/null +++ b/packages/transactional-adapters/transactional-adapter-drizzle/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "." + }, + "include": ["src/**/*.ts", "test/**/*.ts"] +} diff --git a/tsconfig.json b/tsconfig.json index 2df7934..2f41e8a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -48,6 +48,9 @@ }, { "path": "packages/transactional-adapters/transactional-adapter-typeorm" + }, + { + "path": "packages/transactional-adapters/transactional-adapter-drizzle" } ] } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 138b98a..74180ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5165,6 +5165,34 @@ __metadata: languageName: node linkType: hard +"@nestjs-cls/transactional-adapter-drizzle@workspace:packages/transactional-adapters/transactional-adapter-drizzle": + version: 0.0.0-use.local + resolution: "@nestjs-cls/transactional-adapter-drizzle@workspace:packages/transactional-adapters/transactional-adapter-drizzle" + 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" + drizzle-orm: "npm:^0.34.1" + jest: "npm:^29.7.0" + reflect-metadata: "npm:^0.1.13" + rimraf: "npm:^3.0.2" + rxjs: "npm:^7.5.5" + sqlite3: "npm:^5.1.7" + ts-jest: "npm:^29.1.2" + ts-loader: "npm:^9.3.0" + ts-node: "npm:^10.8.1" + tsconfig-paths: "npm:^4.0.0" + typescript: "npm:5.0" + peerDependencies: + "@nestjs-cls/transactional": "workspace:^2.4.2" + drizzle-orm: "*" + nestjs-cls: "workspace:^4.4.1" + languageName: unknown + linkType: soft + "@nestjs-cls/transactional-adapter-knex@workspace:packages/transactional-adapters/transactional-adapter-knex": version: 0.0.0-use.local resolution: "@nestjs-cls/transactional-adapter-knex@workspace:packages/transactional-adapters/transactional-adapter-knex" @@ -11079,6 +11107,98 @@ __metadata: languageName: node linkType: hard +"drizzle-orm@npm:^0.34.1": + version: 0.34.1 + resolution: "drizzle-orm@npm:0.34.1" + peerDependencies: + "@aws-sdk/client-rds-data": ">=3" + "@cloudflare/workers-types": ">=3" + "@electric-sql/pglite": ">=0.1.1" + "@libsql/client": ">=0.10.0" + "@neondatabase/serverless": ">=0.1" + "@op-engineering/op-sqlite": ">=2" + "@opentelemetry/api": ^1.4.1 + "@planetscale/database": ">=1" + "@prisma/client": "*" + "@tidbcloud/serverless": "*" + "@types/better-sqlite3": "*" + "@types/pg": "*" + "@types/react": ">=18" + "@types/sql.js": "*" + "@vercel/postgres": ">=0.8.0" + "@xata.io/client": "*" + better-sqlite3: ">=7" + bun-types: "*" + expo-sqlite: ">=13.2.0" + knex: "*" + kysely: "*" + mysql2: ">=2" + pg: ">=8" + postgres: ">=3" + react: ">=18" + sql.js: ">=1" + sqlite3: ">=5" + peerDependenciesMeta: + "@aws-sdk/client-rds-data": + optional: true + "@cloudflare/workers-types": + optional: true + "@electric-sql/pglite": + optional: true + "@libsql/client": + optional: true + "@neondatabase/serverless": + optional: true + "@op-engineering/op-sqlite": + optional: true + "@opentelemetry/api": + optional: true + "@planetscale/database": + optional: true + "@prisma/client": + optional: true + "@tidbcloud/serverless": + optional: true + "@types/better-sqlite3": + optional: true + "@types/pg": + optional: true + "@types/react": + optional: true + "@types/sql.js": + optional: true + "@vercel/postgres": + optional: true + "@xata.io/client": + optional: true + better-sqlite3: + optional: true + bun-types: + optional: true + expo-sqlite: + optional: true + knex: + optional: true + kysely: + optional: true + mysql2: + optional: true + pg: + optional: true + postgres: + optional: true + prisma: + optional: true + react: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + checksum: 067b360d41994953bb958d216b827d78b8a9550517e12b3cdf85be7cb361e982817f511a9ac317c84184aaa096321e23b43481318ee8b3c4c80f77d243628730 + languageName: node + linkType: hard + "dset@npm:^3.1.2": version: 3.1.2 resolution: "dset@npm:3.1.2"