@e22m4u/js-repository 0.8.7 → 0.8.9

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.
Files changed (70) hide show
  1. package/dist/cjs/index.cjs +452 -406
  2. package/package.json +7 -7
  3. package/src/adapter/adapter-loader.js +2 -5
  4. package/src/adapter/adapter-loader.spec.js +2 -2
  5. package/src/adapter/adapter-registry.spec.js +2 -2
  6. package/src/adapter/builtin/memory-adapter.js +5 -5
  7. package/src/adapter/builtin/memory-adapter.spec.js +12 -12
  8. package/src/adapter/decorator/data-sanitizing-decorator.js +1 -2
  9. package/src/adapter/decorator/default-values-decorator.js +1 -2
  10. package/src/adapter/decorator/fields-filtering-decorator.js +1 -2
  11. package/src/adapter/decorator/inclusion-decorator.js +1 -2
  12. package/src/adapter/decorator/property-uniqueness-decorator.js +1 -2
  13. package/src/adapter/decorator/required-property-decorator.js +1 -2
  14. package/src/database-schema.spec.js +3 -5
  15. package/src/definition/datasource/datasource-definition-validator.js +3 -3
  16. package/src/definition/datasource/datasource-definition-validator.spec.js +3 -6
  17. package/src/definition/definition-registry.d.ts +10 -0
  18. package/src/definition/definition-registry.js +28 -19
  19. package/src/definition/definition-registry.spec.js +64 -117
  20. package/src/definition/model/model-data-sanitizer.js +2 -4
  21. package/src/definition/model/model-definition-utils.js +12 -14
  22. package/src/definition/model/model-definition-utils.spec.js +12 -21
  23. package/src/definition/model/model-definition-validator.js +12 -12
  24. package/src/definition/model/model-definition-validator.spec.js +12 -15
  25. package/src/definition/model/properties/primary-keys-definition-validator.js +4 -4
  26. package/src/definition/model/properties/primary-keys-definition-validator.spec.js +8 -8
  27. package/src/definition/model/properties/properties-definition-validator.js +42 -43
  28. package/src/definition/model/properties/properties-definition-validator.spec.js +45 -45
  29. package/src/definition/model/properties/property-uniqueness-validator.js +7 -11
  30. package/src/definition/model/properties/property-uniqueness-validator.spec.js +57 -60
  31. package/src/definition/model/properties/required-property-validator.js +1 -1
  32. package/src/definition/model/properties/required-property-validator.spec.js +1 -1
  33. package/src/definition/model/relations/relations-definition-validator.js +40 -42
  34. package/src/definition/model/relations/relations-definition-validator.spec.js +44 -45
  35. package/src/errors/invalid-operator-value-error.js +1 -1
  36. package/src/errors/invalid-operator-value-error.spec.js +1 -1
  37. package/src/filter/fields-clause-tool.js +95 -53
  38. package/src/filter/fields-clause-tool.spec.js +210 -387
  39. package/src/filter/include-clause-tool.js +9 -9
  40. package/src/filter/include-clause-tool.spec.js +4 -4
  41. package/src/filter/operator-clause-tool.js +20 -32
  42. package/src/filter/operator-clause-tool.spec.js +25 -49
  43. package/src/filter/order-clause-tool.js +55 -27
  44. package/src/filter/order-clause-tool.spec.js +151 -90
  45. package/src/filter/slice-clause-tool.js +5 -6
  46. package/src/filter/slice-clause-tool.spec.js +8 -24
  47. package/src/filter/where-clause-tool.js +18 -11
  48. package/src/filter/where-clause-tool.spec.js +27 -17
  49. package/src/relations/belongs-to-resolver.js +18 -30
  50. package/src/relations/belongs-to-resolver.spec.js +21 -44
  51. package/src/relations/has-many-resolver.js +28 -44
  52. package/src/relations/has-many-resolver.spec.js +44 -68
  53. package/src/relations/has-one-resolver.js +28 -44
  54. package/src/relations/has-one-resolver.spec.js +44 -68
  55. package/src/relations/references-many-resolver.js +8 -14
  56. package/src/relations/references-many-resolver.spec.js +12 -24
  57. package/src/repository/repository-registry.js +4 -6
  58. package/src/repository/repository-registry.spec.js +0 -19
  59. package/src/repository/repository.js +1 -1
  60. package/src/utils/exclude-object-keys.js +2 -2
  61. package/src/utils/exclude-object-keys.spec.js +2 -2
  62. package/src/utils/index.d.ts +0 -1
  63. package/src/utils/index.js +0 -1
  64. package/src/utils/like-to-regexp.js +1 -2
  65. package/src/utils/like-to-regexp.spec.js +5 -5
  66. package/src/utils/select-object-keys.js +6 -7
  67. package/src/utils/select-object-keys.spec.js +3 -6
  68. package/src/utils/model-name-to-model-key.d.ts +0 -6
  69. package/src/utils/model-name-to-model-key.js +0 -18
  70. package/src/utils/model-name-to-model-key.spec.js +0 -94
@@ -6,8 +6,68 @@ const S = new OrderClauseTool();
6
6
 
7
7
  describe('OrderClauseTool', function () {
8
8
  describe('sort', function () {
9
+ it('should require the parameter "entities" to be an array', function () {
10
+ const throwable = v => () => S.sort(v, 'prop');
11
+ const error = s =>
12
+ format('Parameter "entities" must be an Array, but %s was given.', s);
13
+ expect(throwable('str')).to.throw(error('"str"'));
14
+ expect(throwable('')).to.throw(error('""'));
15
+ expect(throwable(10)).to.throw(error('10'));
16
+ expect(throwable(0)).to.throw(error('0'));
17
+ expect(throwable(true)).to.throw(error('true'));
18
+ expect(throwable(false)).to.throw(error('false'));
19
+ expect(throwable({})).to.throw(error('Object'));
20
+ expect(throwable(undefined)).to.throw(error('undefined'));
21
+ expect(throwable(null)).to.throw(error('null'));
22
+ throwable([{prop: true}])();
23
+ throwable([{}])();
24
+ });
25
+
26
+ it('should require the parameter "clause" to be a correct value', function () {
27
+ const entities = [{prop: 1}, {prop: 2}];
28
+ const throwable = v => () => S.sort(entities, v);
29
+ const error = s =>
30
+ format(
31
+ 'Option "order" must be a non-empty String or an Array ' +
32
+ 'of non-empty String, but %s was given.',
33
+ s,
34
+ );
35
+ expect(throwable('')).to.throw(error('""'));
36
+ expect(throwable(10)).to.throw(error('10'));
37
+ expect(throwable(0)).to.throw(error('0'));
38
+ expect(throwable(true)).to.throw(error('true'));
39
+ expect(throwable(false)).to.throw(error('false'));
40
+ expect(throwable({})).to.throw(error('Object'));
41
+ throwable('prop')();
42
+ throwable(['prop'])();
43
+ throwable([])();
44
+ throwable(undefined)();
45
+ throwable(null)();
46
+ });
47
+
48
+ it('should require elements of the parameter "clause" to be a non-empty string', function () {
49
+ const entities = [{prop: 1}, {prop: 2}];
50
+ const throwable = v => () => S.sort(entities, [v]);
51
+ const error = s =>
52
+ format(
53
+ 'Element 0 of the option "order" must be a non-empty String, ' +
54
+ 'but %s was given.',
55
+ s,
56
+ );
57
+ expect(throwable('')).to.throw(error('""'));
58
+ expect(throwable(10)).to.throw(error('10'));
59
+ expect(throwable(0)).to.throw(error('0'));
60
+ expect(throwable(true)).to.throw(error('true'));
61
+ expect(throwable(false)).to.throw(error('false'));
62
+ expect(throwable([])).to.throw(error('Array'));
63
+ expect(throwable({})).to.throw(error('Object'));
64
+ expect(throwable(undefined)).to.throw(error('undefined'));
65
+ expect(throwable(null)).to.throw(error('null'));
66
+ throwable('prop')();
67
+ });
68
+
9
69
  describe('single field', function () {
10
- it('does not throw an error if the given field is not exist', function () {
70
+ it('does not throw an error if the given field does not exist', function () {
11
71
  const objects = [{foo: 1}, {foo: 2}, {foo: 3}, {foo: 4}];
12
72
  S.sort(objects, 'bar');
13
73
  expect(objects).to.have.length(4);
@@ -83,7 +143,7 @@ describe('OrderClauseTool', function () {
83
143
  });
84
144
 
85
145
  describe('multiple fields', function () {
86
- it('does not throw an error if multiple fields are not exist', function () {
146
+ it('does not throw an error if multiple fields do not exist', function () {
87
147
  const objects = [{foo: 1}, {foo: 2}, {foo: 3}, {foo: 4}];
88
148
  S.sort(objects, ['bar', 'baz']);
89
149
  expect(objects).to.have.length(4);
@@ -281,7 +341,7 @@ describe('OrderClauseTool', function () {
281
341
  });
282
342
 
283
343
  describe('nested single field', function () {
284
- it('does not throw an error if the nested field is not exist', function () {
344
+ it('does not throw an error if the nested field does not exist', function () {
285
345
  const objects = [
286
346
  {foo: 1},
287
347
  {foo: 2, bar: undefined},
@@ -392,7 +452,7 @@ describe('OrderClauseTool', function () {
392
452
  });
393
453
 
394
454
  describe('nested multiple fields', function () {
395
- it('does not throw an error if nested multiple fields are not exist', function () {
455
+ it('does not throw an error if nested multiple fields do not exist', function () {
396
456
  const objects = [
397
457
  {foo: 1},
398
458
  {foo: 2, bar: undefined},
@@ -596,102 +656,103 @@ describe('OrderClauseTool', function () {
596
656
  });
597
657
 
598
658
  describe('validateOrderClause', function () {
599
- describe('single field', function () {
600
- it('requires the first argument as a non-empty string', function () {
601
- const throwable = v => () => OrderClauseTool.validateOrderClause(v);
602
- const error = v =>
603
- format(
604
- 'The provided option "order" should be a non-empty String ' +
605
- 'or an Array of non-empty String, but %s was given.',
606
- v,
607
- );
608
- expect(throwable('')).to.throw(error('""'));
609
- expect(throwable(10)).to.throw(error('10'));
610
- expect(throwable(0)).to.throw(error('0'));
611
- expect(throwable(true)).to.throw(error('true'));
612
- expect(throwable(false)).to.throw(error('false'));
613
- expect(throwable({})).to.throw(error('Object'));
614
- throwable('field')();
615
- throwable(undefined)();
616
- throwable(null)();
617
- });
659
+ it('should require the parameter "clause" to be a correct value', function () {
660
+ const throwable = v => () => OrderClauseTool.validateOrderClause(v);
661
+ const error = s =>
662
+ format(
663
+ 'Option "order" must be a non-empty String or an Array ' +
664
+ 'of non-empty String, but %s was given.',
665
+ s,
666
+ );
667
+ expect(throwable('')).to.throw(error('""'));
668
+ expect(throwable(10)).to.throw(error('10'));
669
+ expect(throwable(0)).to.throw(error('0'));
670
+ expect(throwable(true)).to.throw(error('true'));
671
+ expect(throwable(false)).to.throw(error('false'));
672
+ expect(throwable({})).to.throw(error('Object'));
673
+ throwable('prop')();
674
+ throwable(['prop'])();
675
+ throwable([])();
676
+ throwable(undefined)();
677
+ throwable(null)();
618
678
  });
619
679
 
620
- describe('multiple fields', function () {
621
- it('requires the first argument as a non-empty string', function () {
622
- const throwable = v => () => OrderClauseTool.validateOrderClause(v);
623
- const error = v =>
624
- format(
625
- 'The provided option "order" should be a non-empty String ' +
626
- 'or an Array of non-empty String, but %s was given.',
627
- v,
628
- );
629
- expect(throwable([''])).to.throw(error('""'));
630
- expect(throwable([10])).to.throw(error('10'));
631
- expect(throwable([0])).to.throw(error('0'));
632
- expect(throwable([true])).to.throw(error('true'));
633
- expect(throwable([false])).to.throw(error('false'));
634
- expect(throwable([{}])).to.throw(error('Object'));
635
- expect(throwable([undefined])).to.throw(error('undefined'));
636
- expect(throwable([null])).to.throw(error('null'));
637
- throwable(['field'])();
638
- throwable([])();
639
- });
680
+ it('should require elements of the parameter "clause" to be a non-empty string', function () {
681
+ const throwable = v => () => OrderClauseTool.validateOrderClause([v]);
682
+ const error = s =>
683
+ format(
684
+ 'Element 0 of the option "order" must be a non-empty String, ' +
685
+ 'but %s was given.',
686
+ s,
687
+ );
688
+ expect(throwable('')).to.throw(error('""'));
689
+ expect(throwable(10)).to.throw(error('10'));
690
+ expect(throwable(0)).to.throw(error('0'));
691
+ expect(throwable(true)).to.throw(error('true'));
692
+ expect(throwable(false)).to.throw(error('false'));
693
+ expect(throwable([])).to.throw(error('Array'));
694
+ expect(throwable({})).to.throw(error('Object'));
695
+ expect(throwable(undefined)).to.throw(error('undefined'));
696
+ expect(throwable(null)).to.throw(error('null'));
697
+ throwable('prop')();
640
698
  });
641
699
  });
642
700
 
643
701
  describe('normalizeOrderClause', function () {
644
- describe('single field', function () {
645
- it('requires the first argument as a non-empty string', function () {
646
- const throwable = v => () => OrderClauseTool.normalizeOrderClause(v);
647
- const error = v =>
648
- format(
649
- 'The provided option "order" should be a non-empty String ' +
650
- 'or an Array of non-empty String, but %s was given.',
651
- v,
652
- );
653
- expect(throwable('')).to.throw(error('""'));
654
- expect(throwable(10)).to.throw(error('10'));
655
- expect(throwable(0)).to.throw(error('0'));
656
- expect(throwable(true)).to.throw(error('true'));
657
- expect(throwable(false)).to.throw(error('false'));
658
- expect(throwable({})).to.throw(error('Object'));
659
- expect(throwable('field')()).to.be.eql(['field']);
660
- expect(throwable(undefined)()).to.be.undefined;
661
- expect(throwable(null)()).to.be.undefined;
662
- });
702
+ it('should require the parameter "clause" to be a correct value', function () {
703
+ const throwable = v => () => OrderClauseTool.normalizeOrderClause(v);
704
+ const error = s =>
705
+ format(
706
+ 'Option "order" must be a non-empty String or an Array ' +
707
+ 'of non-empty String, but %s was given.',
708
+ s,
709
+ );
710
+ expect(throwable('')).to.throw(error('""'));
711
+ expect(throwable(10)).to.throw(error('10'));
712
+ expect(throwable(0)).to.throw(error('0'));
713
+ expect(throwable(true)).to.throw(error('true'));
714
+ expect(throwable(false)).to.throw(error('false'));
715
+ expect(throwable({})).to.throw(error('Object'));
716
+ throwable('prop')();
717
+ throwable(['prop'])();
718
+ throwable([])();
719
+ throwable(undefined)();
720
+ throwable(null)();
721
+ });
663
722
 
664
- it('returns an array of string', function () {
665
- const fn = OrderClauseTool.normalizeOrderClause;
666
- expect(fn('foo')).to.be.eql(['foo']);
667
- });
723
+ it('should require elements of the parameter "clause" to be a non-empty string', function () {
724
+ const throwable = v => () => OrderClauseTool.normalizeOrderClause([v]);
725
+ const error = s =>
726
+ format(
727
+ 'Element 0 of the option "order" must be a non-empty String, ' +
728
+ 'but %s was given.',
729
+ s,
730
+ );
731
+ expect(throwable('')).to.throw(error('""'));
732
+ expect(throwable(10)).to.throw(error('10'));
733
+ expect(throwable(0)).to.throw(error('0'));
734
+ expect(throwable(true)).to.throw(error('true'));
735
+ expect(throwable(false)).to.throw(error('false'));
736
+ expect(throwable([])).to.throw(error('Array'));
737
+ expect(throwable({})).to.throw(error('Object'));
738
+ expect(throwable(undefined)).to.throw(error('undefined'));
739
+ expect(throwable(null)).to.throw(error('null'));
740
+ throwable('prop')();
668
741
  });
669
742
 
670
- describe('multiple fields', function () {
671
- it('requires the first argument as a non-empty string', function () {
672
- const throwable = v => () => OrderClauseTool.normalizeOrderClause(v);
673
- const error = v =>
674
- format(
675
- 'The provided option "order" should be a non-empty String ' +
676
- 'or an Array of non-empty String, but %s was given.',
677
- v,
678
- );
679
- expect(throwable([''])).to.throw(error('""'));
680
- expect(throwable([10])).to.throw(error('10'));
681
- expect(throwable([0])).to.throw(error('0'));
682
- expect(throwable([true])).to.throw(error('true'));
683
- expect(throwable([false])).to.throw(error('false'));
684
- expect(throwable([{}])).to.throw(error('Object'));
685
- expect(throwable([undefined])).to.throw(error('undefined'));
686
- expect(throwable([null])).to.throw(error('null'));
687
- expect(throwable(['field'])()).to.be.eql(['field']);
688
- expect(throwable([])()).to.be.undefined;
689
- });
743
+ it('should wrap a string value with an array', function () {
744
+ const res = OrderClauseTool.normalizeOrderClause('foo');
745
+ expect(res).to.be.eql(['foo']);
746
+ });
690
747
 
691
- it('returns an array of strings', function () {
692
- const fn = OrderClauseTool.normalizeOrderClause;
693
- expect(fn(['foo', 'bar'])).to.be.eql(['foo', 'bar']);
694
- });
748
+ it('should return a non-empty array as is', function () {
749
+ const res = OrderClauseTool.normalizeOrderClause(['foo', 'bar']);
750
+ expect(res).to.be.eql(['foo', 'bar']);
751
+ });
752
+
753
+ it('should return undefined for an empty array', function () {
754
+ const res = OrderClauseTool.normalizeOrderClause([]);
755
+ expect(res).to.be.undefined;
695
756
  });
696
757
  });
697
758
  });
@@ -16,20 +16,19 @@ export class SliceClauseTool extends Service {
16
16
  slice(entities, skip = undefined, limit = undefined) {
17
17
  if (!Array.isArray(entities)) {
18
18
  throw new InvalidArgumentError(
19
- 'The first argument of SliceClauseTool.slice ' +
20
- 'should be an Array, but %v was given.',
19
+ 'Parameter "entities" must be an Array, but %v was given.',
21
20
  entities,
22
21
  );
23
22
  }
24
23
  if (skip != null && typeof skip !== 'number') {
25
24
  throw new InvalidArgumentError(
26
- 'The provided option "skip" should be a Number, but %v was given.',
25
+ 'Option "skip" must be a Number, but %v was given.',
27
26
  skip,
28
27
  );
29
28
  }
30
29
  if (limit != null && typeof limit !== 'number') {
31
30
  throw new InvalidArgumentError(
32
- 'The provided option "limit" should be a Number, but %v was given.',
31
+ 'Option "limit" must be a Number, but %v was given.',
33
32
  limit,
34
33
  );
35
34
  }
@@ -49,7 +48,7 @@ export class SliceClauseTool extends Service {
49
48
  }
50
49
  if (typeof skip !== 'number') {
51
50
  throw new InvalidArgumentError(
52
- 'The provided option "skip" should be a Number, but %v was given.',
51
+ 'Option "skip" must be a Number, but %v was given.',
53
52
  skip,
54
53
  );
55
54
  }
@@ -66,7 +65,7 @@ export class SliceClauseTool extends Service {
66
65
  }
67
66
  if (typeof limit !== 'number') {
68
67
  throw new InvalidArgumentError(
69
- 'The provided option "limit" should be a Number, but %v was given.',
68
+ 'Option "limit" must be a Number, but %v was given.',
70
69
  limit,
71
70
  );
72
71
  }
@@ -6,14 +6,10 @@ const S = new SliceClauseTool();
6
6
 
7
7
  describe('SliceClauseTool', function () {
8
8
  describe('slice', function () {
9
- it('requires the first argument to be an array', function () {
9
+ it('requires the parameter "entities" to be an array', function () {
10
10
  const throwable = v => () => S.slice(v);
11
11
  const error = v =>
12
- format(
13
- 'The first argument of SliceClauseTool.slice ' +
14
- 'should be an Array, but %s was given.',
15
- v,
16
- );
12
+ format('Parameter "entities" must be an Array, but %s was given.', v);
17
13
  expect(throwable('str')).to.throw(error('"str"'));
18
14
  expect(throwable('')).to.throw(error('""'));
19
15
  expect(throwable(10)).to.throw(error('10'));
@@ -27,14 +23,11 @@ describe('SliceClauseTool', function () {
27
23
  expect(throwable([])()).to.be.eql([]);
28
24
  });
29
25
 
30
- it('requires the provided second argument to be a number', function () {
26
+ it('requires the parameter "skip" to be a number', function () {
31
27
  const items = [{foo: 'bar'}];
32
28
  const throwable = v => () => S.slice(items, v);
33
29
  const error = v =>
34
- format(
35
- 'The provided option "skip" should be a Number, but %s was given.',
36
- v,
37
- );
30
+ format('Option "skip" must be a Number, but %s was given.', v);
38
31
  expect(throwable('str')).to.throw(error('"str"'));
39
32
  expect(throwable('')).to.throw(error('""'));
40
33
  expect(throwable(true)).to.throw(error('true'));
@@ -47,14 +40,11 @@ describe('SliceClauseTool', function () {
47
40
  expect(throwable(null)()).to.be.eql(items);
48
41
  });
49
42
 
50
- it('requires the provided third argument to be a number', function () {
43
+ it('requires the parameter "limit" to be a number', function () {
51
44
  const items = [{foo: 'bar'}];
52
45
  const throwable = v => () => S.slice(items, undefined, v);
53
46
  const error = v =>
54
- format(
55
- 'The provided option "limit" should be a Number, but %s was given.',
56
- v,
57
- );
47
+ format('Option "limit" must be a Number, but %s was given.', v);
58
48
  expect(throwable('str')).to.throw(error('"str"'));
59
49
  expect(throwable('')).to.throw(error('""'));
60
50
  expect(throwable(true)).to.throw(error('true'));
@@ -118,10 +108,7 @@ describe('SliceClauseTool', function () {
118
108
  it('requires a number value', function () {
119
109
  const throwable = v => () => SliceClauseTool.validateSkipClause(v);
120
110
  const error = v =>
121
- format(
122
- 'The provided option "skip" should be a Number, but %s was given.',
123
- v,
124
- );
111
+ format('Option "skip" must be a Number, but %s was given.', v);
125
112
  expect(throwable('str')).to.throw(error('"str"'));
126
113
  expect(throwable('')).to.throw(error('""'));
127
114
  expect(throwable(true)).to.throw(error('true'));
@@ -139,10 +126,7 @@ describe('SliceClauseTool', function () {
139
126
  it('requires a number value or a falsy value', function () {
140
127
  const throwable = v => () => SliceClauseTool.validateLimitClause(v);
141
128
  const error = v =>
142
- format(
143
- 'The provided option "limit" should be a Number, but %s was given.',
144
- v,
145
- );
129
+ format('Option "limit" must be a Number, but %s was given.', v);
146
130
  expect(throwable('str')).to.throw(error('"str"'));
147
131
  expect(throwable('')).to.throw(error('""'));
148
132
  expect(throwable(true)).to.throw(error('true'));
@@ -41,8 +41,7 @@ export class WhereClauseTool extends Service {
41
41
  filter(entities, where = undefined) {
42
42
  if (!Array.isArray(entities)) {
43
43
  throw new InvalidArgumentError(
44
- 'The first argument of WhereClauseTool.filter should be ' +
45
- 'an Array of Object, but %v was given.',
44
+ 'Parameter "entities" must be an Array of Object, but %v was given.',
46
45
  entities,
47
46
  );
48
47
  }
@@ -59,18 +58,22 @@ export class WhereClauseTool extends Service {
59
58
  * @returns {Function}
60
59
  */
61
60
  _createFilter(whereClause) {
62
- if (typeof whereClause !== 'object' || Array.isArray(whereClause)) {
61
+ if (
62
+ !whereClause ||
63
+ typeof whereClause !== 'object' ||
64
+ Array.isArray(whereClause)
65
+ ) {
63
66
  throw new InvalidArgumentError(
64
- 'The provided option "where" should be an Object, but %v was given.',
67
+ 'Option "where" must be an Object, but %v was given.',
65
68
  whereClause,
66
69
  );
67
70
  }
68
71
  const keys = Object.keys(whereClause);
69
- return data => {
70
- if (typeof data !== 'object') {
72
+ return (data, index) => {
73
+ if (!data || typeof data !== 'object' || Array.isArray(data)) {
71
74
  throw new InvalidArgumentError(
72
- 'The first argument of WhereClauseTool.filter should be ' +
73
- 'an Array of Object, but %v was given.',
75
+ 'Entity at index %d must be an Object, but %v was given.',
76
+ index,
74
77
  data,
75
78
  );
76
79
  }
@@ -79,14 +82,18 @@ export class WhereClauseTool extends Service {
79
82
  if (key === 'and' && key in whereClause) {
80
83
  const andClause = whereClause[key];
81
84
  if (Array.isArray(andClause)) {
82
- return andClause.every(clause => this._createFilter(clause)(data));
85
+ return andClause.every(clause =>
86
+ this._createFilter(clause)(data, index),
87
+ );
83
88
  }
84
89
  }
85
90
  // OrClause (recursion)
86
91
  else if (key === 'or' && key in whereClause) {
87
92
  const orClause = whereClause[key];
88
93
  if (Array.isArray(orClause)) {
89
- return orClause.some(clause => this._createFilter(clause)(data));
94
+ return orClause.some(clause =>
95
+ this._createFilter(clause)(data, index),
96
+ );
90
97
  }
91
98
  }
92
99
  // PropertiesClause (properties)
@@ -172,7 +179,7 @@ export class WhereClauseTool extends Service {
172
179
  }
173
180
  if (typeof clause !== 'object' || Array.isArray(clause)) {
174
181
  throw new InvalidArgumentError(
175
- 'The provided option "where" should be an Object, but %v was given.',
182
+ 'Option "where" must be an Object, but %v was given.',
176
183
  clause,
177
184
  );
178
185
  }
@@ -59,13 +59,12 @@ const OBJECTS = [
59
59
 
60
60
  describe('WhereClauseTool', function () {
61
61
  describe('filter', function () {
62
- it('requires the first argument to be an array of objects', function () {
62
+ it('requires the parameter "entities" to be an array of objects', function () {
63
63
  const throwable = v => () => S.filter(v, {});
64
- const error = v =>
64
+ const error = s =>
65
65
  format(
66
- 'The first argument of WhereClauseTool.filter should be ' +
67
- 'an Array of Object, but %s was given.',
68
- v,
66
+ 'Parameter "entities" must be an Array of Object, but %s was given.',
67
+ s,
69
68
  );
70
69
  expect(throwable('str')).to.throw(error('"str"'));
71
70
  expect(throwable('')).to.throw(error('""'));
@@ -80,13 +79,27 @@ describe('WhereClauseTool', function () {
80
79
  expect(throwable([])()).to.be.eql([]);
81
80
  });
82
81
 
83
- it('requires the second argument to be an object', function () {
82
+ it('requires elements of the parameter "entities" to be an object', function () {
83
+ const throwable = v => () => S.filter([v], {});
84
+ const error = s =>
85
+ format('Entity at index 0 must be an Object, but %s was given.', s);
86
+ expect(throwable('str')).to.throw(error('"str"'));
87
+ expect(throwable('')).to.throw(error('""'));
88
+ expect(throwable(10)).to.throw(error('10'));
89
+ expect(throwable(0)).to.throw(error('0'));
90
+ expect(throwable(true)).to.throw(error('true'));
91
+ expect(throwable(false)).to.throw(error('false'));
92
+ expect(throwable([])).to.throw(error('Array'));
93
+ expect(throwable(undefined)).to.throw(error('undefined'));
94
+ expect(throwable(null)).to.throw(error('null'));
95
+ throwable({foo: 'bar'})();
96
+ throwable({})();
97
+ });
98
+
99
+ it('requires the parameter "where" to be an object', function () {
84
100
  const throwable = v => () => S.filter(OBJECTS, v);
85
- const error = v =>
86
- format(
87
- 'The provided option "where" should be an Object, but %s was given.',
88
- v,
89
- );
101
+ const error = s =>
102
+ format('Option "where" must be an Object, but %s was given.', s);
90
103
  expect(throwable('str')).to.throw(error('"str"'));
91
104
  expect(throwable('')).to.throw(error('""'));
92
105
  expect(throwable(10)).to.throw(error('10'));
@@ -390,13 +403,10 @@ describe('WhereClauseTool', function () {
390
403
  });
391
404
 
392
405
  describe('validateWhereClause', function () {
393
- it('requires the first argument to be an object or a function', function () {
406
+ it('requires the option "where" to be an object or a function', function () {
394
407
  const throwable = v => () => WhereClauseTool.validateWhereClause(v);
395
- const error = v =>
396
- format(
397
- 'The provided option "where" should be an Object, but %s was given.',
398
- v,
399
- );
408
+ const error = s =>
409
+ format('Option "where" must be an Object, but %s was given.', s);
400
410
  expect(throwable('str')).to.throw(error('"str"'));
401
411
  expect(throwable('')).to.throw(error('""'));
402
412
  expect(throwable(10)).to.throw(error('10'));