@globalart/nestjs-typeorm-outbox 1.1.1 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1
2
  let _nestjs_common = require("@nestjs/common");
2
3
  let _globalart_text_utils = require("@globalart/text-utils");
3
4
  let typeorm = require("typeorm");
@@ -17,13 +18,13 @@ const InjectTypeormOutboxService = () => (0, _nestjs_common.Inject)(TYPEORM_OUTB
17
18
  const InjectTypeormOutboxBroker = () => (0, _nestjs_common.Inject)(TYPEORM_OUTBOX_BROKER_TOKEN);
18
19
 
19
20
  //#endregion
20
- //#region \0@oxc-project+runtime@0.110.0/helpers/decorateMetadata.js
21
+ //#region \0@oxc-project+runtime@0.112.0/helpers/decorateMetadata.js
21
22
  function __decorateMetadata(k, v) {
22
23
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
23
24
  }
24
25
 
25
26
  //#endregion
26
- //#region \0@oxc-project+runtime@0.110.0/helpers/decorate.js
27
+ //#region \0@oxc-project+runtime@0.112.0/helpers/decorate.js
27
28
  function __decorate(decorators, target, key, desc) {
28
29
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
29
30
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -130,7 +131,7 @@ var TypeormOutboxModuleOptions = class {
130
131
  };
131
132
 
132
133
  //#endregion
133
- //#region \0@oxc-project+runtime@0.110.0/helpers/decorateParam.js
134
+ //#region \0@oxc-project+runtime@0.112.0/helpers/decorateParam.js
134
135
  function __decorateParam(paramIndex, decorator) {
135
136
  return function(target, key) {
136
137
  decorator(target, key, paramIndex);
@@ -146,7 +147,7 @@ let TypeormOutboxCronService = class TypeormOutboxCronService {
146
147
  this.moduleConfig = moduleConfig;
147
148
  this.dataSource = dataSource;
148
149
  }
149
- onModuleInit() {
150
+ onApplicationBootstrap() {
150
151
  this.validateBrokerClient();
151
152
  new cron.CronJob(this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND, () => {
152
153
  this.executeCronJob();
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["CronJob","Transport","TypeOrmModule","ClientProxyFactory"],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.enums.ts","../src/core/typeorm-outbox.interfaces.ts","../src/core/typeorm-outbox-cron.service.ts","../src/core/typeorm-outbox.service.ts","../src/core/typeorm-outbox.module.ts"],"sourcesContent":["import { Inject } from \"@nestjs/common\";\n\nexport const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_CRON_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_SERVICE_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_BROKER_TOKEN\",\n);\n\nexport const InjectTypeormOutboxCronConfig = () =>\n Inject(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);\nexport const InjectTypeormOutboxModuleConfig = () =>\n Inject(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);\nexport const InjectTypeormOutboxService = () =>\n Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);\nexport const InjectTypeormOutboxBroker = () =>\n Inject(TYPEORM_OUTBOX_BROKER_TOKEN);\n","import {\n Column,\n CreateDateColumn,\n Entity,\n PrimaryGeneratedColumn,\n UpdateDateColumn,\n} from \"typeorm\";\n\n@Entity('outbox')\nexport class TypeormOutboxEntity {\n @PrimaryGeneratedColumn()\n id!: number;\n\n @CreateDateColumn({ name: 'created_at' })\n createdAt!: Date;\n\n @UpdateDateColumn({ name: 'updated_at' })\n updatedAt!: Date;\n\n @Column(\"character varying\", { name: 'destination_topic' })\n destinationTopic!: string;\n\n @Column(\"jsonb\", { nullable: true })\n headers!: Record<string, string>;\n\n @Column(\"jsonb\", { nullable: true })\n keys!: Record<string, unknown>;\n\n @Column(\"jsonb\")\n payload!: Record<string, any>;\n}\n","export enum CronExpression {\n EVERY_SECOND = \"* * * * * *\",\n EVERY_2_SECONDS = \"*/2 * * * * *\",\n EVERY_3_SECONDS = \"*/3 * * * * *\",\n EVERY_4_SECONDS = \"*/4 * * * * *\",\n EVERY_5_SECONDS = \"*/5 * * * * *\",\n EVERY_6_SECONDS = \"*/6 * * * * *\",\n EVERY_7_SECONDS = \"*/7 * * * * *\",\n EVERY_8_SECONDS = \"*/8 * * * * *\",\n EVERY_9_SECONDS = \"*/9 * * * * *\",\n EVERY_10_SECONDS = \"*/10 * * * * *\",\n EVERY_11_SECONDS = \"*/11 * * * * *\",\n EVERY_12_SECONDS = \"*/12 * * * * *\",\n EVERY_13_SECONDS = \"*/13 * * * * *\",\n EVERY_14_SECONDS = \"*/14 * * * * *\",\n EVERY_15_SECONDS = \"*/15 * * * * *\",\n EVERY_16_SECONDS = \"*/16 * * * * *\",\n EVERY_17_SECONDS = \"*/17 * * * * *\",\n EVERY_18_SECONDS = \"*/18 * * * * *\",\n EVERY_19_SECONDS = \"*/19 * * * * *\",\n EVERY_20_SECONDS = \"*/20 * * * * *\",\n EVERY_21_SECONDS = \"*/21 * * * * *\",\n EVERY_22_SECONDS = \"*/22 * * * * *\",\n EVERY_23_SECONDS = \"*/23 * * * * *\",\n EVERY_24_SECONDS = \"*/24 * * * * *\",\n EVERY_25_SECONDS = \"*/25 * * * * *\",\n EVERY_26_SECONDS = \"*/26 * * * * *\",\n EVERY_27_SECONDS = \"*/27 * * * * *\",\n EVERY_28_SECONDS = \"*/28 * * * * *\",\n EVERY_29_SECONDS = \"*/29 * * * * *\",\n EVERY_30_SECONDS = \"*/30 * * * * *\",\n EVERY_31_SECONDS = \"*/31 * * * * *\",\n EVERY_32_SECONDS = \"*/32 * * * * *\",\n EVERY_33_SECONDS = \"*/33 * * * * *\",\n EVERY_34_SECONDS = \"*/34 * * * * *\",\n EVERY_35_SECONDS = \"*/35 * * * * *\",\n EVERY_36_SECONDS = \"*/36 * * * * *\",\n EVERY_37_SECONDS = \"*/37 * * * * *\",\n EVERY_38_SECONDS = \"*/38 * * * * *\",\n EVERY_39_SECONDS = \"*/39 * * * * *\",\n EVERY_40_SECONDS = \"*/40 * * * * *\",\n EVERY_41_SECONDS = \"*/41 * * * * *\",\n EVERY_42_SECONDS = \"*/42 * * * * *\",\n EVERY_43_SECONDS = \"*/43 * * * * *\",\n EVERY_44_SECONDS = \"*/44 * * * * *\",\n EVERY_45_SECONDS = \"*/45 * * * * *\",\n EVERY_46_SECONDS = \"*/46 * * * * *\",\n EVERY_47_SECONDS = \"*/47 * * * * *\",\n EVERY_48_SECONDS = \"*/48 * * * * *\",\n EVERY_49_SECONDS = \"*/49 * * * * *\",\n EVERY_50_SECONDS = \"*/50 * * * * *\",\n EVERY_51_SECONDS = \"*/51 * * * * *\",\n EVERY_52_SECONDS = \"*/52 * * * * *\",\n EVERY_53_SECONDS = \"*/53 * * * * *\",\n EVERY_54_SECONDS = \"*/54 * * * * *\",\n EVERY_55_SECONDS = \"*/55 * * * * *\",\n EVERY_56_SECONDS = \"*/56 * * * * *\",\n EVERY_57_SECONDS = \"*/57 * * * * *\",\n EVERY_58_SECONDS = \"*/58 * * * * *\",\n EVERY_59_SECONDS = \"*/59 * * * * *\",\n EVERY_MINUTE = \"0 * * * * *\",\n}","import { KafkaOptions, MqttOptions, NatsOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\ntype BrokerConfig = MqttOptions | NatsOptions | KafkaOptions;\n\nexport class TypeormOutboxRegisterCronModuleOptions {\n brokerConfig: BrokerConfig = {};\n typeOrmConnectionName?: string = \"default\";\n cronExpression?: string = CronExpression.EVERY_SECOND;\n}\n\nexport interface TypeormOutboxRegisterCronAsyncOptions\n extends Pick<ModuleMetadata, \"imports\"> {\n inject?: InjectionToken[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: unknown[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\n\nexport interface TypeormOutboxModuleAsyncOptions\n extends Pick<ModuleMetadata, \"imports\"> {\n inject?: InjectionToken[];\n useFactory?: (\n ...args: unknown[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import { Injectable, OnModuleInit } from \"@nestjs/common\";\nimport { InjectTypeormOutboxBroker, InjectTypeormOutboxCronConfig } from \"./typeorm-outbox.di-tokens\";\nimport { hashStringToInt } from \"@globalart/text-utils\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy, Transport } from \"@nestjs/microservices\";\nimport { CronJob } from \"cron\";\nimport { TypeormOutboxRegisterCronModuleOptions } from \"./typeorm-outbox.interfaces\";\nimport { DataSource } from \"typeorm\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\n@Injectable()\nexport class TypeormOutboxCronService implements OnModuleInit {\n constructor(\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n @InjectTypeormOutboxCronConfig()\n private readonly moduleConfig: TypeormOutboxRegisterCronModuleOptions,\n private readonly dataSource: DataSource,\n ) { }\n\n onModuleInit() {\n this.validateBrokerClient();\n const cronJob = new CronJob(this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND, () => {\n this.executeCronJob();\n });\n cronJob.start();\n }\n\n private validateBrokerClient() {\n const brokerConfig = this.moduleConfig.brokerConfig;\n if (![Transport.KAFKA, Transport.NATS, Transport.MQTT].includes(brokerConfig?.transport as Transport)) {\n throw new Error(`[TypeormOutboxCronService] Broker config must be an instance of KafkaOptions, NatsOptions, or MqttOptions`);\n }\n }\n\n private async executeCronJob() {\n const queryRunner = this.dataSource.createQueryRunner();\n await queryRunner.connect();\n const lockKey = hashStringToInt('typeorm-outbox-cron-lock');\n\n try {\n const lockResult = await queryRunner.query(\n 'SELECT pg_try_advisory_lock($1) as locked',\n [lockKey],\n );\n\n if (!lockResult[0].locked) {\n return;\n }\n try {\n await queryRunner.startTransaction('REPEATABLE READ');\n \n const entities = await queryRunner.manager.find(TypeormOutboxEntity, {\n order: {\n createdAt: 'ASC',\n },\n });\n \n for (const entity of entities) {\n await firstValueFrom(\n this.brokerClient.emit(entity.destinationTopic, {\n key: entity.keys,\n value: entity.payload,\n headers: entity.headers,\n }),\n );\n await queryRunner.manager.delete(TypeormOutboxEntity, entity.id);\n }\n\n await queryRunner.commitTransaction();\n } catch (error) {\n await queryRunner.rollbackTransaction();\n throw error;\n } finally {\n await queryRunner.query('SELECT pg_advisory_unlock($1)', [lockKey]);\n }\n } finally {\n await queryRunner.release();\n }\n }\n}\n","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\n\nexport interface CreateOutboxOptions {\n destinationTopic: string;\n payload: Record<string, unknown>;\n headers?: Record<string, string>;\n keys?: Record<string, unknown>;\n}\n\n@Injectable()\nexport class TypeormOutboxService {\n constructor(\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n ) {}\n\n async create(options: CreateOutboxOptions): Promise<TypeormOutboxEntity> {\n return this.outboxRepository.save({\n destinationTopic: options.destinationTopic,\n headers: options.headers,\n keys: options.keys,\n payload: options.payload,\n });\n }\n}\n","import { TypeOrmModule } from \"@nestjs/typeorm\";\nimport { DynamicModule, Module, Provider } from \"@nestjs/common\";\nimport {\n TypeormOutboxRegisterCronAsyncOptions,\n TypeormOutboxRegisterCronModuleOptions,\n TypeormOutboxModuleOptions,\n TypeormOutboxModuleAsyncOptions,\n} from \"./typeorm-outbox.interfaces\";\nimport {\n TYPEORM_OUTBOX_BROKER_TOKEN,\n TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n TYPEORM_OUTBOX_SERVICE_TOKEN,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { TypeormOutboxService } from \"./typeorm-outbox.service\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\nimport { TypeormOutboxCronService } from \"./typeorm-outbox-cron.service\";\n\n@Module({})\nexport class TypeormOutboxModule {\n private static createServiceProvider(): Provider {\n return {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n }\n\n private static createBrokerProvider(useValue: unknown = null): Provider {\n return {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue,\n };\n }\n\n private static createTypeOrmFeature(connectionName?: string) {\n return TypeOrmModule.forFeature(\n [TypeormOutboxEntity],\n connectionName || \"default\",\n );\n }\n\n private static createModuleConfigProvider(\n options: TypeormOutboxModuleOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: {\n ...new TypeormOutboxModuleOptions(),\n ...options,\n },\n };\n }\n\n private static createAsyncModuleConfigProvider(\n options: TypeormOutboxModuleAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = (await options.useFactory?.(...args)) as\n | TypeormOutboxModuleOptions;\n \n return {\n ...new TypeormOutboxModuleOptions(),\n ...moduleOptions,\n };\n },\n inject: options.inject || [],\n };\n }\n\n private static createCronConfigProvider(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = await options.useFactory?.(...args);\n return {\n ...new TypeormOutboxRegisterCronModuleOptions(),\n ...moduleOptions,\n };\n },\n inject: options.inject || [],\n };\n }\n\n private static createCronBrokerProvider(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = await options.useFactory?.(...args);\n const config = {\n ...new TypeormOutboxRegisterCronModuleOptions(),\n ...moduleOptions,\n };\n return ClientProxyFactory.create(config?.brokerConfig ?? {});\n },\n inject: options.inject || [],\n };\n }\n\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const configProvider = this.createModuleConfigProvider(options);\n const serviceProvider = this.createServiceProvider();\n const brokerProvider = this.createBrokerProvider();\n const PROVIDERS = [configProvider, serviceProvider, brokerProvider];\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [this.createTypeOrmFeature(options.typeOrmConnectionName)],\n providers: [...PROVIDERS],\n exports: [...PROVIDERS],\n };\n }\n\n static forRootAsync(\n options: TypeormOutboxModuleAsyncOptions,\n ): DynamicModule {\n const configProvider = this.createAsyncModuleConfigProvider(options);\n const serviceProvider = this.createServiceProvider();\n const brokerProvider = this.createBrokerProvider();\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [this.createTypeOrmFeature()],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const configProvider = this.createCronConfigProvider(options);\n const brokerProvider = this.createCronBrokerProvider(options);\n const serviceProvider = this.createServiceProvider();\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [\n this.createTypeOrmFeature(),\n ],\n providers: [\n TypeormOutboxCronService,\n configProvider,\n brokerProvider,\n serviceProvider,\n ],\n exports: [configProvider, brokerProvider, serviceProvider],\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["CronJob","Transport","TypeOrmModule","ClientProxyFactory"],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.enums.ts","../src/core/typeorm-outbox.interfaces.ts","../src/core/typeorm-outbox-cron.service.ts","../src/core/typeorm-outbox.service.ts","../src/core/typeorm-outbox.module.ts"],"sourcesContent":["import { Inject } from \"@nestjs/common\";\n\nexport const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_CRON_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_SERVICE_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_BROKER_TOKEN\",\n);\n\nexport const InjectTypeormOutboxCronConfig = () =>\n Inject(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);\nexport const InjectTypeormOutboxModuleConfig = () =>\n Inject(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);\nexport const InjectTypeormOutboxService = () =>\n Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);\nexport const InjectTypeormOutboxBroker = () =>\n Inject(TYPEORM_OUTBOX_BROKER_TOKEN);\n","import {\n Column,\n CreateDateColumn,\n Entity,\n PrimaryGeneratedColumn,\n UpdateDateColumn,\n} from \"typeorm\";\n\n@Entity('outbox')\nexport class TypeormOutboxEntity {\n @PrimaryGeneratedColumn()\n id!: number;\n\n @CreateDateColumn({ name: 'created_at' })\n createdAt!: Date;\n\n @UpdateDateColumn({ name: 'updated_at' })\n updatedAt!: Date;\n\n @Column(\"character varying\", { name: 'destination_topic' })\n destinationTopic!: string;\n\n @Column(\"jsonb\", { nullable: true })\n headers!: Record<string, string>;\n\n @Column(\"jsonb\", { nullable: true })\n keys!: Record<string, unknown>;\n\n @Column(\"jsonb\")\n payload!: Record<string, any>;\n}\n","export enum CronExpression {\n EVERY_SECOND = \"* * * * * *\",\n EVERY_2_SECONDS = \"*/2 * * * * *\",\n EVERY_3_SECONDS = \"*/3 * * * * *\",\n EVERY_4_SECONDS = \"*/4 * * * * *\",\n EVERY_5_SECONDS = \"*/5 * * * * *\",\n EVERY_6_SECONDS = \"*/6 * * * * *\",\n EVERY_7_SECONDS = \"*/7 * * * * *\",\n EVERY_8_SECONDS = \"*/8 * * * * *\",\n EVERY_9_SECONDS = \"*/9 * * * * *\",\n EVERY_10_SECONDS = \"*/10 * * * * *\",\n EVERY_11_SECONDS = \"*/11 * * * * *\",\n EVERY_12_SECONDS = \"*/12 * * * * *\",\n EVERY_13_SECONDS = \"*/13 * * * * *\",\n EVERY_14_SECONDS = \"*/14 * * * * *\",\n EVERY_15_SECONDS = \"*/15 * * * * *\",\n EVERY_16_SECONDS = \"*/16 * * * * *\",\n EVERY_17_SECONDS = \"*/17 * * * * *\",\n EVERY_18_SECONDS = \"*/18 * * * * *\",\n EVERY_19_SECONDS = \"*/19 * * * * *\",\n EVERY_20_SECONDS = \"*/20 * * * * *\",\n EVERY_21_SECONDS = \"*/21 * * * * *\",\n EVERY_22_SECONDS = \"*/22 * * * * *\",\n EVERY_23_SECONDS = \"*/23 * * * * *\",\n EVERY_24_SECONDS = \"*/24 * * * * *\",\n EVERY_25_SECONDS = \"*/25 * * * * *\",\n EVERY_26_SECONDS = \"*/26 * * * * *\",\n EVERY_27_SECONDS = \"*/27 * * * * *\",\n EVERY_28_SECONDS = \"*/28 * * * * *\",\n EVERY_29_SECONDS = \"*/29 * * * * *\",\n EVERY_30_SECONDS = \"*/30 * * * * *\",\n EVERY_31_SECONDS = \"*/31 * * * * *\",\n EVERY_32_SECONDS = \"*/32 * * * * *\",\n EVERY_33_SECONDS = \"*/33 * * * * *\",\n EVERY_34_SECONDS = \"*/34 * * * * *\",\n EVERY_35_SECONDS = \"*/35 * * * * *\",\n EVERY_36_SECONDS = \"*/36 * * * * *\",\n EVERY_37_SECONDS = \"*/37 * * * * *\",\n EVERY_38_SECONDS = \"*/38 * * * * *\",\n EVERY_39_SECONDS = \"*/39 * * * * *\",\n EVERY_40_SECONDS = \"*/40 * * * * *\",\n EVERY_41_SECONDS = \"*/41 * * * * *\",\n EVERY_42_SECONDS = \"*/42 * * * * *\",\n EVERY_43_SECONDS = \"*/43 * * * * *\",\n EVERY_44_SECONDS = \"*/44 * * * * *\",\n EVERY_45_SECONDS = \"*/45 * * * * *\",\n EVERY_46_SECONDS = \"*/46 * * * * *\",\n EVERY_47_SECONDS = \"*/47 * * * * *\",\n EVERY_48_SECONDS = \"*/48 * * * * *\",\n EVERY_49_SECONDS = \"*/49 * * * * *\",\n EVERY_50_SECONDS = \"*/50 * * * * *\",\n EVERY_51_SECONDS = \"*/51 * * * * *\",\n EVERY_52_SECONDS = \"*/52 * * * * *\",\n EVERY_53_SECONDS = \"*/53 * * * * *\",\n EVERY_54_SECONDS = \"*/54 * * * * *\",\n EVERY_55_SECONDS = \"*/55 * * * * *\",\n EVERY_56_SECONDS = \"*/56 * * * * *\",\n EVERY_57_SECONDS = \"*/57 * * * * *\",\n EVERY_58_SECONDS = \"*/58 * * * * *\",\n EVERY_59_SECONDS = \"*/59 * * * * *\",\n EVERY_MINUTE = \"0 * * * * *\",\n}","import { KafkaOptions, MqttOptions, NatsOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\ntype BrokerConfig = MqttOptions | NatsOptions | KafkaOptions;\n\nexport class TypeormOutboxRegisterCronModuleOptions {\n brokerConfig: BrokerConfig = {};\n typeOrmConnectionName?: string = \"default\";\n cronExpression?: string = CronExpression.EVERY_SECOND;\n}\n\nexport interface TypeormOutboxRegisterCronAsyncOptions\n extends Pick<ModuleMetadata, \"imports\"> {\n inject?: InjectionToken[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: unknown[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\n\nexport interface TypeormOutboxModuleAsyncOptions\n extends Pick<ModuleMetadata, \"imports\"> {\n inject?: InjectionToken[];\n useFactory?: (\n ...args: unknown[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import {\n Injectable,\n OnApplicationBootstrap,\n OnModuleInit,\n} from \"@nestjs/common\";\nimport {\n InjectTypeormOutboxBroker,\n InjectTypeormOutboxCronConfig,\n} from \"./typeorm-outbox.di-tokens\";\nimport { hashStringToInt } from \"@globalart/text-utils\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy, Transport } from \"@nestjs/microservices\";\nimport { CronJob } from \"cron\";\nimport { TypeormOutboxRegisterCronModuleOptions } from \"./typeorm-outbox.interfaces\";\nimport { DataSource } from \"typeorm\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\n@Injectable()\nexport class TypeormOutboxCronService implements OnApplicationBootstrap {\n constructor(\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n @InjectTypeormOutboxCronConfig()\n private readonly moduleConfig: TypeormOutboxRegisterCronModuleOptions,\n private readonly dataSource: DataSource,\n ) {}\n\n onApplicationBootstrap() {\n this.validateBrokerClient();\n const cronJob = new CronJob(\n this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND,\n () => {\n this.executeCronJob();\n },\n );\n cronJob.start();\n }\n\n private validateBrokerClient() {\n const brokerConfig = this.moduleConfig.brokerConfig;\n if (\n ![Transport.KAFKA, Transport.NATS, Transport.MQTT].includes(\n brokerConfig?.transport as Transport,\n )\n ) {\n throw new Error(\n `[TypeormOutboxCronService] Broker config must be an instance of KafkaOptions, NatsOptions, or MqttOptions`,\n );\n }\n }\n\n private async executeCronJob() {\n const queryRunner = this.dataSource.createQueryRunner();\n await queryRunner.connect();\n const lockKey = hashStringToInt(\"typeorm-outbox-cron-lock\");\n\n try {\n const lockResult = await queryRunner.query(\n \"SELECT pg_try_advisory_lock($1) as locked\",\n [lockKey],\n );\n\n if (!lockResult[0].locked) {\n return;\n }\n try {\n await queryRunner.startTransaction(\"REPEATABLE READ\");\n\n const entities = await queryRunner.manager.find(TypeormOutboxEntity, {\n order: {\n createdAt: \"ASC\",\n },\n });\n\n for (const entity of entities) {\n await firstValueFrom(\n this.brokerClient.emit(entity.destinationTopic, {\n key: entity.keys,\n value: entity.payload,\n headers: entity.headers,\n }),\n );\n await queryRunner.manager.delete(TypeormOutboxEntity, entity.id);\n }\n\n await queryRunner.commitTransaction();\n } catch (error) {\n await queryRunner.rollbackTransaction();\n throw error;\n } finally {\n await queryRunner.query(\"SELECT pg_advisory_unlock($1)\", [lockKey]);\n }\n } finally {\n await queryRunner.release();\n }\n }\n}\n","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\n\nexport interface CreateOutboxOptions {\n destinationTopic: string;\n payload: Record<string, unknown>;\n headers?: Record<string, string>;\n keys?: Record<string, unknown>;\n}\n\n@Injectable()\nexport class TypeormOutboxService {\n constructor(\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n ) {}\n\n async create(options: CreateOutboxOptions): Promise<TypeormOutboxEntity> {\n return this.outboxRepository.save({\n destinationTopic: options.destinationTopic,\n headers: options.headers,\n keys: options.keys,\n payload: options.payload,\n });\n }\n}\n","import { TypeOrmModule } from \"@nestjs/typeorm\";\nimport { DynamicModule, Module, Provider } from \"@nestjs/common\";\nimport {\n TypeormOutboxRegisterCronAsyncOptions,\n TypeormOutboxRegisterCronModuleOptions,\n TypeormOutboxModuleOptions,\n TypeormOutboxModuleAsyncOptions,\n} from \"./typeorm-outbox.interfaces\";\nimport {\n TYPEORM_OUTBOX_BROKER_TOKEN,\n TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n TYPEORM_OUTBOX_SERVICE_TOKEN,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { TypeormOutboxService } from \"./typeorm-outbox.service\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\nimport { TypeormOutboxCronService } from \"./typeorm-outbox-cron.service\";\n\n@Module({})\nexport class TypeormOutboxModule {\n private static createServiceProvider(): Provider {\n return {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n }\n\n private static createBrokerProvider(useValue: unknown = null): Provider {\n return {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue,\n };\n }\n\n private static createTypeOrmFeature(connectionName?: string) {\n return TypeOrmModule.forFeature(\n [TypeormOutboxEntity],\n connectionName || \"default\",\n );\n }\n\n private static createModuleConfigProvider(\n options: TypeormOutboxModuleOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: {\n ...new TypeormOutboxModuleOptions(),\n ...options,\n },\n };\n }\n\n private static createAsyncModuleConfigProvider(\n options: TypeormOutboxModuleAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = (await options.useFactory?.(...args)) as\n | TypeormOutboxModuleOptions;\n \n return {\n ...new TypeormOutboxModuleOptions(),\n ...moduleOptions,\n };\n },\n inject: options.inject || [],\n };\n }\n\n private static createCronConfigProvider(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = await options.useFactory?.(...args);\n return {\n ...new TypeormOutboxRegisterCronModuleOptions(),\n ...moduleOptions,\n };\n },\n inject: options.inject || [],\n };\n }\n\n private static createCronBrokerProvider(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = await options.useFactory?.(...args);\n const config = {\n ...new TypeormOutboxRegisterCronModuleOptions(),\n ...moduleOptions,\n };\n return ClientProxyFactory.create(config?.brokerConfig ?? {});\n },\n inject: options.inject || [],\n };\n }\n\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const configProvider = this.createModuleConfigProvider(options);\n const serviceProvider = this.createServiceProvider();\n const brokerProvider = this.createBrokerProvider();\n const PROVIDERS = [configProvider, serviceProvider, brokerProvider];\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [this.createTypeOrmFeature(options.typeOrmConnectionName)],\n providers: [...PROVIDERS],\n exports: [...PROVIDERS],\n };\n }\n\n static forRootAsync(\n options: TypeormOutboxModuleAsyncOptions,\n ): DynamicModule {\n const configProvider = this.createAsyncModuleConfigProvider(options);\n const serviceProvider = this.createServiceProvider();\n const brokerProvider = this.createBrokerProvider();\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [this.createTypeOrmFeature()],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const configProvider = this.createCronConfigProvider(options);\n const brokerProvider = this.createCronBrokerProvider(options);\n const serviceProvider = this.createServiceProvider();\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [\n this.createTypeOrmFeature(),\n ],\n providers: [\n TypeormOutboxCronService,\n configProvider,\n brokerProvider,\n serviceProvider,\n ],\n exports: [configProvider, brokerProvider, serviceProvider],\n };\n }\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { DynamicModule, InjectionToken, ModuleMetadata, OnModuleInit, Type } from "@nestjs/common";
1
+ import { DynamicModule, InjectionToken, ModuleMetadata, OnApplicationBootstrap, Type } from "@nestjs/common";
2
2
  import { ClientProxy, KafkaOptions, MqttOptions, NatsOptions } from "@nestjs/microservices";
3
3
  import { DataSource, Repository } from "typeorm";
4
4
 
@@ -24,12 +24,12 @@ interface TypeormOutboxModuleAsyncOptions extends Pick<ModuleMetadata, "imports"
24
24
  }
25
25
  //#endregion
26
26
  //#region src/core/typeorm-outbox-cron.service.d.ts
27
- declare class TypeormOutboxCronService implements OnModuleInit {
27
+ declare class TypeormOutboxCronService implements OnApplicationBootstrap {
28
28
  private readonly brokerClient;
29
29
  private readonly moduleConfig;
30
30
  private readonly dataSource;
31
31
  constructor(brokerClient: ClientProxy, moduleConfig: TypeormOutboxRegisterCronModuleOptions, dataSource: DataSource);
32
- onModuleInit(): void;
32
+ onApplicationBootstrap(): void;
33
33
  private validateBrokerClient;
34
34
  private executeCronJob;
35
35
  }
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { DynamicModule, InjectionToken, ModuleMetadata, OnModuleInit, Type } from "@nestjs/common";
1
+ import { DynamicModule, InjectionToken, ModuleMetadata, OnApplicationBootstrap, Type } from "@nestjs/common";
2
2
  import { DataSource, Repository } from "typeorm";
3
3
  import { ClientProxy, KafkaOptions, MqttOptions, NatsOptions } from "@nestjs/microservices";
4
4
 
@@ -24,12 +24,12 @@ interface TypeormOutboxModuleAsyncOptions extends Pick<ModuleMetadata, "imports"
24
24
  }
25
25
  //#endregion
26
26
  //#region src/core/typeorm-outbox-cron.service.d.ts
27
- declare class TypeormOutboxCronService implements OnModuleInit {
27
+ declare class TypeormOutboxCronService implements OnApplicationBootstrap {
28
28
  private readonly brokerClient;
29
29
  private readonly moduleConfig;
30
30
  private readonly dataSource;
31
31
  constructor(brokerClient: ClientProxy, moduleConfig: TypeormOutboxRegisterCronModuleOptions, dataSource: DataSource);
32
- onModuleInit(): void;
32
+ onApplicationBootstrap(): void;
33
33
  private validateBrokerClient;
34
34
  private executeCronJob;
35
35
  }
package/dist/index.mjs CHANGED
@@ -17,13 +17,13 @@ const InjectTypeormOutboxService = () => Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);
17
17
  const InjectTypeormOutboxBroker = () => Inject(TYPEORM_OUTBOX_BROKER_TOKEN);
18
18
 
19
19
  //#endregion
20
- //#region \0@oxc-project+runtime@0.110.0/helpers/decorateMetadata.js
20
+ //#region \0@oxc-project+runtime@0.112.0/helpers/decorateMetadata.js
21
21
  function __decorateMetadata(k, v) {
22
22
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
23
23
  }
24
24
 
25
25
  //#endregion
26
- //#region \0@oxc-project+runtime@0.110.0/helpers/decorate.js
26
+ //#region \0@oxc-project+runtime@0.112.0/helpers/decorate.js
27
27
  function __decorate(decorators, target, key, desc) {
28
28
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
29
29
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -130,7 +130,7 @@ var TypeormOutboxModuleOptions = class {
130
130
  };
131
131
 
132
132
  //#endregion
133
- //#region \0@oxc-project+runtime@0.110.0/helpers/decorateParam.js
133
+ //#region \0@oxc-project+runtime@0.112.0/helpers/decorateParam.js
134
134
  function __decorateParam(paramIndex, decorator) {
135
135
  return function(target, key) {
136
136
  decorator(target, key, paramIndex);
@@ -146,7 +146,7 @@ let TypeormOutboxCronService = class TypeormOutboxCronService {
146
146
  this.moduleConfig = moduleConfig;
147
147
  this.dataSource = dataSource;
148
148
  }
149
- onModuleInit() {
149
+ onApplicationBootstrap() {
150
150
  this.validateBrokerClient();
151
151
  new CronJob(this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND, () => {
152
152
  this.executeCronJob();
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.enums.ts","../src/core/typeorm-outbox.interfaces.ts","../src/core/typeorm-outbox-cron.service.ts","../src/core/typeorm-outbox.service.ts","../src/core/typeorm-outbox.module.ts"],"sourcesContent":["import { Inject } from \"@nestjs/common\";\n\nexport const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_CRON_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_SERVICE_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_BROKER_TOKEN\",\n);\n\nexport const InjectTypeormOutboxCronConfig = () =>\n Inject(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);\nexport const InjectTypeormOutboxModuleConfig = () =>\n Inject(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);\nexport const InjectTypeormOutboxService = () =>\n Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);\nexport const InjectTypeormOutboxBroker = () =>\n Inject(TYPEORM_OUTBOX_BROKER_TOKEN);\n","import {\n Column,\n CreateDateColumn,\n Entity,\n PrimaryGeneratedColumn,\n UpdateDateColumn,\n} from \"typeorm\";\n\n@Entity('outbox')\nexport class TypeormOutboxEntity {\n @PrimaryGeneratedColumn()\n id!: number;\n\n @CreateDateColumn({ name: 'created_at' })\n createdAt!: Date;\n\n @UpdateDateColumn({ name: 'updated_at' })\n updatedAt!: Date;\n\n @Column(\"character varying\", { name: 'destination_topic' })\n destinationTopic!: string;\n\n @Column(\"jsonb\", { nullable: true })\n headers!: Record<string, string>;\n\n @Column(\"jsonb\", { nullable: true })\n keys!: Record<string, unknown>;\n\n @Column(\"jsonb\")\n payload!: Record<string, any>;\n}\n","export enum CronExpression {\n EVERY_SECOND = \"* * * * * *\",\n EVERY_2_SECONDS = \"*/2 * * * * *\",\n EVERY_3_SECONDS = \"*/3 * * * * *\",\n EVERY_4_SECONDS = \"*/4 * * * * *\",\n EVERY_5_SECONDS = \"*/5 * * * * *\",\n EVERY_6_SECONDS = \"*/6 * * * * *\",\n EVERY_7_SECONDS = \"*/7 * * * * *\",\n EVERY_8_SECONDS = \"*/8 * * * * *\",\n EVERY_9_SECONDS = \"*/9 * * * * *\",\n EVERY_10_SECONDS = \"*/10 * * * * *\",\n EVERY_11_SECONDS = \"*/11 * * * * *\",\n EVERY_12_SECONDS = \"*/12 * * * * *\",\n EVERY_13_SECONDS = \"*/13 * * * * *\",\n EVERY_14_SECONDS = \"*/14 * * * * *\",\n EVERY_15_SECONDS = \"*/15 * * * * *\",\n EVERY_16_SECONDS = \"*/16 * * * * *\",\n EVERY_17_SECONDS = \"*/17 * * * * *\",\n EVERY_18_SECONDS = \"*/18 * * * * *\",\n EVERY_19_SECONDS = \"*/19 * * * * *\",\n EVERY_20_SECONDS = \"*/20 * * * * *\",\n EVERY_21_SECONDS = \"*/21 * * * * *\",\n EVERY_22_SECONDS = \"*/22 * * * * *\",\n EVERY_23_SECONDS = \"*/23 * * * * *\",\n EVERY_24_SECONDS = \"*/24 * * * * *\",\n EVERY_25_SECONDS = \"*/25 * * * * *\",\n EVERY_26_SECONDS = \"*/26 * * * * *\",\n EVERY_27_SECONDS = \"*/27 * * * * *\",\n EVERY_28_SECONDS = \"*/28 * * * * *\",\n EVERY_29_SECONDS = \"*/29 * * * * *\",\n EVERY_30_SECONDS = \"*/30 * * * * *\",\n EVERY_31_SECONDS = \"*/31 * * * * *\",\n EVERY_32_SECONDS = \"*/32 * * * * *\",\n EVERY_33_SECONDS = \"*/33 * * * * *\",\n EVERY_34_SECONDS = \"*/34 * * * * *\",\n EVERY_35_SECONDS = \"*/35 * * * * *\",\n EVERY_36_SECONDS = \"*/36 * * * * *\",\n EVERY_37_SECONDS = \"*/37 * * * * *\",\n EVERY_38_SECONDS = \"*/38 * * * * *\",\n EVERY_39_SECONDS = \"*/39 * * * * *\",\n EVERY_40_SECONDS = \"*/40 * * * * *\",\n EVERY_41_SECONDS = \"*/41 * * * * *\",\n EVERY_42_SECONDS = \"*/42 * * * * *\",\n EVERY_43_SECONDS = \"*/43 * * * * *\",\n EVERY_44_SECONDS = \"*/44 * * * * *\",\n EVERY_45_SECONDS = \"*/45 * * * * *\",\n EVERY_46_SECONDS = \"*/46 * * * * *\",\n EVERY_47_SECONDS = \"*/47 * * * * *\",\n EVERY_48_SECONDS = \"*/48 * * * * *\",\n EVERY_49_SECONDS = \"*/49 * * * * *\",\n EVERY_50_SECONDS = \"*/50 * * * * *\",\n EVERY_51_SECONDS = \"*/51 * * * * *\",\n EVERY_52_SECONDS = \"*/52 * * * * *\",\n EVERY_53_SECONDS = \"*/53 * * * * *\",\n EVERY_54_SECONDS = \"*/54 * * * * *\",\n EVERY_55_SECONDS = \"*/55 * * * * *\",\n EVERY_56_SECONDS = \"*/56 * * * * *\",\n EVERY_57_SECONDS = \"*/57 * * * * *\",\n EVERY_58_SECONDS = \"*/58 * * * * *\",\n EVERY_59_SECONDS = \"*/59 * * * * *\",\n EVERY_MINUTE = \"0 * * * * *\",\n}","import { KafkaOptions, MqttOptions, NatsOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\ntype BrokerConfig = MqttOptions | NatsOptions | KafkaOptions;\n\nexport class TypeormOutboxRegisterCronModuleOptions {\n brokerConfig: BrokerConfig = {};\n typeOrmConnectionName?: string = \"default\";\n cronExpression?: string = CronExpression.EVERY_SECOND;\n}\n\nexport interface TypeormOutboxRegisterCronAsyncOptions\n extends Pick<ModuleMetadata, \"imports\"> {\n inject?: InjectionToken[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: unknown[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\n\nexport interface TypeormOutboxModuleAsyncOptions\n extends Pick<ModuleMetadata, \"imports\"> {\n inject?: InjectionToken[];\n useFactory?: (\n ...args: unknown[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import { Injectable, OnModuleInit } from \"@nestjs/common\";\nimport { InjectTypeormOutboxBroker, InjectTypeormOutboxCronConfig } from \"./typeorm-outbox.di-tokens\";\nimport { hashStringToInt } from \"@globalart/text-utils\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy, Transport } from \"@nestjs/microservices\";\nimport { CronJob } from \"cron\";\nimport { TypeormOutboxRegisterCronModuleOptions } from \"./typeorm-outbox.interfaces\";\nimport { DataSource } from \"typeorm\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\n@Injectable()\nexport class TypeormOutboxCronService implements OnModuleInit {\n constructor(\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n @InjectTypeormOutboxCronConfig()\n private readonly moduleConfig: TypeormOutboxRegisterCronModuleOptions,\n private readonly dataSource: DataSource,\n ) { }\n\n onModuleInit() {\n this.validateBrokerClient();\n const cronJob = new CronJob(this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND, () => {\n this.executeCronJob();\n });\n cronJob.start();\n }\n\n private validateBrokerClient() {\n const brokerConfig = this.moduleConfig.brokerConfig;\n if (![Transport.KAFKA, Transport.NATS, Transport.MQTT].includes(brokerConfig?.transport as Transport)) {\n throw new Error(`[TypeormOutboxCronService] Broker config must be an instance of KafkaOptions, NatsOptions, or MqttOptions`);\n }\n }\n\n private async executeCronJob() {\n const queryRunner = this.dataSource.createQueryRunner();\n await queryRunner.connect();\n const lockKey = hashStringToInt('typeorm-outbox-cron-lock');\n\n try {\n const lockResult = await queryRunner.query(\n 'SELECT pg_try_advisory_lock($1) as locked',\n [lockKey],\n );\n\n if (!lockResult[0].locked) {\n return;\n }\n try {\n await queryRunner.startTransaction('REPEATABLE READ');\n \n const entities = await queryRunner.manager.find(TypeormOutboxEntity, {\n order: {\n createdAt: 'ASC',\n },\n });\n \n for (const entity of entities) {\n await firstValueFrom(\n this.brokerClient.emit(entity.destinationTopic, {\n key: entity.keys,\n value: entity.payload,\n headers: entity.headers,\n }),\n );\n await queryRunner.manager.delete(TypeormOutboxEntity, entity.id);\n }\n\n await queryRunner.commitTransaction();\n } catch (error) {\n await queryRunner.rollbackTransaction();\n throw error;\n } finally {\n await queryRunner.query('SELECT pg_advisory_unlock($1)', [lockKey]);\n }\n } finally {\n await queryRunner.release();\n }\n }\n}\n","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\n\nexport interface CreateOutboxOptions {\n destinationTopic: string;\n payload: Record<string, unknown>;\n headers?: Record<string, string>;\n keys?: Record<string, unknown>;\n}\n\n@Injectable()\nexport class TypeormOutboxService {\n constructor(\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n ) {}\n\n async create(options: CreateOutboxOptions): Promise<TypeormOutboxEntity> {\n return this.outboxRepository.save({\n destinationTopic: options.destinationTopic,\n headers: options.headers,\n keys: options.keys,\n payload: options.payload,\n });\n }\n}\n","import { TypeOrmModule } from \"@nestjs/typeorm\";\nimport { DynamicModule, Module, Provider } from \"@nestjs/common\";\nimport {\n TypeormOutboxRegisterCronAsyncOptions,\n TypeormOutboxRegisterCronModuleOptions,\n TypeormOutboxModuleOptions,\n TypeormOutboxModuleAsyncOptions,\n} from \"./typeorm-outbox.interfaces\";\nimport {\n TYPEORM_OUTBOX_BROKER_TOKEN,\n TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n TYPEORM_OUTBOX_SERVICE_TOKEN,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { TypeormOutboxService } from \"./typeorm-outbox.service\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\nimport { TypeormOutboxCronService } from \"./typeorm-outbox-cron.service\";\n\n@Module({})\nexport class TypeormOutboxModule {\n private static createServiceProvider(): Provider {\n return {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n }\n\n private static createBrokerProvider(useValue: unknown = null): Provider {\n return {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue,\n };\n }\n\n private static createTypeOrmFeature(connectionName?: string) {\n return TypeOrmModule.forFeature(\n [TypeormOutboxEntity],\n connectionName || \"default\",\n );\n }\n\n private static createModuleConfigProvider(\n options: TypeormOutboxModuleOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: {\n ...new TypeormOutboxModuleOptions(),\n ...options,\n },\n };\n }\n\n private static createAsyncModuleConfigProvider(\n options: TypeormOutboxModuleAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = (await options.useFactory?.(...args)) as\n | TypeormOutboxModuleOptions;\n \n return {\n ...new TypeormOutboxModuleOptions(),\n ...moduleOptions,\n };\n },\n inject: options.inject || [],\n };\n }\n\n private static createCronConfigProvider(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = await options.useFactory?.(...args);\n return {\n ...new TypeormOutboxRegisterCronModuleOptions(),\n ...moduleOptions,\n };\n },\n inject: options.inject || [],\n };\n }\n\n private static createCronBrokerProvider(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = await options.useFactory?.(...args);\n const config = {\n ...new TypeormOutboxRegisterCronModuleOptions(),\n ...moduleOptions,\n };\n return ClientProxyFactory.create(config?.brokerConfig ?? {});\n },\n inject: options.inject || [],\n };\n }\n\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const configProvider = this.createModuleConfigProvider(options);\n const serviceProvider = this.createServiceProvider();\n const brokerProvider = this.createBrokerProvider();\n const PROVIDERS = [configProvider, serviceProvider, brokerProvider];\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [this.createTypeOrmFeature(options.typeOrmConnectionName)],\n providers: [...PROVIDERS],\n exports: [...PROVIDERS],\n };\n }\n\n static forRootAsync(\n options: TypeormOutboxModuleAsyncOptions,\n ): DynamicModule {\n const configProvider = this.createAsyncModuleConfigProvider(options);\n const serviceProvider = this.createServiceProvider();\n const brokerProvider = this.createBrokerProvider();\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [this.createTypeOrmFeature()],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const configProvider = this.createCronConfigProvider(options);\n const brokerProvider = this.createCronBrokerProvider(options);\n const serviceProvider = this.createServiceProvider();\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [\n this.createTypeOrmFeature(),\n ],\n providers: [\n TypeormOutboxCronService,\n configProvider,\n brokerProvider,\n serviceProvider,\n ],\n exports: [configProvider, brokerProvider, serviceProvider],\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.enums.ts","../src/core/typeorm-outbox.interfaces.ts","../src/core/typeorm-outbox-cron.service.ts","../src/core/typeorm-outbox.service.ts","../src/core/typeorm-outbox.module.ts"],"sourcesContent":["import { Inject } from \"@nestjs/common\";\n\nexport const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_CRON_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_SERVICE_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_BROKER_TOKEN\",\n);\n\nexport const InjectTypeormOutboxCronConfig = () =>\n Inject(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);\nexport const InjectTypeormOutboxModuleConfig = () =>\n Inject(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);\nexport const InjectTypeormOutboxService = () =>\n Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);\nexport const InjectTypeormOutboxBroker = () =>\n Inject(TYPEORM_OUTBOX_BROKER_TOKEN);\n","import {\n Column,\n CreateDateColumn,\n Entity,\n PrimaryGeneratedColumn,\n UpdateDateColumn,\n} from \"typeorm\";\n\n@Entity('outbox')\nexport class TypeormOutboxEntity {\n @PrimaryGeneratedColumn()\n id!: number;\n\n @CreateDateColumn({ name: 'created_at' })\n createdAt!: Date;\n\n @UpdateDateColumn({ name: 'updated_at' })\n updatedAt!: Date;\n\n @Column(\"character varying\", { name: 'destination_topic' })\n destinationTopic!: string;\n\n @Column(\"jsonb\", { nullable: true })\n headers!: Record<string, string>;\n\n @Column(\"jsonb\", { nullable: true })\n keys!: Record<string, unknown>;\n\n @Column(\"jsonb\")\n payload!: Record<string, any>;\n}\n","export enum CronExpression {\n EVERY_SECOND = \"* * * * * *\",\n EVERY_2_SECONDS = \"*/2 * * * * *\",\n EVERY_3_SECONDS = \"*/3 * * * * *\",\n EVERY_4_SECONDS = \"*/4 * * * * *\",\n EVERY_5_SECONDS = \"*/5 * * * * *\",\n EVERY_6_SECONDS = \"*/6 * * * * *\",\n EVERY_7_SECONDS = \"*/7 * * * * *\",\n EVERY_8_SECONDS = \"*/8 * * * * *\",\n EVERY_9_SECONDS = \"*/9 * * * * *\",\n EVERY_10_SECONDS = \"*/10 * * * * *\",\n EVERY_11_SECONDS = \"*/11 * * * * *\",\n EVERY_12_SECONDS = \"*/12 * * * * *\",\n EVERY_13_SECONDS = \"*/13 * * * * *\",\n EVERY_14_SECONDS = \"*/14 * * * * *\",\n EVERY_15_SECONDS = \"*/15 * * * * *\",\n EVERY_16_SECONDS = \"*/16 * * * * *\",\n EVERY_17_SECONDS = \"*/17 * * * * *\",\n EVERY_18_SECONDS = \"*/18 * * * * *\",\n EVERY_19_SECONDS = \"*/19 * * * * *\",\n EVERY_20_SECONDS = \"*/20 * * * * *\",\n EVERY_21_SECONDS = \"*/21 * * * * *\",\n EVERY_22_SECONDS = \"*/22 * * * * *\",\n EVERY_23_SECONDS = \"*/23 * * * * *\",\n EVERY_24_SECONDS = \"*/24 * * * * *\",\n EVERY_25_SECONDS = \"*/25 * * * * *\",\n EVERY_26_SECONDS = \"*/26 * * * * *\",\n EVERY_27_SECONDS = \"*/27 * * * * *\",\n EVERY_28_SECONDS = \"*/28 * * * * *\",\n EVERY_29_SECONDS = \"*/29 * * * * *\",\n EVERY_30_SECONDS = \"*/30 * * * * *\",\n EVERY_31_SECONDS = \"*/31 * * * * *\",\n EVERY_32_SECONDS = \"*/32 * * * * *\",\n EVERY_33_SECONDS = \"*/33 * * * * *\",\n EVERY_34_SECONDS = \"*/34 * * * * *\",\n EVERY_35_SECONDS = \"*/35 * * * * *\",\n EVERY_36_SECONDS = \"*/36 * * * * *\",\n EVERY_37_SECONDS = \"*/37 * * * * *\",\n EVERY_38_SECONDS = \"*/38 * * * * *\",\n EVERY_39_SECONDS = \"*/39 * * * * *\",\n EVERY_40_SECONDS = \"*/40 * * * * *\",\n EVERY_41_SECONDS = \"*/41 * * * * *\",\n EVERY_42_SECONDS = \"*/42 * * * * *\",\n EVERY_43_SECONDS = \"*/43 * * * * *\",\n EVERY_44_SECONDS = \"*/44 * * * * *\",\n EVERY_45_SECONDS = \"*/45 * * * * *\",\n EVERY_46_SECONDS = \"*/46 * * * * *\",\n EVERY_47_SECONDS = \"*/47 * * * * *\",\n EVERY_48_SECONDS = \"*/48 * * * * *\",\n EVERY_49_SECONDS = \"*/49 * * * * *\",\n EVERY_50_SECONDS = \"*/50 * * * * *\",\n EVERY_51_SECONDS = \"*/51 * * * * *\",\n EVERY_52_SECONDS = \"*/52 * * * * *\",\n EVERY_53_SECONDS = \"*/53 * * * * *\",\n EVERY_54_SECONDS = \"*/54 * * * * *\",\n EVERY_55_SECONDS = \"*/55 * * * * *\",\n EVERY_56_SECONDS = \"*/56 * * * * *\",\n EVERY_57_SECONDS = \"*/57 * * * * *\",\n EVERY_58_SECONDS = \"*/58 * * * * *\",\n EVERY_59_SECONDS = \"*/59 * * * * *\",\n EVERY_MINUTE = \"0 * * * * *\",\n}","import { KafkaOptions, MqttOptions, NatsOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\ntype BrokerConfig = MqttOptions | NatsOptions | KafkaOptions;\n\nexport class TypeormOutboxRegisterCronModuleOptions {\n brokerConfig: BrokerConfig = {};\n typeOrmConnectionName?: string = \"default\";\n cronExpression?: string = CronExpression.EVERY_SECOND;\n}\n\nexport interface TypeormOutboxRegisterCronAsyncOptions\n extends Pick<ModuleMetadata, \"imports\"> {\n inject?: InjectionToken[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: unknown[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\n\nexport interface TypeormOutboxModuleAsyncOptions\n extends Pick<ModuleMetadata, \"imports\"> {\n inject?: InjectionToken[];\n useFactory?: (\n ...args: unknown[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import {\n Injectable,\n OnApplicationBootstrap,\n OnModuleInit,\n} from \"@nestjs/common\";\nimport {\n InjectTypeormOutboxBroker,\n InjectTypeormOutboxCronConfig,\n} from \"./typeorm-outbox.di-tokens\";\nimport { hashStringToInt } from \"@globalart/text-utils\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy, Transport } from \"@nestjs/microservices\";\nimport { CronJob } from \"cron\";\nimport { TypeormOutboxRegisterCronModuleOptions } from \"./typeorm-outbox.interfaces\";\nimport { DataSource } from \"typeorm\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\n@Injectable()\nexport class TypeormOutboxCronService implements OnApplicationBootstrap {\n constructor(\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n @InjectTypeormOutboxCronConfig()\n private readonly moduleConfig: TypeormOutboxRegisterCronModuleOptions,\n private readonly dataSource: DataSource,\n ) {}\n\n onApplicationBootstrap() {\n this.validateBrokerClient();\n const cronJob = new CronJob(\n this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND,\n () => {\n this.executeCronJob();\n },\n );\n cronJob.start();\n }\n\n private validateBrokerClient() {\n const brokerConfig = this.moduleConfig.brokerConfig;\n if (\n ![Transport.KAFKA, Transport.NATS, Transport.MQTT].includes(\n brokerConfig?.transport as Transport,\n )\n ) {\n throw new Error(\n `[TypeormOutboxCronService] Broker config must be an instance of KafkaOptions, NatsOptions, or MqttOptions`,\n );\n }\n }\n\n private async executeCronJob() {\n const queryRunner = this.dataSource.createQueryRunner();\n await queryRunner.connect();\n const lockKey = hashStringToInt(\"typeorm-outbox-cron-lock\");\n\n try {\n const lockResult = await queryRunner.query(\n \"SELECT pg_try_advisory_lock($1) as locked\",\n [lockKey],\n );\n\n if (!lockResult[0].locked) {\n return;\n }\n try {\n await queryRunner.startTransaction(\"REPEATABLE READ\");\n\n const entities = await queryRunner.manager.find(TypeormOutboxEntity, {\n order: {\n createdAt: \"ASC\",\n },\n });\n\n for (const entity of entities) {\n await firstValueFrom(\n this.brokerClient.emit(entity.destinationTopic, {\n key: entity.keys,\n value: entity.payload,\n headers: entity.headers,\n }),\n );\n await queryRunner.manager.delete(TypeormOutboxEntity, entity.id);\n }\n\n await queryRunner.commitTransaction();\n } catch (error) {\n await queryRunner.rollbackTransaction();\n throw error;\n } finally {\n await queryRunner.query(\"SELECT pg_advisory_unlock($1)\", [lockKey]);\n }\n } finally {\n await queryRunner.release();\n }\n }\n}\n","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\n\nexport interface CreateOutboxOptions {\n destinationTopic: string;\n payload: Record<string, unknown>;\n headers?: Record<string, string>;\n keys?: Record<string, unknown>;\n}\n\n@Injectable()\nexport class TypeormOutboxService {\n constructor(\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n ) {}\n\n async create(options: CreateOutboxOptions): Promise<TypeormOutboxEntity> {\n return this.outboxRepository.save({\n destinationTopic: options.destinationTopic,\n headers: options.headers,\n keys: options.keys,\n payload: options.payload,\n });\n }\n}\n","import { TypeOrmModule } from \"@nestjs/typeorm\";\nimport { DynamicModule, Module, Provider } from \"@nestjs/common\";\nimport {\n TypeormOutboxRegisterCronAsyncOptions,\n TypeormOutboxRegisterCronModuleOptions,\n TypeormOutboxModuleOptions,\n TypeormOutboxModuleAsyncOptions,\n} from \"./typeorm-outbox.interfaces\";\nimport {\n TYPEORM_OUTBOX_BROKER_TOKEN,\n TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n TYPEORM_OUTBOX_SERVICE_TOKEN,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { TypeormOutboxService } from \"./typeorm-outbox.service\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\nimport { TypeormOutboxCronService } from \"./typeorm-outbox-cron.service\";\n\n@Module({})\nexport class TypeormOutboxModule {\n private static createServiceProvider(): Provider {\n return {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n }\n\n private static createBrokerProvider(useValue: unknown = null): Provider {\n return {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue,\n };\n }\n\n private static createTypeOrmFeature(connectionName?: string) {\n return TypeOrmModule.forFeature(\n [TypeormOutboxEntity],\n connectionName || \"default\",\n );\n }\n\n private static createModuleConfigProvider(\n options: TypeormOutboxModuleOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: {\n ...new TypeormOutboxModuleOptions(),\n ...options,\n },\n };\n }\n\n private static createAsyncModuleConfigProvider(\n options: TypeormOutboxModuleAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = (await options.useFactory?.(...args)) as\n | TypeormOutboxModuleOptions;\n \n return {\n ...new TypeormOutboxModuleOptions(),\n ...moduleOptions,\n };\n },\n inject: options.inject || [],\n };\n }\n\n private static createCronConfigProvider(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = await options.useFactory?.(...args);\n return {\n ...new TypeormOutboxRegisterCronModuleOptions(),\n ...moduleOptions,\n };\n },\n inject: options.inject || [],\n };\n }\n\n private static createCronBrokerProvider(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): Provider {\n return {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = await options.useFactory?.(...args);\n const config = {\n ...new TypeormOutboxRegisterCronModuleOptions(),\n ...moduleOptions,\n };\n return ClientProxyFactory.create(config?.brokerConfig ?? {});\n },\n inject: options.inject || [],\n };\n }\n\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const configProvider = this.createModuleConfigProvider(options);\n const serviceProvider = this.createServiceProvider();\n const brokerProvider = this.createBrokerProvider();\n const PROVIDERS = [configProvider, serviceProvider, brokerProvider];\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [this.createTypeOrmFeature(options.typeOrmConnectionName)],\n providers: [...PROVIDERS],\n exports: [...PROVIDERS],\n };\n }\n\n static forRootAsync(\n options: TypeormOutboxModuleAsyncOptions,\n ): DynamicModule {\n const configProvider = this.createAsyncModuleConfigProvider(options);\n const serviceProvider = this.createServiceProvider();\n const brokerProvider = this.createBrokerProvider();\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [this.createTypeOrmFeature()],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const configProvider = this.createCronConfigProvider(options);\n const brokerProvider = this.createCronBrokerProvider(options);\n const serviceProvider = this.createServiceProvider();\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [\n this.createTypeOrmFeature(),\n ],\n providers: [\n TypeormOutboxCronService,\n configProvider,\n brokerProvider,\n serviceProvider,\n ],\n exports: [configProvider, brokerProvider, serviceProvider],\n };\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@globalart/nestjs-typeorm-outbox",
3
3
  "description": "TypeORM Outbox integration for NestJS",
4
- "version": "1.1.1",
4
+ "version": "1.2.1",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
7
7
  "module": "dist/index.mjs",
@@ -46,8 +46,8 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@globalart/text-utils": "^1.0.5",
49
- "@nestjs/common": "11.1.12",
50
- "@nestjs/core": "11.1.12",
49
+ "@nestjs/common": "11.1.13",
50
+ "@nestjs/core": "11.1.13",
51
51
  "@nestjs/microservices": "^11.1.12",
52
52
  "@nestjs/typeorm": "^11.0.0",
53
53
  "cron": "^4.4.0",
@@ -57,11 +57,11 @@
57
57
  "typeorm": "^0.3.28"
58
58
  },
59
59
  "devDependencies": {
60
- "@types/node": "25.1.0",
60
+ "@types/node": "25.2.3",
61
61
  "prettier": "^3.8.1",
62
62
  "reflect-metadata": "^0.2.2",
63
63
  "release-it": "19.2.4",
64
- "tsdown": "0.20.1",
64
+ "tsdown": "0.20.3",
65
65
  "typescript": "^5.9.3"
66
66
  }
67
67
  }