@e22m4u/js-repository 0.8.4 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -49
- package/dist/cjs/index.cjs +762 -353
- package/eslint.config.js +1 -0
- package/package.json +14 -14
- package/src/adapter/adapter-loader.js +9 -4
- package/src/adapter/adapter-registry.js +3 -1
- package/src/adapter/builtin/memory-adapter.js +29 -13
- package/src/adapter/decorator/data-sanitizing-decorator.js +2 -1
- package/src/adapter/decorator/default-values-decorator.js +2 -1
- package/src/adapter/decorator/fields-filtering-decorator.js +14 -7
- package/src/adapter/decorator/inclusion-decorator.js +14 -7
- package/src/adapter/decorator/property-uniqueness-decorator.js +2 -1
- package/src/adapter/decorator/required-property-decorator.js +2 -1
- package/src/definition/datasource/datasource-definition-validator.js +6 -3
- package/src/definition/definition-registry.js +8 -4
- package/src/definition/model/model-data-sanitizer.js +4 -2
- package/src/definition/model/model-definition-utils.js +74 -35
- package/src/definition/model/model-definition-utils.spec.js +2 -6
- package/src/definition/model/model-definition-validator.js +10 -5
- package/src/definition/model/properties/primary-keys-definition-validator.js +4 -2
- package/src/definition/model/properties/properties-definition-validator.js +36 -18
- package/src/definition/model/properties/property-uniqueness-validator.js +30 -18
- package/src/definition/model/properties/property-uniqueness-validator.spec.js +734 -74
- package/src/definition/model/properties/required-property-validator.js +7 -12
- package/src/definition/model/properties/required-property-validator.spec.js +7 -46
- package/src/definition/model/relations/relations-definition-validator.js +70 -33
- package/src/filter/fields-clause-tool.js +31 -12
- package/src/filter/include-clause-tool.js +38 -15
- package/src/filter/operator-clause-tool.js +55 -23
- package/src/filter/order-clause-tool.js +36 -13
- package/src/filter/slice-clause-tool.js +16 -7
- package/src/filter/where-clause-tool.js +24 -10
- package/src/relations/belongs-to-resolver.js +44 -20
- package/src/relations/has-many-resolver.js +52 -25
- package/src/relations/has-one-resolver.js +58 -27
- package/src/relations/references-many-resolver.js +24 -11
- package/src/repository/repository-registry.js +3 -1
- package/src/repository/repository.js +2 -1
- package/src/utils/capitalize.js +3 -1
- package/src/utils/clone-deep.js +6 -2
- package/src/utils/exclude-object-keys.js +2 -1
- package/src/utils/get-value-by-path.js +6 -2
- package/src/utils/is-deep-equal.js +21 -7
- package/src/utils/is-promise.js +6 -2
- package/src/utils/model-name-to-model-key.js +2 -1
- package/src/utils/select-object-keys.js +9 -4
- package/src/utils/singularize.js +3 -1
|
@@ -19,39 +19,48 @@ export class FieldsClauseTool extends Service {
|
|
|
19
19
|
const isArray = Array.isArray(input);
|
|
20
20
|
let entities = isArray ? input : [input];
|
|
21
21
|
entities.forEach(entity => {
|
|
22
|
-
if (!entity || typeof entity !== 'object' || Array.isArray(entity))
|
|
22
|
+
if (!entity || typeof entity !== 'object' || Array.isArray(entity)) {
|
|
23
23
|
throw new InvalidArgumentError(
|
|
24
24
|
'The first argument of FieldsClauseTool.filter should be an Object or ' +
|
|
25
25
|
'an Array of Object, but %v was given.',
|
|
26
26
|
entity,
|
|
27
27
|
);
|
|
28
|
+
}
|
|
28
29
|
});
|
|
29
30
|
|
|
30
|
-
if (!modelName || typeof modelName !== 'string')
|
|
31
|
+
if (!modelName || typeof modelName !== 'string') {
|
|
31
32
|
throw new InvalidArgumentError(
|
|
32
33
|
'The second argument of FieldsClauseTool.filter should be ' +
|
|
33
34
|
'a non-empty String, but %v was given.',
|
|
34
35
|
modelName,
|
|
35
36
|
);
|
|
37
|
+
}
|
|
36
38
|
|
|
37
|
-
if (clause == null)
|
|
39
|
+
if (clause == null) {
|
|
40
|
+
return input;
|
|
41
|
+
}
|
|
38
42
|
const fields = Array.isArray(clause) ? clause.slice() : [clause];
|
|
39
|
-
if (!fields.length)
|
|
43
|
+
if (!fields.length) {
|
|
44
|
+
return input;
|
|
45
|
+
}
|
|
40
46
|
|
|
41
47
|
fields.forEach(field => {
|
|
42
|
-
if (!field || typeof field !== 'string')
|
|
48
|
+
if (!field || typeof field !== 'string') {
|
|
43
49
|
throw new InvalidArgumentError(
|
|
44
50
|
'The provided option "fields" should be a non-empty String ' +
|
|
45
51
|
'or an Array of non-empty String, but %v was given.',
|
|
46
52
|
field,
|
|
47
53
|
);
|
|
54
|
+
}
|
|
48
55
|
});
|
|
49
56
|
|
|
50
57
|
const pkPropName =
|
|
51
58
|
this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
|
|
52
59
|
modelName,
|
|
53
60
|
);
|
|
54
|
-
if (fields.indexOf(pkPropName) === -1)
|
|
61
|
+
if (fields.indexOf(pkPropName) === -1) {
|
|
62
|
+
fields.push(pkPropName);
|
|
63
|
+
}
|
|
55
64
|
|
|
56
65
|
entities = entities.map(entity => selectObjectKeys(entity, fields));
|
|
57
66
|
return isArray ? entities : entities[0];
|
|
@@ -63,16 +72,21 @@ export class FieldsClauseTool extends Service {
|
|
|
63
72
|
* @param {string|string[]|undefined} clause
|
|
64
73
|
*/
|
|
65
74
|
static validateFieldsClause(clause) {
|
|
66
|
-
if (clause == null)
|
|
75
|
+
if (clause == null) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
67
78
|
const fields = Array.isArray(clause) ? clause : [clause];
|
|
68
|
-
if (!fields.length)
|
|
79
|
+
if (!fields.length) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
69
82
|
fields.forEach(field => {
|
|
70
|
-
if (!field || typeof field !== 'string')
|
|
83
|
+
if (!field || typeof field !== 'string') {
|
|
71
84
|
throw new InvalidArgumentError(
|
|
72
85
|
'The provided option "fields" should be a non-empty String ' +
|
|
73
86
|
'or an Array of non-empty String, but %v was given.',
|
|
74
87
|
field,
|
|
75
88
|
);
|
|
89
|
+
}
|
|
76
90
|
});
|
|
77
91
|
}
|
|
78
92
|
|
|
@@ -83,16 +97,21 @@ export class FieldsClauseTool extends Service {
|
|
|
83
97
|
* @returns {string[]|undefined}
|
|
84
98
|
*/
|
|
85
99
|
static normalizeFieldsClause(clause) {
|
|
86
|
-
if (clause == null)
|
|
100
|
+
if (clause == null) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
87
103
|
const fields = Array.isArray(clause) ? clause : [clause];
|
|
88
|
-
if (!fields.length)
|
|
104
|
+
if (!fields.length) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
89
107
|
fields.forEach(field => {
|
|
90
|
-
if (!field || typeof field !== 'string')
|
|
108
|
+
if (!field || typeof field !== 'string') {
|
|
91
109
|
throw new InvalidArgumentError(
|
|
92
110
|
'The provided option "fields" should be a non-empty String ' +
|
|
93
111
|
'or an Array of non-empty String, but %v was given.',
|
|
94
112
|
field,
|
|
95
113
|
);
|
|
114
|
+
}
|
|
96
115
|
});
|
|
97
116
|
return fields;
|
|
98
117
|
}
|
|
@@ -178,8 +178,9 @@ export class IncludeClauseTool extends Service {
|
|
|
178
178
|
relNames.push(el);
|
|
179
179
|
} else if (typeof el === 'object') {
|
|
180
180
|
Object.keys(el).forEach(key => {
|
|
181
|
-
if (Object.prototype.hasOwnProperty.call(el, key))
|
|
181
|
+
if (Object.prototype.hasOwnProperty.call(el, key)) {
|
|
182
182
|
relNames.push(key);
|
|
183
|
+
}
|
|
183
184
|
});
|
|
184
185
|
}
|
|
185
186
|
});
|
|
@@ -187,26 +188,32 @@ export class IncludeClauseTool extends Service {
|
|
|
187
188
|
const duplicateNames = relNames.filter(
|
|
188
189
|
(name, i) => relNames.indexOf(name) !== i,
|
|
189
190
|
);
|
|
190
|
-
if (duplicateNames.length)
|
|
191
|
+
if (duplicateNames.length) {
|
|
191
192
|
throw new InvalidArgumentError(
|
|
192
193
|
'The provided option "include" has duplicates of %v.',
|
|
193
194
|
duplicateNames[0],
|
|
194
195
|
);
|
|
196
|
+
}
|
|
195
197
|
} else if (typeof clause === 'object') {
|
|
196
198
|
// validate object
|
|
197
199
|
if ('relation' in clause) {
|
|
198
200
|
// {relation: 'name', scope: {}}
|
|
199
|
-
if (!clause.relation || typeof clause.relation !== 'string')
|
|
201
|
+
if (!clause.relation || typeof clause.relation !== 'string') {
|
|
200
202
|
throw new InvalidArgumentError(
|
|
201
203
|
'The provided option "relation" should be ' +
|
|
202
204
|
'a non-empty String, but %v was given.',
|
|
203
205
|
clause.relation,
|
|
204
206
|
);
|
|
205
|
-
|
|
207
|
+
}
|
|
208
|
+
if ('scope' in clause && clause) {
|
|
209
|
+
this.validateScopeClause(clause.scope);
|
|
210
|
+
}
|
|
206
211
|
} else {
|
|
207
212
|
// {foo: 'bar', 'baz': ['qux'], ...}
|
|
208
213
|
Object.keys(clause).forEach(key => {
|
|
209
|
-
if (!Object.prototype.hasOwnProperty.call(clause, key))
|
|
214
|
+
if (!Object.prototype.hasOwnProperty.call(clause, key)) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
210
217
|
this.validateIncludeClause(key);
|
|
211
218
|
this.validateIncludeClause(clause[key]);
|
|
212
219
|
});
|
|
@@ -227,12 +234,15 @@ export class IncludeClauseTool extends Service {
|
|
|
227
234
|
* @param {object|undefined} clause
|
|
228
235
|
*/
|
|
229
236
|
static validateScopeClause(clause) {
|
|
230
|
-
if (clause == null)
|
|
231
|
-
|
|
237
|
+
if (clause == null) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (typeof clause !== 'object' || Array.isArray(clause)) {
|
|
232
241
|
throw new InvalidArgumentError(
|
|
233
242
|
'The provided option "scope" should be an Object, but %v was given.',
|
|
234
243
|
clause,
|
|
235
244
|
);
|
|
245
|
+
}
|
|
236
246
|
// {where: ...}
|
|
237
247
|
if (clause.where != null) {
|
|
238
248
|
WhereClauseTool.validateWhereClause(clause.where);
|
|
@@ -284,33 +294,41 @@ export class IncludeClauseTool extends Service {
|
|
|
284
294
|
const duplicateNames = relNames.filter(
|
|
285
295
|
(name, i) => relNames.indexOf(name) !== i,
|
|
286
296
|
);
|
|
287
|
-
if (duplicateNames.length)
|
|
297
|
+
if (duplicateNames.length) {
|
|
288
298
|
throw new InvalidArgumentError(
|
|
289
299
|
'The provided option "include" has duplicates of %v.',
|
|
290
300
|
duplicateNames[0],
|
|
291
301
|
);
|
|
302
|
+
}
|
|
292
303
|
} else if (typeof clause === 'object') {
|
|
293
304
|
// normalize object
|
|
294
305
|
if ('relation' in clause) {
|
|
295
306
|
// {relation: 'name', scope: {...}}
|
|
296
|
-
if (!clause.relation || typeof clause.relation !== 'string')
|
|
307
|
+
if (!clause.relation || typeof clause.relation !== 'string') {
|
|
297
308
|
throw new InvalidArgumentError(
|
|
298
309
|
'The provided option "relation" should be ' +
|
|
299
310
|
'a non-empty String, but %v was given.',
|
|
300
311
|
clause.relation,
|
|
301
312
|
);
|
|
313
|
+
}
|
|
302
314
|
const normalized = {relation: clause.relation};
|
|
303
315
|
const scope = this.normalizeScopeClause(clause.scope);
|
|
304
|
-
if (scope)
|
|
316
|
+
if (scope) {
|
|
317
|
+
normalized.scope = scope;
|
|
318
|
+
}
|
|
305
319
|
result.push(normalized);
|
|
306
320
|
} else {
|
|
307
321
|
// {foo: 'bar', baz: ['qux'], ...}
|
|
308
322
|
Object.keys(clause).forEach(key => {
|
|
309
|
-
if (!Object.prototype.hasOwnProperty.call(clause, key))
|
|
323
|
+
if (!Object.prototype.hasOwnProperty.call(clause, key)) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
310
326
|
this.validateIncludeClause(key);
|
|
311
327
|
const normalized = {relation: key};
|
|
312
328
|
const include = this.normalizeIncludeClause(clause[key]);
|
|
313
|
-
if (include.length)
|
|
329
|
+
if (include.length) {
|
|
330
|
+
normalized.scope = {include};
|
|
331
|
+
}
|
|
314
332
|
result.push(normalized);
|
|
315
333
|
});
|
|
316
334
|
}
|
|
@@ -332,12 +350,15 @@ export class IncludeClauseTool extends Service {
|
|
|
332
350
|
* @returns {object|undefined}
|
|
333
351
|
*/
|
|
334
352
|
static normalizeScopeClause(clause) {
|
|
335
|
-
if (clause == null)
|
|
336
|
-
|
|
353
|
+
if (clause == null) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (typeof clause !== 'object' || Array.isArray(clause)) {
|
|
337
357
|
throw new InvalidArgumentError(
|
|
338
358
|
'The provided option "scope" should be an Object, but %v was given.',
|
|
339
359
|
clause,
|
|
340
360
|
);
|
|
361
|
+
}
|
|
341
362
|
const result = {};
|
|
342
363
|
// {where: ...}
|
|
343
364
|
if (clause.where != null) {
|
|
@@ -368,7 +389,9 @@ export class IncludeClauseTool extends Service {
|
|
|
368
389
|
if (clause.include != null) {
|
|
369
390
|
result.include = this.normalizeIncludeClause(clause.include);
|
|
370
391
|
}
|
|
371
|
-
if (Object.keys(result).length)
|
|
392
|
+
if (Object.keys(result).length) {
|
|
393
|
+
return result;
|
|
394
|
+
}
|
|
372
395
|
return undefined;
|
|
373
396
|
}
|
|
374
397
|
}
|
|
@@ -47,8 +47,12 @@ export class OperatorClauseTool extends Service {
|
|
|
47
47
|
}
|
|
48
48
|
// лексикографическое сравнение
|
|
49
49
|
if (type1 === 'string' && type2 === 'string') {
|
|
50
|
-
if (val1 > val2)
|
|
51
|
-
|
|
50
|
+
if (val1 > val2) {
|
|
51
|
+
return 1;
|
|
52
|
+
}
|
|
53
|
+
if (val1 < val2) {
|
|
54
|
+
return -1;
|
|
55
|
+
}
|
|
52
56
|
return 0;
|
|
53
57
|
}
|
|
54
58
|
return NaN;
|
|
@@ -62,12 +66,13 @@ export class OperatorClauseTool extends Service {
|
|
|
62
66
|
* @returns {boolean|undefined}
|
|
63
67
|
*/
|
|
64
68
|
testAll(clause, value) {
|
|
65
|
-
if (!clause || typeof clause !== 'object' || Array.isArray(clause))
|
|
69
|
+
if (!clause || typeof clause !== 'object' || Array.isArray(clause)) {
|
|
66
70
|
throw new InvalidArgumentError(
|
|
67
71
|
'The first argument of OperatorUtils.testAll ' +
|
|
68
72
|
'should be an Object, but %v was given.',
|
|
69
73
|
clause,
|
|
70
74
|
);
|
|
75
|
+
}
|
|
71
76
|
const operatorMap = {
|
|
72
77
|
eq: this.testEqNeq,
|
|
73
78
|
neq: this.testEqNeq,
|
|
@@ -130,14 +135,19 @@ export class OperatorClauseTool extends Service {
|
|
|
130
135
|
* @returns {boolean|undefined}
|
|
131
136
|
*/
|
|
132
137
|
testEqNeq(clause, value) {
|
|
133
|
-
if (!clause || typeof clause !== 'object')
|
|
138
|
+
if (!clause || typeof clause !== 'object') {
|
|
134
139
|
throw new InvalidArgumentError(
|
|
135
140
|
'The first argument of OperatorUtils.testEqNeq ' +
|
|
136
141
|
'should be an Object, but %v was given.',
|
|
137
142
|
clause,
|
|
138
143
|
);
|
|
139
|
-
|
|
140
|
-
if ('
|
|
144
|
+
}
|
|
145
|
+
if ('eq' in clause) {
|
|
146
|
+
return this.compare(clause.eq, value, true) === 0;
|
|
147
|
+
}
|
|
148
|
+
if ('neq' in clause) {
|
|
149
|
+
return this.compare(clause.neq, value, true) !== 0;
|
|
150
|
+
}
|
|
141
151
|
}
|
|
142
152
|
|
|
143
153
|
/**
|
|
@@ -176,16 +186,25 @@ export class OperatorClauseTool extends Service {
|
|
|
176
186
|
* @returns {boolean|undefined}
|
|
177
187
|
*/
|
|
178
188
|
testGtLt(clause, value) {
|
|
179
|
-
if (!clause || typeof clause !== 'object')
|
|
189
|
+
if (!clause || typeof clause !== 'object') {
|
|
180
190
|
throw new InvalidArgumentError(
|
|
181
191
|
'The first argument of OperatorUtils.testGtLt ' +
|
|
182
192
|
'should be an Object, but %v was given.',
|
|
183
193
|
clause,
|
|
184
194
|
);
|
|
185
|
-
|
|
186
|
-
if ('
|
|
187
|
-
|
|
188
|
-
|
|
195
|
+
}
|
|
196
|
+
if ('gt' in clause) {
|
|
197
|
+
return this.compare(value, clause.gt) > 0;
|
|
198
|
+
}
|
|
199
|
+
if ('gte' in clause) {
|
|
200
|
+
return this.compare(value, clause.gte) >= 0;
|
|
201
|
+
}
|
|
202
|
+
if ('lt' in clause) {
|
|
203
|
+
return this.compare(value, clause.lt) < 0;
|
|
204
|
+
}
|
|
205
|
+
if ('lte' in clause) {
|
|
206
|
+
return this.compare(value, clause.lte) <= 0;
|
|
207
|
+
}
|
|
189
208
|
}
|
|
190
209
|
|
|
191
210
|
/**
|
|
@@ -203,12 +222,13 @@ export class OperatorClauseTool extends Service {
|
|
|
203
222
|
* @returns {boolean|undefined}
|
|
204
223
|
*/
|
|
205
224
|
testInq(clause, value) {
|
|
206
|
-
if (!clause || typeof clause !== 'object')
|
|
225
|
+
if (!clause || typeof clause !== 'object') {
|
|
207
226
|
throw new InvalidArgumentError(
|
|
208
227
|
'The first argument of OperatorUtils.testInq ' +
|
|
209
228
|
'should be an Object, but %v was given.',
|
|
210
229
|
clause,
|
|
211
230
|
);
|
|
231
|
+
}
|
|
212
232
|
if ('inq' in clause && clause.inq !== undefined) {
|
|
213
233
|
if (!clause.inq || !Array.isArray(clause.inq)) {
|
|
214
234
|
throw new InvalidOperatorValueError(
|
|
@@ -241,12 +261,13 @@ export class OperatorClauseTool extends Service {
|
|
|
241
261
|
* @returns {boolean|undefined}
|
|
242
262
|
*/
|
|
243
263
|
testNin(clause, value) {
|
|
244
|
-
if (!clause || typeof clause !== 'object')
|
|
264
|
+
if (!clause || typeof clause !== 'object') {
|
|
245
265
|
throw new InvalidArgumentError(
|
|
246
266
|
'The first argument of OperatorUtils.testNin ' +
|
|
247
267
|
'should be an Object, but %v was given.',
|
|
248
268
|
clause,
|
|
249
269
|
);
|
|
270
|
+
}
|
|
250
271
|
if ('nin' in clause && clause.nin !== undefined) {
|
|
251
272
|
if (!clause.nin || !Array.isArray(clause.nin)) {
|
|
252
273
|
throw new InvalidOperatorValueError(
|
|
@@ -276,12 +297,13 @@ export class OperatorClauseTool extends Service {
|
|
|
276
297
|
* @returns {boolean|undefined}
|
|
277
298
|
*/
|
|
278
299
|
testBetween(clause, value) {
|
|
279
|
-
if (!clause || typeof clause !== 'object')
|
|
300
|
+
if (!clause || typeof clause !== 'object') {
|
|
280
301
|
throw new InvalidArgumentError(
|
|
281
302
|
'The first argument of OperatorUtils.testBetween ' +
|
|
282
303
|
'should be an Object, but %v was given.',
|
|
283
304
|
clause,
|
|
284
305
|
);
|
|
306
|
+
}
|
|
285
307
|
if ('between' in clause && clause.between !== undefined) {
|
|
286
308
|
if (!Array.isArray(clause.between) || clause.between.length !== 2) {
|
|
287
309
|
throw new InvalidOperatorValueError(
|
|
@@ -312,12 +334,13 @@ export class OperatorClauseTool extends Service {
|
|
|
312
334
|
* @returns {boolean|undefined}
|
|
313
335
|
*/
|
|
314
336
|
testExists(clause, value) {
|
|
315
|
-
if (!clause || typeof clause !== 'object')
|
|
337
|
+
if (!clause || typeof clause !== 'object') {
|
|
316
338
|
throw new InvalidArgumentError(
|
|
317
339
|
'The first argument of OperatorUtils.testExists ' +
|
|
318
340
|
'should be an Object, but %v was given.',
|
|
319
341
|
clause,
|
|
320
342
|
);
|
|
343
|
+
}
|
|
321
344
|
if ('exists' in clause && clause.exists !== undefined) {
|
|
322
345
|
if (typeof clause.exists !== 'boolean') {
|
|
323
346
|
throw new InvalidOperatorValueError(
|
|
@@ -345,15 +368,17 @@ export class OperatorClauseTool extends Service {
|
|
|
345
368
|
* @returns {boolean|undefined}
|
|
346
369
|
*/
|
|
347
370
|
testLike(clause, value) {
|
|
348
|
-
if (!clause || typeof clause !== 'object' || Array.isArray(clause))
|
|
371
|
+
if (!clause || typeof clause !== 'object' || Array.isArray(clause)) {
|
|
349
372
|
throw new InvalidArgumentError(
|
|
350
373
|
'The first argument of OperatorUtils.testLike ' +
|
|
351
374
|
'should be an Object, but %v was given.',
|
|
352
375
|
clause,
|
|
353
376
|
);
|
|
377
|
+
}
|
|
354
378
|
if ('like' in clause && clause.like !== undefined) {
|
|
355
|
-
if (typeof clause.like !== 'string')
|
|
379
|
+
if (typeof clause.like !== 'string') {
|
|
356
380
|
throw new InvalidOperatorValueError('like', 'a String', clause.like);
|
|
381
|
+
}
|
|
357
382
|
return likeToRegexp(clause.like).test(value);
|
|
358
383
|
}
|
|
359
384
|
}
|
|
@@ -373,12 +398,13 @@ export class OperatorClauseTool extends Service {
|
|
|
373
398
|
* @returns {boolean|undefined}
|
|
374
399
|
*/
|
|
375
400
|
testNlike(clause, value) {
|
|
376
|
-
if (!clause || typeof clause !== 'object' || Array.isArray(clause))
|
|
401
|
+
if (!clause || typeof clause !== 'object' || Array.isArray(clause)) {
|
|
377
402
|
throw new InvalidArgumentError(
|
|
378
403
|
'The first argument of OperatorUtils.testNlike ' +
|
|
379
404
|
'should be an Object, but %v was given.',
|
|
380
405
|
clause,
|
|
381
406
|
);
|
|
407
|
+
}
|
|
382
408
|
if ('nlike' in clause && clause.nlike !== undefined) {
|
|
383
409
|
if (typeof clause.nlike !== 'string') {
|
|
384
410
|
throw new InvalidOperatorValueError('nlike', 'a String', clause.nlike);
|
|
@@ -402,12 +428,13 @@ export class OperatorClauseTool extends Service {
|
|
|
402
428
|
* @returns {boolean|undefined}
|
|
403
429
|
*/
|
|
404
430
|
testIlike(clause, value) {
|
|
405
|
-
if (!clause || typeof clause !== 'object' || Array.isArray(clause))
|
|
431
|
+
if (!clause || typeof clause !== 'object' || Array.isArray(clause)) {
|
|
406
432
|
throw new InvalidArgumentError(
|
|
407
433
|
'The first argument of OperatorUtils.testIlike ' +
|
|
408
434
|
'should be an Object, but %v was given.',
|
|
409
435
|
clause,
|
|
410
436
|
);
|
|
437
|
+
}
|
|
411
438
|
if ('ilike' in clause && clause.ilike !== undefined) {
|
|
412
439
|
if (typeof clause.ilike !== 'string') {
|
|
413
440
|
throw new InvalidOperatorValueError('ilike', 'a String', clause.ilike);
|
|
@@ -431,12 +458,13 @@ export class OperatorClauseTool extends Service {
|
|
|
431
458
|
* @returns {boolean|undefined}
|
|
432
459
|
*/
|
|
433
460
|
testNilike(clause, value) {
|
|
434
|
-
if (!clause || typeof clause !== 'object' || Array.isArray(clause))
|
|
461
|
+
if (!clause || typeof clause !== 'object' || Array.isArray(clause)) {
|
|
435
462
|
throw new InvalidArgumentError(
|
|
436
463
|
'The first argument of OperatorUtils.testNilike ' +
|
|
437
464
|
'should be an Object, but %v was given.',
|
|
438
465
|
clause,
|
|
439
466
|
);
|
|
467
|
+
}
|
|
440
468
|
if ('nilike' in clause && clause.nilike !== undefined) {
|
|
441
469
|
if (typeof clause.nilike !== 'string') {
|
|
442
470
|
throw new InvalidOperatorValueError(
|
|
@@ -472,12 +500,13 @@ export class OperatorClauseTool extends Service {
|
|
|
472
500
|
* @returns {boolean|undefined}
|
|
473
501
|
*/
|
|
474
502
|
testRegexp(clause, value) {
|
|
475
|
-
if (!clause || typeof clause !== 'object')
|
|
503
|
+
if (!clause || typeof clause !== 'object') {
|
|
476
504
|
throw new InvalidArgumentError(
|
|
477
505
|
'The first argument of OperatorUtils.testRegexp ' +
|
|
478
506
|
'should be an Object, but %v was given.',
|
|
479
507
|
clause,
|
|
480
508
|
);
|
|
509
|
+
}
|
|
481
510
|
if ('regexp' in clause && clause.regexp !== undefined) {
|
|
482
511
|
if (
|
|
483
512
|
typeof clause.regexp !== 'string' &&
|
|
@@ -490,12 +519,15 @@ export class OperatorClauseTool extends Service {
|
|
|
490
519
|
);
|
|
491
520
|
}
|
|
492
521
|
const flags = clause.flags || undefined;
|
|
493
|
-
if (flags && typeof flags !== 'string')
|
|
522
|
+
if (flags && typeof flags !== 'string') {
|
|
494
523
|
throw new InvalidArgumentError(
|
|
495
524
|
'RegExp flags should be a String, but %v was given.',
|
|
496
525
|
clause.flags,
|
|
497
526
|
);
|
|
498
|
-
|
|
527
|
+
}
|
|
528
|
+
if (!value || typeof value !== 'string') {
|
|
529
|
+
return false;
|
|
530
|
+
}
|
|
499
531
|
const regExp = stringToRegexp(clause.regexp, flags);
|
|
500
532
|
return !!value.match(regExp);
|
|
501
533
|
}
|
|
@@ -13,22 +13,31 @@ export class OrderClauseTool extends Service {
|
|
|
13
13
|
* @param {string|string[]|undefined} clause
|
|
14
14
|
*/
|
|
15
15
|
sort(entities, clause) {
|
|
16
|
-
if (clause == null)
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
if (clause == null) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(clause) === false) {
|
|
20
|
+
clause = [clause];
|
|
21
|
+
}
|
|
22
|
+
if (!clause.length) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
19
25
|
const mapping = [];
|
|
20
26
|
clause.forEach((key, index) => {
|
|
21
|
-
if (!key || typeof key !== 'string')
|
|
27
|
+
if (!key || typeof key !== 'string') {
|
|
22
28
|
throw new InvalidArgumentError(
|
|
23
29
|
'The provided option "order" should be a non-empty String ' +
|
|
24
30
|
'or an Array of non-empty String, but %v was given.',
|
|
25
31
|
key,
|
|
26
32
|
);
|
|
33
|
+
}
|
|
27
34
|
let reverse = 1;
|
|
28
35
|
const matches = key.match(/\s+(A|DE)SC$/i);
|
|
29
36
|
if (matches) {
|
|
30
37
|
key = key.replace(/\s+(A|DE)SC/i, '');
|
|
31
|
-
if (matches[1].toLowerCase() === 'de')
|
|
38
|
+
if (matches[1].toLowerCase() === 'de') {
|
|
39
|
+
reverse = -1;
|
|
40
|
+
}
|
|
32
41
|
}
|
|
33
42
|
mapping[index] = {key: key, reverse};
|
|
34
43
|
});
|
|
@@ -41,16 +50,23 @@ export class OrderClauseTool extends Service {
|
|
|
41
50
|
* @param {string|string[]|undefined} clause
|
|
42
51
|
*/
|
|
43
52
|
static validateOrderClause(clause) {
|
|
44
|
-
if (clause == null)
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
if (clause == null) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(clause) === false) {
|
|
57
|
+
clause = [clause];
|
|
58
|
+
}
|
|
59
|
+
if (!clause.length) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
47
62
|
clause.forEach(field => {
|
|
48
|
-
if (!field || typeof field !== 'string')
|
|
63
|
+
if (!field || typeof field !== 'string') {
|
|
49
64
|
throw new InvalidArgumentError(
|
|
50
65
|
'The provided option "order" should be a non-empty String ' +
|
|
51
66
|
'or an Array of non-empty String, but %v was given.',
|
|
52
67
|
field,
|
|
53
68
|
);
|
|
69
|
+
}
|
|
54
70
|
});
|
|
55
71
|
}
|
|
56
72
|
|
|
@@ -61,16 +77,23 @@ export class OrderClauseTool extends Service {
|
|
|
61
77
|
* @returns {string[]|undefined}
|
|
62
78
|
*/
|
|
63
79
|
static normalizeOrderClause(clause) {
|
|
64
|
-
if (clause == null)
|
|
65
|
-
|
|
66
|
-
|
|
80
|
+
if (clause == null) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (Array.isArray(clause) === false) {
|
|
84
|
+
clause = [clause];
|
|
85
|
+
}
|
|
86
|
+
if (!clause.length) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
67
89
|
clause.forEach(field => {
|
|
68
|
-
if (!field || typeof field !== 'string')
|
|
90
|
+
if (!field || typeof field !== 'string') {
|
|
69
91
|
throw new InvalidArgumentError(
|
|
70
92
|
'The provided option "order" should be a non-empty String ' +
|
|
71
93
|
'or an Array of non-empty String, but %v was given.',
|
|
72
94
|
field,
|
|
73
95
|
);
|
|
96
|
+
}
|
|
74
97
|
});
|
|
75
98
|
return clause;
|
|
76
99
|
}
|
|
@@ -14,22 +14,25 @@ export class SliceClauseTool extends Service {
|
|
|
14
14
|
* @returns {object[]}
|
|
15
15
|
*/
|
|
16
16
|
slice(entities, skip = undefined, limit = undefined) {
|
|
17
|
-
if (!Array.isArray(entities))
|
|
17
|
+
if (!Array.isArray(entities)) {
|
|
18
18
|
throw new InvalidArgumentError(
|
|
19
19
|
'The first argument of SliceClauseTool.slice ' +
|
|
20
20
|
'should be an Array, but %v was given.',
|
|
21
21
|
entities,
|
|
22
22
|
);
|
|
23
|
-
|
|
23
|
+
}
|
|
24
|
+
if (skip != null && typeof skip !== 'number') {
|
|
24
25
|
throw new InvalidArgumentError(
|
|
25
26
|
'The provided option "skip" should be a Number, but %v was given.',
|
|
26
27
|
skip,
|
|
27
28
|
);
|
|
28
|
-
|
|
29
|
+
}
|
|
30
|
+
if (limit != null && typeof limit !== 'number') {
|
|
29
31
|
throw new InvalidArgumentError(
|
|
30
32
|
'The provided option "limit" should be a Number, but %v was given.',
|
|
31
33
|
limit,
|
|
32
34
|
);
|
|
35
|
+
}
|
|
33
36
|
skip = skip || 0;
|
|
34
37
|
limit = limit || entities.length;
|
|
35
38
|
return entities.slice(skip, skip + limit);
|
|
@@ -41,12 +44,15 @@ export class SliceClauseTool extends Service {
|
|
|
41
44
|
* @param {number|undefined} skip
|
|
42
45
|
*/
|
|
43
46
|
static validateSkipClause(skip) {
|
|
44
|
-
if (skip == null)
|
|
45
|
-
|
|
47
|
+
if (skip == null) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (typeof skip !== 'number') {
|
|
46
51
|
throw new InvalidArgumentError(
|
|
47
52
|
'The provided option "skip" should be a Number, but %v was given.',
|
|
48
53
|
skip,
|
|
49
54
|
);
|
|
55
|
+
}
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
/**
|
|
@@ -55,11 +61,14 @@ export class SliceClauseTool extends Service {
|
|
|
55
61
|
* @param {number|undefined} limit
|
|
56
62
|
*/
|
|
57
63
|
static validateLimitClause(limit) {
|
|
58
|
-
if (limit == null)
|
|
59
|
-
|
|
64
|
+
if (limit == null) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (typeof limit !== 'number') {
|
|
60
68
|
throw new InvalidArgumentError(
|
|
61
69
|
'The provided option "limit" should be a Number, but %v was given.',
|
|
62
70
|
limit,
|
|
63
71
|
);
|
|
72
|
+
}
|
|
64
73
|
}
|
|
65
74
|
}
|