@globalart/nestjs-typeorm-outbox 1.0.0
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/README.md +11 -0
- package/dist/index.cjs +282 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +77 -0
- package/dist/index.d.mts +77 -0
- package/dist/index.mjs +248 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @globalart/nestjs-typeorm-outbox
|
|
2
|
+
|
|
3
|
+
A NestJS module for working with TypeORM outbox pattern. Provides a convenient API for creating outbox messages, sending them to the database, and processing them.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
For complete documentation, examples, and API reference, please visit the [official documentation](https://globalart.js.org/packages/nestjs-typeorm-outbox).
|
|
8
|
+
|
|
9
|
+
## License
|
|
10
|
+
|
|
11
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
let _nestjs_common = require("@nestjs/common");
|
|
2
|
+
let _nestjs_schedule = require("@nestjs/schedule");
|
|
3
|
+
let _globalart_text_utils = require("@globalart/text-utils");
|
|
4
|
+
let typeorm = require("typeorm");
|
|
5
|
+
let _nestjs_typeorm = require("@nestjs/typeorm");
|
|
6
|
+
let rxjs = require("rxjs");
|
|
7
|
+
let _nestjs_microservices = require("@nestjs/microservices");
|
|
8
|
+
|
|
9
|
+
//#region src/core/typeorm-outbox.di-tokens.ts
|
|
10
|
+
const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol("TYPEORM_OUTBOX_CRON_CONFIG_TOKEN");
|
|
11
|
+
const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol("TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN");
|
|
12
|
+
const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol("TYPEORM_OUTBOX_SERVICE_TOKEN");
|
|
13
|
+
const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol("TYPEORM_OUTBOX_BROKER_TOKEN");
|
|
14
|
+
const InjectTypeormOutboxCronConfig = () => (0, _nestjs_common.Inject)(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);
|
|
15
|
+
const InjectTypeormOutboxModuleConfig = () => (0, _nestjs_common.Inject)(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);
|
|
16
|
+
const InjectTypeormOutboxService = () => (0, _nestjs_common.Inject)(TYPEORM_OUTBOX_SERVICE_TOKEN);
|
|
17
|
+
const InjectTypeormOutboxBroker = () => (0, _nestjs_common.Inject)(TYPEORM_OUTBOX_BROKER_TOKEN);
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region \0@oxc-project+runtime@0.108.0/helpers/decorateMetadata.js
|
|
21
|
+
function __decorateMetadata(k, v) {
|
|
22
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region \0@oxc-project+runtime@0.108.0/helpers/decorate.js
|
|
27
|
+
function __decorate(decorators, target, key, desc) {
|
|
28
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
29
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
30
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
31
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/core/typeorm-outbox.entity.ts
|
|
36
|
+
var _ref$2, _ref2$1, _ref3$1, _ref4, _ref5;
|
|
37
|
+
let TypeormOutboxEntity = class TypeormOutboxEntity {
|
|
38
|
+
id;
|
|
39
|
+
createdAt;
|
|
40
|
+
updatedAt;
|
|
41
|
+
destinationTopic;
|
|
42
|
+
headers;
|
|
43
|
+
keys;
|
|
44
|
+
payload;
|
|
45
|
+
};
|
|
46
|
+
__decorate([(0, typeorm.PrimaryGeneratedColumn)("uuid"), __decorateMetadata("design:type", String)], TypeormOutboxEntity.prototype, "id", void 0);
|
|
47
|
+
__decorate([(0, typeorm.CreateDateColumn)({ name: "created_at" }), __decorateMetadata("design:type", typeof (_ref$2 = typeof Date !== "undefined" && Date) === "function" ? _ref$2 : Object)], TypeormOutboxEntity.prototype, "createdAt", void 0);
|
|
48
|
+
__decorate([(0, typeorm.UpdateDateColumn)({ name: "updated_at" }), __decorateMetadata("design:type", typeof (_ref2$1 = typeof Date !== "undefined" && Date) === "function" ? _ref2$1 : Object)], TypeormOutboxEntity.prototype, "updatedAt", void 0);
|
|
49
|
+
__decorate([(0, typeorm.Column)("character varying", { name: "destination_topic" }), __decorateMetadata("design:type", String)], TypeormOutboxEntity.prototype, "destinationTopic", void 0);
|
|
50
|
+
__decorate([(0, typeorm.Column)("jsonb", { nullable: true }), __decorateMetadata("design:type", typeof (_ref3$1 = typeof Record !== "undefined" && Record) === "function" ? _ref3$1 : Object)], TypeormOutboxEntity.prototype, "headers", void 0);
|
|
51
|
+
__decorate([(0, typeorm.Column)("jsonb", { nullable: true }), __decorateMetadata("design:type", typeof (_ref4 = typeof Record !== "undefined" && Record) === "function" ? _ref4 : Object)], TypeormOutboxEntity.prototype, "keys", void 0);
|
|
52
|
+
__decorate([(0, typeorm.Column)("jsonb"), __decorateMetadata("design:type", typeof (_ref5 = typeof Record !== "undefined" && Record) === "function" ? _ref5 : Object)], TypeormOutboxEntity.prototype, "payload", void 0);
|
|
53
|
+
TypeormOutboxEntity = __decorate([(0, typeorm.Entity)("outbox")], TypeormOutboxEntity);
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region \0@oxc-project+runtime@0.108.0/helpers/decorateParam.js
|
|
57
|
+
function __decorateParam(paramIndex, decorator) {
|
|
58
|
+
return function(target, key) {
|
|
59
|
+
decorator(target, key, paramIndex);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/core/typeorm-outbox.controller.ts
|
|
65
|
+
var _ref$1, _ref2, _ref3;
|
|
66
|
+
let TypeormOutboxController = class TypeormOutboxController {
|
|
67
|
+
constructor(entityManager, outboxRepository, brokerClient) {
|
|
68
|
+
this.entityManager = entityManager;
|
|
69
|
+
this.outboxRepository = outboxRepository;
|
|
70
|
+
this.brokerClient = brokerClient;
|
|
71
|
+
}
|
|
72
|
+
async handleOutboxCron() {
|
|
73
|
+
await this.executeCronJob();
|
|
74
|
+
}
|
|
75
|
+
async executeCronJob() {
|
|
76
|
+
const lockId = (0, _globalart_text_utils.hashStringToInt)("typeorm-outbox-cron-job");
|
|
77
|
+
const [{ pg_try_advisory_xact_lock: acquired }] = await this.entityManager.query(`SELECT pg_try_advisory_xact_lock(${lockId})`);
|
|
78
|
+
if (!acquired) return;
|
|
79
|
+
const entities = await this.outboxRepository.find();
|
|
80
|
+
for (const entity of entities) {
|
|
81
|
+
await (0, rxjs.firstValueFrom)(this.brokerClient.emit(entity.destinationTopic, {
|
|
82
|
+
key: entity.keys,
|
|
83
|
+
value: entity.payload,
|
|
84
|
+
headers: entity.headers
|
|
85
|
+
}));
|
|
86
|
+
await this.outboxRepository.delete(entity.id);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
__decorate([
|
|
91
|
+
(0, _nestjs_schedule.Cron)(_nestjs_schedule.CronExpression.EVERY_10_SECONDS),
|
|
92
|
+
__decorateMetadata("design:type", Function),
|
|
93
|
+
__decorateMetadata("design:paramtypes", []),
|
|
94
|
+
__decorateMetadata("design:returntype", Promise)
|
|
95
|
+
], TypeormOutboxController.prototype, "handleOutboxCron", null);
|
|
96
|
+
TypeormOutboxController = __decorate([
|
|
97
|
+
(0, _nestjs_common.Controller)(),
|
|
98
|
+
__decorateParam(1, (0, _nestjs_typeorm.InjectRepository)(TypeormOutboxEntity)),
|
|
99
|
+
__decorateParam(2, InjectTypeormOutboxBroker()),
|
|
100
|
+
__decorateMetadata("design:paramtypes", [
|
|
101
|
+
typeof (_ref$1 = typeof typeorm.EntityManager !== "undefined" && typeorm.EntityManager) === "function" ? _ref$1 : Object,
|
|
102
|
+
typeof (_ref2 = typeof typeorm.Repository !== "undefined" && typeorm.Repository) === "function" ? _ref2 : Object,
|
|
103
|
+
typeof (_ref3 = typeof _nestjs_microservices.ClientProxy !== "undefined" && _nestjs_microservices.ClientProxy) === "function" ? _ref3 : Object
|
|
104
|
+
])
|
|
105
|
+
], TypeormOutboxController);
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/core/typeorm-outbox.interfaces.ts
|
|
109
|
+
var TypeormOutboxRegisterCronModuleOptions = class {
|
|
110
|
+
typeOrmConnectionName = "default";
|
|
111
|
+
kafkaConfig = {};
|
|
112
|
+
};
|
|
113
|
+
var TypeormOutboxModuleOptions = class {
|
|
114
|
+
typeOrmConnectionName = "default";
|
|
115
|
+
};
|
|
116
|
+
var TypeormOutboxModuleAsyncOptions = class {
|
|
117
|
+
imports = [];
|
|
118
|
+
inject = [];
|
|
119
|
+
useFactory;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
//#endregion
|
|
123
|
+
//#region src/core/typeorm-outbox.service.ts
|
|
124
|
+
var _ref;
|
|
125
|
+
let TypeormOutboxService = class TypeormOutboxService {
|
|
126
|
+
constructor(outboxRepository) {
|
|
127
|
+
this.outboxRepository = outboxRepository;
|
|
128
|
+
}
|
|
129
|
+
async create(options) {
|
|
130
|
+
await this.outboxRepository.save({
|
|
131
|
+
destinationTopic: options.destinationTopic,
|
|
132
|
+
headers: options.headers,
|
|
133
|
+
keys: options.keys,
|
|
134
|
+
payload: options.payload
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
TypeormOutboxService = __decorate([
|
|
139
|
+
(0, _nestjs_common.Injectable)(),
|
|
140
|
+
__decorateParam(0, (0, _nestjs_typeorm.InjectRepository)(TypeormOutboxEntity)),
|
|
141
|
+
__decorateMetadata("design:paramtypes", [typeof (_ref = typeof typeorm.Repository !== "undefined" && typeorm.Repository) === "function" ? _ref : Object])
|
|
142
|
+
], TypeormOutboxService);
|
|
143
|
+
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/core/typeorm-outbox.module.ts
|
|
146
|
+
var _TypeormOutboxModule;
|
|
147
|
+
let TypeormOutboxModule = _TypeormOutboxModule = class TypeormOutboxModule {
|
|
148
|
+
static forRoot(options = {}) {
|
|
149
|
+
const configProvider = {
|
|
150
|
+
provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,
|
|
151
|
+
useValue: options
|
|
152
|
+
};
|
|
153
|
+
const serviceProvider = {
|
|
154
|
+
provide: TYPEORM_OUTBOX_SERVICE_TOKEN,
|
|
155
|
+
useClass: TypeormOutboxService
|
|
156
|
+
};
|
|
157
|
+
const brokerProvider = {
|
|
158
|
+
provide: TYPEORM_OUTBOX_BROKER_TOKEN,
|
|
159
|
+
useValue: null
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
module: _TypeormOutboxModule,
|
|
163
|
+
imports: [_nestjs_typeorm.TypeOrmModule.forFeature([TypeormOutboxEntity], options.typeOrmConnectionName)],
|
|
164
|
+
providers: [
|
|
165
|
+
configProvider,
|
|
166
|
+
serviceProvider,
|
|
167
|
+
brokerProvider
|
|
168
|
+
],
|
|
169
|
+
exports: [
|
|
170
|
+
configProvider,
|
|
171
|
+
serviceProvider,
|
|
172
|
+
brokerProvider
|
|
173
|
+
]
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
static forRootAsync(options) {
|
|
177
|
+
const configProvider = {
|
|
178
|
+
provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,
|
|
179
|
+
useFactory: async (...args) => {
|
|
180
|
+
return options.useFactory?.(...args);
|
|
181
|
+
},
|
|
182
|
+
inject: options.inject || []
|
|
183
|
+
};
|
|
184
|
+
const serviceProvider = {
|
|
185
|
+
provide: TYPEORM_OUTBOX_SERVICE_TOKEN,
|
|
186
|
+
useClass: TypeormOutboxService
|
|
187
|
+
};
|
|
188
|
+
const brokerProvider = {
|
|
189
|
+
provide: TYPEORM_OUTBOX_BROKER_TOKEN,
|
|
190
|
+
useValue: null
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
module: _TypeormOutboxModule,
|
|
194
|
+
imports: [_nestjs_typeorm.TypeOrmModule.forFeature([TypeormOutboxEntity], "default")],
|
|
195
|
+
providers: [
|
|
196
|
+
configProvider,
|
|
197
|
+
serviceProvider,
|
|
198
|
+
brokerProvider
|
|
199
|
+
],
|
|
200
|
+
exports: [
|
|
201
|
+
configProvider,
|
|
202
|
+
serviceProvider,
|
|
203
|
+
brokerProvider
|
|
204
|
+
]
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
static registerCronAsync(options) {
|
|
208
|
+
const configProvider = {
|
|
209
|
+
provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,
|
|
210
|
+
useFactory: async (...args) => {
|
|
211
|
+
return options.useFactory?.(...args);
|
|
212
|
+
},
|
|
213
|
+
inject: options.inject || []
|
|
214
|
+
};
|
|
215
|
+
const brokerProvider = {
|
|
216
|
+
provide: TYPEORM_OUTBOX_BROKER_TOKEN,
|
|
217
|
+
useFactory: async (...args) => {
|
|
218
|
+
const moduleOptions = options?.useFactory?.(...args);
|
|
219
|
+
return _nestjs_microservices.ClientProxyFactory.create(moduleOptions?.kafkaConfig ?? {});
|
|
220
|
+
},
|
|
221
|
+
inject: options.inject || []
|
|
222
|
+
};
|
|
223
|
+
const serviceProvider = {
|
|
224
|
+
provide: TYPEORM_OUTBOX_SERVICE_TOKEN,
|
|
225
|
+
useClass: TypeormOutboxService
|
|
226
|
+
};
|
|
227
|
+
return {
|
|
228
|
+
module: _TypeormOutboxModule,
|
|
229
|
+
imports: [_nestjs_schedule.ScheduleModule.forRoot(), _nestjs_typeorm.TypeOrmModule.forFeature([TypeormOutboxEntity], "default")],
|
|
230
|
+
controllers: [TypeormOutboxController],
|
|
231
|
+
providers: [
|
|
232
|
+
configProvider,
|
|
233
|
+
brokerProvider,
|
|
234
|
+
serviceProvider
|
|
235
|
+
],
|
|
236
|
+
exports: [
|
|
237
|
+
configProvider,
|
|
238
|
+
brokerProvider,
|
|
239
|
+
serviceProvider
|
|
240
|
+
]
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
TypeormOutboxModule = _TypeormOutboxModule = __decorate([(0, _nestjs_common.Module)({})], TypeormOutboxModule);
|
|
245
|
+
|
|
246
|
+
//#endregion
|
|
247
|
+
exports.InjectTypeormOutboxBroker = InjectTypeormOutboxBroker;
|
|
248
|
+
exports.InjectTypeormOutboxCronConfig = InjectTypeormOutboxCronConfig;
|
|
249
|
+
exports.InjectTypeormOutboxModuleConfig = InjectTypeormOutboxModuleConfig;
|
|
250
|
+
exports.InjectTypeormOutboxService = InjectTypeormOutboxService;
|
|
251
|
+
exports.TYPEORM_OUTBOX_BROKER_TOKEN = TYPEORM_OUTBOX_BROKER_TOKEN;
|
|
252
|
+
exports.TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = TYPEORM_OUTBOX_CRON_CONFIG_TOKEN;
|
|
253
|
+
exports.TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN;
|
|
254
|
+
exports.TYPEORM_OUTBOX_SERVICE_TOKEN = TYPEORM_OUTBOX_SERVICE_TOKEN;
|
|
255
|
+
Object.defineProperty(exports, 'TypeormOutboxController', {
|
|
256
|
+
enumerable: true,
|
|
257
|
+
get: function () {
|
|
258
|
+
return TypeormOutboxController;
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
Object.defineProperty(exports, 'TypeormOutboxEntity', {
|
|
262
|
+
enumerable: true,
|
|
263
|
+
get: function () {
|
|
264
|
+
return TypeormOutboxEntity;
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
Object.defineProperty(exports, 'TypeormOutboxModule', {
|
|
268
|
+
enumerable: true,
|
|
269
|
+
get: function () {
|
|
270
|
+
return TypeormOutboxModule;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
exports.TypeormOutboxModuleAsyncOptions = TypeormOutboxModuleAsyncOptions;
|
|
274
|
+
exports.TypeormOutboxModuleOptions = TypeormOutboxModuleOptions;
|
|
275
|
+
exports.TypeormOutboxRegisterCronModuleOptions = TypeormOutboxRegisterCronModuleOptions;
|
|
276
|
+
Object.defineProperty(exports, 'TypeormOutboxService', {
|
|
277
|
+
enumerable: true,
|
|
278
|
+
get: function () {
|
|
279
|
+
return TypeormOutboxService;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +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(\"uuid\")\n id!: string;\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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"}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { EntityManager, Repository } from "typeorm";
|
|
2
|
+
import { ClientProxy, KafkaOptions } from "@nestjs/microservices";
|
|
3
|
+
import { DynamicModule, InjectionToken, ModuleMetadata, Type } from "@nestjs/common";
|
|
4
|
+
|
|
5
|
+
//#region src/core/typeorm-outbox.entity.d.ts
|
|
6
|
+
declare class TypeormOutboxEntity {
|
|
7
|
+
id: string;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
updatedAt: Date;
|
|
10
|
+
destinationTopic: string;
|
|
11
|
+
headers: Record<string, string>;
|
|
12
|
+
keys: Record<any, any>;
|
|
13
|
+
payload: Record<string, any>;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/core/typeorm-outbox.controller.d.ts
|
|
17
|
+
declare class TypeormOutboxController {
|
|
18
|
+
private readonly entityManager;
|
|
19
|
+
private readonly outboxRepository;
|
|
20
|
+
private readonly brokerClient;
|
|
21
|
+
constructor(entityManager: EntityManager, outboxRepository: Repository<TypeormOutboxEntity>, brokerClient: ClientProxy);
|
|
22
|
+
handleOutboxCron(): Promise<void>;
|
|
23
|
+
executeCronJob(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/core/typeorm-outbox.di-tokens.d.ts
|
|
27
|
+
declare const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN: unique symbol;
|
|
28
|
+
declare const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN: unique symbol;
|
|
29
|
+
declare const TYPEORM_OUTBOX_SERVICE_TOKEN: unique symbol;
|
|
30
|
+
declare const TYPEORM_OUTBOX_BROKER_TOKEN: unique symbol;
|
|
31
|
+
declare const InjectTypeormOutboxCronConfig: () => PropertyDecorator & ParameterDecorator;
|
|
32
|
+
declare const InjectTypeormOutboxModuleConfig: () => PropertyDecorator & ParameterDecorator;
|
|
33
|
+
declare const InjectTypeormOutboxService: () => PropertyDecorator & ParameterDecorator;
|
|
34
|
+
declare const InjectTypeormOutboxBroker: () => PropertyDecorator & ParameterDecorator;
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/core/typeorm-outbox.interfaces.d.ts
|
|
37
|
+
declare class TypeormOutboxRegisterCronModuleOptions {
|
|
38
|
+
typeOrmConnectionName?: string;
|
|
39
|
+
kafkaConfig?: KafkaOptions;
|
|
40
|
+
}
|
|
41
|
+
interface TypeormOutboxRegisterCronAsyncOptions extends Pick<ModuleMetadata, "imports"> {
|
|
42
|
+
inject?: any[];
|
|
43
|
+
useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;
|
|
44
|
+
useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;
|
|
45
|
+
useFactory?: (...args: any[]) => Promise<TypeormOutboxRegisterCronModuleOptions> | TypeormOutboxRegisterCronModuleOptions;
|
|
46
|
+
}
|
|
47
|
+
declare class TypeormOutboxModuleOptions {
|
|
48
|
+
typeOrmConnectionName?: string;
|
|
49
|
+
}
|
|
50
|
+
declare class TypeormOutboxModuleAsyncOptions {
|
|
51
|
+
imports?: Type[];
|
|
52
|
+
inject?: InjectionToken[];
|
|
53
|
+
useFactory?: (...args: any[]) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/core/typeorm-outbox.module.d.ts
|
|
57
|
+
declare class TypeormOutboxModule {
|
|
58
|
+
static forRoot(options?: TypeormOutboxModuleOptions): DynamicModule;
|
|
59
|
+
static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule;
|
|
60
|
+
static registerCronAsync(options: TypeormOutboxRegisterCronAsyncOptions): DynamicModule;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/core/typeorm-outbox.service.d.ts
|
|
64
|
+
type createOutboxOptions = {
|
|
65
|
+
destinationTopic: string;
|
|
66
|
+
payload: Record<string, any>;
|
|
67
|
+
headers?: Record<string, string>;
|
|
68
|
+
keys?: Record<any, any>;
|
|
69
|
+
};
|
|
70
|
+
declare class TypeormOutboxService {
|
|
71
|
+
private readonly outboxRepository;
|
|
72
|
+
constructor(outboxRepository: Repository<TypeormOutboxEntity>);
|
|
73
|
+
create(options: createOutboxOptions): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { InjectTypeormOutboxBroker, InjectTypeormOutboxCronConfig, InjectTypeormOutboxModuleConfig, InjectTypeormOutboxService, TYPEORM_OUTBOX_BROKER_TOKEN, TYPEORM_OUTBOX_CRON_CONFIG_TOKEN, TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN, TYPEORM_OUTBOX_SERVICE_TOKEN, TypeormOutboxController, TypeormOutboxEntity, TypeormOutboxModule, TypeormOutboxModuleAsyncOptions, TypeormOutboxModuleOptions, TypeormOutboxRegisterCronAsyncOptions, TypeormOutboxRegisterCronModuleOptions, TypeormOutboxService };
|
|
77
|
+
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { DynamicModule, InjectionToken, ModuleMetadata, Type } from "@nestjs/common";
|
|
2
|
+
import { EntityManager, Repository } from "typeorm";
|
|
3
|
+
import { ClientProxy, KafkaOptions } from "@nestjs/microservices";
|
|
4
|
+
|
|
5
|
+
//#region src/core/typeorm-outbox.entity.d.ts
|
|
6
|
+
declare class TypeormOutboxEntity {
|
|
7
|
+
id: string;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
updatedAt: Date;
|
|
10
|
+
destinationTopic: string;
|
|
11
|
+
headers: Record<string, string>;
|
|
12
|
+
keys: Record<any, any>;
|
|
13
|
+
payload: Record<string, any>;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/core/typeorm-outbox.controller.d.ts
|
|
17
|
+
declare class TypeormOutboxController {
|
|
18
|
+
private readonly entityManager;
|
|
19
|
+
private readonly outboxRepository;
|
|
20
|
+
private readonly brokerClient;
|
|
21
|
+
constructor(entityManager: EntityManager, outboxRepository: Repository<TypeormOutboxEntity>, brokerClient: ClientProxy);
|
|
22
|
+
handleOutboxCron(): Promise<void>;
|
|
23
|
+
executeCronJob(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/core/typeorm-outbox.di-tokens.d.ts
|
|
27
|
+
declare const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN: unique symbol;
|
|
28
|
+
declare const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN: unique symbol;
|
|
29
|
+
declare const TYPEORM_OUTBOX_SERVICE_TOKEN: unique symbol;
|
|
30
|
+
declare const TYPEORM_OUTBOX_BROKER_TOKEN: unique symbol;
|
|
31
|
+
declare const InjectTypeormOutboxCronConfig: () => PropertyDecorator & ParameterDecorator;
|
|
32
|
+
declare const InjectTypeormOutboxModuleConfig: () => PropertyDecorator & ParameterDecorator;
|
|
33
|
+
declare const InjectTypeormOutboxService: () => PropertyDecorator & ParameterDecorator;
|
|
34
|
+
declare const InjectTypeormOutboxBroker: () => PropertyDecorator & ParameterDecorator;
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/core/typeorm-outbox.interfaces.d.ts
|
|
37
|
+
declare class TypeormOutboxRegisterCronModuleOptions {
|
|
38
|
+
typeOrmConnectionName?: string;
|
|
39
|
+
kafkaConfig?: KafkaOptions;
|
|
40
|
+
}
|
|
41
|
+
interface TypeormOutboxRegisterCronAsyncOptions extends Pick<ModuleMetadata, "imports"> {
|
|
42
|
+
inject?: any[];
|
|
43
|
+
useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;
|
|
44
|
+
useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;
|
|
45
|
+
useFactory?: (...args: any[]) => Promise<TypeormOutboxRegisterCronModuleOptions> | TypeormOutboxRegisterCronModuleOptions;
|
|
46
|
+
}
|
|
47
|
+
declare class TypeormOutboxModuleOptions {
|
|
48
|
+
typeOrmConnectionName?: string;
|
|
49
|
+
}
|
|
50
|
+
declare class TypeormOutboxModuleAsyncOptions {
|
|
51
|
+
imports?: Type[];
|
|
52
|
+
inject?: InjectionToken[];
|
|
53
|
+
useFactory?: (...args: any[]) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/core/typeorm-outbox.module.d.ts
|
|
57
|
+
declare class TypeormOutboxModule {
|
|
58
|
+
static forRoot(options?: TypeormOutboxModuleOptions): DynamicModule;
|
|
59
|
+
static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule;
|
|
60
|
+
static registerCronAsync(options: TypeormOutboxRegisterCronAsyncOptions): DynamicModule;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/core/typeorm-outbox.service.d.ts
|
|
64
|
+
type createOutboxOptions = {
|
|
65
|
+
destinationTopic: string;
|
|
66
|
+
payload: Record<string, any>;
|
|
67
|
+
headers?: Record<string, string>;
|
|
68
|
+
keys?: Record<any, any>;
|
|
69
|
+
};
|
|
70
|
+
declare class TypeormOutboxService {
|
|
71
|
+
private readonly outboxRepository;
|
|
72
|
+
constructor(outboxRepository: Repository<TypeormOutboxEntity>);
|
|
73
|
+
create(options: createOutboxOptions): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { InjectTypeormOutboxBroker, InjectTypeormOutboxCronConfig, InjectTypeormOutboxModuleConfig, InjectTypeormOutboxService, TYPEORM_OUTBOX_BROKER_TOKEN, TYPEORM_OUTBOX_CRON_CONFIG_TOKEN, TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN, TYPEORM_OUTBOX_SERVICE_TOKEN, TypeormOutboxController, TypeormOutboxEntity, TypeormOutboxModule, TypeormOutboxModuleAsyncOptions, TypeormOutboxModuleOptions, TypeormOutboxRegisterCronAsyncOptions, TypeormOutboxRegisterCronModuleOptions, TypeormOutboxService };
|
|
77
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { Controller, Inject, Injectable, Module } from "@nestjs/common";
|
|
2
|
+
import { Cron, CronExpression, ScheduleModule } from "@nestjs/schedule";
|
|
3
|
+
import { hashStringToInt } from "@globalart/text-utils";
|
|
4
|
+
import { Column, CreateDateColumn, Entity, EntityManager, PrimaryGeneratedColumn, Repository, UpdateDateColumn } from "typeorm";
|
|
5
|
+
import { InjectRepository, TypeOrmModule } from "@nestjs/typeorm";
|
|
6
|
+
import { firstValueFrom } from "rxjs";
|
|
7
|
+
import { ClientProxy, ClientProxyFactory } from "@nestjs/microservices";
|
|
8
|
+
|
|
9
|
+
//#region src/core/typeorm-outbox.di-tokens.ts
|
|
10
|
+
const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol("TYPEORM_OUTBOX_CRON_CONFIG_TOKEN");
|
|
11
|
+
const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol("TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN");
|
|
12
|
+
const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol("TYPEORM_OUTBOX_SERVICE_TOKEN");
|
|
13
|
+
const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol("TYPEORM_OUTBOX_BROKER_TOKEN");
|
|
14
|
+
const InjectTypeormOutboxCronConfig = () => Inject(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);
|
|
15
|
+
const InjectTypeormOutboxModuleConfig = () => Inject(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);
|
|
16
|
+
const InjectTypeormOutboxService = () => Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);
|
|
17
|
+
const InjectTypeormOutboxBroker = () => Inject(TYPEORM_OUTBOX_BROKER_TOKEN);
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region \0@oxc-project+runtime@0.108.0/helpers/decorateMetadata.js
|
|
21
|
+
function __decorateMetadata(k, v) {
|
|
22
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region \0@oxc-project+runtime@0.108.0/helpers/decorate.js
|
|
27
|
+
function __decorate(decorators, target, key, desc) {
|
|
28
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
29
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
30
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
31
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/core/typeorm-outbox.entity.ts
|
|
36
|
+
var _ref$2, _ref2$1, _ref3$1, _ref4, _ref5;
|
|
37
|
+
let TypeormOutboxEntity = class TypeormOutboxEntity {
|
|
38
|
+
id;
|
|
39
|
+
createdAt;
|
|
40
|
+
updatedAt;
|
|
41
|
+
destinationTopic;
|
|
42
|
+
headers;
|
|
43
|
+
keys;
|
|
44
|
+
payload;
|
|
45
|
+
};
|
|
46
|
+
__decorate([PrimaryGeneratedColumn("uuid"), __decorateMetadata("design:type", String)], TypeormOutboxEntity.prototype, "id", void 0);
|
|
47
|
+
__decorate([CreateDateColumn({ name: "created_at" }), __decorateMetadata("design:type", typeof (_ref$2 = typeof Date !== "undefined" && Date) === "function" ? _ref$2 : Object)], TypeormOutboxEntity.prototype, "createdAt", void 0);
|
|
48
|
+
__decorate([UpdateDateColumn({ name: "updated_at" }), __decorateMetadata("design:type", typeof (_ref2$1 = typeof Date !== "undefined" && Date) === "function" ? _ref2$1 : Object)], TypeormOutboxEntity.prototype, "updatedAt", void 0);
|
|
49
|
+
__decorate([Column("character varying", { name: "destination_topic" }), __decorateMetadata("design:type", String)], TypeormOutboxEntity.prototype, "destinationTopic", void 0);
|
|
50
|
+
__decorate([Column("jsonb", { nullable: true }), __decorateMetadata("design:type", typeof (_ref3$1 = typeof Record !== "undefined" && Record) === "function" ? _ref3$1 : Object)], TypeormOutboxEntity.prototype, "headers", void 0);
|
|
51
|
+
__decorate([Column("jsonb", { nullable: true }), __decorateMetadata("design:type", typeof (_ref4 = typeof Record !== "undefined" && Record) === "function" ? _ref4 : Object)], TypeormOutboxEntity.prototype, "keys", void 0);
|
|
52
|
+
__decorate([Column("jsonb"), __decorateMetadata("design:type", typeof (_ref5 = typeof Record !== "undefined" && Record) === "function" ? _ref5 : Object)], TypeormOutboxEntity.prototype, "payload", void 0);
|
|
53
|
+
TypeormOutboxEntity = __decorate([Entity("outbox")], TypeormOutboxEntity);
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region \0@oxc-project+runtime@0.108.0/helpers/decorateParam.js
|
|
57
|
+
function __decorateParam(paramIndex, decorator) {
|
|
58
|
+
return function(target, key) {
|
|
59
|
+
decorator(target, key, paramIndex);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/core/typeorm-outbox.controller.ts
|
|
65
|
+
var _ref$1, _ref2, _ref3;
|
|
66
|
+
let TypeormOutboxController = class TypeormOutboxController {
|
|
67
|
+
constructor(entityManager, outboxRepository, brokerClient) {
|
|
68
|
+
this.entityManager = entityManager;
|
|
69
|
+
this.outboxRepository = outboxRepository;
|
|
70
|
+
this.brokerClient = brokerClient;
|
|
71
|
+
}
|
|
72
|
+
async handleOutboxCron() {
|
|
73
|
+
await this.executeCronJob();
|
|
74
|
+
}
|
|
75
|
+
async executeCronJob() {
|
|
76
|
+
const lockId = hashStringToInt("typeorm-outbox-cron-job");
|
|
77
|
+
const [{ pg_try_advisory_xact_lock: acquired }] = await this.entityManager.query(`SELECT pg_try_advisory_xact_lock(${lockId})`);
|
|
78
|
+
if (!acquired) return;
|
|
79
|
+
const entities = await this.outboxRepository.find();
|
|
80
|
+
for (const entity of entities) {
|
|
81
|
+
await firstValueFrom(this.brokerClient.emit(entity.destinationTopic, {
|
|
82
|
+
key: entity.keys,
|
|
83
|
+
value: entity.payload,
|
|
84
|
+
headers: entity.headers
|
|
85
|
+
}));
|
|
86
|
+
await this.outboxRepository.delete(entity.id);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
__decorate([
|
|
91
|
+
Cron(CronExpression.EVERY_10_SECONDS),
|
|
92
|
+
__decorateMetadata("design:type", Function),
|
|
93
|
+
__decorateMetadata("design:paramtypes", []),
|
|
94
|
+
__decorateMetadata("design:returntype", Promise)
|
|
95
|
+
], TypeormOutboxController.prototype, "handleOutboxCron", null);
|
|
96
|
+
TypeormOutboxController = __decorate([
|
|
97
|
+
Controller(),
|
|
98
|
+
__decorateParam(1, InjectRepository(TypeormOutboxEntity)),
|
|
99
|
+
__decorateParam(2, InjectTypeormOutboxBroker()),
|
|
100
|
+
__decorateMetadata("design:paramtypes", [
|
|
101
|
+
typeof (_ref$1 = typeof EntityManager !== "undefined" && EntityManager) === "function" ? _ref$1 : Object,
|
|
102
|
+
typeof (_ref2 = typeof Repository !== "undefined" && Repository) === "function" ? _ref2 : Object,
|
|
103
|
+
typeof (_ref3 = typeof ClientProxy !== "undefined" && ClientProxy) === "function" ? _ref3 : Object
|
|
104
|
+
])
|
|
105
|
+
], TypeormOutboxController);
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/core/typeorm-outbox.interfaces.ts
|
|
109
|
+
var TypeormOutboxRegisterCronModuleOptions = class {
|
|
110
|
+
typeOrmConnectionName = "default";
|
|
111
|
+
kafkaConfig = {};
|
|
112
|
+
};
|
|
113
|
+
var TypeormOutboxModuleOptions = class {
|
|
114
|
+
typeOrmConnectionName = "default";
|
|
115
|
+
};
|
|
116
|
+
var TypeormOutboxModuleAsyncOptions = class {
|
|
117
|
+
imports = [];
|
|
118
|
+
inject = [];
|
|
119
|
+
useFactory;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
//#endregion
|
|
123
|
+
//#region src/core/typeorm-outbox.service.ts
|
|
124
|
+
var _ref;
|
|
125
|
+
let TypeormOutboxService = class TypeormOutboxService {
|
|
126
|
+
constructor(outboxRepository) {
|
|
127
|
+
this.outboxRepository = outboxRepository;
|
|
128
|
+
}
|
|
129
|
+
async create(options) {
|
|
130
|
+
await this.outboxRepository.save({
|
|
131
|
+
destinationTopic: options.destinationTopic,
|
|
132
|
+
headers: options.headers,
|
|
133
|
+
keys: options.keys,
|
|
134
|
+
payload: options.payload
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
TypeormOutboxService = __decorate([
|
|
139
|
+
Injectable(),
|
|
140
|
+
__decorateParam(0, InjectRepository(TypeormOutboxEntity)),
|
|
141
|
+
__decorateMetadata("design:paramtypes", [typeof (_ref = typeof Repository !== "undefined" && Repository) === "function" ? _ref : Object])
|
|
142
|
+
], TypeormOutboxService);
|
|
143
|
+
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/core/typeorm-outbox.module.ts
|
|
146
|
+
var _TypeormOutboxModule;
|
|
147
|
+
let TypeormOutboxModule = _TypeormOutboxModule = class TypeormOutboxModule {
|
|
148
|
+
static forRoot(options = {}) {
|
|
149
|
+
const configProvider = {
|
|
150
|
+
provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,
|
|
151
|
+
useValue: options
|
|
152
|
+
};
|
|
153
|
+
const serviceProvider = {
|
|
154
|
+
provide: TYPEORM_OUTBOX_SERVICE_TOKEN,
|
|
155
|
+
useClass: TypeormOutboxService
|
|
156
|
+
};
|
|
157
|
+
const brokerProvider = {
|
|
158
|
+
provide: TYPEORM_OUTBOX_BROKER_TOKEN,
|
|
159
|
+
useValue: null
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
module: _TypeormOutboxModule,
|
|
163
|
+
imports: [TypeOrmModule.forFeature([TypeormOutboxEntity], options.typeOrmConnectionName)],
|
|
164
|
+
providers: [
|
|
165
|
+
configProvider,
|
|
166
|
+
serviceProvider,
|
|
167
|
+
brokerProvider
|
|
168
|
+
],
|
|
169
|
+
exports: [
|
|
170
|
+
configProvider,
|
|
171
|
+
serviceProvider,
|
|
172
|
+
brokerProvider
|
|
173
|
+
]
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
static forRootAsync(options) {
|
|
177
|
+
const configProvider = {
|
|
178
|
+
provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,
|
|
179
|
+
useFactory: async (...args) => {
|
|
180
|
+
return options.useFactory?.(...args);
|
|
181
|
+
},
|
|
182
|
+
inject: options.inject || []
|
|
183
|
+
};
|
|
184
|
+
const serviceProvider = {
|
|
185
|
+
provide: TYPEORM_OUTBOX_SERVICE_TOKEN,
|
|
186
|
+
useClass: TypeormOutboxService
|
|
187
|
+
};
|
|
188
|
+
const brokerProvider = {
|
|
189
|
+
provide: TYPEORM_OUTBOX_BROKER_TOKEN,
|
|
190
|
+
useValue: null
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
module: _TypeormOutboxModule,
|
|
194
|
+
imports: [TypeOrmModule.forFeature([TypeormOutboxEntity], "default")],
|
|
195
|
+
providers: [
|
|
196
|
+
configProvider,
|
|
197
|
+
serviceProvider,
|
|
198
|
+
brokerProvider
|
|
199
|
+
],
|
|
200
|
+
exports: [
|
|
201
|
+
configProvider,
|
|
202
|
+
serviceProvider,
|
|
203
|
+
brokerProvider
|
|
204
|
+
]
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
static registerCronAsync(options) {
|
|
208
|
+
const configProvider = {
|
|
209
|
+
provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,
|
|
210
|
+
useFactory: async (...args) => {
|
|
211
|
+
return options.useFactory?.(...args);
|
|
212
|
+
},
|
|
213
|
+
inject: options.inject || []
|
|
214
|
+
};
|
|
215
|
+
const brokerProvider = {
|
|
216
|
+
provide: TYPEORM_OUTBOX_BROKER_TOKEN,
|
|
217
|
+
useFactory: async (...args) => {
|
|
218
|
+
const moduleOptions = options?.useFactory?.(...args);
|
|
219
|
+
return ClientProxyFactory.create(moduleOptions?.kafkaConfig ?? {});
|
|
220
|
+
},
|
|
221
|
+
inject: options.inject || []
|
|
222
|
+
};
|
|
223
|
+
const serviceProvider = {
|
|
224
|
+
provide: TYPEORM_OUTBOX_SERVICE_TOKEN,
|
|
225
|
+
useClass: TypeormOutboxService
|
|
226
|
+
};
|
|
227
|
+
return {
|
|
228
|
+
module: _TypeormOutboxModule,
|
|
229
|
+
imports: [ScheduleModule.forRoot(), TypeOrmModule.forFeature([TypeormOutboxEntity], "default")],
|
|
230
|
+
controllers: [TypeormOutboxController],
|
|
231
|
+
providers: [
|
|
232
|
+
configProvider,
|
|
233
|
+
brokerProvider,
|
|
234
|
+
serviceProvider
|
|
235
|
+
],
|
|
236
|
+
exports: [
|
|
237
|
+
configProvider,
|
|
238
|
+
brokerProvider,
|
|
239
|
+
serviceProvider
|
|
240
|
+
]
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
TypeormOutboxModule = _TypeormOutboxModule = __decorate([Module({})], TypeormOutboxModule);
|
|
245
|
+
|
|
246
|
+
//#endregion
|
|
247
|
+
export { InjectTypeormOutboxBroker, InjectTypeormOutboxCronConfig, InjectTypeormOutboxModuleConfig, InjectTypeormOutboxService, TYPEORM_OUTBOX_BROKER_TOKEN, TYPEORM_OUTBOX_CRON_CONFIG_TOKEN, TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN, TYPEORM_OUTBOX_SERVICE_TOKEN, TypeormOutboxController, TypeormOutboxEntity, TypeormOutboxModule, TypeormOutboxModuleAsyncOptions, TypeormOutboxModuleOptions, TypeormOutboxRegisterCronModuleOptions, TypeormOutboxService };
|
|
248
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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(\"uuid\")\n id!: string;\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":";;;;;;;;;AAEA,MAAa,mCAAmC,OAC9C,mCACD;AACD,MAAa,qCAAqC,OAChD,qCACD;AACD,MAAa,+BAA+B,OAC1C,+BACD;AACD,MAAa,8BAA8B,OACzC,8BACD;AAED,MAAa,sCACX,OAAO,iCAAiC;AAC1C,MAAa,wCACX,OAAO,mCAAmC;AAC5C,MAAa,mCACX,OAAO,6BAA6B;AACtC,MAAa,kCACX,OAAO,4BAA4B;;;;;;;;;;;;;;;;;;;;ACb9B,gCAAM,oBAAoB;CAC/B,AACA;CAEA,AACA;CAEA,AACA;CAEA,AACA;CAEA,AACA;CAEA,AACA;CAEA,AACA;;YAnBC,uBAAuB,OAAO;YAG9B,iBAAiB,EAAE,MAAM,cAAc,CAAC;YAGxC,iBAAiB,EAAE,MAAM,cAAc,CAAC;YAGxC,OAAO,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;YAG1D,OAAO,SAAS,EAAE,UAAU,MAAM,CAAC;YAGnC,OAAO,SAAS,EAAE,UAAU,MAAM,CAAC;YAGnC,OAAO,QAAQ;kCApBjB,OAAO,SAAS;;;;;;;;;;;;;ACGV,oCAAM,wBAAwB;CACnC,YACE,AAAiB,eACjB,AACiB,kBACjB,AACiB,cACjB;EALiB;EAEA;EAEA;;CAGnB,MACM,mBAAmB;AACvB,QAAM,KAAK,gBAAgB;;CAG7B,MAAM,iBAAiB;EACrB,MAAM,SAAS,gBAAgB,0BAA0B;EACzD,MAAM,CAAC,EAAE,2BAA2B,cAClC,MAAM,KAAK,cAAc,MACvB,oCAAoC,OAAO,GAC5C;AAEH,MAAI,CAAC,SACH;EAEF,MAAM,WAAW,MAAM,KAAK,iBAAiB,MAAM;AAEnD,OAAK,MAAM,UAAU,UAAU;AAC7B,SAAM,eACJ,KAAK,aAAa,KAAK,OAAO,kBAAkB;IAC9C,KAAK,OAAO;IACZ,OAAO,OAAO;IACd,SAAS,OAAO;IACjB,CAAC,CACH;AACD,SAAM,KAAK,iBAAiB,OAAO,OAAO,GAAG;;;;;CAzBhD,KAAK,eAAe,iBAAiB;;;;;;CAVvC,YAAY;oBAIR,iBAAiB,oBAAoB;oBAErC,2BAA2B;;;;;;;;;;ACZhC,IAAa,yCAAb,MAAoD;CAClD,wBAAiC;CACjC,cAA6B,EAAE;;AAiBjC,IAAa,6BAAb,MAAwC;CACtC,wBAAiC;;AAEnC,IAAa,kCAAb,MAA6C;CAC3C,UAAmB,EAAE;CACrB,SAA4B,EAAE;CAC9B;;;;;;AChBK,iCAAM,qBAAqB;CAChC,YACE,AACiB,kBACjB;EADiB;;CAGnB,MAAM,OAAO,SAA8B;AACzC,QAAM,KAAK,iBAAiB,KAAK;GAC/B,kBAAkB,QAAQ;GAC1B,SAAS,QAAQ;GACjB,MAAM,QAAQ;GACd,SAAS,QAAQ;GAClB,CAAC;;;;CAbL,YAAY;oBAGR,iBAAiB,oBAAoB;;;;;;;ACMnC,uDAAM,oBAAoB;CAC/B,OAAO,QAAQ,UAAsC,EAAE,EAAiB;EACtE,MAAM,iBAA2B;GAC/B,SAAS;GACT,UAAU;GACX;EACD,MAAM,kBAA4B;GAChC,SAAS;GACT,UAAU;GACX;EACD,MAAM,iBAA2B;GAC/B,SAAS;GACT,UAAU;GACX;AAED,SAAO;GACL;GACA,SAAS,CACP,cAAc,WACZ,CAAC,oBAAoB,EACrB,QAAQ,sBACT,CACF;GACD,WAAW;IAAC;IAAgB;IAAiB;IAAe;GAC5D,SAAS;IAAC;IAAgB;IAAiB;IAAe;GAC3D;;CAGH,OAAO,aAAa,SAAyD;EAC3E,MAAM,iBAA2B;GAC/B,SAAS;GACT,YAAY,OAAO,GAAG,SAAoB;AAIxC,WAHsB,QAAQ,aAC5B,GAAG,KACJ;;GAGH,QAAQ,QAAQ,UAAU,EAAE;GAC7B;EACD,MAAM,kBAA4B;GAChC,SAAS;GACT,UAAU;GACX;EACD,MAAM,iBAA2B;GAC/B,SAAS;GACT,UAAU;GACX;AAED,SAAO;GACL;GACA,SAAS,CAAC,cAAc,WAAW,CAAC,oBAAoB,EAAE,UAAU,CAAC;GACrE,WAAW;IAAC;IAAgB;IAAiB;IAAe;GAC5D,SAAS;IAAC;IAAgB;IAAiB;IAAe;GAC3D;;CAGH,OAAO,kBACL,SACe;EACf,MAAM,iBAA2B;GAC/B,SAAS;GACT,YAAY,OAAO,GAAG,SAAoB;AAIxC,WAHsB,QAAQ,aAC5B,GAAG,KACJ;;GAGH,QAAQ,QAAQ,UAAU,EAAE;GAC7B;EAED,MAAM,iBAA2B;GAC/B,SAAS;GACT,YAAY,OAAO,GAAG,SAAoB;IACxC,MAAM,gBAAgB,SAAS,aAC7B,GAAG,KACJ;AACD,WAAO,mBAAmB,OAAO,eAAe,eAAe,EAAE,CAAC;;GAEpE,QAAQ,QAAQ,UAAU,EAAE;GAC7B;EACD,MAAM,kBAA4B;GAChC,SAAS;GACT,UAAU;GACX;AAED,SAAO;GACL;GACA,SAAS,CACP,eAAe,SAAS,EACxB,cAAc,WAAW,CAAC,oBAAoB,EAAE,UAAU,CAC3D;GACD,aAAa,CAAC,wBAAwB;GACtC,WAAW;IAAC;IAAgB;IAAgB;IAAgB;GAC5D,SAAS;IAAC;IAAgB;IAAgB;IAAgB;GAC3D;;;yDA/FJ,OAAO,EAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@globalart/nestjs-typeorm-outbox",
|
|
3
|
+
"description": "TypeORM Outbox integration for NestJS",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.mjs",
|
|
7
|
+
"module": "dist/index.mjs",
|
|
8
|
+
"types": "dist/index.d.mts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.mts",
|
|
13
|
+
"default": "./dist/index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/GlobalArtInc/ecosystem.git#main",
|
|
28
|
+
"directory": "packages/nestjs-temporal"
|
|
29
|
+
},
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"author": "GlobalArt, Inc",
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"nestjs",
|
|
37
|
+
"temporal"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"format": "prettier --write \"**/*.ts\"",
|
|
41
|
+
"build": "tsdown",
|
|
42
|
+
"build:watch": "tsdown --watch",
|
|
43
|
+
"prepublishOnly": "npm run build",
|
|
44
|
+
"publish:dev": "npm publish --access public --tag dev",
|
|
45
|
+
"publish:npm": "release-it --config ../../.release-it.json"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@nestjs/common": "11.1.12",
|
|
49
|
+
"cron": "^4.4.0",
|
|
50
|
+
"@nestjs/schedule": "^6.1.0",
|
|
51
|
+
"@nestjs/core": "11.1.12",
|
|
52
|
+
"@nestjs/microservices": "^11.1.12",
|
|
53
|
+
"@nestjs/typeorm": "^11.0.0",
|
|
54
|
+
"typeorm": "^0.3.28",
|
|
55
|
+
"lodash": "^4.17.21",
|
|
56
|
+
"rxjs": "^7.8.2",
|
|
57
|
+
"kafkajs": "^2.2.4",
|
|
58
|
+
"@globalart/text-utils": "^1.0.5"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "25.0.9",
|
|
62
|
+
"reflect-metadata": "^0.2.2",
|
|
63
|
+
"release-it": "19.2.4",
|
|
64
|
+
"tsdown": "0.20.0-beta.4",
|
|
65
|
+
"typescript": "^5.9.3",
|
|
66
|
+
"prettier": "^3.8.1"
|
|
67
|
+
}
|
|
68
|
+
}
|