nicot 1.2.12 → 1.3.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/dist/index.cjs CHANGED
@@ -4,6 +4,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __getProtoOf = Object.getPrototypeOf;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __commonJS = (cb, mod) => function __require() {
8
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ };
7
10
  var __export = (target, all) => {
8
11
  for (var name in all)
9
12
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -35,6 +38,539 @@ var __decorateClass = (decorators, target, key, kind) => {
35
38
  return result;
36
39
  };
37
40
 
41
+ // node_modules/@nestjs/typeorm/dist/typeorm.constants.js
42
+ var require_typeorm_constants = __commonJS({
43
+ "node_modules/@nestjs/typeorm/dist/typeorm.constants.js"(exports2) {
44
+ "use strict";
45
+ Object.defineProperty(exports2, "__esModule", { value: true });
46
+ exports2.DEFAULT_DATA_SOURCE_NAME = exports2.TYPEORM_MODULE_ID = exports2.TYPEORM_MODULE_OPTIONS = void 0;
47
+ exports2.TYPEORM_MODULE_OPTIONS = "TypeOrmModuleOptions";
48
+ exports2.TYPEORM_MODULE_ID = "TypeOrmModuleId";
49
+ exports2.DEFAULT_DATA_SOURCE_NAME = "default";
50
+ }
51
+ });
52
+
53
+ // node_modules/@nestjs/typeorm/dist/exceptions/circular-dependency.exception.js
54
+ var require_circular_dependency_exception = __commonJS({
55
+ "node_modules/@nestjs/typeorm/dist/exceptions/circular-dependency.exception.js"(exports2) {
56
+ "use strict";
57
+ Object.defineProperty(exports2, "__esModule", { value: true });
58
+ exports2.CircularDependencyException = void 0;
59
+ var CircularDependencyException = class extends Error {
60
+ constructor(context) {
61
+ const ctx = context ? ` inside ${context}` : ``;
62
+ super(`A circular dependency has been detected${ctx}. Please, make sure that each side of a bidirectional relationships are decorated with "forwardRef()". Also, try to eliminate barrel files because they can lead to an unexpected behavior too.`);
63
+ }
64
+ };
65
+ exports2.CircularDependencyException = CircularDependencyException;
66
+ }
67
+ });
68
+
69
+ // node_modules/@nestjs/typeorm/dist/common/typeorm.utils.js
70
+ var require_typeorm_utils = __commonJS({
71
+ "node_modules/@nestjs/typeorm/dist/common/typeorm.utils.js"(exports2) {
72
+ "use strict";
73
+ Object.defineProperty(exports2, "__esModule", { value: true });
74
+ exports2.generateString = exports2.getConnectionToken = void 0;
75
+ exports2.getRepositoryToken = getRepositoryToken;
76
+ exports2.getCustomRepositoryToken = getCustomRepositoryToken;
77
+ exports2.getDataSourceToken = getDataSourceToken;
78
+ exports2.getDataSourcePrefix = getDataSourcePrefix;
79
+ exports2.getEntityManagerToken = getEntityManagerToken2;
80
+ exports2.handleRetry = handleRetry;
81
+ exports2.getDataSourceName = getDataSourceName;
82
+ var common_1 = require("@nestjs/common");
83
+ var operators_1 = require("rxjs/operators");
84
+ var typeorm_1 = require("typeorm");
85
+ var circular_dependency_exception_1 = require_circular_dependency_exception();
86
+ var typeorm_constants_1 = require_typeorm_constants();
87
+ var logger = new common_1.Logger("TypeOrmModule");
88
+ function getRepositoryToken(entity, dataSource = typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME) {
89
+ if (entity === null || entity === void 0) {
90
+ throw new circular_dependency_exception_1.CircularDependencyException("@InjectRepository()");
91
+ }
92
+ const dataSourcePrefix = getDataSourcePrefix(dataSource);
93
+ if (entity instanceof Function && (entity.prototype instanceof typeorm_1.Repository || entity.prototype instanceof typeorm_1.AbstractRepository)) {
94
+ if (!dataSourcePrefix) {
95
+ return entity;
96
+ }
97
+ return `${dataSourcePrefix}${getCustomRepositoryToken(entity)}`;
98
+ }
99
+ if (entity instanceof typeorm_1.EntitySchema) {
100
+ return `${dataSourcePrefix}${entity.options.target ? entity.options.target.name : entity.options.name}Repository`;
101
+ }
102
+ return `${dataSourcePrefix}${entity.name}Repository`;
103
+ }
104
+ function getCustomRepositoryToken(repository) {
105
+ if (repository === null || repository === void 0) {
106
+ throw new circular_dependency_exception_1.CircularDependencyException("@InjectRepository()");
107
+ }
108
+ return repository.name;
109
+ }
110
+ function getDataSourceToken(dataSource = typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME) {
111
+ return typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME === dataSource ? typeorm_1.DataSource ?? typeorm_1.Connection : "string" === typeof dataSource ? `${dataSource}DataSource` : typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME === dataSource.name || !dataSource.name ? typeorm_1.DataSource ?? typeorm_1.Connection : `${dataSource.name}DataSource`;
112
+ }
113
+ exports2.getConnectionToken = getDataSourceToken;
114
+ function getDataSourcePrefix(dataSource = typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME) {
115
+ if (dataSource === typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME) {
116
+ return "";
117
+ }
118
+ if (typeof dataSource === "string") {
119
+ return dataSource + "_";
120
+ }
121
+ if (dataSource.name === typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME || !dataSource.name) {
122
+ return "";
123
+ }
124
+ return dataSource.name + "_";
125
+ }
126
+ function getEntityManagerToken2(dataSource = typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME) {
127
+ return typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME === dataSource ? typeorm_1.EntityManager : "string" === typeof dataSource ? `${dataSource}EntityManager` : typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME === dataSource.name || !dataSource.name ? typeorm_1.EntityManager : `${dataSource.name}EntityManager`;
128
+ }
129
+ function handleRetry(retryAttempts = 9, retryDelay = 3e3, dataSourceName = typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME, verboseRetryLog = false, toRetry) {
130
+ return (source) => source.pipe((0, operators_1.retryWhen)((e) => e.pipe((0, operators_1.scan)((errorCount, error) => {
131
+ if (toRetry && !toRetry(error)) {
132
+ throw error;
133
+ }
134
+ const dataSourceInfo = dataSourceName === typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME ? "" : ` (${dataSourceName})`;
135
+ const verboseMessage = verboseRetryLog ? ` Message: ${error.message}.` : "";
136
+ logger.error(`Unable to connect to the database${dataSourceInfo}.${verboseMessage} Retrying (${errorCount + 1})...`, error.stack);
137
+ if (errorCount + 1 >= retryAttempts) {
138
+ throw error;
139
+ }
140
+ return errorCount + 1;
141
+ }, 0), (0, operators_1.delay)(retryDelay))));
142
+ }
143
+ function getDataSourceName(options) {
144
+ return options && options.name ? options.name : typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME;
145
+ }
146
+ var generateString = () => crypto.randomUUID();
147
+ exports2.generateString = generateString;
148
+ }
149
+ });
150
+
151
+ // node_modules/@nestjs/typeorm/dist/common/typeorm.decorators.js
152
+ var require_typeorm_decorators = __commonJS({
153
+ "node_modules/@nestjs/typeorm/dist/common/typeorm.decorators.js"(exports2) {
154
+ "use strict";
155
+ Object.defineProperty(exports2, "__esModule", { value: true });
156
+ exports2.InjectEntityManager = exports2.InjectConnection = exports2.InjectDataSource = exports2.InjectRepository = void 0;
157
+ var common_1 = require("@nestjs/common");
158
+ var typeorm_constants_1 = require_typeorm_constants();
159
+ var typeorm_utils_1 = require_typeorm_utils();
160
+ var InjectRepository = (entity, dataSource = typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME) => (0, common_1.Inject)((0, typeorm_utils_1.getRepositoryToken)(entity, dataSource));
161
+ exports2.InjectRepository = InjectRepository;
162
+ var InjectDataSource = (dataSource) => (0, common_1.Inject)((0, typeorm_utils_1.getDataSourceToken)(dataSource));
163
+ exports2.InjectDataSource = InjectDataSource;
164
+ exports2.InjectConnection = exports2.InjectDataSource;
165
+ var InjectEntityManager = (dataSource) => (0, common_1.Inject)((0, typeorm_utils_1.getEntityManagerToken)(dataSource));
166
+ exports2.InjectEntityManager = InjectEntityManager;
167
+ }
168
+ });
169
+
170
+ // node_modules/@nestjs/typeorm/dist/common/index.js
171
+ var require_common = __commonJS({
172
+ "node_modules/@nestjs/typeorm/dist/common/index.js"(exports2) {
173
+ "use strict";
174
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
175
+ if (k2 === void 0) k2 = k;
176
+ var desc = Object.getOwnPropertyDescriptor(m, k);
177
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
178
+ desc = { enumerable: true, get: function() {
179
+ return m[k];
180
+ } };
181
+ }
182
+ Object.defineProperty(o, k2, desc);
183
+ }) : (function(o, m, k, k2) {
184
+ if (k2 === void 0) k2 = k;
185
+ o[k2] = m[k];
186
+ }));
187
+ var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
188
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
189
+ };
190
+ Object.defineProperty(exports2, "__esModule", { value: true });
191
+ __exportStar(require_typeorm_decorators(), exports2);
192
+ __exportStar(require_typeorm_utils(), exports2);
193
+ }
194
+ });
195
+
196
+ // node_modules/@nestjs/typeorm/dist/interfaces/typeorm-options.interface.js
197
+ var require_typeorm_options_interface = __commonJS({
198
+ "node_modules/@nestjs/typeorm/dist/interfaces/typeorm-options.interface.js"(exports2) {
199
+ "use strict";
200
+ Object.defineProperty(exports2, "__esModule", { value: true });
201
+ }
202
+ });
203
+
204
+ // node_modules/@nestjs/typeorm/dist/interfaces/index.js
205
+ var require_interfaces = __commonJS({
206
+ "node_modules/@nestjs/typeorm/dist/interfaces/index.js"(exports2) {
207
+ "use strict";
208
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
209
+ if (k2 === void 0) k2 = k;
210
+ var desc = Object.getOwnPropertyDescriptor(m, k);
211
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
212
+ desc = { enumerable: true, get: function() {
213
+ return m[k];
214
+ } };
215
+ }
216
+ Object.defineProperty(o, k2, desc);
217
+ }) : (function(o, m, k, k2) {
218
+ if (k2 === void 0) k2 = k;
219
+ o[k2] = m[k];
220
+ }));
221
+ var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
222
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
223
+ };
224
+ Object.defineProperty(exports2, "__esModule", { value: true });
225
+ __exportStar(require_typeorm_options_interface(), exports2);
226
+ }
227
+ });
228
+
229
+ // node_modules/@nestjs/typeorm/dist/entities-metadata.storage.js
230
+ var require_entities_metadata_storage = __commonJS({
231
+ "node_modules/@nestjs/typeorm/dist/entities-metadata.storage.js"(exports2) {
232
+ "use strict";
233
+ Object.defineProperty(exports2, "__esModule", { value: true });
234
+ exports2.EntitiesMetadataStorage = void 0;
235
+ var EntitiesMetadataStorage = class {
236
+ static addEntitiesByDataSource(dataSource, entities) {
237
+ const dataSourceToken = typeof dataSource === "string" ? dataSource : dataSource.name;
238
+ if (!dataSourceToken) {
239
+ return;
240
+ }
241
+ let collection = this.storage.get(dataSourceToken);
242
+ if (!collection) {
243
+ collection = [];
244
+ this.storage.set(dataSourceToken, collection);
245
+ }
246
+ entities.forEach((entity) => {
247
+ if (collection.includes(entity)) {
248
+ return;
249
+ }
250
+ collection.push(entity);
251
+ });
252
+ }
253
+ static getEntitiesByDataSource(dataSource) {
254
+ const dataSourceToken = typeof dataSource === "string" ? dataSource : dataSource.name;
255
+ if (!dataSourceToken) {
256
+ return [];
257
+ }
258
+ return this.storage.get(dataSourceToken) || [];
259
+ }
260
+ };
261
+ exports2.EntitiesMetadataStorage = EntitiesMetadataStorage;
262
+ EntitiesMetadataStorage.storage = /* @__PURE__ */ new Map();
263
+ }
264
+ });
265
+
266
+ // node_modules/@nestjs/typeorm/dist/typeorm-core.module.js
267
+ var require_typeorm_core_module = __commonJS({
268
+ "node_modules/@nestjs/typeorm/dist/typeorm-core.module.js"(exports2) {
269
+ "use strict";
270
+ var __decorate = exports2 && exports2.__decorate || function(decorators, target, key, desc) {
271
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
272
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
273
+ 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;
274
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
275
+ };
276
+ var __metadata = exports2 && exports2.__metadata || function(k, v) {
277
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
278
+ };
279
+ var __param = exports2 && exports2.__param || function(paramIndex, decorator) {
280
+ return function(target, key) {
281
+ decorator(target, key, paramIndex);
282
+ };
283
+ };
284
+ var TypeOrmCoreModule_1;
285
+ Object.defineProperty(exports2, "__esModule", { value: true });
286
+ exports2.TypeOrmCoreModule = void 0;
287
+ var common_1 = require("@nestjs/common");
288
+ var core_1 = require("@nestjs/core");
289
+ var rxjs_1 = require("rxjs");
290
+ var typeorm_1 = require("typeorm");
291
+ var typeorm_utils_1 = require_typeorm_utils();
292
+ var entities_metadata_storage_1 = require_entities_metadata_storage();
293
+ var typeorm_constants_1 = require_typeorm_constants();
294
+ var TypeOrmCoreModule = TypeOrmCoreModule_1 = class TypeOrmCoreModule {
295
+ constructor(options, moduleRef) {
296
+ this.options = options;
297
+ this.moduleRef = moduleRef;
298
+ this.logger = new common_1.Logger("TypeOrmModule");
299
+ }
300
+ static forRoot(options = {}) {
301
+ const typeOrmModuleOptions = {
302
+ provide: typeorm_constants_1.TYPEORM_MODULE_OPTIONS,
303
+ useValue: options
304
+ };
305
+ const dataSourceProvider = {
306
+ provide: (0, typeorm_utils_1.getDataSourceToken)(options),
307
+ useFactory: async () => await this.createDataSourceFactory(options)
308
+ };
309
+ const entityManagerProvider = this.createEntityManagerProvider(options);
310
+ const providers = [
311
+ entityManagerProvider,
312
+ dataSourceProvider,
313
+ typeOrmModuleOptions
314
+ ];
315
+ const exports3 = [entityManagerProvider, dataSourceProvider];
316
+ if (dataSourceProvider.provide === typeorm_1.DataSource) {
317
+ providers.push({
318
+ provide: typeorm_1.Connection,
319
+ useExisting: typeorm_1.DataSource
320
+ });
321
+ exports3.push(typeorm_1.Connection);
322
+ }
323
+ return {
324
+ module: TypeOrmCoreModule_1,
325
+ providers,
326
+ exports: exports3
327
+ };
328
+ }
329
+ static forRootAsync(options) {
330
+ const dataSourceProvider = {
331
+ provide: (0, typeorm_utils_1.getDataSourceToken)(options),
332
+ useFactory: async (typeOrmOptions) => {
333
+ if (options.name) {
334
+ return await this.createDataSourceFactory({
335
+ ...typeOrmOptions,
336
+ name: options.name
337
+ }, options.dataSourceFactory);
338
+ }
339
+ return await this.createDataSourceFactory(typeOrmOptions, options.dataSourceFactory);
340
+ },
341
+ inject: [typeorm_constants_1.TYPEORM_MODULE_OPTIONS]
342
+ };
343
+ const entityManagerProvider = {
344
+ provide: (0, typeorm_utils_1.getEntityManagerToken)(options),
345
+ useFactory: (dataSource) => dataSource.manager,
346
+ inject: [(0, typeorm_utils_1.getDataSourceToken)(options)]
347
+ };
348
+ const asyncProviders = this.createAsyncProviders(options);
349
+ const providers = [
350
+ ...asyncProviders,
351
+ entityManagerProvider,
352
+ dataSourceProvider,
353
+ {
354
+ provide: typeorm_constants_1.TYPEORM_MODULE_ID,
355
+ useValue: (0, typeorm_utils_1.generateString)()
356
+ },
357
+ ...options.extraProviders || []
358
+ ];
359
+ const exports3 = [
360
+ entityManagerProvider,
361
+ dataSourceProvider
362
+ ];
363
+ if (dataSourceProvider.provide === typeorm_1.DataSource) {
364
+ providers.push({
365
+ provide: typeorm_1.Connection,
366
+ useExisting: typeorm_1.DataSource
367
+ });
368
+ exports3.push(typeorm_1.Connection);
369
+ }
370
+ return {
371
+ module: TypeOrmCoreModule_1,
372
+ imports: options.imports,
373
+ providers,
374
+ exports: exports3
375
+ };
376
+ }
377
+ async onApplicationShutdown() {
378
+ const dataSource = this.moduleRef.get((0, typeorm_utils_1.getDataSourceToken)(this.options));
379
+ try {
380
+ if (dataSource && dataSource.isInitialized) {
381
+ await dataSource.destroy();
382
+ }
383
+ } catch (e) {
384
+ this.logger.error(e?.message);
385
+ }
386
+ }
387
+ static createAsyncProviders(options) {
388
+ if (options.useExisting || options.useFactory) {
389
+ return [this.createAsyncOptionsProvider(options)];
390
+ }
391
+ const useClass = options.useClass;
392
+ return [
393
+ this.createAsyncOptionsProvider(options),
394
+ {
395
+ provide: useClass,
396
+ useClass
397
+ }
398
+ ];
399
+ }
400
+ static createAsyncOptionsProvider(options) {
401
+ if (options.useFactory) {
402
+ return {
403
+ provide: typeorm_constants_1.TYPEORM_MODULE_OPTIONS,
404
+ useFactory: options.useFactory,
405
+ inject: options.inject || []
406
+ };
407
+ }
408
+ const inject = [
409
+ options.useClass || options.useExisting
410
+ ];
411
+ return {
412
+ provide: typeorm_constants_1.TYPEORM_MODULE_OPTIONS,
413
+ useFactory: async (optionsFactory) => await optionsFactory.createTypeOrmOptions(options.name),
414
+ inject
415
+ };
416
+ }
417
+ static createEntityManagerProvider(options) {
418
+ return {
419
+ provide: (0, typeorm_utils_1.getEntityManagerToken)(options),
420
+ useFactory: (dataSource) => dataSource.manager,
421
+ inject: [(0, typeorm_utils_1.getDataSourceToken)(options)]
422
+ };
423
+ }
424
+ static async createDataSourceFactory(options, dataSourceFactory) {
425
+ const dataSourceToken = (0, typeorm_utils_1.getDataSourceName)(options);
426
+ const createTypeormDataSource = dataSourceFactory ?? ((options2) => {
427
+ return typeorm_1.DataSource === void 0 ? (0, typeorm_1.createConnection)(options2) : new typeorm_1.DataSource(options2);
428
+ });
429
+ return await (0, rxjs_1.lastValueFrom)((0, rxjs_1.defer)(async () => {
430
+ let dataSource;
431
+ if (!options.autoLoadEntities) {
432
+ dataSource = await createTypeormDataSource(options);
433
+ } else {
434
+ let entities = options.entities;
435
+ if (Array.isArray(entities)) {
436
+ entities = entities.concat(entities_metadata_storage_1.EntitiesMetadataStorage.getEntitiesByDataSource(dataSourceToken));
437
+ } else {
438
+ entities = entities_metadata_storage_1.EntitiesMetadataStorage.getEntitiesByDataSource(dataSourceToken);
439
+ }
440
+ dataSource = await createTypeormDataSource({
441
+ ...options,
442
+ entities
443
+ });
444
+ }
445
+ return dataSource.initialize && !dataSource.isInitialized && !options.manualInitialization ? dataSource.initialize() : dataSource;
446
+ }).pipe((0, typeorm_utils_1.handleRetry)(options.retryAttempts, options.retryDelay, dataSourceToken, options.verboseRetryLog, options.toRetry)));
447
+ }
448
+ };
449
+ exports2.TypeOrmCoreModule = TypeOrmCoreModule;
450
+ exports2.TypeOrmCoreModule = TypeOrmCoreModule = TypeOrmCoreModule_1 = __decorate([
451
+ (0, common_1.Global)(),
452
+ (0, common_1.Module)({}),
453
+ __param(0, (0, common_1.Inject)(typeorm_constants_1.TYPEORM_MODULE_OPTIONS)),
454
+ __metadata("design:paramtypes", [Object, core_1.ModuleRef])
455
+ ], TypeOrmCoreModule);
456
+ }
457
+ });
458
+
459
+ // node_modules/@nestjs/typeorm/dist/typeorm.providers.js
460
+ var require_typeorm_providers = __commonJS({
461
+ "node_modules/@nestjs/typeorm/dist/typeorm.providers.js"(exports2) {
462
+ "use strict";
463
+ Object.defineProperty(exports2, "__esModule", { value: true });
464
+ exports2.createTypeOrmProviders = createTypeOrmProviders;
465
+ var typeorm_1 = require("typeorm");
466
+ var typeorm_utils_1 = require_typeorm_utils();
467
+ function createTypeOrmProviders(entities, dataSource) {
468
+ return (entities || []).map((entity) => ({
469
+ provide: (0, typeorm_utils_1.getRepositoryToken)(entity, dataSource),
470
+ useFactory: (dataSource2) => {
471
+ const entityMetadata = dataSource2.entityMetadatas.find((meta) => meta.target === entity);
472
+ const isTreeEntity = typeof entityMetadata?.treeType !== "undefined";
473
+ return isTreeEntity ? dataSource2.getTreeRepository(entity) : dataSource2.options.type === "mongodb" ? dataSource2.getMongoRepository(entity) : dataSource2.getRepository(entity);
474
+ },
475
+ inject: [(0, typeorm_utils_1.getDataSourceToken)(dataSource)],
476
+ /**
477
+ * Extra property to workaround dynamic modules serialisation issue
478
+ * that occurs when "TypeOrm#forFeature()" method is called with the same number
479
+ * of arguments and all entities share the same class names.
480
+ */
481
+ targetEntitySchema: (0, typeorm_1.getMetadataArgsStorage)().tables.find((item) => item.target === entity)
482
+ }));
483
+ }
484
+ }
485
+ });
486
+
487
+ // node_modules/@nestjs/typeorm/dist/typeorm.module.js
488
+ var require_typeorm_module = __commonJS({
489
+ "node_modules/@nestjs/typeorm/dist/typeorm.module.js"(exports2) {
490
+ "use strict";
491
+ var __decorate = exports2 && exports2.__decorate || function(decorators, target, key, desc) {
492
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
493
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
494
+ 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;
495
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
496
+ };
497
+ var TypeOrmModule_1;
498
+ Object.defineProperty(exports2, "__esModule", { value: true });
499
+ exports2.TypeOrmModule = void 0;
500
+ var common_1 = require("@nestjs/common");
501
+ var entities_metadata_storage_1 = require_entities_metadata_storage();
502
+ var typeorm_core_module_1 = require_typeorm_core_module();
503
+ var typeorm_constants_1 = require_typeorm_constants();
504
+ var typeorm_providers_1 = require_typeorm_providers();
505
+ var TypeOrmModule2 = TypeOrmModule_1 = class TypeOrmModule {
506
+ static forRoot(options) {
507
+ return {
508
+ module: TypeOrmModule_1,
509
+ imports: [typeorm_core_module_1.TypeOrmCoreModule.forRoot(options)]
510
+ };
511
+ }
512
+ static forFeature(entities = [], dataSource = typeorm_constants_1.DEFAULT_DATA_SOURCE_NAME) {
513
+ const providers = (0, typeorm_providers_1.createTypeOrmProviders)(entities, dataSource);
514
+ entities_metadata_storage_1.EntitiesMetadataStorage.addEntitiesByDataSource(dataSource, [...entities]);
515
+ return {
516
+ module: TypeOrmModule_1,
517
+ providers,
518
+ exports: providers
519
+ };
520
+ }
521
+ static forRootAsync(options) {
522
+ return {
523
+ module: TypeOrmModule_1,
524
+ imports: [typeorm_core_module_1.TypeOrmCoreModule.forRootAsync(options)]
525
+ };
526
+ }
527
+ };
528
+ exports2.TypeOrmModule = TypeOrmModule2;
529
+ exports2.TypeOrmModule = TypeOrmModule2 = TypeOrmModule_1 = __decorate([
530
+ (0, common_1.Module)({})
531
+ ], TypeOrmModule2);
532
+ }
533
+ });
534
+
535
+ // node_modules/@nestjs/typeorm/dist/index.js
536
+ var require_dist = __commonJS({
537
+ "node_modules/@nestjs/typeorm/dist/index.js"(exports2) {
538
+ "use strict";
539
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
540
+ if (k2 === void 0) k2 = k;
541
+ var desc = Object.getOwnPropertyDescriptor(m, k);
542
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
543
+ desc = { enumerable: true, get: function() {
544
+ return m[k];
545
+ } };
546
+ }
547
+ Object.defineProperty(o, k2, desc);
548
+ }) : (function(o, m, k, k2) {
549
+ if (k2 === void 0) k2 = k;
550
+ o[k2] = m[k];
551
+ }));
552
+ var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
553
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
554
+ };
555
+ Object.defineProperty(exports2, "__esModule", { value: true });
556
+ __exportStar(require_common(), exports2);
557
+ __exportStar(require_interfaces(), exports2);
558
+ __exportStar(require_typeorm_module(), exports2);
559
+ }
560
+ });
561
+
562
+ // node_modules/@nestjs/typeorm/index.js
563
+ var require_typeorm = __commonJS({
564
+ "node_modules/@nestjs/typeorm/index.js"(exports2) {
565
+ "use strict";
566
+ function __export2(m) {
567
+ for (var p in m) if (!exports2.hasOwnProperty(p)) exports2[p] = m[p];
568
+ }
569
+ exports2.__esModule = true;
570
+ __export2(require_dist());
571
+ }
572
+ });
573
+
38
574
  // index.ts
39
575
  var index_exports = {};
40
576
  __export(index_exports, {
@@ -65,6 +601,8 @@ __export(index_exports, {
65
601
  ImportDataDto: () => ImportDataDto,
66
602
  ImportEntryBaseDto: () => ImportEntryBaseDto,
67
603
  ImportEntryDto: () => ImportEntryDto,
604
+ InjectTransactionalEntityManager: () => InjectTransactionalEntityManager,
605
+ InjectTransactionalRepository: () => InjectTransactionalRepository,
68
606
  Inner: () => Inner,
69
607
  IntColumn: () => IntColumn,
70
608
  InternalColumn: () => InternalColumn,
@@ -74,6 +612,7 @@ __export(index_exports, {
74
612
  NotCreatable: () => NotCreatable,
75
613
  NotInResult: () => NotInResult,
76
614
  NotQueryable: () => NotQueryable,
615
+ NotUpsertable: () => NotUpsertable,
77
616
  NotWritable: () => NotWritable,
78
617
  OmitPipe: () => OmitPipe,
79
618
  OptionalDataPipe: () => OptionalDataPipe,
@@ -112,6 +651,10 @@ __export(index_exports, {
112
651
  StringJsonColumn: () => StringJsonColumn,
113
652
  TextColumn: () => TextColumn,
114
653
  TimeBase: () => TimeBase,
654
+ TransactionalTypeOrmInterceptor: () => TransactionalTypeOrmInterceptor,
655
+ TransactionalTypeOrmModule: () => TransactionalTypeOrmModule,
656
+ UpsertColumn: () => UpsertColumn,
657
+ UpsertableEntity: () => UpsertableEntity,
115
658
  UuidColumn: () => UuidColumn,
116
659
  applyQueryMatchBoolean: () => applyQueryMatchBoolean,
117
660
  applyQueryMatchBooleanMySQL: () => applyQueryMatchBooleanMySQL,
@@ -124,7 +667,11 @@ __export(index_exports, {
124
667
  createQueryCondition: () => createQueryCondition,
125
668
  createQueryOperator: () => createQueryOperator,
126
669
  createQueryOperatorArrayify: () => createQueryOperatorArrayify,
127
- createQueryWrap: () => createQueryWrap
670
+ createQueryWrap: () => createQueryWrap,
671
+ getTransactionalEntityManagerProvider: () => getTransactionalEntityManagerProvider,
672
+ getTransactionalEntityManagerToken: () => getTransactionalEntityManagerToken,
673
+ getTransactionalRepositoryProvider: () => getTransactionalRepositoryProvider,
674
+ getTransactionalRepositoryToken: () => getTransactionalRepositoryToken
128
675
  });
129
676
  module.exports = __toCommonJS(index_exports);
130
677
  __reExport(index_exports, require("nesties"), module.exports);
@@ -175,6 +722,7 @@ var import_class_validator2 = require("class-validator");
175
722
 
176
723
  // src/utility/metadata.ts
177
724
  var import_typed_reflector = require("typed-reflector");
725
+ var import_lodash = __toESM(require("lodash"));
178
726
  var Metadata = new import_typed_reflector.MetadataSetter();
179
727
  var reflector = new import_typed_reflector.Reflector();
180
728
  function getSpecificFields(obj, type, filter = () => true) {
@@ -187,11 +735,11 @@ function getSpecificFields(obj, type, filter = () => true) {
187
735
  });
188
736
  }
189
737
  function getNotInResultFields(obj, keepEntityVersioningDates = false) {
190
- return getSpecificFields(
191
- obj,
192
- "notInResult",
193
- (meta) => !keepEntityVersioningDates || !meta.entityVersioningDate
194
- );
738
+ const res = getSpecificFields(obj, "notInResult");
739
+ if (keepEntityVersioningDates) {
740
+ return import_lodash.default.difference(res, getSpecificFields(obj, "entityVersioningDate"));
741
+ }
742
+ return res;
195
743
  }
196
744
 
197
745
  // src/decorators/access.ts
@@ -207,8 +755,12 @@ var NotCreatable = () => (0, import_nesties2.MergePropertyDecorators)([
207
755
  var NotChangeable = () => (0, import_nesties2.MergePropertyDecorators)([
208
756
  Metadata.set("notChangeable", true, "notChangeableFields")
209
757
  ]);
758
+ var NotUpsertable = () => (0, import_nesties2.MergePropertyDecorators)([
759
+ (0, import_class_validator2.IsOptional)(),
760
+ Metadata.set("notUpsertable", true, "notUpsertableFields")
761
+ ]);
210
762
  var NotQueryable = () => Metadata.set("notQueryable", true, "notQueryableFields");
211
- var NotInResult = (options = {}) => Metadata.set("notInResult", options, "notInResultFields");
763
+ var NotInResult = () => Metadata.set("notInResult", true, "notInResultFields");
212
764
 
213
765
  // src/decorators/property.ts
214
766
  var import_swagger2 = require("@nestjs/swagger");
@@ -890,6 +1442,24 @@ var BindingValue = (bindingKey = DefaultBindingKey) => (obj, key, des) => {
890
1442
  )(obj, key);
891
1443
  };
892
1444
 
1445
+ // src/decorators/upsert.ts
1446
+ var import_typeorm3 = require("typeorm");
1447
+ var UpsertColumn = () => Metadata.set("upsertColumn", true, "upsertColumnFields");
1448
+ var UpsertableEntity = () => (cls) => {
1449
+ const upsertColumns = getSpecificFields(cls, "upsertColumn");
1450
+ const bindingColumns = getSpecificFields(cls, "bindingColumn");
1451
+ if (!upsertColumns.length && !bindingColumns.length) {
1452
+ throw new Error(
1453
+ `UpsertableEntity ${cls.name} must have at least one UpsertColumn or BindingColumn defined.`
1454
+ );
1455
+ }
1456
+ Metadata.set("upsertableEntity", true)(cls);
1457
+ if (!bindingColumns.length && upsertColumns.length === 1 && upsertColumns[0] === "id") {
1458
+ return;
1459
+ }
1460
+ (0, import_typeorm3.Unique)([.../* @__PURE__ */ new Set([...bindingColumns, ...upsertColumns])])(cls);
1461
+ };
1462
+
893
1463
  // src/dto/cursor-pagination.ts
894
1464
  var CursorPaginationDto = class {
895
1465
  };
@@ -963,10 +1533,10 @@ function CursorPaginationReturnMessageDto(type) {
963
1533
  }
964
1534
 
965
1535
  // src/crud-base.ts
966
- var import_typeorm7 = require("typeorm");
1536
+ var import_typeorm8 = require("typeorm");
967
1537
 
968
1538
  // src/bases/time-base.ts
969
- var import_typeorm3 = require("typeorm");
1539
+ var import_typeorm4 = require("typeorm");
970
1540
 
971
1541
  // src/bases/page-settings.ts
972
1542
  var import_class_validator5 = require("class-validator");
@@ -1021,6 +1591,7 @@ __decorateClass([
1021
1591
  ], PageSettingsDto.prototype, "recordsPerPage", 2);
1022
1592
 
1023
1593
  // src/bases/time-base.ts
1594
+ var EntityVersioningDate = () => Metadata.set("entityVersioningDate", true, "entityVersioningDateFields");
1024
1595
  var TimeBase = class extends PageSettingsDto {
1025
1596
  isValidInCreate() {
1026
1597
  return;
@@ -1043,28 +1614,40 @@ var TimeBase = class extends PageSettingsDto {
1043
1614
  // eslint-disable-next-line @typescript-eslint/no-empty-function
1044
1615
  async beforeUpdate() {
1045
1616
  }
1617
+ isValidInUpsert() {
1618
+ return;
1619
+ }
1620
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1621
+ async beforeUpsert() {
1622
+ }
1623
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1624
+ async afterUpsert() {
1625
+ }
1046
1626
  };
1047
1627
  __decorateClass([
1048
- (0, import_typeorm3.CreateDateColumn)({ select: false }),
1628
+ (0, import_typeorm4.CreateDateColumn)({ select: false }),
1049
1629
  NotColumn(),
1050
- NotInResult({ entityVersioningDate: true }),
1630
+ NotInResult(),
1631
+ EntityVersioningDate(),
1051
1632
  Reflect.metadata("design:type", Date)
1052
1633
  ], TimeBase.prototype, "createTime", 2);
1053
1634
  __decorateClass([
1054
- (0, import_typeorm3.UpdateDateColumn)({ select: false }),
1635
+ (0, import_typeorm4.UpdateDateColumn)({ select: false }),
1055
1636
  NotColumn(),
1056
- NotInResult({ entityVersioningDate: true }),
1637
+ NotInResult(),
1638
+ EntityVersioningDate(),
1057
1639
  Reflect.metadata("design:type", Date)
1058
1640
  ], TimeBase.prototype, "updateTime", 2);
1059
1641
  __decorateClass([
1060
- (0, import_typeorm3.DeleteDateColumn)({ select: false }),
1642
+ (0, import_typeorm4.DeleteDateColumn)({ select: false }),
1061
1643
  NotColumn(),
1062
- NotInResult({ entityVersioningDate: true }),
1644
+ NotInResult(),
1645
+ EntityVersioningDate(),
1063
1646
  Reflect.metadata("design:type", Date)
1064
1647
  ], TimeBase.prototype, "deleteTime", 2);
1065
1648
 
1066
1649
  // src/bases/id-base.ts
1067
- var import_typeorm4 = require("typeorm");
1650
+ var import_typeorm5 = require("typeorm");
1068
1651
  var import_class_validator6 = require("class-validator");
1069
1652
  var import_nesties7 = require("nesties");
1070
1653
  function IdBase(idOptions = {}) {
@@ -1084,7 +1667,7 @@ function IdBase(idOptions = {}) {
1084
1667
  columnExtras: { nullable: false, primary: true }
1085
1668
  }),
1086
1669
  Reflect.metadata("design:type", Number),
1087
- (0, import_typeorm4.Generated)("increment"),
1670
+ (0, import_typeorm5.Generated)("increment"),
1088
1671
  QueryEqual(),
1089
1672
  Metadata.set(
1090
1673
  "notRequiredButHasDefault",
@@ -1120,7 +1703,8 @@ function StringIdBase(idOptions) {
1120
1703
  ...idOptions.uuid ? [UuidColumn({ ...columnOptions, generated: true }), NotWritable()] : [
1121
1704
  StringColumn(idOptions.length || 255, columnOptions),
1122
1705
  (0, import_class_validator6.IsNotEmpty)(),
1123
- NotChangeable()
1706
+ NotChangeable(),
1707
+ UpsertColumn()
1124
1708
  ]
1125
1709
  ];
1126
1710
  const dec = (0, import_nesties7.MergePropertyDecorators)(decs);
@@ -1131,14 +1715,14 @@ function StringIdBase(idOptions) {
1131
1715
  // src/crud-base.ts
1132
1716
  var import_common2 = require("@nestjs/common");
1133
1717
  var import_StringUtils = require("typeorm/util/StringUtils");
1134
- var import_lodash3 = __toESM(require("lodash"));
1718
+ var import_lodash4 = __toESM(require("lodash"));
1135
1719
  var import_nesties8 = require("nesties");
1136
1720
 
1137
1721
  // src/utility/get-typeorm-relations.ts
1138
- var import_typeorm5 = require("typeorm");
1139
- var import_lodash = __toESM(require("lodash"));
1722
+ var import_typeorm6 = require("typeorm");
1723
+ var import_lodash2 = __toESM(require("lodash"));
1140
1724
  function getTypeormRelations(cl) {
1141
- const relations = (0, import_typeorm5.getMetadataArgsStorage)().relations.filter(
1725
+ const relations = (0, import_typeorm6.getMetadataArgsStorage)().relations.filter(
1142
1726
  (r) => r.target === cl
1143
1727
  );
1144
1728
  const typeormRelations = relations.map((relation) => {
@@ -1177,7 +1761,7 @@ function getTypeormRelations(cl) {
1177
1761
  };
1178
1762
  }
1179
1763
  );
1180
- return import_lodash.default.uniqBy(
1764
+ return import_lodash2.default.uniqBy(
1181
1765
  [...typeormRelations, ...computedRelations],
1182
1766
  // Merge typeorm relations and computed relations
1183
1767
  (r) => r.propertyName
@@ -1185,8 +1769,8 @@ function getTypeormRelations(cl) {
1185
1769
  }
1186
1770
 
1187
1771
  // src/utility/cursor-pagination-utils.ts
1188
- var import_typeorm6 = require("typeorm");
1189
- var import_lodash2 = __toESM(require("lodash"));
1772
+ var import_typeorm7 = require("typeorm");
1773
+ var import_lodash3 = __toESM(require("lodash"));
1190
1774
  var import_superjson = __toESM(require("superjson"));
1191
1775
 
1192
1776
  // src/utility/filter-relations.ts
@@ -1354,7 +1938,7 @@ async function getPaginatedResult(qb, entityClass, entityAliasName, take, cursor
1354
1938
  );
1355
1939
  if (keys.length) {
1356
1940
  const staircasedKeys = keys.map(
1357
- (key, i) => import_lodash2.default.range(i + 1).map((j) => keys[j])
1941
+ (key, i) => import_lodash3.default.range(i + 1).map((j) => keys[j])
1358
1942
  );
1359
1943
  const cursorKey = (key) => `_cursor_${key.replace(/\./g, "__").replace(/"/g, "")}`;
1360
1944
  const expressionMatrix = staircasedKeys.map(
@@ -1404,8 +1988,8 @@ async function getPaginatedResult(qb, entityClass, entityAliasName, take, cursor
1404
1988
  ).filter((s) => !s.includes("__never__"));
1405
1989
  if (expressionMatrix.length) {
1406
1990
  qb.andWhere(
1407
- new import_typeorm6.Brackets((sqb) => {
1408
- const levelToBrackets = (level) => new import_typeorm6.Brackets((qb2) => {
1991
+ new import_typeorm7.Brackets((sqb) => {
1992
+ const levelToBrackets = (level) => new import_typeorm7.Brackets((qb2) => {
1409
1993
  level.forEach((expr, i) => {
1410
1994
  if (i === 0) {
1411
1995
  qb2.where(expr);
@@ -1658,22 +2242,30 @@ var CrudBase = class {
1658
2242
  this._restoreBindings(snap);
1659
2243
  return res;
1660
2244
  }
2245
+ async _mayBeTransaction(cb, manager = this.repo.manager) {
2246
+ const hasActiveTx = !!manager.queryRunner?.isTransactionActive;
2247
+ const getRepo = (m) => m.getRepository(this.entityClass);
2248
+ if (hasActiveTx) {
2249
+ return cb(manager, getRepo(manager));
2250
+ } else {
2251
+ return manager.transaction(async (tdb) => await cb(tdb, getRepo(tdb)));
2252
+ }
2253
+ }
1661
2254
  async _batchCreate(ents, beforeCreate, skipErrors = false) {
1662
2255
  const entsWithId = ents.filter((ent) => ent.id != null);
1663
- return this.repo.manager.transaction(async (mdb) => {
2256
+ return this._mayBeTransaction(async (mdb, repo) => {
1664
2257
  let skipped = [];
1665
- const repo = mdb.getRepository(this.entityClass);
1666
2258
  let entsToSave = ents;
1667
2259
  if (entsWithId.length) {
1668
2260
  const entIds = entsWithId.map((ent) => ent.id);
1669
- const entIdChunks = import_lodash3.default.chunk(entIds, 65535);
2261
+ const entIdChunks = import_lodash4.default.chunk(entIds, 65535);
1670
2262
  const existingEnts = (await Promise.all(
1671
2263
  entIdChunks.map(
1672
2264
  (chunk) => repo.find({
1673
2265
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1674
2266
  // @ts-ignore
1675
2267
  where: {
1676
- id: (0, import_typeorm7.In)(chunk)
2268
+ id: (0, import_typeorm8.In)(chunk)
1677
2269
  },
1678
2270
  select: this.crudOptions.createOrUpdate ? void 0 : ["id", "deleteTime"],
1679
2271
  withDeleted: true
@@ -1737,7 +2329,7 @@ var CrudBase = class {
1737
2329
  await beforeCreate(repo);
1738
2330
  }
1739
2331
  try {
1740
- const entChunksToSave = import_lodash3.default.chunk(
2332
+ const entChunksToSave = import_lodash4.default.chunk(
1741
2333
  entsToSave,
1742
2334
  Math.floor(
1743
2335
  65535 / Math.max(1, Object.keys(entsToSave[0] || {}).length)
@@ -1770,19 +2362,22 @@ var CrudBase = class {
1770
2362
  let ent = new this.entityClass();
1771
2363
  Object.assign(
1772
2364
  ent,
1773
- (0, import_lodash3.omit)(_ent, ...this._typeormRelations.map((r) => r.propertyName))
2365
+ (0, import_lodash4.omit)(_ent, ...this._typeormRelations.map((r) => r.propertyName))
1774
2366
  );
1775
2367
  const invalidReason = ent.isValidInCreate();
1776
2368
  if (invalidReason) {
1777
2369
  throw new import_nesties8.BlankReturnMessageDto(400, invalidReason).toException();
1778
2370
  }
1779
- const savedEnt = await this.repo.manager.transaction(async (mdb) => {
1780
- const repo = mdb.getRepository(this.entityClass);
2371
+ const savedEnt = await this._mayBeTransaction(async (mdb, repo) => {
1781
2372
  if (ent.id != null) {
1782
2373
  const existingEnt = await repo.findOne({
1783
2374
  where: { id: ent.id },
1784
2375
  select: this.crudOptions.createOrUpdate ? void 0 : ["id", "deleteTime"],
1785
- withDeleted: true
2376
+ withDeleted: true,
2377
+ lock: {
2378
+ mode: "pessimistic_write",
2379
+ tables: [repo.metadata.tableName]
2380
+ }
1786
2381
  });
1787
2382
  if (existingEnt) {
1788
2383
  if (existingEnt.deleteTime) {
@@ -1872,12 +2467,24 @@ var CrudBase = class {
1872
2467
  });
1873
2468
  }
1874
2469
  }
2470
+ _applyQueryKeepEntityVersioningDates(qb) {
2471
+ if (this.crudOptions.keepEntityVersioningDates) {
2472
+ const versioningDateFields = getSpecificFields(
2473
+ this.entityClass,
2474
+ "entityVersioningDate"
2475
+ );
2476
+ for (const field of versioningDateFields) {
2477
+ qb.addSelect(`${this.entityAliasName}.${field}`);
2478
+ }
2479
+ }
2480
+ }
1875
2481
  async findOne(id, extraQuery = () => {
1876
2482
  }) {
1877
2483
  const bindingEnt = await this.getBindingPartialEntity();
1878
2484
  const query = this.queryBuilder().where(`${this.entityAliasName}.id = :id`, { id }).take(1);
1879
2485
  this._applyQueryRelations(query);
1880
2486
  this._applyQueryFromBinding(bindingEnt, query);
2487
+ this._applyQueryKeepEntityVersioningDates(query);
1881
2488
  this.extraGetQuery(query);
1882
2489
  extraQuery(query);
1883
2490
  query.take(1);
@@ -1919,6 +2526,7 @@ var CrudBase = class {
1919
2526
  this._applyQueryRelations(query);
1920
2527
  this._applyQueryFilters(query, newEnt);
1921
2528
  this._applyQueryFromBinding(bindingEnt, query);
2529
+ this._applyQueryKeepEntityVersioningDates(query);
1922
2530
  const pageSettings = newEnt instanceof PageSettingsDto ? newEnt : Object.assign(new PageSettingsDto(), newEnt);
1923
2531
  this.extraGetQuery(query);
1924
2532
  extraQuery(query);
@@ -2011,6 +2619,116 @@ var CrudBase = class {
2011
2619
  }
2012
2620
  return new import_nesties8.BlankReturnMessageDto(200, "success");
2013
2621
  }
2622
+ async upsert(_ent) {
2623
+ const bindingEnt = await this.getBindingPartialEntity();
2624
+ if (!_ent) {
2625
+ throw new import_nesties8.BlankReturnMessageDto(400, "Invalid entity").toException();
2626
+ }
2627
+ const ent = new this.entityClass();
2628
+ Object.assign(
2629
+ ent,
2630
+ (0, import_lodash4.omit)(_ent, ...this._typeormRelations.map((r) => r.propertyName))
2631
+ );
2632
+ const invalidReason = ent.isValidInUpsert();
2633
+ if (invalidReason) {
2634
+ throw new import_nesties8.BlankReturnMessageDto(400, invalidReason).toException();
2635
+ }
2636
+ const upsertColumns = getSpecificFields(this.entityClass, "upsertColumn");
2637
+ const conditions = {
2638
+ ...import_lodash4.default.pick(ent, upsertColumns),
2639
+ ...bindingEnt
2640
+ };
2641
+ const conditionKeys = [
2642
+ .../* @__PURE__ */ new Set([
2643
+ ...getSpecificFields(this.entityClass, "bindingColumn"),
2644
+ ...upsertColumns
2645
+ ])
2646
+ ];
2647
+ Object.assign(ent, conditions);
2648
+ let deleteColumnProperty = "";
2649
+ if (!this.crudOptions.hardDelete) {
2650
+ const deleteColumn = this.repo.manager.connection.getMetadata(
2651
+ this.entityClass
2652
+ ).deleteDateColumn;
2653
+ if (deleteColumn) {
2654
+ ent[deleteColumn.propertyName] = null;
2655
+ deleteColumnProperty = deleteColumn.propertyName;
2656
+ }
2657
+ }
2658
+ await ent.beforeUpsert?.();
2659
+ try {
2660
+ const savedEnt = await this._mayBeTransaction(async (mdb, repo) => {
2661
+ const res = await repo.upsert(ent, {
2662
+ conflictPaths: conditionKeys
2663
+ });
2664
+ const insertedId = res.identifiers[0]?.id;
2665
+ const fetchSaved = () => {
2666
+ const qb = repo.createQueryBuilder(this.entityAliasName);
2667
+ if (insertedId != null) {
2668
+ qb.where(`${this.entityAliasName}.id = :id`, { id: insertedId });
2669
+ } else {
2670
+ conditionKeys.forEach((key, i) => {
2671
+ const paramKey = `_cond_${key}`;
2672
+ qb[i === 0 ? "where" : "andWhere"](
2673
+ `${this.entityAliasName}.${key} = :${paramKey}`,
2674
+ {
2675
+ [paramKey]: conditions[key]
2676
+ }
2677
+ );
2678
+ });
2679
+ }
2680
+ qb.take(1);
2681
+ if (deleteColumnProperty) {
2682
+ if (!this.crudOptions.keepEntityVersioningDates) {
2683
+ qb.addSelect(`${this.entityAliasName}.${deleteColumnProperty}`);
2684
+ }
2685
+ qb.withDeleted();
2686
+ }
2687
+ this._applyQueryKeepEntityVersioningDates(qb);
2688
+ if (this.crudOptions.upsertIncludeRelations) {
2689
+ this._applyQueryRelations(qb);
2690
+ }
2691
+ return qb.getOne();
2692
+ };
2693
+ let saved = await fetchSaved();
2694
+ if (!saved) {
2695
+ this.log.error(
2696
+ `Failed to upsert entity ${JSON.stringify(
2697
+ ent
2698
+ )}: cannot find saved entity after upsert.`
2699
+ );
2700
+ throw new import_nesties8.BlankReturnMessageDto(500, "Internal error").toException();
2701
+ }
2702
+ if (deleteColumnProperty && saved[deleteColumnProperty]) {
2703
+ await repo.restore(insertedId ? { id: insertedId } : conditions);
2704
+ saved = await fetchSaved();
2705
+ if (!saved || saved[deleteColumnProperty]) {
2706
+ this.log.error(
2707
+ `Failed to upsert entity ${JSON.stringify(
2708
+ ent
2709
+ )}: cannot restore soft-deleted entity after upsert.`
2710
+ );
2711
+ throw new import_nesties8.BlankReturnMessageDto(
2712
+ 500,
2713
+ "Internal error"
2714
+ ).toException();
2715
+ }
2716
+ }
2717
+ return saved;
2718
+ });
2719
+ await savedEnt.afterUpsert?.();
2720
+ this.cleanEntityNotInResultFields(savedEnt);
2721
+ return new this.entityReturnMessageDto(200, "success", savedEnt);
2722
+ } catch (e) {
2723
+ if (e instanceof import_common2.HttpException) {
2724
+ throw e;
2725
+ }
2726
+ this.log.error(
2727
+ `Failed to upsert entity ${JSON.stringify(ent)}: ${e.toString()}`
2728
+ );
2729
+ throw new import_nesties8.BlankReturnMessageDto(500, "Internal error").toException();
2730
+ }
2731
+ }
2014
2732
  async delete(id, cond = {}) {
2015
2733
  const bindingEnt = await this.getBindingPartialEntity();
2016
2734
  let result;
@@ -2039,11 +2757,11 @@ var CrudBase = class {
2039
2757
  const newEnt = new this.entityClass();
2040
2758
  Object.assign(
2041
2759
  newEnt,
2042
- (0, import_lodash3.omit)(ent, ...this._typeormRelations.map((r) => r.propertyName))
2760
+ (0, import_lodash4.omit)(ent, ...this._typeormRelations.map((r) => r.propertyName))
2043
2761
  );
2044
2762
  return newEnt;
2045
2763
  });
2046
- const invalidResults = import_lodash3.default.compact(
2764
+ const invalidResults = import_lodash4.default.compact(
2047
2765
  await Promise.all(
2048
2766
  ents.map(async (ent) => {
2049
2767
  const reason = ent.isValidInCreate();
@@ -2216,9 +2934,10 @@ var CrudBase = class {
2216
2934
  await flush();
2217
2935
  return result;
2218
2936
  };
2219
- const res = await (options.repo ? op(options.repo) : this.repo.manager.transaction(
2220
- (tdb) => op(tdb.getRepository(this.entityClass))
2221
- ));
2937
+ const res = await this._mayBeTransaction(
2938
+ (tdb, repo) => op(repo),
2939
+ options.repo?.manager || this.repo.manager
2940
+ );
2222
2941
  return res == null ? new import_nesties8.BlankReturnMessageDto(200, "success") : new import_nesties8.GenericReturnMessageDto(200, "success", res);
2223
2942
  }
2224
2943
  async _loadFullTextIndex() {
@@ -2272,7 +2991,7 @@ function CrudService(entityClass, crudOptions = {}) {
2272
2991
  var import_common3 = require("@nestjs/common");
2273
2992
  var import_nesties10 = require("nesties");
2274
2993
  var import_swagger6 = require("@nestjs/swagger");
2275
- var import_lodash5 = __toESM(require("lodash"));
2994
+ var import_lodash6 = __toESM(require("lodash"));
2276
2995
  var import_nesties11 = require("nesties");
2277
2996
 
2278
2997
  // src/bases/base-restful-controller.ts
@@ -2281,6 +3000,7 @@ var RestfulMethods = [
2281
3000
  "findAll",
2282
3001
  "create",
2283
3002
  "update",
3003
+ "upsert",
2284
3004
  "delete",
2285
3005
  "import"
2286
3006
  ];
@@ -2315,6 +3035,9 @@ var BaseRestfulController = class {
2315
3035
  update(id, dto) {
2316
3036
  return this._service.update(id, dto);
2317
3037
  }
3038
+ upsert(dto) {
3039
+ return this._service.upsert(dto);
3040
+ }
2318
3041
  delete(id) {
2319
3042
  return this._service.delete(id);
2320
3043
  }
@@ -2346,7 +3069,7 @@ var PickTypeExpose = (cl, keys) => {
2346
3069
 
2347
3070
  // src/utility/patch-column-in-get.ts
2348
3071
  var import_nesties9 = require("nesties");
2349
- var import_lodash4 = __toESM(require("lodash"));
3072
+ var import_lodash5 = __toESM(require("lodash"));
2350
3073
  var import_constants = require("@nestjs/swagger/dist/constants");
2351
3074
  var PatchColumnsInGet = (cl, originalCl = cl, fieldsToOmit = []) => {
2352
3075
  const omit2 = new Set(fieldsToOmit);
@@ -2372,7 +3095,7 @@ var PatchColumnsInGet = (cl, originalCl = cl, fieldsToOmit = []) => {
2372
3095
  field
2373
3096
  );
2374
3097
  }
2375
- const queryableFieldsRemaining = import_lodash4.default.difference(
3098
+ const queryableFieldsRemaining = import_lodash5.default.difference(
2376
3099
  getSpecificFields(useCl, "queryCondition"),
2377
3100
  mutateFields
2378
3101
  );
@@ -2433,7 +3156,7 @@ var _RestfulFactory = class _RestfulFactory {
2433
3156
  this.entityClass,
2434
3157
  {
2435
3158
  ...this.options,
2436
- fieldsToOmit: import_lodash5.default.uniq([...this.options.fieldsToOmit || [], ...fields])
3159
+ fieldsToOmit: import_lodash6.default.uniq([...this.options.fieldsToOmit || [], ...fields])
2437
3160
  },
2438
3161
  this.__resolveVisited
2439
3162
  );
@@ -2443,7 +3166,7 @@ var _RestfulFactory = class _RestfulFactory {
2443
3166
  this.entityClass,
2444
3167
  {
2445
3168
  ...this.options,
2446
- writeFieldsToOmit: import_lodash5.default.uniq([
3169
+ writeFieldsToOmit: import_lodash6.default.uniq([
2447
3170
  ...this.options.writeFieldsToOmit || [],
2448
3171
  ...fields
2449
3172
  ])
@@ -2456,7 +3179,7 @@ var _RestfulFactory = class _RestfulFactory {
2456
3179
  this.entityClass,
2457
3180
  {
2458
3181
  ...this.options,
2459
- createFieldsToOmit: import_lodash5.default.uniq([
3182
+ createFieldsToOmit: import_lodash6.default.uniq([
2460
3183
  ...this.options.createFieldsToOmit || [],
2461
3184
  ...fields
2462
3185
  ])
@@ -2469,7 +3192,7 @@ var _RestfulFactory = class _RestfulFactory {
2469
3192
  this.entityClass,
2470
3193
  {
2471
3194
  ...this.options,
2472
- updateFieldsToOmit: import_lodash5.default.uniq([
3195
+ updateFieldsToOmit: import_lodash6.default.uniq([
2473
3196
  ...this.options.updateFieldsToOmit || [],
2474
3197
  ...fields
2475
3198
  ])
@@ -2477,12 +3200,25 @@ var _RestfulFactory = class _RestfulFactory {
2477
3200
  this.__resolveVisited
2478
3201
  );
2479
3202
  }
3203
+ omitUpsert(...fields) {
3204
+ return new _RestfulFactory(
3205
+ this.entityClass,
3206
+ {
3207
+ ...this.options,
3208
+ upsertFieldsToOmit: import_lodash6.default.uniq([
3209
+ ...this.options.upsertFieldsToOmit || [],
3210
+ ...fields
3211
+ ])
3212
+ },
3213
+ this.__resolveVisited
3214
+ );
3215
+ }
2480
3216
  omitFindAll(...fields) {
2481
3217
  return new _RestfulFactory(
2482
3218
  this.entityClass,
2483
3219
  {
2484
3220
  ...this.options,
2485
- findAllFieldsToOmit: import_lodash5.default.uniq([
3221
+ findAllFieldsToOmit: import_lodash6.default.uniq([
2486
3222
  ...this.options.findAllFieldsToOmit || [],
2487
3223
  ...fields
2488
3224
  ])
@@ -2495,7 +3231,7 @@ var _RestfulFactory = class _RestfulFactory {
2495
3231
  this.entityClass,
2496
3232
  {
2497
3233
  ...this.options,
2498
- outputFieldsToOmit: import_lodash5.default.uniq([
3234
+ outputFieldsToOmit: import_lodash6.default.uniq([
2499
3235
  ...this.options.outputFieldsToOmit || [],
2500
3236
  ...fields
2501
3237
  ])
@@ -2557,7 +3293,7 @@ var _RestfulFactory = class _RestfulFactory {
2557
3293
  return this.options.entityClassName || this.entityClass.name;
2558
3294
  }
2559
3295
  get fieldsToOmit() {
2560
- return import_lodash5.default.uniq([
3296
+ return import_lodash6.default.uniq([
2561
3297
  ...getSpecificFields(this.entityClass, "notColumn"),
2562
3298
  ...this.options.fieldsToOmit || [],
2563
3299
  ...getTypeormRelations(this.entityClass).map(
@@ -2566,7 +3302,7 @@ var _RestfulFactory = class _RestfulFactory {
2566
3302
  ]);
2567
3303
  }
2568
3304
  get fieldsInCreateToOmit() {
2569
- return import_lodash5.default.uniq([
3305
+ return import_lodash6.default.uniq([
2570
3306
  ...this.fieldsToOmit,
2571
3307
  ...this.options.writeFieldsToOmit || [],
2572
3308
  ...this.options.createFieldsToOmit || [],
@@ -2581,7 +3317,7 @@ var _RestfulFactory = class _RestfulFactory {
2581
3317
  );
2582
3318
  }
2583
3319
  get fieldsInUpdateToOmit() {
2584
- return import_lodash5.default.uniq([
3320
+ return import_lodash6.default.uniq([
2585
3321
  ...this.fieldsToOmit,
2586
3322
  ...this.options.writeFieldsToOmit || [],
2587
3323
  ...this.options.updateFieldsToOmit || [],
@@ -2595,21 +3331,36 @@ var _RestfulFactory = class _RestfulFactory {
2595
3331
  `Update${this.entityClassName}Dto`
2596
3332
  );
2597
3333
  }
3334
+ get fieldsInUpsertToOmit() {
3335
+ return import_lodash6.default.uniq([
3336
+ ...this.fieldsToOmit,
3337
+ ...this.options.writeFieldsToOmit || [],
3338
+ ...this.options.upsertFieldsToOmit || [],
3339
+ ...getSpecificFields(this.entityClass, "notWritable"),
3340
+ ...getSpecificFields(this.entityClass, "notUpsertable")
3341
+ ]);
3342
+ }
3343
+ get upsertDto() {
3344
+ return (0, import_nesties11.RenameClass)(
3345
+ OmitTypeExclude(this.entityClass, this.fieldsInUpsertToOmit),
3346
+ `Upsert${this.entityClassName}Dto`
3347
+ );
3348
+ }
2598
3349
  get importDto() {
2599
3350
  return ImportDataDto(this.createDto);
2600
3351
  }
2601
3352
  get fieldsInGetToOmit() {
2602
- return import_lodash5.default.uniq([
3353
+ return import_lodash6.default.uniq([
2603
3354
  ...this.fieldsToOmit,
2604
3355
  ...getSpecificFields(this.entityClass, "notQueryable"),
2605
- ...import_lodash5.default.difference(
3356
+ ...import_lodash6.default.difference(
2606
3357
  getSpecificFields(this.entityClass, "requireGetMutator"),
2607
3358
  getSpecificFields(this.entityClass, "getMutator")
2608
3359
  )
2609
3360
  ]);
2610
3361
  }
2611
3362
  get queryableFields() {
2612
- return import_lodash5.default.difference(
3363
+ return import_lodash6.default.difference(
2613
3364
  [
2614
3365
  ...getSpecificFields(this.entityClass, "queryCondition"),
2615
3366
  "pageCount",
@@ -2687,7 +3438,7 @@ var _RestfulFactory = class _RestfulFactory {
2687
3438
  const relationFactory = new _RestfulFactory(
2688
3439
  relation.propertyClass,
2689
3440
  {
2690
- entityClassName: `${this.entityClassName}${this.options.relations ? (0, import_lodash5.upperFirst)(relation.propertyName) : relation.propertyClass.name}`,
3441
+ entityClassName: `${this.entityClassName}${this.options.relations ? (0, import_lodash6.upperFirst)(relation.propertyName) : relation.propertyClass.name}`,
2691
3442
  relations: this.options.relations && getNextLevelRelations(
2692
3443
  this.options.relations.map(extractRelationName),
2693
3444
  relation.propertyName
@@ -2741,6 +3492,21 @@ var _RestfulFactory = class _RestfulFactory {
2741
3492
  `${this.entityClassName}CreateResultDto`
2742
3493
  );
2743
3494
  }
3495
+ get entityUpsertResultDto() {
3496
+ return (0, import_nesties11.RenameClass)(
3497
+ (0, import_swagger6.OmitType)(this.entityResultDto, [
3498
+ ...this.options.upsertIncludeRelations ? [] : getTypeormRelations(this.entityClass).map(
3499
+ (r) => r.propertyName
3500
+ ),
3501
+ ...getSpecificFields(
3502
+ this.entityClass,
3503
+ "notColumn",
3504
+ (m) => m.hideInUpsert
3505
+ )
3506
+ ]),
3507
+ `${this.entityClassName}UpsertResultDto`
3508
+ );
3509
+ }
2744
3510
  get entityReturnMessageDto() {
2745
3511
  return (0, import_nesties10.ReturnMessageDto)(this.entityResultDto);
2746
3512
  }
@@ -2776,7 +3542,7 @@ var _RestfulFactory = class _RestfulFactory {
2776
3542
  (0, import_common3.HttpCode)(200),
2777
3543
  (0, import_swagger6.ApiOperation)({
2778
3544
  summary: `Create a new ${this.entityClassName}`,
2779
- ...import_lodash5.default.omit(extras, "prefix")
3545
+ ...import_lodash6.default.omit(extras, "prefix")
2780
3546
  }),
2781
3547
  (0, import_swagger6.ApiBody)({ type: this.createDto }),
2782
3548
  (0, import_swagger6.ApiOkResponse)({ type: this.entityCreateReturnMessageDto }),
@@ -2786,12 +3552,36 @@ var _RestfulFactory = class _RestfulFactory {
2786
3552
  createParam() {
2787
3553
  return (0, import_common3.Body)((0, import_nesties10.DataPipe)(), OmitPipe(this.fieldsInCreateToOmit));
2788
3554
  }
3555
+ isUpsertable() {
3556
+ return !!reflector.get("upsertableEntity", this.entityClass);
3557
+ }
3558
+ upsert(extras = {}) {
3559
+ if (!this.isUpsertable()) {
3560
+ throw new Error(
3561
+ `Entity ${this.entityClass.name} is not upsertable. Please define at least one UpsertColumn or BindingColumn, and set @UpsertableEntity() decorator.`
3562
+ );
3563
+ }
3564
+ return (0, import_nesties10.MergeMethodDecorators)([
3565
+ this.usePrefix(import_common3.Put, extras.prefix),
3566
+ (0, import_common3.HttpCode)(200),
3567
+ (0, import_swagger6.ApiOperation)({
3568
+ summary: `Upsert a ${this.entityClassName}`,
3569
+ ...import_lodash6.default.omit(extras, "prefix")
3570
+ }),
3571
+ (0, import_swagger6.ApiBody)({ type: this.upsertDto }),
3572
+ (0, import_swagger6.ApiOkResponse)({ type: this.entityUpsertResultDto }),
3573
+ (0, import_nesties10.ApiError)(400, `The ${this.entityClassName} is not valid`)
3574
+ ]);
3575
+ }
3576
+ upsertParam() {
3577
+ return (0, import_common3.Body)((0, import_nesties10.DataPipe)(), OmitPipe(this.fieldsInUpsertToOmit));
3578
+ }
2789
3579
  findOne(extras = {}) {
2790
3580
  return (0, import_nesties10.MergeMethodDecorators)([
2791
3581
  this.usePrefix(import_common3.Get, extras.prefix, ":id"),
2792
3582
  (0, import_swagger6.ApiOperation)({
2793
3583
  summary: `Find a ${this.entityClassName} by id`,
2794
- ...import_lodash5.default.omit(extras, "prefix")
3584
+ ...import_lodash6.default.omit(extras, "prefix")
2795
3585
  }),
2796
3586
  (0, import_swagger6.ApiParam)({ name: "id", type: this.idType, required: true }),
2797
3587
  (0, import_swagger6.ApiOkResponse)({ type: this.entityReturnMessageDto }),
@@ -2813,7 +3603,7 @@ var _RestfulFactory = class _RestfulFactory {
2813
3603
  this.usePrefix(import_common3.Get, extras.prefix),
2814
3604
  (0, import_swagger6.ApiOperation)({
2815
3605
  summary: `Find all ${this.entityClassName}`,
2816
- ...import_lodash5.default.omit(extras, "prefix")
3606
+ ...import_lodash6.default.omit(extras, "prefix")
2817
3607
  }),
2818
3608
  (0, import_swagger6.ApiOkResponse)({ type: this.entityArrayReturnMessageDto })
2819
3609
  ]);
@@ -2823,14 +3613,14 @@ var _RestfulFactory = class _RestfulFactory {
2823
3613
  this.usePrefix(import_common3.Get, extras.prefix),
2824
3614
  (0, import_swagger6.ApiOperation)({
2825
3615
  summary: `Find all ${this.entityClassName}`,
2826
- ...import_lodash5.default.omit(extras, "prefix")
3616
+ ...import_lodash6.default.omit(extras, "prefix")
2827
3617
  }),
2828
3618
  (0, import_swagger6.ApiOkResponse)({ type: this.entityCursorPaginationReturnMessageDto })
2829
3619
  ]);
2830
3620
  }
2831
3621
  getMutatorColumns() {
2832
3622
  const mutatorColumns = getSpecificFields(this.entityClass, "getMutator");
2833
- return import_lodash5.default.difference(mutatorColumns, this.fieldsInGetToOmit);
3623
+ return import_lodash6.default.difference(mutatorColumns, this.fieldsInGetToOmit);
2834
3624
  }
2835
3625
  findAllParam() {
2836
3626
  const mutatorColumns = this.getMutatorColumns();
@@ -2850,7 +3640,7 @@ var _RestfulFactory = class _RestfulFactory {
2850
3640
  (0, import_common3.HttpCode)(200),
2851
3641
  (0, import_swagger6.ApiOperation)({
2852
3642
  summary: `Update a ${this.entityClassName} by id`,
2853
- ...import_lodash5.default.omit(extras, "prefix")
3643
+ ...import_lodash6.default.omit(extras, "prefix")
2854
3644
  }),
2855
3645
  (0, import_swagger6.ApiParam)({ name: "id", type: this.idType, required: true }),
2856
3646
  (0, import_swagger6.ApiBody)({ type: this.updateDto }),
@@ -2872,7 +3662,7 @@ var _RestfulFactory = class _RestfulFactory {
2872
3662
  (0, import_common3.HttpCode)(200),
2873
3663
  (0, import_swagger6.ApiOperation)({
2874
3664
  summary: `Delete a ${this.entityClassName} by id`,
2875
- ...import_lodash5.default.omit(extras, "prefix")
3665
+ ...import_lodash6.default.omit(extras, "prefix")
2876
3666
  }),
2877
3667
  (0, import_swagger6.ApiParam)({ name: "id", type: this.idType, required: true }),
2878
3668
  (0, import_nesties10.ApiBlankResponse)(),
@@ -2889,7 +3679,7 @@ var _RestfulFactory = class _RestfulFactory {
2889
3679
  (0, import_common3.HttpCode)(200),
2890
3680
  (0, import_swagger6.ApiOperation)({
2891
3681
  summary: `Import ${this.entityClassName}`,
2892
- ...import_lodash5.default.omit(extras, "prefix")
3682
+ ...import_lodash6.default.omit(extras, "prefix")
2893
3683
  }),
2894
3684
  (0, import_swagger6.ApiBody)({ type: this.importDto }),
2895
3685
  (0, import_swagger6.ApiOkResponse)({ type: this.importReturnMessageDto }),
@@ -2901,8 +3691,8 @@ var _RestfulFactory = class _RestfulFactory {
2901
3691
  this.usePrefix(import_common3.Post, options.prefix, ":id", operationName),
2902
3692
  (0, import_common3.HttpCode)(200),
2903
3693
  (0, import_swagger6.ApiOperation)({
2904
- summary: `${(0, import_lodash5.upperFirst)(operationName)} a ${this.entityClassName} by id`,
2905
- ...import_lodash5.default.omit(options, "prefix", "returnType")
3694
+ summary: `${(0, import_lodash6.upperFirst)(operationName)} a ${this.entityClassName} by id`,
3695
+ ...import_lodash6.default.omit(options, "prefix", "returnType")
2906
3696
  }),
2907
3697
  options.returnType ? (0, import_nesties10.ApiTypeResponse)(options.returnType) : (0, import_nesties10.ApiBlankResponse)(),
2908
3698
  (0, import_nesties10.ApiError)(
@@ -2926,6 +3716,7 @@ var _RestfulFactory = class _RestfulFactory {
2926
3716
  (m) => routeOptions?.routes?.[m]?.enabled === true
2927
3717
  );
2928
3718
  const validMethods = RestfulMethods.filter((m) => {
3719
+ if (m === "upsert" && !this.isUpsertable()) return false;
2929
3720
  const value = routeOptions?.routes?.[m]?.enabled;
2930
3721
  if (value === false) return false;
2931
3722
  if (value === true) return true;
@@ -2959,6 +3750,11 @@ var _RestfulFactory = class _RestfulFactory {
2959
3750
  paramDecorators: () => [this.idParam(), this.updateParam()],
2960
3751
  methodDecorators: () => [this.update()]
2961
3752
  },
3753
+ upsert: {
3754
+ paramTypes: [this.upsertDto],
3755
+ paramDecorators: () => [this.upsertParam()],
3756
+ methodDecorators: () => [this.upsert()]
3757
+ },
2962
3758
  delete: {
2963
3759
  paramTypes: [this.idType],
2964
3760
  paramDecorators: () => [this.idParam()],
@@ -3025,9 +3821,14 @@ var _RestfulFactory = class _RestfulFactory {
3025
3821
  return (0, import_nesties11.RenameClass)(cl, `${this.entityClassName}Controller`);
3026
3822
  }
3027
3823
  crudService(options = {}) {
3824
+ const keysToMigrate = [
3825
+ "relations",
3826
+ "outputFieldsToOmit",
3827
+ "upsertIncludeRelations",
3828
+ "keepEntityVersioningDates"
3829
+ ];
3028
3830
  return CrudService(this.entityClass, {
3029
- relations: this.options.relations,
3030
- outputFieldsToOmit: this.options.outputFieldsToOmit,
3831
+ ...import_lodash6.default.pick(this.options, keysToMigrate),
3031
3832
  ...options
3032
3833
  });
3033
3834
  }
@@ -3047,6 +3848,12 @@ __decorateClass([
3047
3848
  __decorateClass([
3048
3849
  (0, import_nfkit.Memorize)()
3049
3850
  ], _RestfulFactory.prototype, "updateDto", 1);
3851
+ __decorateClass([
3852
+ (0, import_nfkit.Memorize)()
3853
+ ], _RestfulFactory.prototype, "fieldsInUpsertToOmit", 1);
3854
+ __decorateClass([
3855
+ (0, import_nfkit.Memorize)()
3856
+ ], _RestfulFactory.prototype, "upsertDto", 1);
3050
3857
  __decorateClass([
3051
3858
  (0, import_nfkit.Memorize)()
3052
3859
  ], _RestfulFactory.prototype, "importDto", 1);
@@ -3068,6 +3875,9 @@ __decorateClass([
3068
3875
  __decorateClass([
3069
3876
  (0, import_nfkit.Memorize)()
3070
3877
  ], _RestfulFactory.prototype, "entityCreateResultDto", 1);
3878
+ __decorateClass([
3879
+ (0, import_nfkit.Memorize)()
3880
+ ], _RestfulFactory.prototype, "entityUpsertResultDto", 1);
3071
3881
  __decorateClass([
3072
3882
  (0, import_nfkit.Memorize)()
3073
3883
  ], _RestfulFactory.prototype, "entityReturnMessageDto", 1);
@@ -3152,6 +3962,190 @@ var applyQueryMatchBooleanMySQL = createQueryCondition(
3152
3962
  }
3153
3963
  }
3154
3964
  );
3965
+
3966
+ // src/transactional-typeorm.module.ts
3967
+ var import_typeorm9 = __toESM(require_typeorm());
3968
+ var import_typeorm10 = require("typeorm");
3969
+ var import_common5 = require("@nestjs/common");
3970
+ var import_nesties12 = require("nesties");
3971
+ var import_core = require("@nestjs/core");
3972
+
3973
+ // src/utility/create-dynamic-fetcher-proxy.ts
3974
+ var createDynamicFetcherProxy = (initial, fetcher) => {
3975
+ return new Proxy(initial, {
3976
+ get(_target, prop, receiver) {
3977
+ const current = fetcher();
3978
+ const value = Reflect.get(current, prop, receiver);
3979
+ if (typeof value === "function") {
3980
+ return value.bind(current);
3981
+ }
3982
+ return value;
3983
+ },
3984
+ set(_target, prop, value, receiver) {
3985
+ const current = fetcher();
3986
+ return Reflect.set(current, prop, value, receiver);
3987
+ },
3988
+ has(_target, prop) {
3989
+ const current = fetcher();
3990
+ return Reflect.has(current, prop);
3991
+ },
3992
+ ownKeys(_target) {
3993
+ const current = fetcher();
3994
+ return Reflect.ownKeys(current);
3995
+ },
3996
+ getOwnPropertyDescriptor(_target, prop) {
3997
+ const current = fetcher();
3998
+ return Reflect.getOwnPropertyDescriptor(current, prop);
3999
+ },
4000
+ defineProperty(_target, prop, descriptor) {
4001
+ const current = fetcher();
4002
+ return Reflect.defineProperty(current, prop, descriptor);
4003
+ },
4004
+ deleteProperty(_target, prop) {
4005
+ const current = fetcher();
4006
+ return Reflect.deleteProperty(current, prop);
4007
+ }
4008
+ });
4009
+ };
4010
+
4011
+ // src/utility/create-inject-from-token-factory.ts
4012
+ var import_common4 = require("@nestjs/common");
4013
+ var createInjectFromTokenFactory = (factory) => (...params) => (0, import_common4.Inject)(factory(...params));
4014
+
4015
+ // src/transactional-typeorm.module.ts
4016
+ var import_rxjs = require("rxjs");
4017
+ var requestWeakMap = /* @__PURE__ */ new WeakMap();
4018
+ var normalizeDataSourceToken = (token) => typeof token === "string" ? token : token.name || token.toString();
4019
+ var TransactionalTypeOrmInterceptor = (dataSource) => {
4020
+ const token = (0, import_typeorm9.getEntityManagerToken)(dataSource);
4021
+ const interceptorClass = class SpecificTransactionalTypeOrmInterceptor {
4022
+ constructor(entityManager) {
4023
+ this.entityManager = entityManager;
4024
+ }
4025
+ intercept(context, next) {
4026
+ const request = context.switchToHttp().getRequest();
4027
+ return new import_rxjs.Observable((observer) => {
4028
+ let innerSub = null;
4029
+ let finished = false;
4030
+ let abort;
4031
+ const aborted = new Promise((_7, reject) => {
4032
+ abort = reject;
4033
+ });
4034
+ const run = this.entityManager.transaction(async (txEm) => {
4035
+ requestWeakMap.set(request, txEm);
4036
+ const completion = new Promise((resolve, reject) => {
4037
+ innerSub = next.handle().subscribe({
4038
+ next: (v) => observer.next(v),
4039
+ error: (err) => {
4040
+ finished = true;
4041
+ observer.error(err);
4042
+ reject(err);
4043
+ },
4044
+ complete: () => {
4045
+ finished = true;
4046
+ observer.complete();
4047
+ resolve();
4048
+ }
4049
+ });
4050
+ });
4051
+ await Promise.race([completion, aborted]);
4052
+ }).finally(() => {
4053
+ requestWeakMap.delete(request);
4054
+ }).catch((err) => {
4055
+ if (!finished) observer.error(err);
4056
+ });
4057
+ return () => {
4058
+ try {
4059
+ innerSub?.unsubscribe();
4060
+ } finally {
4061
+ if (!finished) {
4062
+ abort(new Error("Request aborted / subscription unsubscribed"));
4063
+ }
4064
+ }
4065
+ };
4066
+ });
4067
+ }
4068
+ };
4069
+ Object.defineProperty(interceptorClass, "name", {
4070
+ value: `TransactionalTypeOrmInterceptor_${normalizeDataSourceToken(token)}`
4071
+ });
4072
+ Reflect.defineMetadata(
4073
+ "design:paramtypes",
4074
+ [import_typeorm10.EntityManager],
4075
+ interceptorClass
4076
+ );
4077
+ (0, import_common5.Inject)(token)(interceptorClass.prototype, void 0, 0);
4078
+ (0, import_common5.Injectable)()(interceptorClass);
4079
+ return interceptorClass;
4080
+ };
4081
+ var getTransactionalEntityManagerToken = (dataSource) => `Transactional${normalizeDataSourceToken((0, import_typeorm9.getEntityManagerToken)(dataSource))}`;
4082
+ var getTransactionalEntityManagerProvider = (dataSource) => (0, import_nesties12.createProvider)(
4083
+ {
4084
+ provide: getTransactionalEntityManagerToken(dataSource),
4085
+ inject: [(0, import_typeorm9.getEntityManagerToken)(dataSource), import_core.REQUEST],
4086
+ scope: import_common5.Scope.REQUEST
4087
+ },
4088
+ (entityManager, request) => {
4089
+ if (requestWeakMap.has(request)) {
4090
+ return requestWeakMap.get(request);
4091
+ }
4092
+ return createDynamicFetcherProxy(
4093
+ entityManager,
4094
+ () => requestWeakMap.get(request) || entityManager
4095
+ );
4096
+ }
4097
+ );
4098
+ var InjectTransactionalEntityManager = createInjectFromTokenFactory(
4099
+ getTransactionalEntityManagerToken
4100
+ );
4101
+ var getTransactionalRepositoryToken = (entity, dataSource) => `Transactional${normalizeDataSourceToken(
4102
+ (0, import_typeorm9.getEntityManagerToken)(dataSource)
4103
+ )}Repository_${entity.name || entity.toString()}`;
4104
+ var getTransactionalRepositoryProvider = (entity, dataSource) => (0, import_nesties12.createProvider)(
4105
+ {
4106
+ provide: getTransactionalRepositoryToken(entity, dataSource),
4107
+ inject: [(0, import_typeorm9.getEntityManagerToken)(dataSource), import_core.REQUEST],
4108
+ scope: import_common5.Scope.REQUEST
4109
+ },
4110
+ (entityManager, req) => {
4111
+ if (requestWeakMap.has(req)) {
4112
+ const transactionalEntityManager = requestWeakMap.get(req);
4113
+ return transactionalEntityManager.getRepository(entity);
4114
+ }
4115
+ return createDynamicFetcherProxy(
4116
+ entityManager.getRepository(entity),
4117
+ () => {
4118
+ const transactionalEntityManager = requestWeakMap.get(req) || entityManager;
4119
+ return transactionalEntityManager.getRepository(entity);
4120
+ }
4121
+ );
4122
+ }
4123
+ );
4124
+ var InjectTransactionalRepository = createInjectFromTokenFactory(
4125
+ getTransactionalRepositoryToken
4126
+ );
4127
+ var TransactionalTypeOrmModule = class {
4128
+ static forFeature(entities, dataSource) {
4129
+ const entityArray = Array.isArray(entities) ? entities : [entities];
4130
+ const providers = [
4131
+ getTransactionalEntityManagerProvider(dataSource),
4132
+ ...entityArray.map(
4133
+ (entity) => getTransactionalRepositoryProvider(entity, dataSource)
4134
+ )
4135
+ ];
4136
+ const moduleImports = entityArray.length ? [import_typeorm9.TypeOrmModule.forFeature(entityArray, dataSource)] : [];
4137
+ const moduleExports = [...providers, ...moduleImports];
4138
+ return {
4139
+ module: TransactionalTypeOrmModule,
4140
+ imports: moduleImports,
4141
+ providers,
4142
+ exports: moduleExports
4143
+ };
4144
+ }
4145
+ };
4146
+ TransactionalTypeOrmModule = __decorateClass([
4147
+ (0, import_common5.Module)({})
4148
+ ], TransactionalTypeOrmModule);
3155
4149
  // Annotate the CommonJS export names for ESM import in node:
3156
4150
  0 && (module.exports = {
3157
4151
  BindingColumn,
@@ -3181,6 +4175,8 @@ var applyQueryMatchBooleanMySQL = createQueryCondition(
3181
4175
  ImportDataDto,
3182
4176
  ImportEntryBaseDto,
3183
4177
  ImportEntryDto,
4178
+ InjectTransactionalEntityManager,
4179
+ InjectTransactionalRepository,
3184
4180
  Inner,
3185
4181
  IntColumn,
3186
4182
  InternalColumn,
@@ -3190,6 +4186,7 @@ var applyQueryMatchBooleanMySQL = createQueryCondition(
3190
4186
  NotCreatable,
3191
4187
  NotInResult,
3192
4188
  NotQueryable,
4189
+ NotUpsertable,
3193
4190
  NotWritable,
3194
4191
  OmitPipe,
3195
4192
  OptionalDataPipe,
@@ -3228,6 +4225,10 @@ var applyQueryMatchBooleanMySQL = createQueryCondition(
3228
4225
  StringJsonColumn,
3229
4226
  TextColumn,
3230
4227
  TimeBase,
4228
+ TransactionalTypeOrmInterceptor,
4229
+ TransactionalTypeOrmModule,
4230
+ UpsertColumn,
4231
+ UpsertableEntity,
3231
4232
  UuidColumn,
3232
4233
  applyQueryMatchBoolean,
3233
4234
  applyQueryMatchBooleanMySQL,
@@ -3241,6 +4242,10 @@ var applyQueryMatchBooleanMySQL = createQueryCondition(
3241
4242
  createQueryOperator,
3242
4243
  createQueryOperatorArrayify,
3243
4244
  createQueryWrap,
4245
+ getTransactionalEntityManagerProvider,
4246
+ getTransactionalEntityManagerToken,
4247
+ getTransactionalRepositoryProvider,
4248
+ getTransactionalRepositoryToken,
3244
4249
  ...require("nesties")
3245
4250
  });
3246
4251
  //# sourceMappingURL=index.cjs.map