@globalart/nestjs-typeorm-outbox 1.0.1 → 1.0.2
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 +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -160,6 +160,7 @@ let TypeormOutboxModule = _TypeormOutboxModule = class TypeormOutboxModule {
|
|
|
160
160
|
};
|
|
161
161
|
return {
|
|
162
162
|
module: _TypeormOutboxModule,
|
|
163
|
+
global: true,
|
|
163
164
|
imports: [_nestjs_typeorm.TypeOrmModule.forFeature([TypeormOutboxEntity], options.typeOrmConnectionName)],
|
|
164
165
|
providers: [
|
|
165
166
|
configProvider,
|
|
@@ -191,6 +192,7 @@ let TypeormOutboxModule = _TypeormOutboxModule = class TypeormOutboxModule {
|
|
|
191
192
|
};
|
|
192
193
|
return {
|
|
193
194
|
module: _TypeormOutboxModule,
|
|
195
|
+
global: true,
|
|
194
196
|
imports: [_nestjs_typeorm.TypeOrmModule.forFeature([TypeormOutboxEntity], "default")],
|
|
195
197
|
providers: [
|
|
196
198
|
configProvider,
|
|
@@ -226,6 +228,7 @@ let TypeormOutboxModule = _TypeormOutboxModule = class TypeormOutboxModule {
|
|
|
226
228
|
};
|
|
227
229
|
return {
|
|
228
230
|
module: _TypeormOutboxModule,
|
|
231
|
+
global: true,
|
|
229
232
|
imports: [_nestjs_schedule.ScheduleModule.forRoot(), _nestjs_typeorm.TypeOrmModule.forFeature([TypeormOutboxEntity], "default")],
|
|
230
233
|
controllers: [TypeormOutboxController],
|
|
231
234
|
providers: [
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["CronExpression","TypeOrmModule","ClientProxyFactory","ScheduleModule"],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.controller.ts","../src/core/typeorm-outbox.interfaces.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<any, any>;\n\n @Column(\"jsonb\")\n payload!: Record<string, any>;\n}\n","import { Controller } from \"@nestjs/common\";\nimport { InjectTypeormOutboxBroker } from \"./typeorm-outbox.di-tokens\";\nimport { Cron, CronExpression } from \"@nestjs/schedule\";\nimport { hashStringToInt } from \"@globalart/text-utils\";\nimport { EntityManager, Repository } from \"typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy } from \"@nestjs/microservices\";\n\n@Controller()\nexport class TypeormOutboxController {\n constructor(\n private readonly entityManager: EntityManager,\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n ) {}\n\n @Cron(CronExpression.EVERY_10_SECONDS)\n async handleOutboxCron() {\n await this.executeCronJob();\n }\n\n async executeCronJob() {\n const lockId = hashStringToInt(\"typeorm-outbox-cron-job\");\n const [{ pg_try_advisory_xact_lock: acquired }] =\n await this.entityManager.query<{ pg_try_advisory_xact_lock: boolean }[]>(\n `SELECT pg_try_advisory_xact_lock(${lockId})`,\n );\n\n if (!acquired) {\n return;\n }\n const entities = await this.outboxRepository.find();\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 this.outboxRepository.delete(entity.id);\n }\n }\n}\n","import { KafkaOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\n\n// register cron options\nexport class TypeormOutboxRegisterCronModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n kafkaConfig?: KafkaOptions = {};\n}\nexport interface TypeormOutboxRegisterCronAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: any[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: any[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\n// register module options\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\nexport class TypeormOutboxModuleAsyncOptions {\n imports?: Type[] = [];\n inject?: InjectionToken[] = [];\n useFactory?: (\n ...args: any[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\n\ntype createOutboxOptions = {\n destinationTopic: string;\n payload: Record<string, any>;\n headers?: Record<string, string>;\n keys?: Record<any, any>;\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) {\n await 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 { TypeormOutboxController } from \"./typeorm-outbox.controller\";\nimport { ScheduleModule } from \"@nestjs/schedule\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\n\n@Module({})\nexport class TypeormOutboxModule {\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: options,\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue: null,\n };\n\n return {\n module: TypeormOutboxModule,\n imports: [\n TypeOrmModule.forFeature(\n [TypeormOutboxEntity],\n options.typeOrmConnectionName,\n ),\n ],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options.useFactory?.(\n ...args,\n ) as TypeormOutboxModuleOptions;\n return moduleOptions;\n },\n inject: options.inject || [],\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue: null,\n };\n\n return {\n module: TypeormOutboxModule,\n imports: [TypeOrmModule.forFeature([TypeormOutboxEntity], \"default\")],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options.useFactory?.(\n ...args,\n ) as TypeormOutboxRegisterCronModuleOptions;\n return moduleOptions;\n },\n inject: options.inject || [],\n };\n\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options?.useFactory?.(\n ...args,\n ) as TypeormOutboxRegisterCronModuleOptions;\n return ClientProxyFactory.create(moduleOptions?.kafkaConfig ?? {});\n },\n inject: options.inject || [],\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n\n return {\n module: TypeormOutboxModule,\n imports: [\n ScheduleModule.forRoot(),\n TypeOrmModule.forFeature([TypeormOutboxEntity], \"default\")\n ],\n controllers: [TypeormOutboxController],\n providers: [configProvider, brokerProvider, serviceProvider],\n exports: [configProvider, brokerProvider, serviceProvider],\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["CronExpression","TypeOrmModule","ClientProxyFactory","ScheduleModule"],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.controller.ts","../src/core/typeorm-outbox.interfaces.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<any, any>;\n\n @Column(\"jsonb\")\n payload!: Record<string, any>;\n}\n","import { Controller } from \"@nestjs/common\";\nimport { InjectTypeormOutboxBroker } from \"./typeorm-outbox.di-tokens\";\nimport { Cron, CronExpression } from \"@nestjs/schedule\";\nimport { hashStringToInt } from \"@globalart/text-utils\";\nimport { EntityManager, Repository } from \"typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy } from \"@nestjs/microservices\";\n\n@Controller()\nexport class TypeormOutboxController {\n constructor(\n private readonly entityManager: EntityManager,\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n ) {}\n\n @Cron(CronExpression.EVERY_10_SECONDS)\n async handleOutboxCron() {\n await this.executeCronJob();\n }\n\n async executeCronJob() {\n const lockId = hashStringToInt(\"typeorm-outbox-cron-job\");\n const [{ pg_try_advisory_xact_lock: acquired }] =\n await this.entityManager.query<{ pg_try_advisory_xact_lock: boolean }[]>(\n `SELECT pg_try_advisory_xact_lock(${lockId})`,\n );\n\n if (!acquired) {\n return;\n }\n const entities = await this.outboxRepository.find();\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 this.outboxRepository.delete(entity.id);\n }\n }\n}\n","import { KafkaOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\n\n// register cron options\nexport class TypeormOutboxRegisterCronModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n kafkaConfig?: KafkaOptions = {};\n}\nexport interface TypeormOutboxRegisterCronAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: any[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: any[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\n// register module options\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\nexport class TypeormOutboxModuleAsyncOptions {\n imports?: Type[] = [];\n inject?: InjectionToken[] = [];\n useFactory?: (\n ...args: any[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\n\ntype createOutboxOptions = {\n destinationTopic: string;\n payload: Record<string, any>;\n headers?: Record<string, string>;\n keys?: Record<any, any>;\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) {\n await 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 { TypeormOutboxController } from \"./typeorm-outbox.controller\";\nimport { ScheduleModule } from \"@nestjs/schedule\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\n\n@Module({})\nexport class TypeormOutboxModule {\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: options,\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue: null,\n };\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [\n TypeOrmModule.forFeature(\n [TypeormOutboxEntity],\n options.typeOrmConnectionName,\n ),\n ],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options.useFactory?.(\n ...args,\n ) as TypeormOutboxModuleOptions;\n return moduleOptions;\n },\n inject: options.inject || [],\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue: null,\n };\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [TypeOrmModule.forFeature([TypeormOutboxEntity], \"default\")],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options.useFactory?.(\n ...args,\n ) as TypeormOutboxRegisterCronModuleOptions;\n return moduleOptions;\n },\n inject: options.inject || [],\n };\n\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options?.useFactory?.(\n ...args,\n ) as TypeormOutboxRegisterCronModuleOptions;\n return ClientProxyFactory.create(moduleOptions?.kafkaConfig ?? {});\n },\n inject: options.inject || [],\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [\n ScheduleModule.forRoot(),\n TypeOrmModule.forFeature([TypeormOutboxEntity], \"default\")\n ],\n controllers: [TypeormOutboxController],\n providers: [configProvider, brokerProvider, serviceProvider],\n exports: [configProvider, brokerProvider, serviceProvider],\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -160,6 +160,7 @@ let TypeormOutboxModule = _TypeormOutboxModule = class TypeormOutboxModule {
|
|
|
160
160
|
};
|
|
161
161
|
return {
|
|
162
162
|
module: _TypeormOutboxModule,
|
|
163
|
+
global: true,
|
|
163
164
|
imports: [TypeOrmModule.forFeature([TypeormOutboxEntity], options.typeOrmConnectionName)],
|
|
164
165
|
providers: [
|
|
165
166
|
configProvider,
|
|
@@ -191,6 +192,7 @@ let TypeormOutboxModule = _TypeormOutboxModule = class TypeormOutboxModule {
|
|
|
191
192
|
};
|
|
192
193
|
return {
|
|
193
194
|
module: _TypeormOutboxModule,
|
|
195
|
+
global: true,
|
|
194
196
|
imports: [TypeOrmModule.forFeature([TypeormOutboxEntity], "default")],
|
|
195
197
|
providers: [
|
|
196
198
|
configProvider,
|
|
@@ -226,6 +228,7 @@ let TypeormOutboxModule = _TypeormOutboxModule = class TypeormOutboxModule {
|
|
|
226
228
|
};
|
|
227
229
|
return {
|
|
228
230
|
module: _TypeormOutboxModule,
|
|
231
|
+
global: true,
|
|
229
232
|
imports: [ScheduleModule.forRoot(), TypeOrmModule.forFeature([TypeormOutboxEntity], "default")],
|
|
230
233
|
controllers: [TypeormOutboxController],
|
|
231
234
|
providers: [
|
package/dist/index.mjs.map
CHANGED
|
@@ -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.controller.ts","../src/core/typeorm-outbox.interfaces.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<any, any>;\n\n @Column(\"jsonb\")\n payload!: Record<string, any>;\n}\n","import { Controller } from \"@nestjs/common\";\nimport { InjectTypeormOutboxBroker } from \"./typeorm-outbox.di-tokens\";\nimport { Cron, CronExpression } from \"@nestjs/schedule\";\nimport { hashStringToInt } from \"@globalart/text-utils\";\nimport { EntityManager, Repository } from \"typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy } from \"@nestjs/microservices\";\n\n@Controller()\nexport class TypeormOutboxController {\n constructor(\n private readonly entityManager: EntityManager,\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n ) {}\n\n @Cron(CronExpression.EVERY_10_SECONDS)\n async handleOutboxCron() {\n await this.executeCronJob();\n }\n\n async executeCronJob() {\n const lockId = hashStringToInt(\"typeorm-outbox-cron-job\");\n const [{ pg_try_advisory_xact_lock: acquired }] =\n await this.entityManager.query<{ pg_try_advisory_xact_lock: boolean }[]>(\n `SELECT pg_try_advisory_xact_lock(${lockId})`,\n );\n\n if (!acquired) {\n return;\n }\n const entities = await this.outboxRepository.find();\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 this.outboxRepository.delete(entity.id);\n }\n }\n}\n","import { KafkaOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\n\n// register cron options\nexport class TypeormOutboxRegisterCronModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n kafkaConfig?: KafkaOptions = {};\n}\nexport interface TypeormOutboxRegisterCronAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: any[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: any[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\n// register module options\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\nexport class TypeormOutboxModuleAsyncOptions {\n imports?: Type[] = [];\n inject?: InjectionToken[] = [];\n useFactory?: (\n ...args: any[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\n\ntype createOutboxOptions = {\n destinationTopic: string;\n payload: Record<string, any>;\n headers?: Record<string, string>;\n keys?: Record<any, any>;\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) {\n await 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 { TypeormOutboxController } from \"./typeorm-outbox.controller\";\nimport { ScheduleModule } from \"@nestjs/schedule\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\n\n@Module({})\nexport class TypeormOutboxModule {\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: options,\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue: null,\n };\n\n return {\n module: TypeormOutboxModule,\n imports: [\n TypeOrmModule.forFeature(\n [TypeormOutboxEntity],\n options.typeOrmConnectionName,\n ),\n ],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options.useFactory?.(\n ...args,\n ) as TypeormOutboxModuleOptions;\n return moduleOptions;\n },\n inject: options.inject || [],\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue: null,\n };\n\n return {\n module: TypeormOutboxModule,\n imports: [TypeOrmModule.forFeature([TypeormOutboxEntity], \"default\")],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options.useFactory?.(\n ...args,\n ) as TypeormOutboxRegisterCronModuleOptions;\n return moduleOptions;\n },\n inject: options.inject || [],\n };\n\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options?.useFactory?.(\n ...args,\n ) as TypeormOutboxRegisterCronModuleOptions;\n return ClientProxyFactory.create(moduleOptions?.kafkaConfig ?? {});\n },\n inject: options.inject || [],\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n\n return {\n module: TypeormOutboxModule,\n imports: [\n ScheduleModule.forRoot(),\n TypeOrmModule.forFeature([TypeormOutboxEntity], \"default\")\n ],\n controllers: [TypeormOutboxController],\n providers: [configProvider, brokerProvider, serviceProvider],\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.controller.ts","../src/core/typeorm-outbox.interfaces.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<any, any>;\n\n @Column(\"jsonb\")\n payload!: Record<string, any>;\n}\n","import { Controller } from \"@nestjs/common\";\nimport { InjectTypeormOutboxBroker } from \"./typeorm-outbox.di-tokens\";\nimport { Cron, CronExpression } from \"@nestjs/schedule\";\nimport { hashStringToInt } from \"@globalart/text-utils\";\nimport { EntityManager, Repository } from \"typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy } from \"@nestjs/microservices\";\n\n@Controller()\nexport class TypeormOutboxController {\n constructor(\n private readonly entityManager: EntityManager,\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n ) {}\n\n @Cron(CronExpression.EVERY_10_SECONDS)\n async handleOutboxCron() {\n await this.executeCronJob();\n }\n\n async executeCronJob() {\n const lockId = hashStringToInt(\"typeorm-outbox-cron-job\");\n const [{ pg_try_advisory_xact_lock: acquired }] =\n await this.entityManager.query<{ pg_try_advisory_xact_lock: boolean }[]>(\n `SELECT pg_try_advisory_xact_lock(${lockId})`,\n );\n\n if (!acquired) {\n return;\n }\n const entities = await this.outboxRepository.find();\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 this.outboxRepository.delete(entity.id);\n }\n }\n}\n","import { KafkaOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\n\n// register cron options\nexport class TypeormOutboxRegisterCronModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n kafkaConfig?: KafkaOptions = {};\n}\nexport interface TypeormOutboxRegisterCronAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: any[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: any[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\n// register module options\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\nexport class TypeormOutboxModuleAsyncOptions {\n imports?: Type[] = [];\n inject?: InjectionToken[] = [];\n useFactory?: (\n ...args: any[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\n\ntype createOutboxOptions = {\n destinationTopic: string;\n payload: Record<string, any>;\n headers?: Record<string, string>;\n keys?: Record<any, any>;\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) {\n await 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 { TypeormOutboxController } from \"./typeorm-outbox.controller\";\nimport { ScheduleModule } from \"@nestjs/schedule\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\n\n@Module({})\nexport class TypeormOutboxModule {\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: options,\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue: null,\n };\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [\n TypeOrmModule.forFeature(\n [TypeormOutboxEntity],\n options.typeOrmConnectionName,\n ),\n ],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options.useFactory?.(\n ...args,\n ) as TypeormOutboxModuleOptions;\n return moduleOptions;\n },\n inject: options.inject || [],\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue: null,\n };\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [TypeOrmModule.forFeature([TypeormOutboxEntity], \"default\")],\n providers: [configProvider, serviceProvider, brokerProvider],\n exports: [configProvider, serviceProvider, brokerProvider],\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const configProvider: Provider = {\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options.useFactory?.(\n ...args,\n ) as TypeormOutboxRegisterCronModuleOptions;\n return moduleOptions;\n },\n inject: options.inject || [],\n };\n\n const brokerProvider: Provider = {\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: unknown[]) => {\n const moduleOptions = options?.useFactory?.(\n ...args,\n ) as TypeormOutboxRegisterCronModuleOptions;\n return ClientProxyFactory.create(moduleOptions?.kafkaConfig ?? {});\n },\n inject: options.inject || [],\n };\n const serviceProvider: Provider = {\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n };\n\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [\n ScheduleModule.forRoot(),\n TypeOrmModule.forFeature([TypeormOutboxEntity], \"default\")\n ],\n controllers: [TypeormOutboxController],\n providers: [configProvider, brokerProvider, serviceProvider],\n exports: [configProvider, brokerProvider, serviceProvider],\n };\n }\n}\n"],"mappings":"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"}
|