{"_id":"@kickfinance/typeorm-transactional","_rev":"3-6fb426d52b1800f5e35977284ff8f5f0","name":"@kickfinance/typeorm-transactional","dist-tags":{"latest":"0.6.1"},"versions":{"0.6.0":{"name":"@kickfinance/typeorm-transactional","version":"0.6.0","keywords":["typescript","typescript-orm","typeorm","orm","cls-hooked","transaction","isolation","decorator"],"author":{"name":"Ohad David","email":"ohad.david@gmail.com"},"license":"MIT","_id":"@kickfinance/typeorm-transactional@0.6.0","maintainers":[{"name":"conradwadowski","email":"conrad@kick.co"},{"name":"nizarius","email":"dr.potapoff.peter@gmail.com"},{"name":"agarbund","email":"agarbund@gmail.com"}],"homepage":"https://github.com/KickApp/typeorm-transactional#readme","bugs":{"url":"https://github.com/KickApp/typeorm-transactional/issues"},"dist":{"shasum":"661f7d483f8bcae39fa3c6d583f146dbdef9487d","tarball":"https://registry.npmjs.org/@kickfinance/typeorm-transactional/-/typeorm-transactional-0.6.0.tgz","fileCount":60,"integrity":"sha512-KKl0LWbsACREP1M/q0/Iy2tf00N1c1pCwVjy4VQ9nqf7O1jK6rmSd20B/3sp129TaXnAbSMXnoGNfr+t2ZOl8g==","signatures":[{"sig":"MEUCIDVjJFHyOT7xhOeTdLcbHzhNpR6d50diHmZ59Cj5Zq1YAiEAqeXghUNZQSaff1XS5pRGJrOH7BJnwY+zcxZCGsivkok=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74221},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"050922594f5146a5e2e33f335c5b6e12e6d1e624","scripts":{"fix":"npm run fix:lint && npm run fix:format","test":"npm run setup-test-db && jest","build":"npm run clean && tsc -p tsconfig.json","check":"npm run check:lint && npm run check:format","clean":"rm -rf ./dist","fix:lint":"npm run check:lint --fix","check:lint":"eslint --cache \"src/**/*.ts\"","fix:format":"prettier --write \"src/**/*.ts\"","check:format":"prettier --check \"src/**/*.ts\"","setup-test-db":"npm run teardown-test-db; docker compose -f tests/docker-compose.yaml up -d --wait","teardown-test-db":"docker compose -f tests/docker-compose.yaml down --remove-orphans -v"},"_npmUser":{"name":"agarbund","email":"agarbund@gmail.com"},"repository":{"url":"git+https://github.com/KickApp/typeorm-transactional.git","type":"git"},"_npmVersion":"11.12.1","description":"A Transactional Method Decorator for typeorm that uses cls-hooked to handle and propagate transactions between different repositories and service methods. Inpired by Spring Trasnactional Annotation and Sequelize CLS","directories":{},"_nodeVersion":"24.15.0","dependencies":{"semver":"^7.5.1","cls-hooked":"^4.2.2","@types/cls-hooked":"^4.3.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"pg":"^8.7.3","jest":"^28.1.3","rxjs":"^7.5.6","eslint":"^8.20.0","ts-jest":"^28.0.7","typeorm":"^0.3.10","prettier":"^2.7.1","typescript":"^4.7.4","@types/jest":"^28.1.6","@nestjs/core":"^9.0.7","@types/semver":"^7.5.0","@nestjs/common":"^9.0.7","@nestjs/testing":"^9.0.7","@nestjs/typeorm":"^9.0.0","reflect-metadata":"^0.1.13","eslint-config-prettier":"^8.5.0","eslint-plugin-prettier":"^4.2.1","@typescript-eslint/parser":"^5.31.0","@typescript-eslint/eslint-plugin":"^5.31.0"},"peerDependencies":{"typeorm":">= 0.2.8","reflect-metadata":">= 0.1.12"},"_npmOperationalInternal":{"tmp":"tmp/typeorm-transactional_0.6.0_1779786097234_0.6282711846218632","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@kickfinance/typeorm-transactional","version":"0.6.1","keywords":["typescript","typescript-orm","typeorm","orm","cls-hooked","transaction","isolation","decorator"],"author":{"name":"Ohad David","email":"ohad.david@gmail.com"},"license":"MIT","_id":"@kickfinance/typeorm-transactional@0.6.1","maintainers":[{"name":"conradwadowski","email":"conrad@kick.co"},{"name":"nizarius","email":"dr.potapoff.peter@gmail.com"},{"name":"agarbund","email":"agarbund@gmail.com"}],"homepage":"https://github.com/KickApp/typeorm-transactional#readme","bugs":{"url":"https://github.com/KickApp/typeorm-transactional/issues"},"dist":{"shasum":"0d3b047864ad9e0213ed2be220730fc2ff3bf691","tarball":"https://registry.npmjs.org/@kickfinance/typeorm-transactional/-/typeorm-transactional-0.6.1.tgz","fileCount":60,"integrity":"sha512-Ychz/4VAs0WQoBUgjjsRLYlAoI9hbWNZfa9R7TMO9iRpyMTkitVZiE9tcCDM3oGKX3Oy/JxtgMjJy9lHAbwCyQ==","signatures":[{"sig":"MEQCICMvXaQSv+yyJsfcOPHEdC7BSfsS8dqgrDt+JstVy3KPAiBDiRjC7HgXR+6NI5rhioTf7uOE9CCZ7Fsv1fVJ19cxZA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74221},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"08065e2772ff2e0a10e3dc2afd3e399e6f404fc6","scripts":{"fix":"npm run fix:lint && npm run fix:format","test":"npm run setup-test-db && jest","build":"npm run clean && tsc -p tsconfig.json","check":"npm run check:lint && npm run check:format","clean":"rm -rf ./dist","fix:lint":"npm run check:lint --fix","check:lint":"eslint --cache \"src/**/*.ts\"","fix:format":"prettier --write \"src/**/*.ts\"","check:format":"prettier --check \"src/**/*.ts\"","setup-test-db":"npm run teardown-test-db; docker compose -f tests/docker-compose.yaml up -d --wait","teardown-test-db":"docker compose -f tests/docker-compose.yaml down --remove-orphans -v"},"_npmUser":{"name":"agarbund","email":"agarbund@gmail.com"},"repository":{"url":"git+https://github.com/KickApp/typeorm-transactional.git","type":"git"},"_npmVersion":"11.12.1","description":"A Transactional Method Decorator for typeorm that uses cls-hooked to handle and propagate transactions between different repositories and service methods. Inpired by Spring Trasnactional Annotation and Sequelize CLS","directories":{},"_nodeVersion":"24.15.0","dependencies":{"semver":"^7.5.1","cls-hooked":"^4.2.2","@types/cls-hooked":"^4.3.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"pg":"^8.7.3","jest":"^28.1.3","rxjs":"^7.5.6","eslint":"^8.20.0","ts-jest":"^28.0.7","typeorm":"^0.3.10","prettier":"^2.7.1","typescript":"^4.7.4","@types/jest":"^28.1.6","@nestjs/core":"^9.0.7","@types/semver":"^7.5.0","@nestjs/common":"^9.0.7","@nestjs/testing":"^9.0.7","@nestjs/typeorm":"^9.0.0","reflect-metadata":"^0.1.13","eslint-config-prettier":"^8.5.0","eslint-plugin-prettier":"^4.2.1","@typescript-eslint/parser":"^5.31.0","@typescript-eslint/eslint-plugin":"^5.31.0"},"peerDependencies":{"typeorm":">= 0.2.8","reflect-metadata":">= 0.1.12"},"_npmOperationalInternal":{"tmp":"tmp/typeorm-transactional_0.6.1_1779786177961_0.9041848666736765","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-05-26T09:01:37.039Z","modified":"2026-05-27T07:08:32.271Z","0.6.0":"2026-05-26T09:01:37.372Z","0.6.1":"2026-05-26T09:02:58.095Z"},"bugs":{"url":"https://github.com/KickApp/typeorm-transactional/issues"},"author":{"name":"Ohad David","email":"ohad.david@gmail.com"},"license":"MIT","homepage":"https://github.com/KickApp/typeorm-transactional#readme","keywords":["typescript","typescript-orm","typeorm","orm","cls-hooked","transaction","isolation","decorator"],"repository":{"url":"git+https://github.com/KickApp/typeorm-transactional.git","type":"git"},"description":"A Transactional Method Decorator for typeorm that uses cls-hooked to handle and propagate transactions between different repositories and service methods. Inpired by Spring Trasnactional Annotation and Sequelize CLS","maintainers":[{"email":"conrad@kick.co","name":"conradwadowski"},{"email":"agarbund@gmail.com","name":"agarbund"}],"readme":"\n# Typeorm Transactional\n[![npm version](http://img.shields.io/npm/v/@kickfinance/typeorm-transactional.svg?style=flat)](https://npmjs.org/package/@kickfinance/typeorm-transactional \"View this project on npm\")\n\n## It's a fork of [typeorm-transactional](https://github.com/Aliheym/typeorm-transactional) for native async/await support\n\n\nA `Transactional` Method Decorator for [typeorm](http://typeorm.io/) that uses [ALS](https://nodejs.org/api/async_context.html#class-asynclocalstorage) or [cls-hooked](https://www.npmjs.com/package/cls-hooked) to handle and propagate transactions between different repositories and service methods.\n\nSee [Changelog](#CHANGELOG.md)\n\n- [Typeorm Transactional](#typeorm-transactional)\n  - [It's a fork of typeorm-transactional-cls-hooked for new versions of TypeORM.](#its-a-fork-of-typeorm-transactional-cls-hooked-for-new-versions-of-typeorm)\n  - [Installation](#installation)\n  - [Initialization](#initialization)\n  - [Usage](#usage)\n  - [Using Transactional Decorator](#using-transactional-decorator)\n  - [Data Sources](#data-sources)\n  - [Transaction Propagation](#transaction-propagation)\n  - [Isolation Levels](#isolation-levels)\n  - [Hooks](#hooks)\n  - [Unit Test Mocking](#unit-test-mocking)\n  - [API](#api)\n    - [Library Options](#library-options)\n    - [Transaction Options](#transaction-options)\n    - [Storage Driver](#storage-driver)\n    - [initializeTransactionalContext(options): void](#initializetransactionalcontextoptions-void)\n    - [addTransactionalDataSource(input): DataSource](#addtransactionaldatasourceinput-datasource)\n    - [runInTransaction(fn: Callback, options?: Options): Promise\\<...\\>](#runintransactionfn-callback-options-options-promise)\n    - [wrapInTransaction(fn: Callback, options?: Options): WrappedFunction](#wrapintransactionfn-callback-options-options-wrappedfunction)\n    - [runOnTransactionCommit(cb: Callback): void](#runontransactioncommitcb-callback-void)\n    - [runOnTransactionRollback(cb: Callback): void](#runontransactionrollbackcb-callback-void)\n    - [runOnTransactionComplete(cb: Callback): void](#runontransactioncompletecb-callback-void)\n## Installation\n\n```shell\n## npm\nnpm install --save @kickfinance/typeorm-transactional\n\n## Needed dependencies\nnpm install --save typeorm reflect-metadata\n```\n\nOr\n\n```shell\nyarn add @kickfinance/typeorm-transactional\n\n## Needed dependencies\nyarn add typeorm reflect-metadata\n```\n\n> **Note**: You will need to import `reflect-metadata` somewhere in the global place of your app - https://github.com/typeorm/typeorm#installation\n\n## Initialization\n\nIn order to use it, you will first need to initialize the transactional context before your application is started\n\n```typescript\nimport { initializeTransactionalContext, StorageDriver } from '@kickfinance/typeorm-transactional';\n\ninitializeTransactionalContext({ storageDriver: StorageDriver.AUTO });\n...\napp = express()\n...\n```\n---\n**IMPORTANT NOTE**\n\nCalling [initializeTransactionalContext](#initialization) must happen BEFORE any application context is initialized!\n\n\n## Usage\n\nNew versions of TypeORM use `DataSource` instead of `Connection`, so most of the API has been changed and the old API has become deprecated.\n\nTo be able to use TypeORM entities in transactions, you must first add a DataSource using the `addTransactionalDataSource` function:\n\n```typescript\nimport { DataSource } from 'typeorm';\nimport { initializeTransactionalContext, addTransactionalDataSource, StorageDriver } from '@kickfinance/typeorm-transactional';\n...\nconst dataSource = new DataSource({\n\t  type: 'postgres',\n    host: 'localhost',\n    port: 5435,\n    username: 'postgres',\n    password: 'postgres'\n});\n...\n\ninitializeTransactionalContext({ storageDriver: StorageDriver.AUTO });\naddTransactionalDataSource(dataSource);\n\n...\n```\n\nExample for `Nest.js`:\n\n```typescript\n// main.ts\n\nimport { NestFactory } from '@nestjs/core';\nimport { initializeTransactionalContext, StorageDriver } from '@kickfinance/typeorm-transactional';\n\nimport { AppModule } from './app';\n\nconst bootstrap = async () => {\n  initializeTransactionalContext({ storageDriver: StorageDriver.AUTO });\n\n  const app = await NestFactory.create(AppModule, {\n    abortOnError: true,\n  });\n\n  await app.listen(3000);\n};\n\nbootstrap();\n```\n\n\n```typescript\n// app.module.ts\n\nimport { Module } from '@nestjs/common';\nimport { TypeOrmModule } from '@nestjs/typeorm';\nimport { DataSource } from 'typeorm';\nimport { addTransactionalDataSource } from '@kickfinance/typeorm-transactional';\n\n@Module({\n\timports: [\n\t   TypeOrmModule.forRootAsync({\n\t     useFactory() {\n\t       return {\n\t         type: 'postgres',\n\t         host: 'localhost',\n\t         port: 5435,\n\t         username: 'postgres',\n\t         password: 'postgres',\n\t         synchronize: true,\n\t         logging: false,\n\t       };\n\t     },\n\t     async dataSourceFactory(options) {\n\t       if (!options) {\n\t         throw new Error('Invalid options passed');\n\t       }\n\n\t       return addTransactionalDataSource(new DataSource(options));\n\t     },\n\t   }),\n\n\t   ...\n\t ],\n\t providers: [...],\n\t exports: [...],\n})\nclass AppModule {}\n```\n\nUnlike `typeorm-transactional-cls-hooked`, you do not need to use `BaseRepository`or otherwise define repositories.\n\nYou can also use this library with custom TypeORM repositories. You can read more about them [here](https://stackoverflow.com/a/72887316/19150323) and [here](https://orkhan.gitbook.io/typeorm/docs/custom-repository).\n\n**NOTE**:  You can [add](#data-sources) multiple `DataSource` if you need it\n\n\n## Using Transactional Decorator\n\n- Every service method that needs to be transactional, need to use the `@Transactional()` decorator\n- The decorator can take a `connectionName` as argument (by default it is `default`) to specify [the data source ](#data-sources) to be user\n- The decorator can take an optional `propagation` as argument to define the [propagation behaviour](#transaction-propagation)\n- The decorator can take an optional `isolationLevel` as argument to define the [isolation level](#isolation-levels) (by default it will use your database driver's default isolation level)\n\n```typescript\nexport class PostService {\n  constructor(readonly repository: PostRepository)\n\n  @Transactional() // Will open a transaction if one doesn't already exist\n  async createPost(id, message): Promise<Post> {\n    const post = this.repository.create({ id, message })\n    return this.repository.save(post)\n  }\n}\n```\n\nYou can also use `DataSource`/`EntityManager` objects together with repositories in transactions:\n\n```typescript\nexport class PostService {\n  constructor(readonly repository: PostRepository, readonly dataSource: DataSource)\n\n  @Transactional() // Will open a transaction if one doesn't already exist\n  async createAndGetPost(id, message): Promise<Post> {\n    const post = this.repository.create({ id, message })\n\n    await this.repository.save(post)\n\n    return dataSource.createQueryBuilder(Post, 'p').where('id = :id', id).getOne();\n  }\n}\n```\n\n## Data Sources\n\nIn new versions of `TypeORM` the `name` property in `Connection` / `DataSource` is deprecated, so to work conveniently with multiple `DataSource` the function  `addTransactionalDataSource` allows you to specify custom the name:\n\n```typescript\naddTransactionalDataSource({\n\tname: 'second-data-source',\n\tdataSource: new DataSource(...)\n});\n```\n\nIf you don't specify a name, it defaults to `default`.\n\nNow, you can use this `name` in API by passing the `connectionName` property as options to explicitly define which `Data Source` you want to use:\n\n```typescript\n  @Transactional({ connectionName: 'second-data-source' })\n  async fn() { ... }\n```\n\nOR\n\n\n```typescript\nrunInTransaction(() => {\n  // ...\n}, { connectionName: 'second-data-source' })\n```\n\n## Transaction Propagation\n\nThe following propagation options can be specified:\n\n- `MANDATORY` - Support a current transaction, throw an exception if none exists.\n- `NESTED` - Execute within a nested transaction if a current transaction exists, behave like `REQUIRED` else.\n- `NEVER` - Execute non-transactionally, throw an exception if a transaction exists.\n- `NOT_SUPPORTED` - Execute non-transactionally, suspend the current transaction if one exists.\n- `REQUIRED` (default behaviour) - Support a current transaction, create a new one if none exists.\n- `REQUIRES_NEW` - Create a new transaction, and suspend the current transaction if one exists.\n- `SUPPORTS` - Support a current transaction, execute non-transactionally if none exists.\n\n## Isolation Levels\n\nThe following isolation level options can be specified:\n\n- `READ_UNCOMMITTED` - A constant indicating that dirty reads, non-repeatable reads and phantom reads can occur.\n- `READ_COMMITTED` - A constant indicating that dirty reads are prevented; non-repeatable reads and phantom reads can occur.\n- `REPEATABLE_READ` - A constant indicating that dirty reads and non-repeatable reads are prevented; phantom reads can occur.\n- `SERIALIZABLE` = A constant indicating that dirty reads, non-repeatable reads and phantom reads are prevented.\n\n**NOTE**: If a transaction already exist and a method is decorated with `@Transactional` and `propagation` *does not equal* to `REQUIRES_NEW`, then the declared `isolationLevel` value will *not* be taken into account.\n\n## Hooks\n\nBecause you hand over control of the transaction creation to this library, there is no way for you to know whether or not the current transaction was successfully persisted to the database.\n\nTo circumvent that, we expose three helper methods that allow you to hook into the transaction lifecycle and take appropriate action after a commit/rollback.\n\n- `runOnTransactionCommit(cb)` takes a callback to be executed after the current transaction was successfully committed\n- `runOnTransactionRollback(cb)` takes a callback to be executed after the current transaction rolls back. The callback gets the error that initiated the rollback as a parameter.\n- `runOnTransactionComplete(cb)` takes a callback to be executed at the completion of the current transactional context. If there was an error, it gets passed as an argument.\n\n\n\n```typescript\nexport class PostService {\n    constructor(readonly repository: PostRepository, readonly events: EventService) {}\n\n    @Transactional()\n    async createPost(id, message): Promise<Post> {\n        const post = this.repository.create({ id, message });\n        const result = await this.repository.save(post);\n\n        runOnTransactionCommit(() => this.events.emit('post created'));\n\n        return result;\n    }\n}\n```\n\n## Unit Test Mocking\n`@Transactional` can be mocked to prevent running any of the transactional code in unit tests.\n\nThis can be accomplished in Jest with:\n\n```typescript\njest.mock('@kickfinance/typeorm-transactional', () => ({\n  Transactional: () => () => ({}),\n}));\n```\nRepositories, services, etc. can be mocked as usual.\n\n## API\n\n### Library Options\n\n```typescript\n{\n  storageDriver?: StorageDriver,\n  maxHookHandlers?: number\n}\n```\n- `storageDriver` - Determines which [underlying mechanism](#storage-driver) (like Async Local Storage or cls-hooked) the library should use for handling and propagating transactions. By default, it's `StorageDriver.CLS_HOOKED`.\n- `maxHookHandlers` - Controls how many hooks (`commit`, `rollback`, `complete`) can be used simultaneously. If you exceed the number of hooks of same type, you get a warning. This is a useful to find possible memory leaks. You can set this options to `0` or `Infinity` to indicate an unlimited number of listeners. By default, it's `10`.\n\n### Transaction Options\n\n```typescript\n{\n  connectionName?: string;\n  isolationLevel?: IsolationLevel;\n  propagation?: Propagation;\n}\n```\n\n- `connectionName`-  DataSource name to use for this transactional context  ([the data sources](#data-sources))\n- `isolationLevel`- isolation level for transactional context ([isolation levels](#isolation-levels) )\n- `propagation`-  propagation behaviors for nest transactional contexts ([propagation behaviors](#transaction-propagation))\n\n### Storage Driver\n\nOption that determines which underlying mechanism the library should use for handling and propagating transactions.\n\nThe possible variants:\n\n- `AUTO` - Automatically selects the appropriate storage mechanism based on the Node.js version, using `AsyncLocalStorage` for Node.js versions 16 and above, and defaulting to `cls-hooked` for earlier versions.\n- `CLS_HOOKED` - Utilizes the `cls-hooked` package to provide context storage, supporting both legacy Node.js versions with AsyncWrap for versions below 8.2.1, and using `async_hooks` for later versions.\n- `ASYNC_LOCAL_STORAGE` - Uses the built-in `AsyncLocalStorage` feature, available from Node.js version 16 onwards,\n\n> ⚠️ **WARNING:**  Currently, we use `CLS_HOOKED` by default for backward compatibility. However, in the next major release, this default will be switched to `AUTO`.\n\n```typescript\nimport { StorageDriver } from '@kickfinance/typeorm-transactional'\n\ninitializeTransactionalContext({ storageDriver: StorageDriver.AUTO });\n```\n\n### initializeTransactionalContext(options): void\n\nInitialize transactional context.\n\n```typescript\ninitializeTransactionalContext(options?: TypeormTransactionalOptions);\n```\n\nOptionally, you can set some [options](#library-options).\n\n### addTransactionalDataSource(input): DataSource\n\nAdd TypeORM `DataSource` to transactional context.\n\n```typescript\naddTransactionalDataSource(new DataSource(...));\n\naddTransactionalDataSource({ name: 'default', dataSource: new DataSource(...), patch: true });\n```\n\n### runInTransaction(fn: Callback, options?: Options): Promise<...>\n\nRun code in transactional context.\n\n```typescript\n...\n\nrunInTransaction(() => {\n\t...\n\n\tconst user = this.usersRepo.update({ id: 1000 }, { state: action });\n\n\t...\n}, { propagation: Propagation.REQUIRES_NEW });\n\n...\n```\n\n### wrapInTransaction(fn: Callback, options?: Options): WrappedFunction\n\nWrap function in transactional context\n\n```typescript\n...\n\nconst updateUser = wrapInTransaction(() => {\n\t...\n\n\tconst user = this.usersRepo.update({ id: 1000 }, { state: action });\n\n\t...\n}, { propagation: Propagation.NEVER });\n\n...\n\nawait updateUser();\n\n...\n```\n\n### runOnTransactionCommit(cb: Callback): void\n\nTakes a callback to be executed after the current transaction was successfully committed\n\n```typescript\n  @Transactional()\n  async createPost(id, message): Promise<Post> {\n      const post = this.repository.create({ id, message });\n      const result = await this.repository.save(post);\n\n      runOnTransactionCommit(() => this.events.emit('post created'));\n\n      return result;\n  }\n```\n\n### runOnTransactionRollback(cb: Callback): void\n\nTakes a callback to be executed after the current transaction rolls back. The callback gets the error that initiated the rollback as a parameter.\n\n```typescript\n  @Transactional()\n  async createPost(id, message): Promise<Post> {\n      const post = this.repository.create({ id, message });\n      const result = await this.repository.save(post);\n\n      runOnTransactionRollback((e) => this.events.emit(e));\n\n      return result;\n  }\n```\n\n### runOnTransactionComplete(cb: Callback): void\n\nTakes a callback to be executed at the completion of the current transactional context. If there was an error, it gets passed as an argument.\n\n```typescript\n  @Transactional()\n  async createPost(id, message): Promise<Post> {\n      const post = this.repository.create({ id, message });\n      const result = await this.repository.save(post);\n\n      runOnTransactionComplete((e) => this.events.emit(e ? e : 'post created'));\n\n      return result;\n  }\n```\n","readmeFilename":"README.md"}