@e22m4u/js-repository 0.0.34 → 0.0.35

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e22m4u/js-repository",
3
- "version": "0.0.34",
3
+ "version": "0.0.35",
4
4
  "description": "Абстракция для работы с базами данных для Node.js",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -15,7 +15,7 @@ export class DataSanitizingDecorator extends Service {
15
15
  decorate(adapter) {
16
16
  if (!adapter || !(adapter instanceof Adapter))
17
17
  throw new InvalidArgumentError(
18
- 'A first argument of DataSanitizingDecorator.decorate should be ' +
18
+ 'The first argument of DataSanitizingDecorator.decorate should be ' +
19
19
  'an Adapter instance, but %v given.',
20
20
  adapter,
21
21
  );
@@ -15,7 +15,7 @@ export class DataValidationDecorator extends Service {
15
15
  decorate(adapter) {
16
16
  if (!adapter || !(adapter instanceof Adapter))
17
17
  throw new InvalidArgumentError(
18
- 'A first argument of DataValidationDecorator.decorate should be ' +
18
+ 'The first argument of DataValidationDecorator.decorate should be ' +
19
19
  'an Adapter instance, but %v given.',
20
20
  adapter,
21
21
  );
@@ -15,7 +15,7 @@ export class DefaultValuesDecorator extends Service {
15
15
  decorate(adapter) {
16
16
  if (!adapter || !(adapter instanceof Adapter))
17
17
  throw new InvalidArgumentError(
18
- 'A first argument of DefaultValuesDecorator.decorate should be ' +
18
+ 'The first argument of DefaultValuesDecorator.decorate should be ' +
19
19
  'an Adapter instance, but %v given.',
20
20
  adapter,
21
21
  );
@@ -15,7 +15,7 @@ export class FieldsFilteringDecorator extends Service {
15
15
  decorate(adapter) {
16
16
  if (!adapter || !(adapter instanceof Adapter))
17
17
  throw new InvalidArgumentError(
18
- 'A first argument of FieldsFilteringDecorator.decorate should be ' +
18
+ 'The first argument of FieldsFilteringDecorator.decorate should be ' +
19
19
  'an Adapter instance, but %v given.',
20
20
  adapter,
21
21
  );
@@ -15,7 +15,7 @@ export class InclusionDecorator extends Service {
15
15
  decorate(adapter) {
16
16
  if (!adapter || !(adapter instanceof Adapter))
17
17
  throw new InvalidArgumentError(
18
- 'A first argument of InclusionDecorator.decorate should be ' +
18
+ 'The first argument of InclusionDecorator.decorate should be ' +
19
19
  'an Adapter instance, but %v given.',
20
20
  adapter,
21
21
  );
@@ -15,7 +15,7 @@ export class DefaultValuesDefinitionValidator extends Service {
15
15
  validate(modelName, propDefs) {
16
16
  if (!modelName || typeof modelName !== 'string')
17
17
  throw new InvalidArgumentError(
18
- 'A first argument of DefaultValuesDefinitionValidator.validate ' +
18
+ 'The first argument of DefaultValuesDefinitionValidator.validate ' +
19
19
  'should be a non-empty String, but %v given.',
20
20
  modelName,
21
21
  );
@@ -11,7 +11,7 @@ describe('DefaultValuesDefinitionValidator', function () {
11
11
  const validate = v => () => S.validate(v, {});
12
12
  const error = v =>
13
13
  format(
14
- 'A first argument of DefaultValuesDefinitionValidator.validate ' +
14
+ 'The first argument of DefaultValuesDefinitionValidator.validate ' +
15
15
  'should be a non-empty String, but %s given.',
16
16
  v,
17
17
  );
@@ -17,7 +17,7 @@ export class PropertiesDefinitionValidator extends Service {
17
17
  validate(modelName, propDefs) {
18
18
  if (!modelName || typeof modelName !== 'string')
19
19
  throw new InvalidArgumentError(
20
- 'A first argument of PropertiesDefinitionValidator.validate ' +
20
+ 'The first argument of PropertiesDefinitionValidator.validate ' +
21
21
  'should be a non-empty String, but %v given.',
22
22
  modelName,
23
23
  );
@@ -54,7 +54,7 @@ export class PropertiesDefinitionValidator extends Service {
54
54
  _validateProperty(modelName, propName, propDef) {
55
55
  if (!modelName || typeof modelName !== 'string')
56
56
  throw new InvalidArgumentError(
57
- 'A first argument of PropertiesDefinitionValidator._validateProperty ' +
57
+ 'The first argument of PropertiesDefinitionValidator._validateProperty ' +
58
58
  'should be a non-empty String, but %v given.',
59
59
  modelName,
60
60
  );
@@ -19,7 +19,7 @@ describe('PropertiesDefinitionValidator', function () {
19
19
  const validate = v => () => S.validate(v, {});
20
20
  const error = v =>
21
21
  format(
22
- 'A first argument of PropertiesDefinitionValidator.validate ' +
22
+ 'The first argument of PropertiesDefinitionValidator.validate ' +
23
23
  'should be a non-empty String, but %s given.',
24
24
  v,
25
25
  );
@@ -16,7 +16,7 @@ export class RelationsDefinitionValidator extends Service {
16
16
  validate(modelName, relDefs) {
17
17
  if (!modelName || typeof modelName !== 'string')
18
18
  throw new InvalidArgumentError(
19
- 'A first argument of RelationsDefinitionValidator.validate ' +
19
+ 'The first argument of RelationsDefinitionValidator.validate ' +
20
20
  'should be a non-empty String, but %v given.',
21
21
  modelName,
22
22
  );
@@ -44,7 +44,7 @@ export class RelationsDefinitionValidator extends Service {
44
44
  _validateRelation(modelName, relName, relDef) {
45
45
  if (!modelName || typeof modelName !== 'string')
46
46
  throw new InvalidArgumentError(
47
- 'A first argument of RelationsDefinitionValidator._validateRelation ' +
47
+ 'The first argument of RelationsDefinitionValidator._validateRelation ' +
48
48
  'should be a non-empty String, but %v given.',
49
49
  modelName,
50
50
  );
@@ -11,7 +11,7 @@ describe('RelationsDefinitionValidator', function () {
11
11
  const validate = v => () => S.validate(v, {});
12
12
  const error = v =>
13
13
  format(
14
- 'A first argument of RelationsDefinitionValidator.validate ' +
14
+ 'The first argument of RelationsDefinitionValidator.validate ' +
15
15
  'should be a non-empty String, but %s given.',
16
16
  v,
17
17
  );
@@ -163,14 +163,14 @@ export class IncludeClauseTool extends Service {
163
163
  * @param {IncludeClause|undefined} clause
164
164
  */
165
165
  static validateIncludeClause(clause) {
166
- if (!clause) {
167
- // empty
168
- } else if (typeof clause === 'string') {
169
- // string
166
+ if (clause == null) {
167
+ // allows undefined and null
168
+ } else if (clause && typeof clause === 'string') {
169
+ // allows non-empty string
170
170
  } else if (Array.isArray(clause)) {
171
- // array
171
+ // validate array
172
172
  const relNames = [];
173
- clause.flat().forEach(el => {
173
+ clause.flat(Infinity).forEach(el => {
174
174
  this.validateIncludeClause(el);
175
175
  if (typeof el === 'string') {
176
176
  relNames.push(el);
@@ -191,7 +191,7 @@ export class IncludeClauseTool extends Service {
191
191
  duplicateNames[0],
192
192
  );
193
193
  } else if (typeof clause === 'object') {
194
- // object
194
+ // validate object
195
195
  if ('relation' in clause) {
196
196
  // {relation: 'name', scope: {}}
197
197
  if (!clause.relation || typeof clause.relation !== 'string')
@@ -205,14 +205,15 @@ export class IncludeClauseTool extends Service {
205
205
  // {foo: 'bar', 'baz': ['qux'], ...}
206
206
  Object.keys(clause).forEach(key => {
207
207
  if (!Object.prototype.hasOwnProperty.call(clause, key)) return;
208
+ this.validateIncludeClause(key);
208
209
  this.validateIncludeClause(clause[key]);
209
210
  });
210
211
  }
211
212
  } else {
212
- // unknown.
213
+ // unsupported
213
214
  throw new InvalidArgumentError(
214
- 'The provided option "include" should have a value of ' +
215
- 'following types: String, Object or Array, but %v given.',
215
+ 'The provided option "include" should have a non-empty String, ' +
216
+ 'an Object or an Array, but %v given.',
216
217
  clause,
217
218
  );
218
219
  }
@@ -224,24 +225,36 @@ export class IncludeClauseTool extends Service {
224
225
  * @param {object|undefined} clause
225
226
  */
226
227
  static validateScopeClause(clause) {
227
- if (!clause) return;
228
+ if (clause == null) return;
228
229
  if (typeof clause !== 'object' || Array.isArray(clause))
229
230
  throw new InvalidArgumentError(
230
231
  'The provided option "scope" should be an Object, but %v given.',
231
232
  clause,
232
233
  );
233
- if ('where' in clause && clause.where)
234
+ // {where: ...}
235
+ if (clause.where != null) {
234
236
  WhereClauseTool.validateWhereClause(clause.where);
235
- if ('order' in clause && clause.order)
237
+ }
238
+ // {order: ...}
239
+ if (clause.order != null) {
236
240
  OrderClauseTool.validateOrderClause(clause.order);
237
- if ('skip' in clause && clause.skip)
241
+ }
242
+ // {skip: ...}
243
+ if (clause.skip != null) {
238
244
  SliceClauseTool.validateSkipClause(clause.skip);
239
- if ('limit' in clause && clause.limit)
245
+ }
246
+ // {limit: ...}
247
+ if (clause.limit != null) {
240
248
  SliceClauseTool.validateLimitClause(clause.limit);
241
- if ('fields' in clause && clause.fields)
249
+ }
250
+ // {fields: ...}
251
+ if (clause.fields != null) {
242
252
  FieldsClauseTool.validateFieldsClause(clause.fields);
243
- if ('include' in clause && clause.include)
253
+ }
254
+ // {include: ...}
255
+ if (clause.include != null) {
244
256
  IncludeClauseTool.validateIncludeClause(clause.include);
257
+ }
245
258
  }
246
259
 
247
260
  /**
@@ -252,23 +265,16 @@ export class IncludeClauseTool extends Service {
252
265
  */
253
266
  static normalizeIncludeClause(clause) {
254
267
  let result = [];
255
- if (!clause) {
256
- // empty
268
+ if (clause == null) {
269
+ // allows undefined and null
257
270
  return result;
258
- } else if (typeof clause === 'string') {
259
- // string
271
+ } else if (clause && typeof clause === 'string') {
272
+ // normalize non-empty string
260
273
  result.push({relation: clause});
261
274
  } else if (Array.isArray(clause)) {
262
- // array
263
- clause.flat().forEach(el => {
264
- if (Array.isArray(el)) {
265
- el = el
266
- .flat()
267
- .map(v => this.normalizeIncludeClause(v))
268
- .flat();
269
- } else {
270
- el = this.normalizeIncludeClause(el);
271
- }
275
+ // normalize array
276
+ clause.flat(Infinity).forEach(el => {
277
+ el = this.normalizeIncludeClause(el);
272
278
  result = [...result, ...el];
273
279
  });
274
280
  // duplicates checking
@@ -282,7 +288,7 @@ export class IncludeClauseTool extends Service {
282
288
  duplicateNames[0],
283
289
  );
284
290
  } else if (typeof clause === 'object') {
285
- // object
291
+ // normalize object
286
292
  if ('relation' in clause) {
287
293
  // {relation: 'name', scope: {...}}
288
294
  if (!clause.relation || typeof clause.relation !== 'string')
@@ -299,6 +305,7 @@ export class IncludeClauseTool extends Service {
299
305
  // {foo: 'bar', baz: ['qux'], ...}
300
306
  Object.keys(clause).forEach(key => {
301
307
  if (!Object.prototype.hasOwnProperty.call(clause, key)) return;
308
+ this.validateIncludeClause(key);
302
309
  const normalized = {relation: key};
303
310
  const include = this.normalizeIncludeClause(clause[key]);
304
311
  if (include.length) normalized.scope = {include};
@@ -306,10 +313,10 @@ export class IncludeClauseTool extends Service {
306
313
  });
307
314
  }
308
315
  } else {
309
- // unknown
316
+ // unsupported
310
317
  throw new InvalidArgumentError(
311
- 'The provided option "include" should have a value of ' +
312
- 'following types: String, Object or Array, but %v given.',
318
+ 'The provided option "include" should have a non-empty String, ' +
319
+ 'an Object or an Array, but %v given.',
313
320
  clause,
314
321
  );
315
322
  }
@@ -323,7 +330,7 @@ export class IncludeClauseTool extends Service {
323
330
  * @returns {object|undefined}
324
331
  */
325
332
  static normalizeScopeClause(clause) {
326
- if (!clause) return;
333
+ if (clause == null) return;
327
334
  if (typeof clause !== 'object' || Array.isArray(clause))
328
335
  throw new InvalidArgumentError(
329
336
  'The provided option "scope" should be an Object, but %v given.',
@@ -331,33 +338,34 @@ export class IncludeClauseTool extends Service {
331
338
  );
332
339
  const result = {};
333
340
  // {where: ...}
334
- if ('where' in clause && clause.where) {
341
+ if (clause.where != null) {
335
342
  WhereClauseTool.validateWhereClause(clause.where);
336
343
  result.where = clause.where;
337
344
  }
338
345
  // {order: ...}
339
- if ('order' in clause && clause.order) {
346
+ if (clause.order != null) {
340
347
  OrderClauseTool.validateOrderClause(clause.order);
341
348
  result.order = clause.order;
342
349
  }
343
350
  // {skip: ...}
344
- if ('skip' in clause && clause.skip) {
351
+ if (clause.skip != null) {
345
352
  SliceClauseTool.validateSkipClause(clause.skip);
346
353
  result.skip = clause.skip;
347
354
  }
348
355
  // {limit: ...}
349
- if ('limit' in clause && clause.limit) {
356
+ if (clause.limit != null) {
350
357
  SliceClauseTool.validateLimitClause(clause.limit);
351
358
  result.limit = clause.limit;
352
359
  }
353
360
  // {fields: ...}
354
- if ('fields' in clause && clause.fields) {
361
+ if (clause.fields != null) {
355
362
  FieldsClauseTool.validateFieldsClause(clause.fields);
356
363
  result.fields = clause.fields;
357
364
  }
358
365
  // {include: ...}
359
- if ('include' in clause && clause.include)
366
+ if (clause.include != null) {
360
367
  result.include = this.normalizeIncludeClause(clause.include);
368
+ }
361
369
  if (Object.keys(result).length) return result;
362
370
  return undefined;
363
371
  }