nicot 1.1.23 → 1.1.25
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 +2210 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.mjs +2184 -0
- package/dist/index.mjs.map +7 -0
- package/dist/src/crud-base.d.ts +1 -1
- package/dist/src/restful.d.ts +7 -3
- package/index.ts +0 -2
- package/package.json +20 -7
- package/dist/index.js +0 -25
- package/dist/index.js.map +0 -1
- package/dist/src/bases/base-restful-controller.js +0 -53
- package/dist/src/bases/base-restful-controller.js.map +0 -1
- package/dist/src/bases/id-base.js +0 -58
- package/dist/src/bases/id-base.js.map +0 -1
- package/dist/src/bases/index.js +0 -20
- package/dist/src/bases/index.js.map +0 -1
- package/dist/src/bases/page-settings.js +0 -64
- package/dist/src/bases/page-settings.js.map +0 -1
- package/dist/src/bases/time-base.js +0 -53
- package/dist/src/bases/time-base.js.map +0 -1
- package/dist/src/crud-base.js +0 -480
- package/dist/src/crud-base.js.map +0 -1
- package/dist/src/decorators/access.js +0 -24
- package/dist/src/decorators/access.js.map +0 -1
- package/dist/src/decorators/index.js +0 -21
- package/dist/src/decorators/index.js.map +0 -1
- package/dist/src/decorators/pipes.js +0 -26
- package/dist/src/decorators/pipes.js.map +0 -1
- package/dist/src/decorators/property.js +0 -191
- package/dist/src/decorators/property.js.map +0 -1
- package/dist/src/decorators/query.js +0 -67
- package/dist/src/decorators/query.js.map +0 -1
- package/dist/src/dto/cursor-pagination.js +0 -89
- package/dist/src/dto/cursor-pagination.js.map +0 -1
- package/dist/src/dto/import-entry.js +0 -45
- package/dist/src/dto/import-entry.js.map +0 -1
- package/dist/src/dto/index.js +0 -19
- package/dist/src/dto/index.js.map +0 -1
- package/dist/src/restful.js +0 -415
- package/dist/src/restful.js.map +0 -1
- package/dist/src/utility/bigint.js +0 -16
- package/dist/src/utility/bigint.js.map +0 -1
- package/dist/src/utility/cursor-pagination-utils.js +0 -252
- package/dist/src/utility/cursor-pagination-utils.js.map +0 -1
- package/dist/src/utility/filter-relations.js +0 -91
- package/dist/src/utility/filter-relations.js.map +0 -1
- package/dist/src/utility/get-typeorm-relations.js +0 -50
- package/dist/src/utility/get-typeorm-relations.js.map +0 -1
- package/dist/src/utility/index.js +0 -18
- package/dist/src/utility/index.js.map +0 -1
- package/dist/src/utility/metadata.js +0 -21
- package/dist/src/utility/metadata.js.map +0 -1
- package/dist/src/utility/omit-type-exclude.js +0 -14
- package/dist/src/utility/omit-type-exclude.js.map +0 -1
- package/dist/src/utility/query-full-text-column-options.interface.js +0 -3
- package/dist/src/utility/query-full-text-column-options.interface.js.map +0 -1
- package/dist/src/utility/query.js +0 -49
- package/dist/src/utility/query.js.map +0 -1
- package/dist/src/utility/recursive-key-of.js +0 -4
- package/dist/src/utility/recursive-key-of.js.map +0 -1
- package/dist/src/utility/relation-def.js +0 -3
- package/dist/src/utility/relation-def.js.map +0 -1
- package/dist/src/utility/rename-class.js +0 -8
- package/dist/src/utility/rename-class.js.map +0 -1
- package/dist/src/utility/subject-registry.js +0 -19
- package/dist/src/utility/subject-registry.js.map +0 -1
- package/dist/src/utility/type-transformer.js +0 -22
- package/dist/src/utility/type-transformer.js.map +0 -1
- package/dist/src/utility/unshift-order-by.js +0 -18
- package/dist/src/utility/unshift-order-by.js.map +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2210 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
30
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
31
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
32
|
+
if (decorator = decorators[i])
|
|
33
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
34
|
+
if (kind && result) __defProp(target, key, result);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// index.ts
|
|
39
|
+
var index_exports = {};
|
|
40
|
+
__export(index_exports, {
|
|
41
|
+
BlankCursorPaginationReturnMessageDto: () => BlankCursorPaginationReturnMessageDto,
|
|
42
|
+
BoolColumn: () => BoolColumn,
|
|
43
|
+
CreatePipe: () => CreatePipe,
|
|
44
|
+
CrudBase: () => CrudBase,
|
|
45
|
+
CrudService: () => CrudService,
|
|
46
|
+
CursorPaginationDto: () => CursorPaginationDto,
|
|
47
|
+
CursorPaginationReturnMessageDto: () => CursorPaginationReturnMessageDto,
|
|
48
|
+
DateColumn: () => DateColumn,
|
|
49
|
+
EnumColumn: () => EnumColumn,
|
|
50
|
+
FloatColumn: () => FloatColumn,
|
|
51
|
+
GenericCursorPaginationReturnMessageDto: () => GenericCursorPaginationReturnMessageDto,
|
|
52
|
+
GetPipe: () => GetPipe,
|
|
53
|
+
IdBase: () => IdBase,
|
|
54
|
+
ImportDataBaseDto: () => ImportDataBaseDto,
|
|
55
|
+
ImportDataDto: () => ImportDataDto,
|
|
56
|
+
ImportEntryBaseDto: () => ImportEntryBaseDto,
|
|
57
|
+
ImportEntryDto: () => ImportEntryDto,
|
|
58
|
+
Inner: () => Inner,
|
|
59
|
+
IntColumn: () => IntColumn,
|
|
60
|
+
JsonColumn: () => JsonColumn,
|
|
61
|
+
NotChangeable: () => NotChangeable,
|
|
62
|
+
NotColumn: () => NotColumn,
|
|
63
|
+
NotInResult: () => NotInResult,
|
|
64
|
+
NotQueryable: () => NotQueryable,
|
|
65
|
+
NotWritable: () => NotWritable,
|
|
66
|
+
PageSettingsDto: () => PageSettingsDto,
|
|
67
|
+
QueryColumn: () => QueryColumn,
|
|
68
|
+
QueryCondition: () => QueryCondition,
|
|
69
|
+
QueryEqual: () => QueryEqual,
|
|
70
|
+
QueryEqualZeroNullable: () => QueryEqualZeroNullable,
|
|
71
|
+
QueryFullText: () => QueryFullText,
|
|
72
|
+
QueryGreater: () => QueryGreater,
|
|
73
|
+
QueryGreaterEqual: () => QueryGreaterEqual,
|
|
74
|
+
QueryLess: () => QueryLess,
|
|
75
|
+
QueryLessEqual: () => QueryLessEqual,
|
|
76
|
+
QueryLike: () => QueryLike,
|
|
77
|
+
QueryMatchBoolean: () => QueryMatchBoolean,
|
|
78
|
+
QueryNotEqual: () => QueryNotEqual,
|
|
79
|
+
QueryOperator: () => QueryOperator,
|
|
80
|
+
QuerySearch: () => QuerySearch,
|
|
81
|
+
Relation: () => Relation,
|
|
82
|
+
RelationComputed: () => RelationComputed,
|
|
83
|
+
RestfulFactory: () => RestfulFactory,
|
|
84
|
+
StringColumn: () => StringColumn,
|
|
85
|
+
StringIdBase: () => StringIdBase,
|
|
86
|
+
TimeBase: () => TimeBase,
|
|
87
|
+
UpdatePipe: () => UpdatePipe,
|
|
88
|
+
applyQueryMatchBoolean: () => applyQueryMatchBoolean,
|
|
89
|
+
applyQueryProperty: () => applyQueryProperty,
|
|
90
|
+
applyQueryPropertyLike: () => applyQueryPropertyLike,
|
|
91
|
+
applyQueryPropertySearch: () => applyQueryPropertySearch,
|
|
92
|
+
applyQueryPropertyZeroNullable: () => applyQueryPropertyZeroNullable,
|
|
93
|
+
createQueryCondition: () => createQueryCondition,
|
|
94
|
+
createQueryOperator: () => createQueryOperator
|
|
95
|
+
});
|
|
96
|
+
module.exports = __toCommonJS(index_exports);
|
|
97
|
+
__reExport(index_exports, require("nesties"), module.exports);
|
|
98
|
+
|
|
99
|
+
// src/dto/import-entry.ts
|
|
100
|
+
var import_swagger = require("@nestjs/swagger");
|
|
101
|
+
var import_class_transformer = require("class-transformer");
|
|
102
|
+
var import_class_validator = require("class-validator");
|
|
103
|
+
var import_nesties = require("nesties");
|
|
104
|
+
var ImportEntryBaseDto = class {
|
|
105
|
+
};
|
|
106
|
+
__decorateClass([
|
|
107
|
+
(0, import_swagger.ApiProperty)({ description: "Import result", type: String })
|
|
108
|
+
], ImportEntryBaseDto.prototype, "result", 2);
|
|
109
|
+
function ImportEntryDto(type) {
|
|
110
|
+
return (0, import_nesties.InsertField)(
|
|
111
|
+
ImportEntryBaseDto,
|
|
112
|
+
{
|
|
113
|
+
entry: { type, options: { description: "Import entry" } }
|
|
114
|
+
},
|
|
115
|
+
`${(0, import_nesties.getClassFromClassOrArray)(type).name}ImportEntry`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
var ImportDataBaseDto = class {
|
|
119
|
+
};
|
|
120
|
+
__decorateClass([
|
|
121
|
+
(0, import_class_validator.ValidateNested)()
|
|
122
|
+
], ImportDataBaseDto.prototype, "data", 2);
|
|
123
|
+
function ImportDataDto(type) {
|
|
124
|
+
const dtoClass = (0, import_nesties.InsertField)(
|
|
125
|
+
ImportDataBaseDto,
|
|
126
|
+
{
|
|
127
|
+
data: { type: [type], options: { description: "Import data" } }
|
|
128
|
+
},
|
|
129
|
+
`${(0, import_nesties.getClassFromClassOrArray)(type).name}ImportData`
|
|
130
|
+
);
|
|
131
|
+
(0, import_class_transformer.Type)(() => type)(dtoClass.prototype, "data");
|
|
132
|
+
return dtoClass;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// src/dto/cursor-pagination.ts
|
|
136
|
+
var import_class_validator4 = require("class-validator");
|
|
137
|
+
var import_swagger3 = require("@nestjs/swagger");
|
|
138
|
+
var import_nesties6 = require("nesties");
|
|
139
|
+
|
|
140
|
+
// src/decorators/access.ts
|
|
141
|
+
var import_class_transformer2 = require("class-transformer");
|
|
142
|
+
var import_class_validator2 = require("class-validator");
|
|
143
|
+
|
|
144
|
+
// src/utility/metadata.ts
|
|
145
|
+
var import_typed_reflector = require("typed-reflector");
|
|
146
|
+
var Metadata = new import_typed_reflector.MetadataSetter();
|
|
147
|
+
var reflector = new import_typed_reflector.Reflector();
|
|
148
|
+
function getSpecificFields(obj, type, filter = () => true) {
|
|
149
|
+
return reflector.getArray(`${type}Fields`, obj).filter((field) => {
|
|
150
|
+
const value = reflector.get(type, obj, field);
|
|
151
|
+
if (value == null) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
return filter(value, obj);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function getNotInResultFields(obj, keepEntityVersioningDates = false) {
|
|
158
|
+
return getSpecificFields(
|
|
159
|
+
obj,
|
|
160
|
+
"notInResult",
|
|
161
|
+
(meta) => !keepEntityVersioningDates || !meta.entityVersioningDate
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/decorators/access.ts
|
|
166
|
+
var import_nesties2 = require("nesties");
|
|
167
|
+
var NotWritable = () => (0, import_nesties2.MergePropertyDecorators)([
|
|
168
|
+
(0, import_class_transformer2.Expose)({ groups: ["r"] }),
|
|
169
|
+
(0, import_class_validator2.IsOptional)(),
|
|
170
|
+
Metadata.set("notWritable", true, "notWritableFields"),
|
|
171
|
+
Metadata.set("notChangeable", true, "notChangeableFields")
|
|
172
|
+
]);
|
|
173
|
+
var NotChangeable = () => (0, import_nesties2.MergePropertyDecorators)([
|
|
174
|
+
(0, import_class_transformer2.Expose)({ groups: ["r", "c"] }),
|
|
175
|
+
Metadata.set("notChangeable", true, "notChangeableFields")
|
|
176
|
+
]);
|
|
177
|
+
var NotQueryable = () => Metadata.set("notQueryable", true, "notQueryableFields");
|
|
178
|
+
var NotInResult = (options = {}) => Metadata.set("notInResult", options, "notInResultFields");
|
|
179
|
+
|
|
180
|
+
// src/decorators/property.ts
|
|
181
|
+
var import_swagger2 = require("@nestjs/swagger");
|
|
182
|
+
var import_nesties3 = require("nesties");
|
|
183
|
+
var import_typeorm = require("typeorm");
|
|
184
|
+
var import_class_validator3 = require("class-validator");
|
|
185
|
+
var import_class_transformer3 = require("class-transformer");
|
|
186
|
+
|
|
187
|
+
// src/utility/bigint.ts
|
|
188
|
+
var BigintTransformer = class {
|
|
189
|
+
from(dbValue) {
|
|
190
|
+
if (dbValue == null) {
|
|
191
|
+
return dbValue;
|
|
192
|
+
}
|
|
193
|
+
return parseInt(dbValue);
|
|
194
|
+
}
|
|
195
|
+
to(entValue) {
|
|
196
|
+
return entValue;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// src/decorators/property.ts
|
|
201
|
+
var import_nesties4 = require("nesties");
|
|
202
|
+
|
|
203
|
+
// src/utility/type-transformer.ts
|
|
204
|
+
var TypeTransformer = class {
|
|
205
|
+
constructor(definition) {
|
|
206
|
+
this.definition = definition;
|
|
207
|
+
}
|
|
208
|
+
from(dbValue) {
|
|
209
|
+
if (!dbValue) {
|
|
210
|
+
return dbValue;
|
|
211
|
+
}
|
|
212
|
+
if (Array.isArray(this.definition)) {
|
|
213
|
+
return dbValue.map(
|
|
214
|
+
(value) => Object.assign(new this.definition[0](), value)
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
return Object.assign(new this.definition(), dbValue);
|
|
218
|
+
}
|
|
219
|
+
to(entValue) {
|
|
220
|
+
return entValue;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
// src/decorators/property.ts
|
|
225
|
+
function swaggerDecorator(options, injected = {}) {
|
|
226
|
+
return (0, import_swagger2.ApiProperty)({
|
|
227
|
+
default: options.default,
|
|
228
|
+
required: !!(options.required && options.default == null),
|
|
229
|
+
example: options.default,
|
|
230
|
+
description: options.description,
|
|
231
|
+
...injected,
|
|
232
|
+
...options.propertyExtras || {}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function validatorDecorator(options) {
|
|
236
|
+
const decs = [];
|
|
237
|
+
if (!options.required) {
|
|
238
|
+
decs.push((0, import_class_validator3.IsOptional)());
|
|
239
|
+
}
|
|
240
|
+
return (0, import_nesties3.MergePropertyDecorators)(decs);
|
|
241
|
+
}
|
|
242
|
+
function columnDecoratorOptions(options) {
|
|
243
|
+
return {
|
|
244
|
+
default: options.default,
|
|
245
|
+
nullable: !options.required && options.default == null,
|
|
246
|
+
comment: options.description,
|
|
247
|
+
...options.columnExtras
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
var StringColumn = (length, options = {}) => {
|
|
251
|
+
return (0, import_nesties3.MergePropertyDecorators)([
|
|
252
|
+
(0, import_typeorm.Column)("varchar", { length, ...columnDecoratorOptions(options) }),
|
|
253
|
+
(0, import_class_validator3.IsString)(),
|
|
254
|
+
(0, import_class_validator3.MaxLength)(length),
|
|
255
|
+
validatorDecorator(options),
|
|
256
|
+
swaggerDecorator(options, { type: String, maxLength: length })
|
|
257
|
+
]);
|
|
258
|
+
};
|
|
259
|
+
var IntColumn = (type, options = {}) => {
|
|
260
|
+
const decs = [
|
|
261
|
+
(0, import_typeorm.Column)(type, {
|
|
262
|
+
default: options.default,
|
|
263
|
+
unsigned: options.unsigned,
|
|
264
|
+
...type === "bigint" ? { transformer: new BigintTransformer() } : {},
|
|
265
|
+
...columnDecoratorOptions(options)
|
|
266
|
+
}),
|
|
267
|
+
(0, import_class_validator3.IsInt)(),
|
|
268
|
+
validatorDecorator(options),
|
|
269
|
+
swaggerDecorator(options, {
|
|
270
|
+
type: Number,
|
|
271
|
+
minimum: options.unsigned ? 0 : void 0
|
|
272
|
+
})
|
|
273
|
+
];
|
|
274
|
+
if (options.unsigned) {
|
|
275
|
+
decs.push((0, import_class_validator3.Min)(0));
|
|
276
|
+
}
|
|
277
|
+
return (0, import_nesties3.MergePropertyDecorators)(decs);
|
|
278
|
+
};
|
|
279
|
+
var FloatColumn = (type, options = {}) => {
|
|
280
|
+
const decs = [
|
|
281
|
+
(0, import_typeorm.Column)(type, {
|
|
282
|
+
default: options.default,
|
|
283
|
+
unsigned: options.unsigned,
|
|
284
|
+
...columnDecoratorOptions(options)
|
|
285
|
+
}),
|
|
286
|
+
(0, import_class_validator3.IsNumber)(),
|
|
287
|
+
validatorDecorator(options),
|
|
288
|
+
swaggerDecorator(options, {
|
|
289
|
+
type: Number,
|
|
290
|
+
minimum: options.unsigned ? 0 : void 0
|
|
291
|
+
})
|
|
292
|
+
];
|
|
293
|
+
if (options.unsigned) {
|
|
294
|
+
decs.push((0, import_class_validator3.Min)(0));
|
|
295
|
+
}
|
|
296
|
+
return (0, import_nesties3.MergePropertyDecorators)(decs);
|
|
297
|
+
};
|
|
298
|
+
var DateColumn = (options = {}) => {
|
|
299
|
+
return (0, import_nesties3.MergePropertyDecorators)([
|
|
300
|
+
(0, import_typeorm.Column)("timestamp", columnDecoratorOptions(options)),
|
|
301
|
+
(0, import_class_validator3.IsDate)(),
|
|
302
|
+
(0, import_class_transformer3.Transform)(
|
|
303
|
+
(v) => {
|
|
304
|
+
const value = v.value;
|
|
305
|
+
if (value == null || value instanceof Date) return value;
|
|
306
|
+
const timestampToDate = (t, isSeconds) => new Date(isSeconds ? t * 1e3 : t);
|
|
307
|
+
if (typeof value === "number") {
|
|
308
|
+
const isSeconds = !Number.isInteger(value) || value < 1e12;
|
|
309
|
+
return timestampToDate(value, isSeconds);
|
|
310
|
+
}
|
|
311
|
+
if (typeof value === "string" && /^\d+(\.\d+)?$/.test(value)) {
|
|
312
|
+
const isSeconds = value.includes(".") || parseFloat(value) < 1e12;
|
|
313
|
+
return timestampToDate(parseFloat(value), isSeconds);
|
|
314
|
+
}
|
|
315
|
+
return new Date(value);
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
toClassOnly: true
|
|
319
|
+
}
|
|
320
|
+
),
|
|
321
|
+
validatorDecorator(options),
|
|
322
|
+
swaggerDecorator(options, { type: Date })
|
|
323
|
+
]);
|
|
324
|
+
};
|
|
325
|
+
var EnumColumn = (targetEnum, options = {}) => {
|
|
326
|
+
return (0, import_nesties3.MergePropertyDecorators)([
|
|
327
|
+
(0, import_typeorm.Index)(),
|
|
328
|
+
(0, import_typeorm.Column)("enum", {
|
|
329
|
+
enum: targetEnum,
|
|
330
|
+
...columnDecoratorOptions(options)
|
|
331
|
+
}),
|
|
332
|
+
(0, import_class_validator3.IsEnum)(targetEnum),
|
|
333
|
+
validatorDecorator(options),
|
|
334
|
+
swaggerDecorator(options, { enum: targetEnum })
|
|
335
|
+
]);
|
|
336
|
+
};
|
|
337
|
+
var BoolColumn = (options = {}) => (0, import_nesties3.MergePropertyDecorators)([
|
|
338
|
+
(0, import_typeorm.Index)(),
|
|
339
|
+
(0, import_class_transformer3.Transform)((v) => {
|
|
340
|
+
const trueValues = ["true", "1", "yes", "on", true, 1];
|
|
341
|
+
const falseValues = ["false", "0", "no", "off", false, 0];
|
|
342
|
+
if (trueValues.indexOf(v.value) !== -1) return true;
|
|
343
|
+
if (falseValues.indexOf(v.value) !== -1) return false;
|
|
344
|
+
return void 0;
|
|
345
|
+
}),
|
|
346
|
+
(0, import_typeorm.Column)("boolean", columnDecoratorOptions(options)),
|
|
347
|
+
validatorDecorator(options),
|
|
348
|
+
swaggerDecorator(options, { type: Boolean })
|
|
349
|
+
]);
|
|
350
|
+
var JsonColumn = (definition, options = {}) => {
|
|
351
|
+
const cl = (0, import_nesties4.getClassFromClassOrArray)(definition);
|
|
352
|
+
return (0, import_nesties3.MergePropertyDecorators)([
|
|
353
|
+
NotQueryable(),
|
|
354
|
+
(0, import_class_transformer3.Type)(() => cl),
|
|
355
|
+
(0, import_class_validator3.ValidateNested)(),
|
|
356
|
+
(0, import_typeorm.Column)("jsonb", {
|
|
357
|
+
...columnDecoratorOptions(options),
|
|
358
|
+
transformer: new TypeTransformer(definition)
|
|
359
|
+
}),
|
|
360
|
+
validatorDecorator(options),
|
|
361
|
+
swaggerDecorator(options, { type: definition })
|
|
362
|
+
]);
|
|
363
|
+
};
|
|
364
|
+
var NotColumn = (options = {}, specials = {}) => (0, import_nesties3.MergePropertyDecorators)([
|
|
365
|
+
(0, import_class_transformer3.Exclude)(),
|
|
366
|
+
swaggerDecorator({
|
|
367
|
+
required: false,
|
|
368
|
+
...options
|
|
369
|
+
}),
|
|
370
|
+
Metadata.set("notColumn", specials, "notColumnFields")
|
|
371
|
+
]);
|
|
372
|
+
var QueryColumn = (options = {}) => (0, import_nesties3.MergePropertyDecorators)([
|
|
373
|
+
NotWritable(),
|
|
374
|
+
NotInResult(),
|
|
375
|
+
swaggerDecorator({
|
|
376
|
+
required: false,
|
|
377
|
+
...options
|
|
378
|
+
})
|
|
379
|
+
]);
|
|
380
|
+
var RelationComputed = (type) => (obj, propertyKey) => {
|
|
381
|
+
const fun = () => {
|
|
382
|
+
const designType = Reflect.getMetadata("design:type", obj, propertyKey);
|
|
383
|
+
const entityClass = type ? type() : designType;
|
|
384
|
+
return {
|
|
385
|
+
entityClass,
|
|
386
|
+
isArray: designType === Array
|
|
387
|
+
};
|
|
388
|
+
};
|
|
389
|
+
const dec = Metadata.set("relationComputed", fun, "relationComputedFields");
|
|
390
|
+
return dec(obj, propertyKey);
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
// src/decorators/pipes.ts
|
|
394
|
+
var import_common = require("@nestjs/common");
|
|
395
|
+
var CreatePipe = () => new import_common.ValidationPipe({
|
|
396
|
+
transform: true,
|
|
397
|
+
transformOptions: { groups: ["c"], enableImplicitConversion: true }
|
|
398
|
+
});
|
|
399
|
+
var GetPipe = () => new import_common.ValidationPipe({
|
|
400
|
+
transform: true,
|
|
401
|
+
transformOptions: { groups: ["r"], enableImplicitConversion: true },
|
|
402
|
+
skipMissingProperties: true,
|
|
403
|
+
skipNullProperties: true,
|
|
404
|
+
skipUndefinedProperties: true
|
|
405
|
+
});
|
|
406
|
+
var UpdatePipe = () => new import_common.ValidationPipe({
|
|
407
|
+
transform: true,
|
|
408
|
+
transformOptions: { groups: ["u"], enableImplicitConversion: true },
|
|
409
|
+
skipMissingProperties: true,
|
|
410
|
+
skipNullProperties: true,
|
|
411
|
+
skipUndefinedProperties: true
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
// src/utility/query.ts
|
|
415
|
+
function createQueryCondition(cond) {
|
|
416
|
+
return (obj, qb, entityName, ...fields) => {
|
|
417
|
+
for (const field of fields) {
|
|
418
|
+
if (obj[field] == null) {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
const ret = cond(obj, qb, entityName, field);
|
|
422
|
+
if (typeof ret === "string") {
|
|
423
|
+
qb.andWhere(ret);
|
|
424
|
+
} else if (typeof ret === "object" && typeof ret["query"] === "string") {
|
|
425
|
+
const _ret = ret;
|
|
426
|
+
qb.andWhere(_ret.query, _ret.params);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return qb;
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
var applyQueryProperty = createQueryCondition(
|
|
433
|
+
(obj, qb, entityName, field) => qb.andWhere(`${entityName}.${field} = :${field}`, { [field]: obj[field] })
|
|
434
|
+
);
|
|
435
|
+
var applyQueryPropertyLike = createQueryCondition(
|
|
436
|
+
(obj, qb, entityName, field) => qb.andWhere(`${entityName}.${field} like (:${field} || '%')`, {
|
|
437
|
+
[field]: obj[field]
|
|
438
|
+
})
|
|
439
|
+
);
|
|
440
|
+
var applyQueryPropertySearch = createQueryCondition(
|
|
441
|
+
(obj, qb, entityName, field) => qb.andWhere(`${entityName}.${field} like ('%' || :${field} || '%')`, {
|
|
442
|
+
[field]: obj[field]
|
|
443
|
+
})
|
|
444
|
+
);
|
|
445
|
+
var applyQueryPropertyZeroNullable = createQueryCondition(
|
|
446
|
+
(obj, qb, entityName, field) => {
|
|
447
|
+
if ([0, "0"].indexOf(obj[field]) !== -1) {
|
|
448
|
+
qb.andWhere(`${entityName}.${field} IS NULL`);
|
|
449
|
+
} else {
|
|
450
|
+
qb.andWhere(`${entityName}.${field} = :${field}`, {
|
|
451
|
+
[field]: obj[field]
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
);
|
|
456
|
+
var applyQueryMatchBoolean = createQueryCondition(
|
|
457
|
+
(obj, qb, entityName, field) => {
|
|
458
|
+
const value = obj[field];
|
|
459
|
+
if (value === true || value === "true" || value === 1 || value === "1") {
|
|
460
|
+
qb.andWhere(`${entityName}.${field} = TRUE`);
|
|
461
|
+
}
|
|
462
|
+
if (value === false || value === "false" || value === 0 || value === "0") {
|
|
463
|
+
qb.andWhere(`${entityName}.${field} = FALSE`);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
// src/decorators/query.ts
|
|
469
|
+
var import_nesties5 = require("nesties");
|
|
470
|
+
|
|
471
|
+
// src/utility/unshift-order-by.ts
|
|
472
|
+
var unshiftOrderBy = (qb, sort, order, nulls) => {
|
|
473
|
+
const currentOrderBys = Object.entries(qb.expressionMap.allOrderBys);
|
|
474
|
+
qb.orderBy(sort, order, nulls);
|
|
475
|
+
currentOrderBys.forEach(([key, value]) => {
|
|
476
|
+
if (typeof value === "string") {
|
|
477
|
+
qb.addOrderBy(key, value);
|
|
478
|
+
} else {
|
|
479
|
+
qb.addOrderBy(key, value.order, value.nulls);
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
return qb;
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
// src/utility/subject-registry.ts
|
|
486
|
+
var subjectRegistry = /* @__PURE__ */ new WeakMap();
|
|
487
|
+
var addSubject = (qb, select, alias) => {
|
|
488
|
+
let subjects = subjectRegistry.get(qb);
|
|
489
|
+
if (!subjects) {
|
|
490
|
+
subjects = {};
|
|
491
|
+
subjectRegistry.set(qb, subjects);
|
|
492
|
+
}
|
|
493
|
+
subjects[alias] = select;
|
|
494
|
+
return qb.addSelect(select, alias);
|
|
495
|
+
};
|
|
496
|
+
var getSubject = (qb, alias) => {
|
|
497
|
+
return subjectRegistry.get(qb)?.[alias];
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
// src/decorators/query.ts
|
|
501
|
+
var QueryCondition = (cond) => Metadata.set(
|
|
502
|
+
"queryCondition",
|
|
503
|
+
cond,
|
|
504
|
+
"queryConditionFields"
|
|
505
|
+
);
|
|
506
|
+
var QueryEqual = () => QueryCondition(applyQueryProperty);
|
|
507
|
+
var QueryLike = () => QueryCondition(applyQueryPropertyLike);
|
|
508
|
+
var QuerySearch = () => QueryCondition(applyQueryPropertySearch);
|
|
509
|
+
var QueryEqualZeroNullable = () => QueryCondition(applyQueryPropertyZeroNullable);
|
|
510
|
+
var QueryMatchBoolean = () => QueryCondition(applyQueryMatchBoolean);
|
|
511
|
+
var QueryOperator = (operator, field) => QueryCondition((obj, qb, entityName, key) => {
|
|
512
|
+
if (obj[key] == null) return;
|
|
513
|
+
const fieldName = field || key;
|
|
514
|
+
const typeormField = `_query_operator_${entityName}_${fieldName}_${key}`;
|
|
515
|
+
qb.andWhere(`${entityName}.${fieldName} ${operator} :${typeormField}`, {
|
|
516
|
+
[typeormField]: obj[key]
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
var createQueryOperator = (operator) => (field) => QueryOperator(operator, field);
|
|
520
|
+
var QueryGreater = createQueryOperator(">");
|
|
521
|
+
var QueryGreaterEqual = createQueryOperator(">=");
|
|
522
|
+
var QueryLess = createQueryOperator("<");
|
|
523
|
+
var QueryLessEqual = createQueryOperator("<=");
|
|
524
|
+
var QueryNotEqual = createQueryOperator("!=");
|
|
525
|
+
var QueryFullText = (options = {}) => {
|
|
526
|
+
const configurationName = options.parser ? `nicot_parser_${options.parser}` : options.configuration || "english";
|
|
527
|
+
const tsQueryFunction = options.tsQueryFunction || "websearch_to_tsquery";
|
|
528
|
+
return (0, import_nesties5.MergePropertyDecorators)([
|
|
529
|
+
QueryCondition((obj, qb, entityName, key) => {
|
|
530
|
+
if (obj[key] == null) return;
|
|
531
|
+
const fieldName = key;
|
|
532
|
+
const typeormField = key;
|
|
533
|
+
const tsVectorStatement = `to_tsvector('${configurationName}', "${entityName}"."${fieldName}")`;
|
|
534
|
+
const tsQueryStatement = `${tsQueryFunction}('${configurationName}', :${typeormField})`;
|
|
535
|
+
qb.andWhere(`${tsVectorStatement} @@ ${tsQueryStatement}`, {
|
|
536
|
+
[typeormField]: obj[key]
|
|
537
|
+
});
|
|
538
|
+
if (options.orderBySimilarity) {
|
|
539
|
+
const rankVirtualField = `_fulltext_rank_${key}`;
|
|
540
|
+
addSubject(
|
|
541
|
+
qb,
|
|
542
|
+
`ts_rank(${tsVectorStatement}, ${tsQueryStatement})`,
|
|
543
|
+
rankVirtualField
|
|
544
|
+
);
|
|
545
|
+
unshiftOrderBy(qb, `"${rankVirtualField}"`, "DESC");
|
|
546
|
+
}
|
|
547
|
+
}),
|
|
548
|
+
Metadata.set(
|
|
549
|
+
"queryFullTextColumn",
|
|
550
|
+
{
|
|
551
|
+
...options,
|
|
552
|
+
configuration: configurationName
|
|
553
|
+
},
|
|
554
|
+
"queryFullTextColumnFields"
|
|
555
|
+
)
|
|
556
|
+
]);
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
// src/dto/cursor-pagination.ts
|
|
560
|
+
var CursorPaginationDto = class {
|
|
561
|
+
};
|
|
562
|
+
__decorateClass([
|
|
563
|
+
NotWritable(),
|
|
564
|
+
(0, import_class_validator4.IsNotEmpty)(),
|
|
565
|
+
(0, import_class_validator4.IsString)(),
|
|
566
|
+
(0, import_class_validator4.IsOptional)(),
|
|
567
|
+
(0, import_swagger3.ApiProperty)({
|
|
568
|
+
description: "Pagination Cursor",
|
|
569
|
+
required: false,
|
|
570
|
+
type: String
|
|
571
|
+
}),
|
|
572
|
+
NotInResult()
|
|
573
|
+
], CursorPaginationDto.prototype, "paginationCursor", 2);
|
|
574
|
+
__decorateClass([
|
|
575
|
+
NotWritable(),
|
|
576
|
+
(0, import_class_validator4.IsPositive)(),
|
|
577
|
+
(0, import_class_validator4.IsInt)(),
|
|
578
|
+
(0, import_swagger3.ApiProperty)({
|
|
579
|
+
description: "Records per page.",
|
|
580
|
+
required: false,
|
|
581
|
+
type: Number,
|
|
582
|
+
minimum: 1
|
|
583
|
+
}),
|
|
584
|
+
NotInResult()
|
|
585
|
+
], CursorPaginationDto.prototype, "recordsPerPage", 2);
|
|
586
|
+
var BlankCursorPaginationReturnMessageDto = class extends import_nesties6.BlankReturnMessageDto {
|
|
587
|
+
constructor(statusCode, message, cursorResponse) {
|
|
588
|
+
super(statusCode, message);
|
|
589
|
+
this.nextCursor = cursorResponse.nextCursor;
|
|
590
|
+
this.previousCursor = cursorResponse.previousCursor;
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
__decorateClass([
|
|
594
|
+
(0, import_swagger3.ApiProperty)({
|
|
595
|
+
description: "Next Cursor",
|
|
596
|
+
required: false,
|
|
597
|
+
type: String
|
|
598
|
+
})
|
|
599
|
+
], BlankCursorPaginationReturnMessageDto.prototype, "nextCursor", 2);
|
|
600
|
+
__decorateClass([
|
|
601
|
+
(0, import_swagger3.ApiProperty)({
|
|
602
|
+
description: "Previous Cursor",
|
|
603
|
+
required: false,
|
|
604
|
+
type: String
|
|
605
|
+
})
|
|
606
|
+
], BlankCursorPaginationReturnMessageDto.prototype, "previousCursor", 2);
|
|
607
|
+
var GenericCursorPaginationReturnMessageDto = class extends BlankCursorPaginationReturnMessageDto {
|
|
608
|
+
constructor(statusCode, message, data, cursorResponse) {
|
|
609
|
+
super(statusCode, message, cursorResponse);
|
|
610
|
+
this.data = data;
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
function CursorPaginationReturnMessageDto(type) {
|
|
614
|
+
return (0, import_nesties6.InsertField)(
|
|
615
|
+
GenericCursorPaginationReturnMessageDto,
|
|
616
|
+
{
|
|
617
|
+
data: {
|
|
618
|
+
type: [type],
|
|
619
|
+
options: {
|
|
620
|
+
required: false,
|
|
621
|
+
description: "Return data."
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
`${(0, import_nesties6.getClassFromClassOrArray)(type).name}CursorPaginationReturnMessageDto`
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// src/crud-base.ts
|
|
630
|
+
var import_typeorm6 = require("typeorm");
|
|
631
|
+
|
|
632
|
+
// src/bases/time-base.ts
|
|
633
|
+
var import_typeorm2 = require("typeorm");
|
|
634
|
+
|
|
635
|
+
// src/bases/page-settings.ts
|
|
636
|
+
var import_class_validator5 = require("class-validator");
|
|
637
|
+
var import_swagger4 = require("@nestjs/swagger");
|
|
638
|
+
var PageSettingsDto = class {
|
|
639
|
+
getActualPageSettings() {
|
|
640
|
+
return {
|
|
641
|
+
pageCount: this.getPageCount(),
|
|
642
|
+
recordsPerPage: this.getRecordsPerPage()
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
getPageCount() {
|
|
646
|
+
return parseInt(this.pageCount) || 1;
|
|
647
|
+
}
|
|
648
|
+
getRecordsPerPage() {
|
|
649
|
+
return parseInt(this.recordsPerPage) || 25;
|
|
650
|
+
}
|
|
651
|
+
getStartingFrom() {
|
|
652
|
+
return (this.getPageCount() - 1) * this.getRecordsPerPage();
|
|
653
|
+
}
|
|
654
|
+
applyPaginationQuery(qb) {
|
|
655
|
+
qb.take(this.getRecordsPerPage()).skip(this.getStartingFrom());
|
|
656
|
+
}
|
|
657
|
+
applyQuery(qb, entityName) {
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
__decorateClass([
|
|
661
|
+
NotWritable(),
|
|
662
|
+
(0, import_class_validator5.IsPositive)(),
|
|
663
|
+
(0, import_class_validator5.IsInt)(),
|
|
664
|
+
(0, import_swagger4.ApiProperty)({
|
|
665
|
+
description: "The nth page, starting with 1.",
|
|
666
|
+
required: false,
|
|
667
|
+
type: Number,
|
|
668
|
+
minimum: 1
|
|
669
|
+
}),
|
|
670
|
+
NotInResult()
|
|
671
|
+
], PageSettingsDto.prototype, "pageCount", 2);
|
|
672
|
+
__decorateClass([
|
|
673
|
+
NotWritable(),
|
|
674
|
+
(0, import_class_validator5.IsPositive)(),
|
|
675
|
+
(0, import_class_validator5.IsInt)(),
|
|
676
|
+
(0, import_swagger4.ApiProperty)({
|
|
677
|
+
description: "Records per page.",
|
|
678
|
+
required: false,
|
|
679
|
+
type: Number,
|
|
680
|
+
minimum: 1
|
|
681
|
+
}),
|
|
682
|
+
NotInResult()
|
|
683
|
+
], PageSettingsDto.prototype, "recordsPerPage", 2);
|
|
684
|
+
|
|
685
|
+
// src/bases/time-base.ts
|
|
686
|
+
var TimeBase = class extends PageSettingsDto {
|
|
687
|
+
isValidInCreate() {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
691
|
+
async beforeCreate() {
|
|
692
|
+
}
|
|
693
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
694
|
+
async afterCreate() {
|
|
695
|
+
}
|
|
696
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
697
|
+
async beforeGet() {
|
|
698
|
+
}
|
|
699
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
700
|
+
async afterGet() {
|
|
701
|
+
}
|
|
702
|
+
isValidInUpdate() {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
706
|
+
async beforeUpdate() {
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
__decorateClass([
|
|
710
|
+
(0, import_typeorm2.CreateDateColumn)({ select: false }),
|
|
711
|
+
NotColumn(),
|
|
712
|
+
NotInResult({ entityVersioningDate: true })
|
|
713
|
+
], TimeBase.prototype, "createTime", 2);
|
|
714
|
+
__decorateClass([
|
|
715
|
+
(0, import_typeorm2.UpdateDateColumn)({ select: false }),
|
|
716
|
+
NotColumn(),
|
|
717
|
+
NotInResult({ entityVersioningDate: true })
|
|
718
|
+
], TimeBase.prototype, "updateTime", 2);
|
|
719
|
+
__decorateClass([
|
|
720
|
+
(0, import_typeorm2.DeleteDateColumn)({ select: false }),
|
|
721
|
+
NotColumn(),
|
|
722
|
+
NotInResult({ entityVersioningDate: true })
|
|
723
|
+
], TimeBase.prototype, "deleteTime", 2);
|
|
724
|
+
|
|
725
|
+
// src/bases/id-base.ts
|
|
726
|
+
var import_typeorm3 = require("typeorm");
|
|
727
|
+
var import_class_validator6 = require("class-validator");
|
|
728
|
+
var import_nesties7 = require("nesties");
|
|
729
|
+
function IdBase(idOptions = {}) {
|
|
730
|
+
const cl = class IdBase extends TimeBase {
|
|
731
|
+
applyQuery(qb, entityName) {
|
|
732
|
+
super.applyQuery(qb, entityName);
|
|
733
|
+
if (!idOptions.noOrderById) {
|
|
734
|
+
qb.orderBy(`${entityName}.id`, "DESC");
|
|
735
|
+
}
|
|
736
|
+
applyQueryProperty(this, qb, entityName, "id");
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
const dec = (0, import_nesties7.MergePropertyDecorators)([
|
|
740
|
+
NotWritable(),
|
|
741
|
+
IntColumn("bigint", {
|
|
742
|
+
unsigned: true,
|
|
743
|
+
description: idOptions.description,
|
|
744
|
+
columnExtras: { nullable: false, primary: true }
|
|
745
|
+
}),
|
|
746
|
+
Reflect.metadata("design:type", Number),
|
|
747
|
+
(0, import_typeorm3.Generated)("increment")
|
|
748
|
+
]);
|
|
749
|
+
dec(cl.prototype, "id");
|
|
750
|
+
return cl;
|
|
751
|
+
}
|
|
752
|
+
function StringIdBase(idOptions) {
|
|
753
|
+
const cl = class StringIdBase extends TimeBase {
|
|
754
|
+
applyQuery(qb, entityName) {
|
|
755
|
+
super.applyQuery(qb, entityName);
|
|
756
|
+
console.log("idbase order by");
|
|
757
|
+
qb.orderBy(`${entityName}.id`, "ASC");
|
|
758
|
+
applyQueryProperty(this, qb, entityName, "id");
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
const decs = [
|
|
762
|
+
StringColumn(idOptions.length || (idOptions.uuid ? 36 : 255), {
|
|
763
|
+
required: !idOptions.uuid,
|
|
764
|
+
description: idOptions.description,
|
|
765
|
+
columnExtras: { primary: true, nullable: false }
|
|
766
|
+
}),
|
|
767
|
+
Reflect.metadata("design:type", String),
|
|
768
|
+
...idOptions.uuid ? [(0, import_typeorm3.Generated)("uuid"), NotWritable()] : [(0, import_class_validator6.IsString)(), (0, import_class_validator6.IsNotEmpty)(), NotChangeable()]
|
|
769
|
+
];
|
|
770
|
+
const dec = (0, import_nesties7.MergePropertyDecorators)(decs);
|
|
771
|
+
dec(cl.prototype, "id");
|
|
772
|
+
return cl;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
// src/crud-base.ts
|
|
776
|
+
var import_common2 = require("@nestjs/common");
|
|
777
|
+
var import_StringUtils = require("typeorm/util/StringUtils");
|
|
778
|
+
var import_lodash3 = __toESM(require("lodash"));
|
|
779
|
+
var import_nesties8 = require("nesties");
|
|
780
|
+
|
|
781
|
+
// src/utility/get-typeorm-relations.ts
|
|
782
|
+
var import_typeorm4 = require("typeorm");
|
|
783
|
+
var import_lodash = __toESM(require("lodash"));
|
|
784
|
+
function getTypeormRelations(cl) {
|
|
785
|
+
const relations = (0, import_typeorm4.getMetadataArgsStorage)().relations.filter(
|
|
786
|
+
(r) => r.target === cl
|
|
787
|
+
);
|
|
788
|
+
const typeormRelations = relations.map((relation) => {
|
|
789
|
+
const isArray = relation.relationType.endsWith("-many");
|
|
790
|
+
const relationClassFactory = relation.type;
|
|
791
|
+
let propertyClass;
|
|
792
|
+
if (typeof relationClassFactory === "function") {
|
|
793
|
+
const relationClass = relationClassFactory();
|
|
794
|
+
if (typeof relationClass === "function") {
|
|
795
|
+
propertyClass = relationClass;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
if (!propertyClass) {
|
|
799
|
+
propertyClass = Reflect.getMetadata(
|
|
800
|
+
"design:type",
|
|
801
|
+
cl.prototype,
|
|
802
|
+
relation.propertyName
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
return {
|
|
806
|
+
isArray,
|
|
807
|
+
propertyClass,
|
|
808
|
+
propertyName: relation.propertyName,
|
|
809
|
+
computed: false
|
|
810
|
+
};
|
|
811
|
+
});
|
|
812
|
+
const computedRelations = getSpecificFields(cl, "relationComputed").map(
|
|
813
|
+
(field) => {
|
|
814
|
+
const meta = reflector.get("relationComputed", cl, field);
|
|
815
|
+
const res = meta();
|
|
816
|
+
return {
|
|
817
|
+
isArray: res.isArray,
|
|
818
|
+
propertyClass: res.entityClass,
|
|
819
|
+
propertyName: field,
|
|
820
|
+
computed: true
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
);
|
|
824
|
+
return import_lodash.default.uniqBy(
|
|
825
|
+
[...typeormRelations, ...computedRelations],
|
|
826
|
+
// Merge typeorm relations and computed relations
|
|
827
|
+
(r) => r.propertyName
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
// src/utility/cursor-pagination-utils.ts
|
|
832
|
+
var import_typeorm5 = require("typeorm");
|
|
833
|
+
var import_lodash2 = __toESM(require("lodash"));
|
|
834
|
+
var import_superjson = __toESM(require("superjson"));
|
|
835
|
+
|
|
836
|
+
// src/utility/filter-relations.ts
|
|
837
|
+
var extractRelationName = (relation) => {
|
|
838
|
+
if (typeof relation === "string") {
|
|
839
|
+
return relation;
|
|
840
|
+
} else {
|
|
841
|
+
return relation.name;
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
var typeormRelationsCache = /* @__PURE__ */ new Map();
|
|
845
|
+
var fetchTypeormRelations = (cl) => {
|
|
846
|
+
if (typeormRelationsCache.has(cl)) {
|
|
847
|
+
return typeormRelationsCache.get(cl);
|
|
848
|
+
}
|
|
849
|
+
const relations = getTypeormRelations(cl);
|
|
850
|
+
const map = Object.fromEntries(
|
|
851
|
+
relations.map((r) => [r.propertyName, r])
|
|
852
|
+
);
|
|
853
|
+
typeormRelationsCache.set(cl, map);
|
|
854
|
+
return map;
|
|
855
|
+
};
|
|
856
|
+
var filterRelations = (cl, relations, cond = () => true) => {
|
|
857
|
+
return relations?.filter((r) => {
|
|
858
|
+
const relationName = extractRelationName(r);
|
|
859
|
+
const checkLevel = (entityClass, name) => {
|
|
860
|
+
const [currentLevel, ...nextLevel] = name.split(".");
|
|
861
|
+
const relation = fetchTypeormRelations(entityClass)?.[currentLevel];
|
|
862
|
+
if (!relation) {
|
|
863
|
+
throw new Error(
|
|
864
|
+
`Relation ${currentLevel} not found in ${entityClass.name} (Reading ${relationName} in ${cl.name})`
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
if (relation.computed) return false;
|
|
868
|
+
if (!nextLevel.length) return true;
|
|
869
|
+
return checkLevel(relation.propertyClass, nextLevel.join("."));
|
|
870
|
+
};
|
|
871
|
+
return checkLevel(cl, relationName);
|
|
872
|
+
}) || [];
|
|
873
|
+
};
|
|
874
|
+
var queryColumnOptionsFromAlias = (qb, cl, rootAlias, alias) => {
|
|
875
|
+
const [field, key] = alias.split(".");
|
|
876
|
+
if (field === rootAlias) {
|
|
877
|
+
return {
|
|
878
|
+
relations: [],
|
|
879
|
+
column: qb.connection.getMetadata(cl)?.findColumnWithPropertyName(key)
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
const relationLevels = field.split("_");
|
|
883
|
+
let currentClass = cl;
|
|
884
|
+
const relations = [];
|
|
885
|
+
while (relationLevels.length) {
|
|
886
|
+
const f = relationLevels.shift();
|
|
887
|
+
const relation = fetchTypeormRelations(currentClass)?.[f];
|
|
888
|
+
if (!relation || relation.computed) {
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
relations.push(relation);
|
|
892
|
+
currentClass = relation.propertyClass;
|
|
893
|
+
}
|
|
894
|
+
return {
|
|
895
|
+
relations,
|
|
896
|
+
column: qb.connection.getMetadata(currentClass)?.findColumnWithPropertyName(key)
|
|
897
|
+
};
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
// src/utility/cursor-pagination-utils.ts
|
|
901
|
+
function getValueFromOrderBy(orderBy, reversed = false) {
|
|
902
|
+
if (reversed) {
|
|
903
|
+
const value = getValueFromOrderBy(orderBy, false);
|
|
904
|
+
return value === "ASC" ? "DESC" : "ASC";
|
|
905
|
+
}
|
|
906
|
+
return typeof orderBy === "string" ? orderBy : orderBy.order;
|
|
907
|
+
}
|
|
908
|
+
function getNullsFromOrderBy(orderBy, reversed = false) {
|
|
909
|
+
if (reversed) {
|
|
910
|
+
const value = getNullsFromOrderBy(orderBy, false);
|
|
911
|
+
return value === "NULLS FIRST" ? "NULLS LAST" : "NULLS FIRST";
|
|
912
|
+
}
|
|
913
|
+
const nulls = typeof orderBy === "string" ? void 0 : orderBy.nulls;
|
|
914
|
+
if (!nulls) {
|
|
915
|
+
const value = getValueFromOrderBy(orderBy);
|
|
916
|
+
return value === "ASC" ? "NULLS FIRST" : "NULLS LAST";
|
|
917
|
+
}
|
|
918
|
+
return nulls;
|
|
919
|
+
}
|
|
920
|
+
function getOperator(orderBy) {
|
|
921
|
+
const value = getValueFromOrderBy(orderBy);
|
|
922
|
+
return value === "ASC" ? ">" : "<";
|
|
923
|
+
}
|
|
924
|
+
function getReversedTypeormOrderBy(orderBy) {
|
|
925
|
+
if (typeof orderBy === "string") {
|
|
926
|
+
return {
|
|
927
|
+
order: orderBy === "ASC" ? "DESC" : "ASC",
|
|
928
|
+
nulls: void 0
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
return {
|
|
932
|
+
order: orderBy.order === "ASC" ? "DESC" : "ASC",
|
|
933
|
+
nulls: orderBy.nulls ? orderBy.nulls === "NULLS FIRST" ? "NULLS LAST" : "NULLS FIRST" : void 0
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
function reverseQueryOrderBy(qb) {
|
|
937
|
+
const orderBys = getTypeormOrderBy(qb);
|
|
938
|
+
orderBys.forEach(({ key, direction }, i) => {
|
|
939
|
+
const reversed = getReversedTypeormOrderBy(direction);
|
|
940
|
+
if (i === 0) {
|
|
941
|
+
qb.orderBy(key, reversed.order, reversed.nulls);
|
|
942
|
+
} else {
|
|
943
|
+
qb.addOrderBy(key, reversed.order, reversed.nulls);
|
|
944
|
+
}
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
function getTypeormOrderBy(qb) {
|
|
948
|
+
const orderBy = qb.expressionMap.allOrderBys;
|
|
949
|
+
const orderByEntrys = Object.entries(orderBy);
|
|
950
|
+
return orderByEntrys.map(([key, value]) => ({
|
|
951
|
+
key,
|
|
952
|
+
direction: value
|
|
953
|
+
}));
|
|
954
|
+
}
|
|
955
|
+
function extractValueFromOrderByKey(obj, key, entityAliasName) {
|
|
956
|
+
const getField = (obj2, key2) => {
|
|
957
|
+
const value2 = obj2[key2];
|
|
958
|
+
if (value2 == null) return value2;
|
|
959
|
+
if (Array.isArray(value2)) {
|
|
960
|
+
return void 0;
|
|
961
|
+
}
|
|
962
|
+
return value2;
|
|
963
|
+
};
|
|
964
|
+
const [alias, field] = key.split(".");
|
|
965
|
+
if (alias === entityAliasName) {
|
|
966
|
+
return getField(obj, field);
|
|
967
|
+
}
|
|
968
|
+
const aliasParts = alias.split("_");
|
|
969
|
+
if (aliasParts.length === 1) {
|
|
970
|
+
const value2 = getField(obj, alias);
|
|
971
|
+
if (value2 == null) return value2;
|
|
972
|
+
return getField(value2, field);
|
|
973
|
+
}
|
|
974
|
+
const value = getField(obj, aliasParts[0]);
|
|
975
|
+
if (!value == null) return value;
|
|
976
|
+
return extractValueFromOrderByKey(
|
|
977
|
+
value,
|
|
978
|
+
`${aliasParts.slice(1).join("_")}.${field}`
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
function encodeBase64Url(str) {
|
|
982
|
+
return Buffer.from(str).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
983
|
+
}
|
|
984
|
+
function decodeBase64Url(str) {
|
|
985
|
+
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
986
|
+
while (str.length % 4) str += "=";
|
|
987
|
+
return Buffer.from(str, "base64").toString();
|
|
988
|
+
}
|
|
989
|
+
async function getPaginatedResult(qb, entityClass, entityAliasName, take, cursor) {
|
|
990
|
+
const orderBys = getTypeormOrderBy(qb);
|
|
991
|
+
qb.take(take + 1);
|
|
992
|
+
let type = "next";
|
|
993
|
+
if (cursor) {
|
|
994
|
+
const data2 = import_superjson.default.parse(decodeBase64Url(cursor));
|
|
995
|
+
type = data2.type;
|
|
996
|
+
const keys = Object.keys(data2.payload).filter(
|
|
997
|
+
(k) => qb.expressionMap.orderBys[k]
|
|
998
|
+
);
|
|
999
|
+
if (keys.length) {
|
|
1000
|
+
const staircasedKeys = keys.map(
|
|
1001
|
+
(key, i) => import_lodash2.default.range(i + 1).map((j) => keys[j])
|
|
1002
|
+
);
|
|
1003
|
+
const cursorKey = (key) => `_cursor_${key.replace(/\./g, "__").replace(/"/g, "")}`;
|
|
1004
|
+
const expressionMatrix = staircasedKeys.map(
|
|
1005
|
+
(keys2) => keys2.map((key, j) => {
|
|
1006
|
+
const paramKey = cursorKey(key);
|
|
1007
|
+
const cursorValue = data2.payload[key];
|
|
1008
|
+
const orderBy = qb.expressionMap.orderBys[key];
|
|
1009
|
+
const reversed = data2.type === "prev";
|
|
1010
|
+
const order = getValueFromOrderBy(orderBy, reversed);
|
|
1011
|
+
const nulls = getNullsFromOrderBy(orderBy, reversed);
|
|
1012
|
+
const isLast = j === keys2.length - 1;
|
|
1013
|
+
const subject = key.includes('"') ? getSubject(qb, key.replace(/"/g, "")) : key;
|
|
1014
|
+
const mayBeNullAtEnd = () => {
|
|
1015
|
+
const res = nulls === "NULLS LAST" && order === "ASC" || nulls === "NULLS FIRST" && order === "DESC";
|
|
1016
|
+
if (reversed) {
|
|
1017
|
+
return !res;
|
|
1018
|
+
}
|
|
1019
|
+
return res;
|
|
1020
|
+
};
|
|
1021
|
+
if (cursorValue == null) {
|
|
1022
|
+
if (isLast) {
|
|
1023
|
+
if (mayBeNullAtEnd()) {
|
|
1024
|
+
return "__never__";
|
|
1025
|
+
} else {
|
|
1026
|
+
return `${subject} IS NOT NULL`;
|
|
1027
|
+
}
|
|
1028
|
+
} else {
|
|
1029
|
+
return `${subject} IS NULL`;
|
|
1030
|
+
}
|
|
1031
|
+
} else {
|
|
1032
|
+
if (isLast) {
|
|
1033
|
+
const expr = `${subject} ${getOperator(order)} :${paramKey}`;
|
|
1034
|
+
if (mayBeNullAtEnd() && queryColumnOptionsFromAlias(
|
|
1035
|
+
qb,
|
|
1036
|
+
entityClass,
|
|
1037
|
+
entityAliasName,
|
|
1038
|
+
key
|
|
1039
|
+
)?.column?.isNullable) {
|
|
1040
|
+
return `(${expr} OR ${subject} IS NULL)`;
|
|
1041
|
+
}
|
|
1042
|
+
return expr;
|
|
1043
|
+
} else {
|
|
1044
|
+
return `${subject} = :${paramKey}`;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
})
|
|
1048
|
+
).filter((s) => !s.includes("__never__"));
|
|
1049
|
+
if (expressionMatrix.length) {
|
|
1050
|
+
qb.andWhere(
|
|
1051
|
+
new import_typeorm5.Brackets((sqb) => {
|
|
1052
|
+
const levelToBrackets = (level) => new import_typeorm5.Brackets((qb2) => {
|
|
1053
|
+
level.forEach((expr, i) => {
|
|
1054
|
+
if (i === 0) {
|
|
1055
|
+
qb2.where(expr);
|
|
1056
|
+
} else {
|
|
1057
|
+
qb2.andWhere(expr);
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
});
|
|
1061
|
+
const [first, ...rest] = expressionMatrix;
|
|
1062
|
+
sqb.where(levelToBrackets(first));
|
|
1063
|
+
rest.forEach((level) => sqb.orWhere(levelToBrackets(level)));
|
|
1064
|
+
})
|
|
1065
|
+
).setParameters(
|
|
1066
|
+
Object.fromEntries(
|
|
1067
|
+
Object.entries(data2.payload).filter(([k, v]) => qb.expressionMap.orderBys[k] && v != null).map(([k, v]) => [cursorKey(k), v])
|
|
1068
|
+
)
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
if (data2.type === "prev") {
|
|
1073
|
+
reverseQueryOrderBy(qb);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
const { raw, entities: data } = await qb.getRawAndEntities();
|
|
1077
|
+
const rawMapById = /* @__PURE__ */ new Map();
|
|
1078
|
+
const getRawFromEntity = (entity) => {
|
|
1079
|
+
const isNumberId = typeof entity.id === "number";
|
|
1080
|
+
const id = entity.id;
|
|
1081
|
+
if (rawMapById.has(id)) {
|
|
1082
|
+
return rawMapById.get(id);
|
|
1083
|
+
}
|
|
1084
|
+
return raw.find((r) => {
|
|
1085
|
+
let id2 = r[`${entityAliasName}_id`];
|
|
1086
|
+
if (isNumberId) {
|
|
1087
|
+
id2 = Number(id2);
|
|
1088
|
+
if (isNaN(id2)) return false;
|
|
1089
|
+
}
|
|
1090
|
+
if (id2 == null) return false;
|
|
1091
|
+
rawMapById[id2] = r;
|
|
1092
|
+
return id2 === entity.id;
|
|
1093
|
+
});
|
|
1094
|
+
};
|
|
1095
|
+
const enough = data.length > take;
|
|
1096
|
+
const hasNext = enough || type === "prev";
|
|
1097
|
+
const hasPrev = cursor && (enough || type === "next");
|
|
1098
|
+
if (enough) {
|
|
1099
|
+
data.pop();
|
|
1100
|
+
}
|
|
1101
|
+
if (type === "prev") {
|
|
1102
|
+
data.reverse();
|
|
1103
|
+
}
|
|
1104
|
+
const generateCursor = (type2, data2) => {
|
|
1105
|
+
const targetObject = type2 === "prev" ? data2[0] : data2[data2.length - 1];
|
|
1106
|
+
const payload = Object.fromEntries(
|
|
1107
|
+
orderBys.map(({ key }) => {
|
|
1108
|
+
const value = !key.includes(".") || key.includes('"') ? getRawFromEntity(targetObject)?.[key.replace(/"/g, "")] : extractValueFromOrderByKey(targetObject, key, entityAliasName);
|
|
1109
|
+
return [key, value];
|
|
1110
|
+
}).filter((s) => s[1] !== void 0)
|
|
1111
|
+
);
|
|
1112
|
+
return encodeBase64Url(import_superjson.default.stringify({ type: type2, payload }));
|
|
1113
|
+
};
|
|
1114
|
+
return {
|
|
1115
|
+
data,
|
|
1116
|
+
paginatedResult: {
|
|
1117
|
+
nextCursor: hasNext ? generateCursor("next", data) : void 0,
|
|
1118
|
+
previousCursor: hasPrev ? generateCursor("prev", data) : void 0
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
// src/crud-base.ts
|
|
1124
|
+
var import_p_queue = __toESM(require("p-queue"));
|
|
1125
|
+
var Relation = (name, options = {}) => {
|
|
1126
|
+
return { name, inner: false, ...options };
|
|
1127
|
+
};
|
|
1128
|
+
var Inner = (name, options = {}) => {
|
|
1129
|
+
return Relation(name, { inner: true, ...options });
|
|
1130
|
+
};
|
|
1131
|
+
var loadedParsers = /* @__PURE__ */ new Set();
|
|
1132
|
+
var loadFullTextQueue = new import_p_queue.default({
|
|
1133
|
+
concurrency: 1
|
|
1134
|
+
});
|
|
1135
|
+
var CrudBase = class {
|
|
1136
|
+
constructor(entityClass, repo, crudOptions) {
|
|
1137
|
+
this.entityClass = entityClass;
|
|
1138
|
+
this.repo = repo;
|
|
1139
|
+
this.crudOptions = crudOptions;
|
|
1140
|
+
this.entityName = this.entityClass.name;
|
|
1141
|
+
this.entityReturnMessageDto = (0, import_nesties8.ReturnMessageDto)(this.entityClass);
|
|
1142
|
+
this.importEntryDto = ImportEntryDto(this.entityClass);
|
|
1143
|
+
this.importReturnMessageDto = (0, import_nesties8.ReturnMessageDto)([this.importEntryDto]);
|
|
1144
|
+
this.entityPaginatedReturnMessageDto = (0, import_nesties8.PaginatedReturnMessageDto)(
|
|
1145
|
+
this.entityClass
|
|
1146
|
+
);
|
|
1147
|
+
this.entityCursorPaginatedReturnMessageDto = CursorPaginationReturnMessageDto(this.entityClass);
|
|
1148
|
+
this.entityRelations = filterRelations(
|
|
1149
|
+
this.entityClass,
|
|
1150
|
+
this.crudOptions.relations,
|
|
1151
|
+
(r) => !r.computed
|
|
1152
|
+
);
|
|
1153
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
1154
|
+
this.extraGetQuery = this.crudOptions.extraGetQuery || ((qb) => {
|
|
1155
|
+
});
|
|
1156
|
+
this.log = new import_common2.ConsoleLogger(`${this.entityClass.name}Service`);
|
|
1157
|
+
this._typeormRelations = getTypeormRelations(this.entityClass);
|
|
1158
|
+
}
|
|
1159
|
+
_cleanEntityNotInResultFields(ent) {
|
|
1160
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1161
|
+
const runSingleObject = (o, cl) => {
|
|
1162
|
+
if (visited.has(o)) {
|
|
1163
|
+
return o;
|
|
1164
|
+
}
|
|
1165
|
+
const fields = getNotInResultFields(
|
|
1166
|
+
cl,
|
|
1167
|
+
this.crudOptions.keepEntityVersioningDates
|
|
1168
|
+
);
|
|
1169
|
+
for (const field of fields) {
|
|
1170
|
+
delete o[field];
|
|
1171
|
+
}
|
|
1172
|
+
visited.add(o);
|
|
1173
|
+
for (const relation of this._typeormRelations) {
|
|
1174
|
+
const propertyName = relation.propertyName;
|
|
1175
|
+
if (o[propertyName]) {
|
|
1176
|
+
if (Array.isArray(o[propertyName])) {
|
|
1177
|
+
o[propertyName] = o[propertyName].map(
|
|
1178
|
+
(r) => runSingleObject(r, relation.propertyClass)
|
|
1179
|
+
);
|
|
1180
|
+
} else {
|
|
1181
|
+
o[propertyName] = runSingleObject(
|
|
1182
|
+
o[propertyName],
|
|
1183
|
+
relation.propertyClass
|
|
1184
|
+
);
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
return o;
|
|
1189
|
+
};
|
|
1190
|
+
return runSingleObject(ent, this.entityClass);
|
|
1191
|
+
}
|
|
1192
|
+
cleanEntityNotInResultFields(ents) {
|
|
1193
|
+
if (Array.isArray(ents)) {
|
|
1194
|
+
return ents.map((ent) => this._cleanEntityNotInResultFields(ent));
|
|
1195
|
+
} else {
|
|
1196
|
+
return this._cleanEntityNotInResultFields(ents);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
async _batchCreate(ents, beforeCreate, skipErrors = false) {
|
|
1200
|
+
const entsWithId = ents.filter((ent) => ent.id != null);
|
|
1201
|
+
return this.repo.manager.transaction(async (mdb) => {
|
|
1202
|
+
let skipped = [];
|
|
1203
|
+
const repo = mdb.getRepository(this.entityClass);
|
|
1204
|
+
let entsToSave = ents;
|
|
1205
|
+
if (entsWithId.length) {
|
|
1206
|
+
const entIds = entsWithId.map((ent) => ent.id);
|
|
1207
|
+
const entIdChunks = import_lodash3.default.chunk(entIds, 65535);
|
|
1208
|
+
const existingEnts = (await Promise.all(
|
|
1209
|
+
entIdChunks.map(
|
|
1210
|
+
(chunk) => repo.find({
|
|
1211
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1212
|
+
// @ts-ignore
|
|
1213
|
+
where: {
|
|
1214
|
+
id: (0, import_typeorm6.In)(chunk)
|
|
1215
|
+
},
|
|
1216
|
+
select: this.crudOptions.createOrUpdate ? void 0 : ["id", "deleteTime"],
|
|
1217
|
+
withDeleted: true
|
|
1218
|
+
})
|
|
1219
|
+
)
|
|
1220
|
+
)).flat();
|
|
1221
|
+
if (existingEnts.length) {
|
|
1222
|
+
const existingEntsWithoutDeleteTime = existingEnts.filter(
|
|
1223
|
+
(ent) => ent.deleteTime == null
|
|
1224
|
+
);
|
|
1225
|
+
const existingEntsWithDeleteTime = existingEnts.filter(
|
|
1226
|
+
(ent) => ent.deleteTime != null
|
|
1227
|
+
);
|
|
1228
|
+
if (existingEntsWithoutDeleteTime.length) {
|
|
1229
|
+
if (this.crudOptions.createOrUpdate) {
|
|
1230
|
+
const existingIdMap = /* @__PURE__ */ new Map();
|
|
1231
|
+
existingEntsWithoutDeleteTime.forEach((ent) => {
|
|
1232
|
+
existingIdMap.set(ent.id, ent);
|
|
1233
|
+
});
|
|
1234
|
+
entsToSave = [];
|
|
1235
|
+
for (const ent of ents) {
|
|
1236
|
+
if (existingIdMap.has(ent.id)) {
|
|
1237
|
+
const existingEnt = existingIdMap.get(ent.id);
|
|
1238
|
+
Object.assign(existingEnt, ent);
|
|
1239
|
+
entsToSave.push(existingEnt);
|
|
1240
|
+
} else {
|
|
1241
|
+
entsToSave.push(ent);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
} else {
|
|
1245
|
+
if (!skipErrors) {
|
|
1246
|
+
throw new import_nesties8.BlankReturnMessageDto(
|
|
1247
|
+
404,
|
|
1248
|
+
`${this.entityName} ID ${existingEntsWithoutDeleteTime.join(
|
|
1249
|
+
","
|
|
1250
|
+
)} already exists`
|
|
1251
|
+
).toException();
|
|
1252
|
+
}
|
|
1253
|
+
const existingEntsWithoutDeleteTimeIdSet = new Set(
|
|
1254
|
+
existingEntsWithoutDeleteTime.map((e) => e.id)
|
|
1255
|
+
);
|
|
1256
|
+
const skippedEnts = ents.filter(
|
|
1257
|
+
(ent) => existingEntsWithoutDeleteTimeIdSet.has(ent.id)
|
|
1258
|
+
);
|
|
1259
|
+
skipped = skippedEnts.map((ent) => ({
|
|
1260
|
+
result: "Already exists",
|
|
1261
|
+
entry: ent
|
|
1262
|
+
}));
|
|
1263
|
+
const skippedEntsSet = new Set(skippedEnts);
|
|
1264
|
+
entsToSave = ents.filter((ent) => !skippedEntsSet.has(ent));
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
if (existingEntsWithDeleteTime.length) {
|
|
1268
|
+
await repo.delete(
|
|
1269
|
+
existingEntsWithDeleteTime.map((ent) => ent.id)
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
if (beforeCreate) {
|
|
1275
|
+
await beforeCreate(repo);
|
|
1276
|
+
}
|
|
1277
|
+
try {
|
|
1278
|
+
const entChunksToSave = import_lodash3.default.chunk(
|
|
1279
|
+
entsToSave,
|
|
1280
|
+
Math.floor(
|
|
1281
|
+
65535 / Math.max(1, Object.keys(entsToSave[0] || {}).length)
|
|
1282
|
+
)
|
|
1283
|
+
);
|
|
1284
|
+
let results = [];
|
|
1285
|
+
for (const entChunk of entChunksToSave) {
|
|
1286
|
+
const savedChunk = await repo.save(entChunk);
|
|
1287
|
+
results = results.concat(savedChunk);
|
|
1288
|
+
}
|
|
1289
|
+
return {
|
|
1290
|
+
results,
|
|
1291
|
+
skipped
|
|
1292
|
+
};
|
|
1293
|
+
} catch (e) {
|
|
1294
|
+
this.log.error(
|
|
1295
|
+
`Failed to create entity ${JSON.stringify(
|
|
1296
|
+
entsToSave
|
|
1297
|
+
)}: ${e.toString()}`
|
|
1298
|
+
);
|
|
1299
|
+
throw new import_nesties8.BlankReturnMessageDto(500, "Internal error").toException();
|
|
1300
|
+
}
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
async create(_ent, beforeCreate) {
|
|
1304
|
+
if (!_ent) {
|
|
1305
|
+
throw new import_nesties8.BlankReturnMessageDto(400, "Invalid entity").toException();
|
|
1306
|
+
}
|
|
1307
|
+
let ent = new this.entityClass();
|
|
1308
|
+
Object.assign(
|
|
1309
|
+
ent,
|
|
1310
|
+
(0, import_lodash3.omit)(_ent, ...this._typeormRelations.map((r) => r.propertyName))
|
|
1311
|
+
);
|
|
1312
|
+
const invalidReason = ent.isValidInCreate();
|
|
1313
|
+
if (invalidReason) {
|
|
1314
|
+
throw new import_nesties8.BlankReturnMessageDto(400, invalidReason).toException();
|
|
1315
|
+
}
|
|
1316
|
+
const savedEnt = await this.repo.manager.transaction(async (mdb) => {
|
|
1317
|
+
const repo = mdb.getRepository(this.entityClass);
|
|
1318
|
+
if (ent.id != null) {
|
|
1319
|
+
const existingEnt = await repo.findOne({
|
|
1320
|
+
where: { id: ent.id },
|
|
1321
|
+
select: this.crudOptions.createOrUpdate ? void 0 : ["id", "deleteTime"],
|
|
1322
|
+
withDeleted: true
|
|
1323
|
+
});
|
|
1324
|
+
if (existingEnt) {
|
|
1325
|
+
if (existingEnt.deleteTime) {
|
|
1326
|
+
await repo.delete(existingEnt.id);
|
|
1327
|
+
} else if (this.crudOptions.createOrUpdate) {
|
|
1328
|
+
Object.assign(existingEnt, ent);
|
|
1329
|
+
ent = existingEnt;
|
|
1330
|
+
} else {
|
|
1331
|
+
throw new import_nesties8.BlankReturnMessageDto(
|
|
1332
|
+
404,
|
|
1333
|
+
`${this.entityName} ID ${ent.id} already exists`
|
|
1334
|
+
).toException();
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
if (beforeCreate) {
|
|
1339
|
+
await beforeCreate(repo);
|
|
1340
|
+
}
|
|
1341
|
+
await ent.beforeCreate?.();
|
|
1342
|
+
try {
|
|
1343
|
+
const savedEnt2 = await repo.save(ent);
|
|
1344
|
+
await savedEnt2.afterCreate?.();
|
|
1345
|
+
return this.cleanEntityNotInResultFields(savedEnt2);
|
|
1346
|
+
} catch (e) {
|
|
1347
|
+
this.log.error(
|
|
1348
|
+
`Failed to create entity ${JSON.stringify(ent)}: ${e.toString()}`
|
|
1349
|
+
);
|
|
1350
|
+
throw new import_nesties8.BlankReturnMessageDto(500, "Internal error").toException();
|
|
1351
|
+
}
|
|
1352
|
+
});
|
|
1353
|
+
return new this.entityReturnMessageDto(200, "success", savedEnt);
|
|
1354
|
+
}
|
|
1355
|
+
get entityAliasName() {
|
|
1356
|
+
return (0, import_StringUtils.camelCase)(this.entityName);
|
|
1357
|
+
}
|
|
1358
|
+
_applyQueryRelation(qb, relation) {
|
|
1359
|
+
const { name } = relation;
|
|
1360
|
+
const relationUnit = name.split(".");
|
|
1361
|
+
const base = relationUnit.length === 1 ? this.entityAliasName : relationUnit.slice(0, relationUnit.length - 1).join("_");
|
|
1362
|
+
const property = relationUnit[relationUnit.length - 1];
|
|
1363
|
+
const properyAlias = relationUnit.join("_");
|
|
1364
|
+
const methodName = relation.inner ? "innerJoin" : "leftJoin";
|
|
1365
|
+
if (!relation.noSelect) {
|
|
1366
|
+
qb.addSelect(properyAlias);
|
|
1367
|
+
}
|
|
1368
|
+
qb[methodName](
|
|
1369
|
+
`${base}.${property}`,
|
|
1370
|
+
properyAlias,
|
|
1371
|
+
relation.extraCondition || void 0,
|
|
1372
|
+
relation.extraConditionFields || void 0
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
_applyQueryRelations(qb) {
|
|
1376
|
+
for (const relation of this.entityRelations) {
|
|
1377
|
+
if (typeof relation === "string") {
|
|
1378
|
+
this._applyQueryRelation(qb, { name: relation });
|
|
1379
|
+
} else {
|
|
1380
|
+
this._applyQueryRelation(qb, relation);
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
_applyQueryFilters(qb, ent) {
|
|
1385
|
+
const queryFields = reflector.getArray(
|
|
1386
|
+
"queryConditionFields",
|
|
1387
|
+
this.entityClass
|
|
1388
|
+
);
|
|
1389
|
+
for (const field of queryFields) {
|
|
1390
|
+
const condition = reflector.get(
|
|
1391
|
+
"queryCondition",
|
|
1392
|
+
this.entityClass,
|
|
1393
|
+
field
|
|
1394
|
+
);
|
|
1395
|
+
if (condition) {
|
|
1396
|
+
condition(ent, qb, this.entityAliasName, field);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
queryBuilder() {
|
|
1401
|
+
return this.repo.createQueryBuilder(this.entityAliasName);
|
|
1402
|
+
}
|
|
1403
|
+
async findOne(id, extraQuery = () => {
|
|
1404
|
+
}) {
|
|
1405
|
+
const query = this.queryBuilder().where(`${this.entityAliasName}.id = :id`, { id }).take(1);
|
|
1406
|
+
this._applyQueryRelations(query);
|
|
1407
|
+
this.extraGetQuery(query);
|
|
1408
|
+
extraQuery(query);
|
|
1409
|
+
query.take(1);
|
|
1410
|
+
let ent;
|
|
1411
|
+
try {
|
|
1412
|
+
ent = await query.getOne();
|
|
1413
|
+
} catch (e) {
|
|
1414
|
+
const [sql, params] = query.getQueryAndParameters();
|
|
1415
|
+
this.log.error(
|
|
1416
|
+
`Failed to read entity ID ${id} with SQL ${sql} param ${params.join(
|
|
1417
|
+
","
|
|
1418
|
+
)}: ${e.toString()}`
|
|
1419
|
+
);
|
|
1420
|
+
throw new import_nesties8.BlankReturnMessageDto(500, "Internal error").toException();
|
|
1421
|
+
}
|
|
1422
|
+
if (!ent) {
|
|
1423
|
+
throw new import_nesties8.BlankReturnMessageDto(
|
|
1424
|
+
404,
|
|
1425
|
+
`${this.entityName} ID ${id} not found.`
|
|
1426
|
+
).toException();
|
|
1427
|
+
}
|
|
1428
|
+
await ent.afterGet?.();
|
|
1429
|
+
return new this.entityReturnMessageDto(
|
|
1430
|
+
200,
|
|
1431
|
+
"success",
|
|
1432
|
+
this.cleanEntityNotInResultFields(ent)
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1435
|
+
async _preFindAll(ent, extraQuery = () => {
|
|
1436
|
+
}) {
|
|
1437
|
+
const query = this.queryBuilder().where("1 = 1");
|
|
1438
|
+
const newEnt = new this.entityClass();
|
|
1439
|
+
if (ent) {
|
|
1440
|
+
Object.assign(newEnt, ent);
|
|
1441
|
+
await newEnt?.beforeGet?.();
|
|
1442
|
+
newEnt.applyQuery(query, this.entityAliasName);
|
|
1443
|
+
}
|
|
1444
|
+
this._applyQueryRelations(query);
|
|
1445
|
+
this._applyQueryFilters(query, newEnt);
|
|
1446
|
+
const pageSettings = newEnt instanceof PageSettingsDto ? newEnt : Object.assign(new PageSettingsDto(), newEnt);
|
|
1447
|
+
this.extraGetQuery(query);
|
|
1448
|
+
extraQuery(query);
|
|
1449
|
+
return { query, newEnt, pageSettings };
|
|
1450
|
+
}
|
|
1451
|
+
async findAll(ent, extraQuery = () => {
|
|
1452
|
+
}) {
|
|
1453
|
+
const { query, pageSettings } = await this._preFindAll(ent, extraQuery);
|
|
1454
|
+
pageSettings.applyPaginationQuery(query);
|
|
1455
|
+
try {
|
|
1456
|
+
const [data, count] = await query.getManyAndCount();
|
|
1457
|
+
await Promise.all(data.map((ent2) => ent2.afterGet?.()));
|
|
1458
|
+
return new this.entityPaginatedReturnMessageDto(
|
|
1459
|
+
200,
|
|
1460
|
+
"success",
|
|
1461
|
+
this.cleanEntityNotInResultFields(data),
|
|
1462
|
+
count,
|
|
1463
|
+
pageSettings.getActualPageSettings()
|
|
1464
|
+
);
|
|
1465
|
+
} catch (e) {
|
|
1466
|
+
const [sql, params] = query.getQueryAndParameters();
|
|
1467
|
+
this.log.error(
|
|
1468
|
+
`Failed to read entity cond ${JSON.stringify(
|
|
1469
|
+
ent
|
|
1470
|
+
)} with SQL ${sql} param ${params.join(",")}: ${e.toString()}`
|
|
1471
|
+
);
|
|
1472
|
+
throw new import_nesties8.BlankReturnMessageDto(500, "Internal error").toException();
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
async findAllCursorPaginated(ent, extraQuery = () => {
|
|
1476
|
+
}) {
|
|
1477
|
+
const { query, pageSettings } = await this._preFindAll(ent, extraQuery);
|
|
1478
|
+
try {
|
|
1479
|
+
const { data, paginatedResult } = await getPaginatedResult(
|
|
1480
|
+
query,
|
|
1481
|
+
this.entityClass,
|
|
1482
|
+
this.entityAliasName,
|
|
1483
|
+
pageSettings.getRecordsPerPage(),
|
|
1484
|
+
ent.paginationCursor
|
|
1485
|
+
);
|
|
1486
|
+
await Promise.all(data.map((ent2) => ent2.afterGet?.()));
|
|
1487
|
+
return new this.entityCursorPaginatedReturnMessageDto(
|
|
1488
|
+
200,
|
|
1489
|
+
"success",
|
|
1490
|
+
this.cleanEntityNotInResultFields(data),
|
|
1491
|
+
paginatedResult
|
|
1492
|
+
);
|
|
1493
|
+
} catch (e) {
|
|
1494
|
+
const [sql, params] = query.getQueryAndParameters();
|
|
1495
|
+
this.log.error(
|
|
1496
|
+
`Failed to read entity cond ${JSON.stringify(
|
|
1497
|
+
ent
|
|
1498
|
+
)} with SQL ${sql} param ${params.join(",")}: ${e.toString()}`
|
|
1499
|
+
);
|
|
1500
|
+
throw new import_nesties8.BlankReturnMessageDto(500, "Internal error").toException();
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
async update(id, entPart, cond = {}) {
|
|
1504
|
+
let result;
|
|
1505
|
+
const ent = new this.entityClass();
|
|
1506
|
+
Object.assign(ent, entPart);
|
|
1507
|
+
const invalidReason = ent.isValidInUpdate();
|
|
1508
|
+
if (invalidReason) {
|
|
1509
|
+
throw new import_nesties8.BlankReturnMessageDto(400, invalidReason).toException();
|
|
1510
|
+
}
|
|
1511
|
+
await ent.beforeUpdate?.();
|
|
1512
|
+
try {
|
|
1513
|
+
result = await this.repo.update(
|
|
1514
|
+
{
|
|
1515
|
+
id,
|
|
1516
|
+
...cond
|
|
1517
|
+
},
|
|
1518
|
+
ent
|
|
1519
|
+
);
|
|
1520
|
+
} catch (e) {
|
|
1521
|
+
this.log.error(
|
|
1522
|
+
`Failed to update entity ID ${id} to ${JSON.stringify(
|
|
1523
|
+
entPart
|
|
1524
|
+
)}: ${e.toString()}`
|
|
1525
|
+
);
|
|
1526
|
+
throw new import_nesties8.BlankReturnMessageDto(500, "Internal error").toException();
|
|
1527
|
+
}
|
|
1528
|
+
if (!result.affected) {
|
|
1529
|
+
throw new import_nesties8.BlankReturnMessageDto(
|
|
1530
|
+
404,
|
|
1531
|
+
`${this.entityName} ID ${id} not found.`
|
|
1532
|
+
).toException();
|
|
1533
|
+
}
|
|
1534
|
+
return new import_nesties8.BlankReturnMessageDto(200, "success");
|
|
1535
|
+
}
|
|
1536
|
+
async delete(id, cond = {}) {
|
|
1537
|
+
let result;
|
|
1538
|
+
const searchCond = {
|
|
1539
|
+
id,
|
|
1540
|
+
...cond
|
|
1541
|
+
};
|
|
1542
|
+
try {
|
|
1543
|
+
result = await (this.crudOptions.hardDelete || !this.repo.manager.connection.getMetadata(this.entityClass).deleteDateColumn ? this.repo.delete(searchCond) : this.repo.softDelete(searchCond));
|
|
1544
|
+
} catch (e) {
|
|
1545
|
+
this.log.error(`Failed to delete entity ID ${id}: ${e.toString()}`);
|
|
1546
|
+
throw new import_nesties8.BlankReturnMessageDto(500, "Internal error").toException();
|
|
1547
|
+
}
|
|
1548
|
+
if (!result.affected) {
|
|
1549
|
+
throw new import_nesties8.BlankReturnMessageDto(
|
|
1550
|
+
404,
|
|
1551
|
+
`${this.entityName} ID ${id} not found.`
|
|
1552
|
+
).toException();
|
|
1553
|
+
}
|
|
1554
|
+
return new import_nesties8.BlankReturnMessageDto(200, "success");
|
|
1555
|
+
}
|
|
1556
|
+
async importEntities(_ents, extraChecking) {
|
|
1557
|
+
const ents = _ents.map((ent) => {
|
|
1558
|
+
const newEnt = new this.entityClass();
|
|
1559
|
+
Object.assign(
|
|
1560
|
+
newEnt,
|
|
1561
|
+
(0, import_lodash3.omit)(ent, ...this._typeormRelations.map((r) => r.propertyName))
|
|
1562
|
+
);
|
|
1563
|
+
return newEnt;
|
|
1564
|
+
});
|
|
1565
|
+
const invalidResults = import_lodash3.default.compact(
|
|
1566
|
+
await Promise.all(
|
|
1567
|
+
ents.map(async (ent) => {
|
|
1568
|
+
const reason = ent.isValidInCreate();
|
|
1569
|
+
if (reason) {
|
|
1570
|
+
return { entry: ent, result: reason };
|
|
1571
|
+
}
|
|
1572
|
+
if (extraChecking) {
|
|
1573
|
+
const reason2 = await extraChecking(ent);
|
|
1574
|
+
if (reason2) {
|
|
1575
|
+
return { entry: ent, result: reason2 };
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
})
|
|
1579
|
+
)
|
|
1580
|
+
);
|
|
1581
|
+
const remainingEnts = ents.filter(
|
|
1582
|
+
(ent) => !invalidResults.find((result) => result.entry === ent)
|
|
1583
|
+
);
|
|
1584
|
+
await Promise.all(remainingEnts.map((ent) => ent.beforeCreate?.()));
|
|
1585
|
+
const data = await this._batchCreate(remainingEnts, void 0, true);
|
|
1586
|
+
await Promise.all(data.results.map((e) => e.afterCreate?.()));
|
|
1587
|
+
const results = [
|
|
1588
|
+
...invalidResults,
|
|
1589
|
+
...data.skipped,
|
|
1590
|
+
...data.results.map((e) => ({ entry: e, result: "OK" }))
|
|
1591
|
+
];
|
|
1592
|
+
return new this.importReturnMessageDto(
|
|
1593
|
+
200,
|
|
1594
|
+
"success",
|
|
1595
|
+
results.map((r) => {
|
|
1596
|
+
const entry = new this.importEntryDto();
|
|
1597
|
+
Object.assign(entry, r);
|
|
1598
|
+
entry.entry = this.cleanEntityNotInResultFields(r.entry);
|
|
1599
|
+
return entry;
|
|
1600
|
+
})
|
|
1601
|
+
);
|
|
1602
|
+
}
|
|
1603
|
+
async exists(id) {
|
|
1604
|
+
const ent = await this.repo.findOne({ where: { id }, select: ["id"] });
|
|
1605
|
+
return !!ent;
|
|
1606
|
+
}
|
|
1607
|
+
async _loadFullTextIndex() {
|
|
1608
|
+
const fields = reflector.getArray(
|
|
1609
|
+
"queryFullTextColumnFields",
|
|
1610
|
+
this.entityClass
|
|
1611
|
+
);
|
|
1612
|
+
const metadata = this.repo.metadata;
|
|
1613
|
+
const tableName = metadata.tableName;
|
|
1614
|
+
const sqls = [];
|
|
1615
|
+
for (const field of fields) {
|
|
1616
|
+
const options = reflector.get(
|
|
1617
|
+
"queryFullTextColumn",
|
|
1618
|
+
this.entityClass,
|
|
1619
|
+
field
|
|
1620
|
+
);
|
|
1621
|
+
if (!options) continue;
|
|
1622
|
+
const configurationName = options.configuration;
|
|
1623
|
+
const parser = options.parser;
|
|
1624
|
+
if (parser && !loadedParsers.has(parser)) {
|
|
1625
|
+
loadedParsers.add(parser);
|
|
1626
|
+
sqls.push(
|
|
1627
|
+
`CREATE EXTENSION IF NOT EXISTS ${parser};`,
|
|
1628
|
+
`DROP TEXT SEARCH CONFIGURATION IF EXISTS ${configurationName};`,
|
|
1629
|
+
`CREATE TEXT SEARCH CONFIGURATION ${configurationName} (PARSER = ${parser});`,
|
|
1630
|
+
`ALTER TEXT SEARCH CONFIGURATION ${configurationName} ADD MAPPING FOR n, v, a, i, e, l WITH simple;`
|
|
1631
|
+
);
|
|
1632
|
+
}
|
|
1633
|
+
const indexName = `idx_fulltext_${this.entityName}_${field}`;
|
|
1634
|
+
sqls.push(
|
|
1635
|
+
`CREATE INDEX IF NOT EXISTS "${indexName}" ON "${tableName}" USING GIN (to_tsvector('${configurationName}', "${field}"));`
|
|
1636
|
+
);
|
|
1637
|
+
}
|
|
1638
|
+
if (sqls.length) {
|
|
1639
|
+
await this.repo.manager.query(sqls.join("\n"));
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
async onModuleInit() {
|
|
1643
|
+
await loadFullTextQueue.add(() => this._loadFullTextIndex());
|
|
1644
|
+
}
|
|
1645
|
+
};
|
|
1646
|
+
function CrudService(entityClass, crudOptions = {}) {
|
|
1647
|
+
return class CrudServiceImpl extends CrudBase {
|
|
1648
|
+
constructor(repo) {
|
|
1649
|
+
super(entityClass, repo, crudOptions);
|
|
1650
|
+
}
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
// src/restful.ts
|
|
1655
|
+
var import_common3 = require("@nestjs/common");
|
|
1656
|
+
var import_nesties9 = require("nesties");
|
|
1657
|
+
var import_swagger6 = require("@nestjs/swagger");
|
|
1658
|
+
var import_lodash4 = __toESM(require("lodash"));
|
|
1659
|
+
|
|
1660
|
+
// src/utility/rename-class.ts
|
|
1661
|
+
function RenameClass(cls, name) {
|
|
1662
|
+
Object.defineProperty(cls, "name", { value: name });
|
|
1663
|
+
return cls;
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
// src/restful.ts
|
|
1667
|
+
var import_constants = require("@nestjs/swagger/dist/constants");
|
|
1668
|
+
|
|
1669
|
+
// src/bases/base-restful-controller.ts
|
|
1670
|
+
var RestfulMethods = [
|
|
1671
|
+
"findOne",
|
|
1672
|
+
"findAll",
|
|
1673
|
+
"create",
|
|
1674
|
+
"update",
|
|
1675
|
+
"delete",
|
|
1676
|
+
"import"
|
|
1677
|
+
];
|
|
1678
|
+
var BaseRestfulController = class {
|
|
1679
|
+
constructor(serviceOrRepo, _options = {}) {
|
|
1680
|
+
this._options = _options;
|
|
1681
|
+
if (serviceOrRepo instanceof CrudBase) {
|
|
1682
|
+
this.service = serviceOrRepo;
|
|
1683
|
+
} else {
|
|
1684
|
+
const crudServiceClass = CrudService(this._options.entityClass, {
|
|
1685
|
+
relations: this._options.relations
|
|
1686
|
+
});
|
|
1687
|
+
this.service = new crudServiceClass(serviceOrRepo);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
findOne(id) {
|
|
1691
|
+
return this.service.findOne(id);
|
|
1692
|
+
}
|
|
1693
|
+
findAll(dto) {
|
|
1694
|
+
if (this._options.paginateType === "cursor") {
|
|
1695
|
+
return this.service.findAllCursorPaginated(dto);
|
|
1696
|
+
}
|
|
1697
|
+
if (this._options.paginateType === "offset") {
|
|
1698
|
+
return this.service.findAll(dto);
|
|
1699
|
+
}
|
|
1700
|
+
dto["recordsPerPage"] ??= 99999;
|
|
1701
|
+
return this.service.findAll(dto);
|
|
1702
|
+
}
|
|
1703
|
+
create(dto) {
|
|
1704
|
+
return this.service.create(dto);
|
|
1705
|
+
}
|
|
1706
|
+
update(id, dto) {
|
|
1707
|
+
return this.service.update(id, dto);
|
|
1708
|
+
}
|
|
1709
|
+
delete(id) {
|
|
1710
|
+
return this.service.delete(id);
|
|
1711
|
+
}
|
|
1712
|
+
import(data) {
|
|
1713
|
+
return this.service.importEntities(data.data);
|
|
1714
|
+
}
|
|
1715
|
+
};
|
|
1716
|
+
|
|
1717
|
+
// src/utility/omit-type-exclude.ts
|
|
1718
|
+
var import_swagger5 = require("@nestjs/swagger");
|
|
1719
|
+
var import_class_transformer4 = require("class-transformer");
|
|
1720
|
+
var OmitTypeExclude = (cl, keys) => {
|
|
1721
|
+
const omitted = (0, import_swagger5.OmitType)(cl, keys);
|
|
1722
|
+
for (const key of keys) {
|
|
1723
|
+
(0, import_class_transformer4.Exclude)()(omitted.prototype, key);
|
|
1724
|
+
}
|
|
1725
|
+
return omitted;
|
|
1726
|
+
};
|
|
1727
|
+
|
|
1728
|
+
// src/restful.ts
|
|
1729
|
+
var getCurrentLevelRelations = (relations) => relations.filter((r) => !r.includes("."));
|
|
1730
|
+
var getNextLevelRelations = (relations, enteringField) => relations.filter((r) => r.includes(".") && r.startsWith(`${enteringField}.`)).map((r) => r.split(".").slice(1).join("."));
|
|
1731
|
+
var RestfulFactory = class _RestfulFactory {
|
|
1732
|
+
constructor(entityClass, options = {}, __resolveVisited = /* @__PURE__ */ new Map()) {
|
|
1733
|
+
this.entityClass = entityClass;
|
|
1734
|
+
this.options = options;
|
|
1735
|
+
this.__resolveVisited = __resolveVisited;
|
|
1736
|
+
this.fieldsToOmit = import_lodash4.default.uniq([
|
|
1737
|
+
...getSpecificFields(this.entityClass, "notColumn"),
|
|
1738
|
+
...this.options.fieldsToOmit || [],
|
|
1739
|
+
...getTypeormRelations(this.entityClass).map(
|
|
1740
|
+
(r) => r.propertyName
|
|
1741
|
+
)
|
|
1742
|
+
]);
|
|
1743
|
+
this.basicInputDto = OmitTypeExclude(
|
|
1744
|
+
this.entityClass,
|
|
1745
|
+
this.fieldsToOmit
|
|
1746
|
+
);
|
|
1747
|
+
this.createDto = RenameClass(
|
|
1748
|
+
OmitTypeExclude(
|
|
1749
|
+
this.basicInputDto,
|
|
1750
|
+
getSpecificFields(this.entityClass, "notWritable")
|
|
1751
|
+
),
|
|
1752
|
+
`Create${this.entityClass.name}Dto`
|
|
1753
|
+
);
|
|
1754
|
+
this.importDto = ImportDataDto(this.createDto);
|
|
1755
|
+
this.findAllDto = RenameClass(
|
|
1756
|
+
(0, import_swagger6.PartialType)(
|
|
1757
|
+
OmitTypeExclude(
|
|
1758
|
+
this.entityClass instanceof PageSettingsDto ? this.basicInputDto : (0, import_swagger6.IntersectionType)(
|
|
1759
|
+
this.basicInputDto,
|
|
1760
|
+
PageSettingsDto
|
|
1761
|
+
),
|
|
1762
|
+
getSpecificFields(this.entityClass, "notQueryable")
|
|
1763
|
+
)
|
|
1764
|
+
),
|
|
1765
|
+
`Find${this.entityClass.name}Dto`
|
|
1766
|
+
);
|
|
1767
|
+
this.findAllCursorPaginatedDto = RenameClass(
|
|
1768
|
+
(0, import_swagger6.IntersectionType)(
|
|
1769
|
+
OmitTypeExclude(this.findAllDto, ["pageCount"]),
|
|
1770
|
+
CursorPaginationDto
|
|
1771
|
+
),
|
|
1772
|
+
`Find${this.entityClass.name}CursorPaginatedDto`
|
|
1773
|
+
);
|
|
1774
|
+
this.updateDto = RenameClass(
|
|
1775
|
+
(0, import_swagger6.PartialType)(
|
|
1776
|
+
OmitTypeExclude(
|
|
1777
|
+
this.createDto,
|
|
1778
|
+
getSpecificFields(this.entityClass, "notChangeable")
|
|
1779
|
+
)
|
|
1780
|
+
),
|
|
1781
|
+
`Update${this.entityClass.name}Dto`
|
|
1782
|
+
);
|
|
1783
|
+
this.entityResultDto = this.resolveEntityResultDto();
|
|
1784
|
+
this.entityCreateResultDto = RenameClass(
|
|
1785
|
+
(0, import_swagger6.OmitType)(this.entityResultDto, [
|
|
1786
|
+
...getTypeormRelations(this.entityClass).map(
|
|
1787
|
+
(r) => r.propertyName
|
|
1788
|
+
),
|
|
1789
|
+
...getSpecificFields(
|
|
1790
|
+
this.entityClass,
|
|
1791
|
+
"notColumn",
|
|
1792
|
+
(m) => !m.keepInCreate
|
|
1793
|
+
)
|
|
1794
|
+
]),
|
|
1795
|
+
`${this.getEntityClassName()}CreateResultDto`
|
|
1796
|
+
);
|
|
1797
|
+
this.entityReturnMessageDto = (0, import_nesties9.ReturnMessageDto)(this.entityResultDto);
|
|
1798
|
+
this.entityCreateReturnMessageDto = (0, import_nesties9.ReturnMessageDto)(
|
|
1799
|
+
this.entityCreateResultDto
|
|
1800
|
+
);
|
|
1801
|
+
this.entityArrayReturnMessageDto = (0, import_nesties9.PaginatedReturnMessageDto)(
|
|
1802
|
+
this.entityResultDto
|
|
1803
|
+
);
|
|
1804
|
+
this.entityCursorPaginationReturnMessageDto = CursorPaginationReturnMessageDto(this.entityResultDto);
|
|
1805
|
+
this.importReturnMessageDto = (0, import_nesties9.ReturnMessageDto)([
|
|
1806
|
+
ImportEntryDto(this.entityCreateResultDto)
|
|
1807
|
+
]);
|
|
1808
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
1809
|
+
this.idType = Reflect.getMetadata(
|
|
1810
|
+
"design:type",
|
|
1811
|
+
this.entityClass.prototype,
|
|
1812
|
+
"id"
|
|
1813
|
+
);
|
|
1814
|
+
if (options.relations) {
|
|
1815
|
+
filterRelations(entityClass, options.relations);
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
getEntityClassName() {
|
|
1819
|
+
return this.options.entityClassName || this.entityClass.name;
|
|
1820
|
+
}
|
|
1821
|
+
resolveEntityResultDto() {
|
|
1822
|
+
const relations = getTypeormRelations(this.entityClass);
|
|
1823
|
+
const currentLevelRelations = this.options.relations && new Set(
|
|
1824
|
+
getCurrentLevelRelations(
|
|
1825
|
+
this.options.relations.map(extractRelationName)
|
|
1826
|
+
)
|
|
1827
|
+
);
|
|
1828
|
+
const outputFieldsToOmit = /* @__PURE__ */ new Set([
|
|
1829
|
+
...getNotInResultFields(
|
|
1830
|
+
this.entityClass,
|
|
1831
|
+
this.options.keepEntityVersioningDates
|
|
1832
|
+
),
|
|
1833
|
+
...this.options.outputFieldsToOmit || [],
|
|
1834
|
+
...this.options.relations ? relations.map((r) => r.propertyName).filter((r) => !currentLevelRelations.has(r)) : []
|
|
1835
|
+
]);
|
|
1836
|
+
const resultDto = (0, import_swagger6.OmitType)(this.entityClass, [...outputFieldsToOmit]);
|
|
1837
|
+
for (const relation of relations) {
|
|
1838
|
+
if (outputFieldsToOmit.has(relation.propertyName)) continue;
|
|
1839
|
+
const replace = (useClass) => {
|
|
1840
|
+
const oldApiProperty = Reflect.getMetadata(
|
|
1841
|
+
import_constants.DECORATORS.API_MODEL_PROPERTIES,
|
|
1842
|
+
this.entityClass.prototype,
|
|
1843
|
+
relation.propertyName
|
|
1844
|
+
) || {};
|
|
1845
|
+
(0, import_swagger6.ApiProperty)({
|
|
1846
|
+
...oldApiProperty,
|
|
1847
|
+
required: false,
|
|
1848
|
+
type: () => relation.isArray ? [useClass[0]] : useClass[0]
|
|
1849
|
+
})(resultDto.prototype, relation.propertyName);
|
|
1850
|
+
};
|
|
1851
|
+
const existing = this.__resolveVisited.get(relation.propertyClass);
|
|
1852
|
+
if (existing) {
|
|
1853
|
+
replace(existing);
|
|
1854
|
+
} else {
|
|
1855
|
+
if (!this.__resolveVisited.has(this.entityClass) && !this.options.relations) {
|
|
1856
|
+
this.__resolveVisited.set(this.entityClass, [null]);
|
|
1857
|
+
}
|
|
1858
|
+
const relationFactory = new _RestfulFactory(
|
|
1859
|
+
relation.propertyClass,
|
|
1860
|
+
{
|
|
1861
|
+
entityClassName: `${this.getEntityClassName()}${this.options.relations ? (0, import_lodash4.upperFirst)(relation.propertyName) : relation.propertyClass.name}`,
|
|
1862
|
+
relations: this.options.relations && getNextLevelRelations(
|
|
1863
|
+
this.options.relations.map(extractRelationName),
|
|
1864
|
+
relation.propertyName
|
|
1865
|
+
),
|
|
1866
|
+
keepEntityVersioningDates: this.options.keepEntityVersioningDates
|
|
1867
|
+
},
|
|
1868
|
+
this.__resolveVisited
|
|
1869
|
+
);
|
|
1870
|
+
const relationResultDto = relationFactory.entityResultDto;
|
|
1871
|
+
replace([relationResultDto]);
|
|
1872
|
+
if (!this.options.relations) {
|
|
1873
|
+
this.__resolveVisited.set(relation.propertyClass, [
|
|
1874
|
+
relationResultDto
|
|
1875
|
+
]);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
const res = RenameClass(
|
|
1880
|
+
resultDto,
|
|
1881
|
+
`${this.getEntityClassName()}ResultDto`
|
|
1882
|
+
);
|
|
1883
|
+
const currentContainer = this.__resolveVisited.get(this.entityClass);
|
|
1884
|
+
if (currentContainer) {
|
|
1885
|
+
currentContainer[0] = res;
|
|
1886
|
+
}
|
|
1887
|
+
return res;
|
|
1888
|
+
}
|
|
1889
|
+
usePrefix(methodDec, path) {
|
|
1890
|
+
if (path) {
|
|
1891
|
+
if (this.options.prefix) {
|
|
1892
|
+
return methodDec(`${this.options.prefix}/${path}`);
|
|
1893
|
+
} else {
|
|
1894
|
+
return methodDec(path);
|
|
1895
|
+
}
|
|
1896
|
+
} else {
|
|
1897
|
+
if (this.options.prefix) {
|
|
1898
|
+
return methodDec(this.options.prefix);
|
|
1899
|
+
} else {
|
|
1900
|
+
return methodDec();
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
create(extras = {}) {
|
|
1905
|
+
return (0, import_nesties9.MergeMethodDecorators)([
|
|
1906
|
+
this.usePrefix(import_common3.Post),
|
|
1907
|
+
(0, import_common3.HttpCode)(200),
|
|
1908
|
+
(0, import_swagger6.ApiOperation)({
|
|
1909
|
+
summary: `Create a new ${this.getEntityClassName()}`,
|
|
1910
|
+
...extras
|
|
1911
|
+
}),
|
|
1912
|
+
(0, import_swagger6.ApiBody)({ type: this.createDto }),
|
|
1913
|
+
(0, import_swagger6.ApiOkResponse)({ type: this.entityCreateReturnMessageDto }),
|
|
1914
|
+
(0, import_swagger6.ApiBadRequestResponse)({
|
|
1915
|
+
type: import_nesties9.BlankReturnMessageDto,
|
|
1916
|
+
description: `The ${this.getEntityClassName()} is not valid`
|
|
1917
|
+
})
|
|
1918
|
+
]);
|
|
1919
|
+
}
|
|
1920
|
+
createParam() {
|
|
1921
|
+
return (0, import_common3.Body)(CreatePipe());
|
|
1922
|
+
}
|
|
1923
|
+
findOne(extras = {}) {
|
|
1924
|
+
return (0, import_nesties9.MergeMethodDecorators)([
|
|
1925
|
+
this.usePrefix(import_common3.Get, ":id"),
|
|
1926
|
+
(0, import_swagger6.ApiOperation)({
|
|
1927
|
+
summary: `Find a ${this.getEntityClassName()} by id`,
|
|
1928
|
+
...extras
|
|
1929
|
+
}),
|
|
1930
|
+
(0, import_swagger6.ApiParam)({ name: "id", type: this.idType, required: true }),
|
|
1931
|
+
(0, import_swagger6.ApiOkResponse)({ type: this.entityReturnMessageDto }),
|
|
1932
|
+
(0, import_swagger6.ApiNotFoundResponse)({
|
|
1933
|
+
type: import_nesties9.BlankReturnMessageDto,
|
|
1934
|
+
description: `The ${this.getEntityClassName()} with the given id was not found`
|
|
1935
|
+
})
|
|
1936
|
+
]);
|
|
1937
|
+
}
|
|
1938
|
+
idParam() {
|
|
1939
|
+
if (this.idType === Number) {
|
|
1940
|
+
return (0, import_common3.Param)("id", import_common3.ParseIntPipe);
|
|
1941
|
+
} else {
|
|
1942
|
+
return (0, import_common3.Param)("id");
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
findAll(extras = {}) {
|
|
1946
|
+
return (0, import_nesties9.MergeMethodDecorators)([
|
|
1947
|
+
this.usePrefix(import_common3.Get),
|
|
1948
|
+
(0, import_swagger6.ApiOperation)({
|
|
1949
|
+
summary: `Find all ${this.getEntityClassName()}`,
|
|
1950
|
+
...extras
|
|
1951
|
+
}),
|
|
1952
|
+
(0, import_swagger6.ApiOkResponse)({ type: this.entityArrayReturnMessageDto })
|
|
1953
|
+
]);
|
|
1954
|
+
}
|
|
1955
|
+
findAllCursorPaginated(extras = {}) {
|
|
1956
|
+
return (0, import_nesties9.MergeMethodDecorators)([
|
|
1957
|
+
this.usePrefix(import_common3.Get),
|
|
1958
|
+
(0, import_swagger6.ApiOperation)({
|
|
1959
|
+
summary: `Find all ${this.getEntityClassName()}`,
|
|
1960
|
+
...extras
|
|
1961
|
+
}),
|
|
1962
|
+
(0, import_swagger6.ApiOkResponse)({ type: this.entityCursorPaginationReturnMessageDto })
|
|
1963
|
+
]);
|
|
1964
|
+
}
|
|
1965
|
+
findAllParam() {
|
|
1966
|
+
return (0, import_common3.Query)(GetPipe());
|
|
1967
|
+
}
|
|
1968
|
+
update(extras = {}) {
|
|
1969
|
+
return (0, import_nesties9.MergeMethodDecorators)([
|
|
1970
|
+
this.usePrefix(import_common3.Patch, ":id"),
|
|
1971
|
+
(0, import_common3.HttpCode)(200),
|
|
1972
|
+
(0, import_swagger6.ApiOperation)({
|
|
1973
|
+
summary: `Update a ${this.getEntityClassName()} by id`,
|
|
1974
|
+
...extras
|
|
1975
|
+
}),
|
|
1976
|
+
(0, import_swagger6.ApiParam)({ name: "id", type: this.idType, required: true }),
|
|
1977
|
+
(0, import_swagger6.ApiBody)({ type: this.updateDto }),
|
|
1978
|
+
(0, import_swagger6.ApiOkResponse)({ type: import_nesties9.BlankReturnMessageDto }),
|
|
1979
|
+
(0, import_swagger6.ApiNotFoundResponse)({
|
|
1980
|
+
type: import_nesties9.BlankReturnMessageDto,
|
|
1981
|
+
description: `The ${this.getEntityClassName()} with the given id was not found`
|
|
1982
|
+
}),
|
|
1983
|
+
(0, import_swagger6.ApiBadRequestResponse)({
|
|
1984
|
+
type: import_nesties9.BlankReturnMessageDto,
|
|
1985
|
+
description: `The ${this.getEntityClassName()} is not valid`
|
|
1986
|
+
}),
|
|
1987
|
+
(0, import_swagger6.ApiInternalServerErrorResponse)({
|
|
1988
|
+
type: import_nesties9.BlankReturnMessageDto,
|
|
1989
|
+
description: "Internal error"
|
|
1990
|
+
})
|
|
1991
|
+
]);
|
|
1992
|
+
}
|
|
1993
|
+
updateParam() {
|
|
1994
|
+
return (0, import_common3.Body)(UpdatePipe());
|
|
1995
|
+
}
|
|
1996
|
+
delete(extras = {}) {
|
|
1997
|
+
return (0, import_nesties9.MergeMethodDecorators)([
|
|
1998
|
+
this.usePrefix(import_common3.Delete, ":id"),
|
|
1999
|
+
(0, import_common3.HttpCode)(200),
|
|
2000
|
+
(0, import_swagger6.ApiOperation)({
|
|
2001
|
+
summary: `Delete a ${this.getEntityClassName()} by id`,
|
|
2002
|
+
...extras
|
|
2003
|
+
}),
|
|
2004
|
+
(0, import_swagger6.ApiParam)({ name: "id", type: this.idType, required: true }),
|
|
2005
|
+
(0, import_swagger6.ApiOkResponse)({ type: import_nesties9.BlankReturnMessageDto }),
|
|
2006
|
+
(0, import_swagger6.ApiNotFoundResponse)({
|
|
2007
|
+
type: import_nesties9.BlankReturnMessageDto,
|
|
2008
|
+
description: `The ${this.getEntityClassName()} with the given id was not found`
|
|
2009
|
+
}),
|
|
2010
|
+
(0, import_swagger6.ApiInternalServerErrorResponse)({
|
|
2011
|
+
type: import_nesties9.BlankReturnMessageDto,
|
|
2012
|
+
description: "Internal error"
|
|
2013
|
+
})
|
|
2014
|
+
]);
|
|
2015
|
+
}
|
|
2016
|
+
import(extras = {}) {
|
|
2017
|
+
return (0, import_nesties9.MergeMethodDecorators)([
|
|
2018
|
+
(0, import_common3.Post)("import"),
|
|
2019
|
+
(0, import_common3.HttpCode)(200),
|
|
2020
|
+
(0, import_swagger6.ApiOperation)({
|
|
2021
|
+
summary: `Import ${this.getEntityClassName()}`,
|
|
2022
|
+
...extras
|
|
2023
|
+
}),
|
|
2024
|
+
(0, import_swagger6.ApiBody)({ type: this.importDto }),
|
|
2025
|
+
(0, import_swagger6.ApiOkResponse)({ type: this.importReturnMessageDto }),
|
|
2026
|
+
(0, import_swagger6.ApiInternalServerErrorResponse)({
|
|
2027
|
+
type: import_nesties9.BlankReturnMessageDto,
|
|
2028
|
+
description: "Internal error"
|
|
2029
|
+
})
|
|
2030
|
+
]);
|
|
2031
|
+
}
|
|
2032
|
+
baseController(routeOptions = {}) {
|
|
2033
|
+
const _this = this;
|
|
2034
|
+
const cl = class SpecificRestfulController extends BaseRestfulController {
|
|
2035
|
+
constructor(service) {
|
|
2036
|
+
super(service, {
|
|
2037
|
+
paginateType: routeOptions.paginateType || "offset",
|
|
2038
|
+
relations: _this.options.relations,
|
|
2039
|
+
entityClass: _this.entityClass
|
|
2040
|
+
});
|
|
2041
|
+
}
|
|
2042
|
+
};
|
|
2043
|
+
const anyTrueWritten = RestfulMethods.some(
|
|
2044
|
+
(m) => routeOptions?.routes?.[m]?.enabled === true
|
|
2045
|
+
);
|
|
2046
|
+
const validMethods = RestfulMethods.filter((m) => {
|
|
2047
|
+
const value = routeOptions?.routes?.[m]?.enabled;
|
|
2048
|
+
if (value === false) return false;
|
|
2049
|
+
if (value === true) return true;
|
|
2050
|
+
return !anyTrueWritten || value === true;
|
|
2051
|
+
});
|
|
2052
|
+
const useDecorators = {
|
|
2053
|
+
findOne: {
|
|
2054
|
+
paramTypes: [this.idType],
|
|
2055
|
+
paramDecorators: () => [this.idParam()],
|
|
2056
|
+
methodDecorators: () => [this.findOne()]
|
|
2057
|
+
},
|
|
2058
|
+
findAll: {
|
|
2059
|
+
paramTypes: [
|
|
2060
|
+
routeOptions.paginateType === "cursor" ? this.findAllCursorPaginatedDto : routeOptions.paginateType === "none" ? (0, import_swagger6.OmitType)(this.findAllDto, [
|
|
2061
|
+
"pageCount",
|
|
2062
|
+
"recordsPerPage"
|
|
2063
|
+
]) : this.findAllDto
|
|
2064
|
+
],
|
|
2065
|
+
paramDecorators: () => [this.findAllParam()],
|
|
2066
|
+
methodDecorators: () => [
|
|
2067
|
+
routeOptions.paginateType === "cursor" ? this.findAllCursorPaginated() : this.findAll()
|
|
2068
|
+
]
|
|
2069
|
+
},
|
|
2070
|
+
create: {
|
|
2071
|
+
paramTypes: [this.createDto],
|
|
2072
|
+
paramDecorators: () => [this.createParam()],
|
|
2073
|
+
methodDecorators: () => [this.create()]
|
|
2074
|
+
},
|
|
2075
|
+
update: {
|
|
2076
|
+
paramTypes: [this.idType, this.updateDto],
|
|
2077
|
+
paramDecorators: () => [this.idParam(), this.updateParam()],
|
|
2078
|
+
methodDecorators: () => [this.update()]
|
|
2079
|
+
},
|
|
2080
|
+
delete: {
|
|
2081
|
+
paramTypes: [this.idType],
|
|
2082
|
+
paramDecorators: () => [this.idParam()],
|
|
2083
|
+
methodDecorators: () => [this.delete()]
|
|
2084
|
+
},
|
|
2085
|
+
import: {
|
|
2086
|
+
paramTypes: [this.importDto],
|
|
2087
|
+
paramDecorators: () => [this.createParam()],
|
|
2088
|
+
methodDecorators: () => [this.import()]
|
|
2089
|
+
}
|
|
2090
|
+
};
|
|
2091
|
+
for (const method of validMethods) {
|
|
2092
|
+
const methodImpl = function namedMethodImpl(...args) {
|
|
2093
|
+
return BaseRestfulController.prototype[method].apply(this, args);
|
|
2094
|
+
};
|
|
2095
|
+
Object.defineProperty(methodImpl, "name", {
|
|
2096
|
+
value: method,
|
|
2097
|
+
configurable: true
|
|
2098
|
+
});
|
|
2099
|
+
cl.prototype[method] = methodImpl;
|
|
2100
|
+
const paramDecorators = useDecorators[method].paramDecorators();
|
|
2101
|
+
const paramTypes = useDecorators[method].paramTypes;
|
|
2102
|
+
const methodDecorators = [
|
|
2103
|
+
...useDecorators[method].methodDecorators(),
|
|
2104
|
+
...routeOptions?.routes?.[method]?.methodDecorators || [],
|
|
2105
|
+
...routeOptions?.globalMethodDecorators || []
|
|
2106
|
+
];
|
|
2107
|
+
paramDecorators.forEach((paramDecorator, index) => {
|
|
2108
|
+
paramDecorator(cl.prototype, method, index);
|
|
2109
|
+
});
|
|
2110
|
+
Reflect.defineMetadata(
|
|
2111
|
+
"design:paramtypes",
|
|
2112
|
+
paramTypes,
|
|
2113
|
+
cl.prototype,
|
|
2114
|
+
method
|
|
2115
|
+
);
|
|
2116
|
+
const baseDescriptor = Object.getOwnPropertyDescriptor(
|
|
2117
|
+
BaseRestfulController.prototype,
|
|
2118
|
+
method
|
|
2119
|
+
);
|
|
2120
|
+
if (baseDescriptor) {
|
|
2121
|
+
Reflect.defineMetadata(
|
|
2122
|
+
"design:type",
|
|
2123
|
+
baseDescriptor.value,
|
|
2124
|
+
cl.prototype,
|
|
2125
|
+
method
|
|
2126
|
+
);
|
|
2127
|
+
Reflect.defineMetadata(
|
|
2128
|
+
"design:returntype",
|
|
2129
|
+
Promise,
|
|
2130
|
+
cl.prototype,
|
|
2131
|
+
method
|
|
2132
|
+
);
|
|
2133
|
+
}
|
|
2134
|
+
methodDecorators.forEach((methodDecorator) => {
|
|
2135
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
2136
|
+
cl.prototype,
|
|
2137
|
+
method
|
|
2138
|
+
);
|
|
2139
|
+
methodDecorator(cl.prototype, method, descriptor);
|
|
2140
|
+
Object.defineProperty(cl.prototype, method, descriptor);
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
return RenameClass(cl, `${this.getEntityClassName()}Controller`);
|
|
2144
|
+
}
|
|
2145
|
+
crudService(options = {}) {
|
|
2146
|
+
return CrudService(this.entityClass, {
|
|
2147
|
+
relations: this.options.relations,
|
|
2148
|
+
...options
|
|
2149
|
+
});
|
|
2150
|
+
}
|
|
2151
|
+
};
|
|
2152
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2153
|
+
0 && (module.exports = {
|
|
2154
|
+
BlankCursorPaginationReturnMessageDto,
|
|
2155
|
+
BoolColumn,
|
|
2156
|
+
CreatePipe,
|
|
2157
|
+
CrudBase,
|
|
2158
|
+
CrudService,
|
|
2159
|
+
CursorPaginationDto,
|
|
2160
|
+
CursorPaginationReturnMessageDto,
|
|
2161
|
+
DateColumn,
|
|
2162
|
+
EnumColumn,
|
|
2163
|
+
FloatColumn,
|
|
2164
|
+
GenericCursorPaginationReturnMessageDto,
|
|
2165
|
+
GetPipe,
|
|
2166
|
+
IdBase,
|
|
2167
|
+
ImportDataBaseDto,
|
|
2168
|
+
ImportDataDto,
|
|
2169
|
+
ImportEntryBaseDto,
|
|
2170
|
+
ImportEntryDto,
|
|
2171
|
+
Inner,
|
|
2172
|
+
IntColumn,
|
|
2173
|
+
JsonColumn,
|
|
2174
|
+
NotChangeable,
|
|
2175
|
+
NotColumn,
|
|
2176
|
+
NotInResult,
|
|
2177
|
+
NotQueryable,
|
|
2178
|
+
NotWritable,
|
|
2179
|
+
PageSettingsDto,
|
|
2180
|
+
QueryColumn,
|
|
2181
|
+
QueryCondition,
|
|
2182
|
+
QueryEqual,
|
|
2183
|
+
QueryEqualZeroNullable,
|
|
2184
|
+
QueryFullText,
|
|
2185
|
+
QueryGreater,
|
|
2186
|
+
QueryGreaterEqual,
|
|
2187
|
+
QueryLess,
|
|
2188
|
+
QueryLessEqual,
|
|
2189
|
+
QueryLike,
|
|
2190
|
+
QueryMatchBoolean,
|
|
2191
|
+
QueryNotEqual,
|
|
2192
|
+
QueryOperator,
|
|
2193
|
+
QuerySearch,
|
|
2194
|
+
Relation,
|
|
2195
|
+
RelationComputed,
|
|
2196
|
+
RestfulFactory,
|
|
2197
|
+
StringColumn,
|
|
2198
|
+
StringIdBase,
|
|
2199
|
+
TimeBase,
|
|
2200
|
+
UpdatePipe,
|
|
2201
|
+
applyQueryMatchBoolean,
|
|
2202
|
+
applyQueryProperty,
|
|
2203
|
+
applyQueryPropertyLike,
|
|
2204
|
+
applyQueryPropertySearch,
|
|
2205
|
+
applyQueryPropertyZeroNullable,
|
|
2206
|
+
createQueryCondition,
|
|
2207
|
+
createQueryOperator,
|
|
2208
|
+
...require("nesties")
|
|
2209
|
+
});
|
|
2210
|
+
//# sourceMappingURL=index.cjs.map
|