@e22m4u/js-repository 0.0.31

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 (183) hide show
  1. package/.c8rc +9 -0
  2. package/.commitlintrc +5 -0
  3. package/.editorconfig +13 -0
  4. package/.eslintignore +1 -0
  5. package/.eslintrc.cjs +27 -0
  6. package/.husky/commit-msg +4 -0
  7. package/.husky/pre-commit +9 -0
  8. package/.mocharc.cjs +7 -0
  9. package/.prettierrc +7 -0
  10. package/LICENSE +21 -0
  11. package/README.md +523 -0
  12. package/mocha.setup.js +10 -0
  13. package/package.json +57 -0
  14. package/src/adapter/adapter-loader.d.ts +16 -0
  15. package/src/adapter/adapter-loader.js +63 -0
  16. package/src/adapter/adapter-loader.spec.js +31 -0
  17. package/src/adapter/adapter-registry.d.ts +14 -0
  18. package/src/adapter/adapter-registry.js +36 -0
  19. package/src/adapter/adapter-registry.spec.js +36 -0
  20. package/src/adapter/adapter.d.ts +118 -0
  21. package/src/adapter/adapter.js +181 -0
  22. package/src/adapter/adapter.spec.js +144 -0
  23. package/src/adapter/builtin/memory-adapter.d.ts +118 -0
  24. package/src/adapter/builtin/memory-adapter.js +342 -0
  25. package/src/adapter/builtin/memory-adapter.spec.js +2925 -0
  26. package/src/adapter/decorator/data-sanitizing-decorator.d.ts +13 -0
  27. package/src/adapter/decorator/data-sanitizing-decorator.js +44 -0
  28. package/src/adapter/decorator/data-sanitizing-decorator.spec.js +59 -0
  29. package/src/adapter/decorator/data-validation-decorator.d.ts +13 -0
  30. package/src/adapter/decorator/data-validation-decorator.js +41 -0
  31. package/src/adapter/decorator/data-validation-decorator.spec.js +59 -0
  32. package/src/adapter/decorator/default-values-decorator.d.ts +13 -0
  33. package/src/adapter/decorator/default-values-decorator.js +57 -0
  34. package/src/adapter/decorator/default-values-decorator.spec.js +141 -0
  35. package/src/adapter/decorator/fields-filtering-decorator.d.ts +13 -0
  36. package/src/adapter/decorator/fields-filtering-decorator.js +72 -0
  37. package/src/adapter/decorator/fields-filtering-decorator.spec.js +119 -0
  38. package/src/adapter/decorator/inclusion-decorator.d.ts +13 -0
  39. package/src/adapter/decorator/inclusion-decorator.js +78 -0
  40. package/src/adapter/decorator/inclusion-decorator.spec.js +117 -0
  41. package/src/adapter/decorator/index.d.ts +5 -0
  42. package/src/adapter/decorator/index.js +5 -0
  43. package/src/adapter/index.d.ts +3 -0
  44. package/src/adapter/index.js +3 -0
  45. package/src/definition/datasource/datasource-definition-validator.d.ts +14 -0
  46. package/src/definition/datasource/datasource-definition-validator.js +33 -0
  47. package/src/definition/datasource/datasource-definition-validator.spec.js +63 -0
  48. package/src/definition/datasource/datasource-definition.d.ts +7 -0
  49. package/src/definition/datasource/index.d.ts +2 -0
  50. package/src/definition/datasource/index.js +1 -0
  51. package/src/definition/definition-registry.d.ts +50 -0
  52. package/src/definition/definition-registry.js +98 -0
  53. package/src/definition/definition-registry.spec.js +78 -0
  54. package/src/definition/index.d.ts +3 -0
  55. package/src/definition/index.js +3 -0
  56. package/src/definition/model/index.d.ts +7 -0
  57. package/src/definition/model/index.js +6 -0
  58. package/src/definition/model/model-data-sanitizer.d.ts +15 -0
  59. package/src/definition/model/model-data-sanitizer.js +33 -0
  60. package/src/definition/model/model-data-validator.d.ts +32 -0
  61. package/src/definition/model/model-data-validator.js +144 -0
  62. package/src/definition/model/model-data-validator.spec.js +1889 -0
  63. package/src/definition/model/model-definition-utils.d.ts +161 -0
  64. package/src/definition/model/model-definition-utils.js +371 -0
  65. package/src/definition/model/model-definition-utils.spec.js +1474 -0
  66. package/src/definition/model/model-definition-validator.d.ts +14 -0
  67. package/src/definition/model/model-definition-validator.js +83 -0
  68. package/src/definition/model/model-definition-validator.spec.js +143 -0
  69. package/src/definition/model/model-definition.d.ts +28 -0
  70. package/src/definition/model/properties/data-type.d.ts +11 -0
  71. package/src/definition/model/properties/data-type.js +11 -0
  72. package/src/definition/model/properties/default-values-definition-validator.d.ts +15 -0
  73. package/src/definition/model/properties/default-values-definition-validator.js +53 -0
  74. package/src/definition/model/properties/default-values-definition-validator.spec.js +136 -0
  75. package/src/definition/model/properties/index.d.ts +5 -0
  76. package/src/definition/model/properties/index.js +4 -0
  77. package/src/definition/model/properties/primary-keys-definition-validator.d.ts +15 -0
  78. package/src/definition/model/properties/primary-keys-definition-validator.js +55 -0
  79. package/src/definition/model/properties/primary-keys-definition-validator.spec.js +145 -0
  80. package/src/definition/model/properties/properties-definition-validator.d.ts +15 -0
  81. package/src/definition/model/properties/properties-definition-validator.js +194 -0
  82. package/src/definition/model/properties/properties-definition-validator.spec.js +373 -0
  83. package/src/definition/model/properties/property-definition.d.ts +20 -0
  84. package/src/definition/model/relations/index.d.ts +3 -0
  85. package/src/definition/model/relations/index.js +2 -0
  86. package/src/definition/model/relations/relation-definition.d.ts +254 -0
  87. package/src/definition/model/relations/relation-type.d.ts +9 -0
  88. package/src/definition/model/relations/relation-type.js +9 -0
  89. package/src/definition/model/relations/relations-definition-validator.d.ts +15 -0
  90. package/src/definition/model/relations/relations-definition-validator.js +449 -0
  91. package/src/definition/model/relations/relations-definition-validator.spec.js +772 -0
  92. package/src/errors/index.d.ts +3 -0
  93. package/src/errors/index.js +3 -0
  94. package/src/errors/invalid-argument-error.d.ts +6 -0
  95. package/src/errors/invalid-argument-error.js +6 -0
  96. package/src/errors/invalid-argument-error.spec.js +33 -0
  97. package/src/errors/invalid-operator-value-error.d.ts +13 -0
  98. package/src/errors/invalid-operator-value-error.js +24 -0
  99. package/src/errors/invalid-operator-value-error.spec.js +11 -0
  100. package/src/errors/not-implemented-error.d.ts +6 -0
  101. package/src/errors/not-implemented-error.js +6 -0
  102. package/src/errors/not-implemented-error.spec.js +33 -0
  103. package/src/filter/fields-clause-tool.d.ts +38 -0
  104. package/src/filter/fields-clause-tool.js +88 -0
  105. package/src/filter/fields-clause-tool.spec.js +133 -0
  106. package/src/filter/filter.d.ts +335 -0
  107. package/src/filter/include-clause-tool.d.ts +53 -0
  108. package/src/filter/include-clause-tool.js +364 -0
  109. package/src/filter/include-clause-tool.spec.js +653 -0
  110. package/src/filter/index.d.ts +7 -0
  111. package/src/filter/index.js +6 -0
  112. package/src/filter/operator-clause-tool.d.ts +223 -0
  113. package/src/filter/operator-clause-tool.js +515 -0
  114. package/src/filter/operator-clause-tool.spec.js +1064 -0
  115. package/src/filter/order-clause-tool.d.ts +32 -0
  116. package/src/filter/order-clause-tool.js +97 -0
  117. package/src/filter/order-clause-tool.spec.js +438 -0
  118. package/src/filter/slice-clause-tool.d.ts +30 -0
  119. package/src/filter/slice-clause-tool.js +65 -0
  120. package/src/filter/slice-clause-tool.spec.js +117 -0
  121. package/src/filter/where-clause-tool.d.ts +23 -0
  122. package/src/filter/where-clause-tool.js +165 -0
  123. package/src/filter/where-clause-tool.spec.js +280 -0
  124. package/src/index.d.ts +9 -0
  125. package/src/index.js +8 -0
  126. package/src/relations/belongs-to-resolver.d.ts +46 -0
  127. package/src/relations/belongs-to-resolver.js +242 -0
  128. package/src/relations/belongs-to-resolver.spec.js +1047 -0
  129. package/src/relations/has-many-resolver.d.ts +67 -0
  130. package/src/relations/has-many-resolver.js +317 -0
  131. package/src/relations/has-many-resolver.spec.js +2911 -0
  132. package/src/relations/has-one-resolver.d.ts +67 -0
  133. package/src/relations/has-one-resolver.js +311 -0
  134. package/src/relations/has-one-resolver.spec.js +2274 -0
  135. package/src/relations/index.d.ts +4 -0
  136. package/src/relations/index.js +4 -0
  137. package/src/relations/references-many-resolver.d.ts +27 -0
  138. package/src/relations/references-many-resolver.js +113 -0
  139. package/src/relations/references-many-resolver.spec.js +631 -0
  140. package/src/repository/index.d.ts +2 -0
  141. package/src/repository/index.js +2 -0
  142. package/src/repository/repository-registry.d.ts +29 -0
  143. package/src/repository/repository-registry.js +57 -0
  144. package/src/repository/repository-registry.spec.js +38 -0
  145. package/src/repository/repository.d.ts +164 -0
  146. package/src/repository/repository.js +207 -0
  147. package/src/repository/repository.spec.js +202 -0
  148. package/src/schema.d.ts +37 -0
  149. package/src/schema.js +41 -0
  150. package/src/types.d.ts +30 -0
  151. package/src/utils/capitalize.d.ts +6 -0
  152. package/src/utils/capitalize.js +10 -0
  153. package/src/utils/capitalize.spec.js +14 -0
  154. package/src/utils/clone-deep.d.ts +6 -0
  155. package/src/utils/clone-deep.js +61 -0
  156. package/src/utils/clone-deep.spec.js +28 -0
  157. package/src/utils/exclude-object-keys.d.ts +10 -0
  158. package/src/utils/exclude-object-keys.js +20 -0
  159. package/src/utils/exclude-object-keys.spec.js +49 -0
  160. package/src/utils/get-ctor-name.d.ts +6 -0
  161. package/src/utils/get-ctor-name.js +11 -0
  162. package/src/utils/get-ctor-name.spec.js +17 -0
  163. package/src/utils/get-value-by-path.d.ts +12 -0
  164. package/src/utils/get-value-by-path.js +23 -0
  165. package/src/utils/get-value-by-path.spec.js +36 -0
  166. package/src/utils/index.d.ts +10 -0
  167. package/src/utils/index.js +10 -0
  168. package/src/utils/is-ctor.d.ts +7 -0
  169. package/src/utils/is-ctor.js +10 -0
  170. package/src/utils/is-ctor.spec.js +26 -0
  171. package/src/utils/is-pure-object.d.ts +6 -0
  172. package/src/utils/is-pure-object.js +15 -0
  173. package/src/utils/is-pure-object.spec.js +25 -0
  174. package/src/utils/select-object-keys.d.ts +10 -0
  175. package/src/utils/select-object-keys.js +37 -0
  176. package/src/utils/select-object-keys.spec.js +40 -0
  177. package/src/utils/singularize.d.ts +6 -0
  178. package/src/utils/singularize.js +22 -0
  179. package/src/utils/singularize.spec.js +23 -0
  180. package/src/utils/string-to-regexp.d.ts +10 -0
  181. package/src/utils/string-to-regexp.js +22 -0
  182. package/src/utils/string-to-regexp.spec.js +35 -0
  183. package/tsconfig.json +9 -0
@@ -0,0 +1,653 @@
1
+ import {expect} from 'chai';
2
+ import {format} from '@e22m4u/js-format';
3
+ import {IncludeClauseTool} from './include-clause-tool.js';
4
+
5
+ describe('IncludeClauseTool', function () {
6
+ describe('validateIncludeClause', function () {
7
+ it('does not throw for valid values', function () {
8
+ const validate = v => IncludeClauseTool.validateIncludeClause(v);
9
+ // empty
10
+ validate(0);
11
+ validate('');
12
+ validate(null);
13
+ validate(undefined);
14
+ // strings
15
+ validate('foo');
16
+ // arrays
17
+ validate(['foo']);
18
+ validate([['foo']]);
19
+ validate([{foo: 'bar'}]);
20
+ validate([{foo: ['bar']}]);
21
+ validate([{foo: {bar: 'baz'}}]);
22
+ validate([{foo: [{bar: 'baz'}]}]);
23
+ validate([{relation: 'foo', scope: {where: {bar: 'baz'}}}]);
24
+ validate([{relation: 'foo', scope: {include: 'bar'}}]);
25
+ validate([{relation: 'foo', scope: {include: ['bar']}}]);
26
+ validate([{relation: 'foo', scope: {include: {bar: 'baz'}}}]);
27
+ validate([{relation: 'foo', scope: {include: [{bar: 'baz'}]}}]);
28
+ // objects
29
+ validate({foo: 'bar'});
30
+ validate({foo: ['bar']});
31
+ validate({foo: {bar: 'baz'}});
32
+ validate({foo: [{bar: 'baz'}]});
33
+ validate({relation: 'foo'});
34
+ validate({relation: 'foo', scope: {where: {bar: 'baz'}}});
35
+ validate({relation: 'foo', scope: {include: 'bar'}});
36
+ validate({relation: 'foo', scope: {include: ['bar']}});
37
+ validate({relation: 'foo', scope: {include: {bar: 'baz'}}});
38
+ validate({relation: 'foo', scope: {include: [{bar: 'baz'}]}});
39
+ });
40
+
41
+ it('throws an error for unsupported values', function () {
42
+ const validate = v => () => IncludeClauseTool.validateIncludeClause(v);
43
+ const createError = v =>
44
+ format(
45
+ 'The provided option "include" should have a value of ' +
46
+ 'following types: String, Object or Array, but %v given.',
47
+ v,
48
+ );
49
+ const testFor = v => {
50
+ const error = createError(v);
51
+ const clauses = [
52
+ v,
53
+ // arrays
54
+ [v],
55
+ [{foo: v}],
56
+ [{foo: [v]}],
57
+ [{foo: {bar: v}}],
58
+ [{foo: {bar: [v]}}],
59
+ [{foo: [{bar: v}]}],
60
+ [{foo: [{bar: [v]}]}],
61
+ [{relation: 'foo', scope: {include: v}}],
62
+ [{relation: 'foo', scope: {include: {bar: v}}}],
63
+ // objects
64
+ {foo: v},
65
+ {foo: [v]},
66
+ {foo: {bar: v}},
67
+ {foo: {bar: [v]}},
68
+ {foo: [{bar: v}]},
69
+ {foo: [{bar: [v]}]},
70
+ {relation: 'foo', scope: {include: v}},
71
+ {relation: 'foo', scope: {include: {bar: v}}},
72
+ ];
73
+ clauses.forEach(c => expect(validate(c)).to.throw(error));
74
+ };
75
+ testFor(10);
76
+ testFor(true);
77
+ testFor(() => undefined);
78
+ });
79
+
80
+ it('throws an error for duplicates', function () {
81
+ const validate = v => () => IncludeClauseTool.validateIncludeClause(v);
82
+ const error = 'The provided option "include" has duplicates of "foo".';
83
+ const clauses = [
84
+ ['foo', 'foo'],
85
+ [['foo'], 'foo'],
86
+ ['foo', ['foo']],
87
+ [['foo'], ['foo']],
88
+ ['foo', {foo: 'bar'}],
89
+ [{foo: 'bar'}, 'foo'],
90
+ [{foo: 'bar'}, {foo: 'bar'}],
91
+ [[{foo: 'bar'}], 'foo'],
92
+ ['foo', [{foo: 'bar'}]],
93
+ [[{foo: 'bar'}], [{foo: 'bar'}]],
94
+ ];
95
+ clauses.forEach(c => expect(validate(c)).to.throw(error));
96
+ validate({foo: 'foo'})();
97
+ validate([{foo: 'foo'}])();
98
+ });
99
+ });
100
+
101
+ describe('normalizeClause', function () {
102
+ it('normalizes a given string', function () {
103
+ const result = IncludeClauseTool.normalizeIncludeClause('test');
104
+ expect(result).to.be.eql([{relation: 'test'}]);
105
+ });
106
+
107
+ it('normalizes a free-form object', function () {
108
+ const result = IncludeClauseTool.normalizeIncludeClause({foo: 'bar'});
109
+ expect(result).to.be.eql([
110
+ {
111
+ relation: 'foo',
112
+ scope: {
113
+ include: [
114
+ {
115
+ relation: 'bar',
116
+ },
117
+ ],
118
+ },
119
+ },
120
+ ]);
121
+ });
122
+
123
+ it('normalizes a free-form object with a nested array', function () {
124
+ const result = IncludeClauseTool.normalizeIncludeClause({foo: ['bar']});
125
+ expect(result).to.be.eql([
126
+ {
127
+ relation: 'foo',
128
+ scope: {
129
+ include: [
130
+ {
131
+ relation: 'bar',
132
+ },
133
+ ],
134
+ },
135
+ },
136
+ ]);
137
+ });
138
+
139
+ it('normalizes a free-form object with a nested free-form object', function () {
140
+ const result = IncludeClauseTool.normalizeIncludeClause({
141
+ foo: {bar: 'baz'},
142
+ });
143
+ expect(result).to.be.eql([
144
+ {
145
+ relation: 'foo',
146
+ scope: {
147
+ include: [
148
+ {
149
+ relation: 'bar',
150
+ scope: {
151
+ include: [
152
+ {
153
+ relation: 'baz',
154
+ },
155
+ ],
156
+ },
157
+ },
158
+ ],
159
+ },
160
+ },
161
+ ]);
162
+ });
163
+
164
+ it('normalizes a free-form object with a nested inclusion object', function () {
165
+ const result = IncludeClauseTool.normalizeIncludeClause({
166
+ foo: {
167
+ relation: 'bar',
168
+ scope: {
169
+ where: {baz: 'qux'},
170
+ include: 'baz',
171
+ },
172
+ },
173
+ });
174
+ expect(result).to.be.eql([
175
+ {
176
+ relation: 'foo',
177
+ scope: {
178
+ include: [
179
+ {
180
+ relation: 'bar',
181
+ scope: {
182
+ where: {baz: 'qux'},
183
+ include: [
184
+ {
185
+ relation: 'baz',
186
+ },
187
+ ],
188
+ },
189
+ },
190
+ ],
191
+ },
192
+ },
193
+ ]);
194
+ });
195
+
196
+ it('normalizes an inclusion object', function () {
197
+ const result = IncludeClauseTool.normalizeIncludeClause({
198
+ relation: 'foo',
199
+ scope: {
200
+ where: {featured: true},
201
+ order: 'id',
202
+ skip: 5,
203
+ limit: 10,
204
+ fields: 'id',
205
+ include: 'bar',
206
+ },
207
+ });
208
+ expect(result).to.be.eql([
209
+ {
210
+ relation: 'foo',
211
+ scope: {
212
+ where: {featured: true},
213
+ order: 'id',
214
+ skip: 5,
215
+ limit: 10,
216
+ fields: 'id',
217
+ include: [
218
+ {
219
+ relation: 'bar',
220
+ },
221
+ ],
222
+ },
223
+ },
224
+ ]);
225
+ });
226
+
227
+ it('normalizes an inclusion object with a nested array', function () {
228
+ const result = IncludeClauseTool.normalizeIncludeClause({
229
+ relation: 'foo',
230
+ scope: {
231
+ where: {featured: true},
232
+ order: 'id',
233
+ skip: 5,
234
+ limit: 10,
235
+ fields: 'id',
236
+ include: ['bar'],
237
+ },
238
+ });
239
+ expect(result).to.be.eql([
240
+ {
241
+ relation: 'foo',
242
+ scope: {
243
+ where: {featured: true},
244
+ order: 'id',
245
+ skip: 5,
246
+ limit: 10,
247
+ fields: 'id',
248
+ include: [
249
+ {
250
+ relation: 'bar',
251
+ },
252
+ ],
253
+ },
254
+ },
255
+ ]);
256
+ });
257
+
258
+ it('normalizes an inclusion object with a nested free-form object', function () {
259
+ const result = IncludeClauseTool.normalizeIncludeClause({
260
+ relation: 'foo',
261
+ scope: {
262
+ where: {featured: true},
263
+ order: 'id',
264
+ skip: 5,
265
+ limit: 10,
266
+ fields: 'id',
267
+ include: {bar: 'baz'},
268
+ },
269
+ });
270
+ expect(result).to.be.eql([
271
+ {
272
+ relation: 'foo',
273
+ scope: {
274
+ where: {featured: true},
275
+ order: 'id',
276
+ skip: 5,
277
+ limit: 10,
278
+ fields: 'id',
279
+ include: [
280
+ {
281
+ relation: 'bar',
282
+ scope: {
283
+ include: [
284
+ {
285
+ relation: 'baz',
286
+ },
287
+ ],
288
+ },
289
+ },
290
+ ],
291
+ },
292
+ },
293
+ ]);
294
+ });
295
+
296
+ it('normalizes an inclusion object with a nested inclusion object', function () {
297
+ const result = IncludeClauseTool.normalizeIncludeClause({
298
+ relation: 'foo',
299
+ scope: {
300
+ where: {featured: true},
301
+ order: 'id',
302
+ skip: 5,
303
+ limit: 10,
304
+ fields: 'id',
305
+ include: [
306
+ {
307
+ relation: 'bar',
308
+ scope: {
309
+ where: {removed: false},
310
+ order: 'myId',
311
+ skip: 10,
312
+ limit: 5,
313
+ fields: ['id', 'removed'],
314
+ include: 'qwe',
315
+ },
316
+ },
317
+ ],
318
+ },
319
+ });
320
+ expect(result).to.be.eql([
321
+ {
322
+ relation: 'foo',
323
+ scope: {
324
+ where: {featured: true},
325
+ order: 'id',
326
+ skip: 5,
327
+ limit: 10,
328
+ fields: 'id',
329
+ include: [
330
+ {
331
+ relation: 'bar',
332
+ scope: {
333
+ where: {removed: false},
334
+ order: 'myId',
335
+ skip: 10,
336
+ limit: 5,
337
+ fields: ['id', 'removed'],
338
+ include: [
339
+ {
340
+ relation: 'qwe',
341
+ },
342
+ ],
343
+ },
344
+ },
345
+ ],
346
+ },
347
+ },
348
+ ]);
349
+ });
350
+
351
+ it('normalizes an array of strings', function () {
352
+ const result = IncludeClauseTool.normalizeIncludeClause(['foo', 'bar']);
353
+ expect(result).to.be.eql([
354
+ {
355
+ relation: 'foo',
356
+ },
357
+ {
358
+ relation: 'bar',
359
+ },
360
+ ]);
361
+ });
362
+
363
+ it('normalizes an array of nested free-form objects', function () {
364
+ const result = IncludeClauseTool.normalizeIncludeClause([
365
+ {foo: 'bar'},
366
+ {baz: 'qux'},
367
+ ]);
368
+ expect(result).to.be.eql([
369
+ {
370
+ relation: 'foo',
371
+ scope: {
372
+ include: [
373
+ {
374
+ relation: 'bar',
375
+ },
376
+ ],
377
+ },
378
+ },
379
+ {
380
+ relation: 'baz',
381
+ scope: {
382
+ include: [
383
+ {
384
+ relation: 'qux',
385
+ },
386
+ ],
387
+ },
388
+ },
389
+ ]);
390
+ });
391
+
392
+ it('normalizes an array of nested inclusion objects', function () {
393
+ const result = IncludeClauseTool.normalizeIncludeClause([
394
+ {
395
+ relation: 'foo',
396
+ scope: {
397
+ where: {featured: true},
398
+ order: 'id',
399
+ skip: 5,
400
+ limit: 10,
401
+ fields: 'id',
402
+ include: 'bar',
403
+ },
404
+ },
405
+ {
406
+ relation: 'baz',
407
+ },
408
+ ]);
409
+ expect(result).to.be.eql([
410
+ {
411
+ relation: 'foo',
412
+ scope: {
413
+ where: {featured: true},
414
+ order: 'id',
415
+ skip: 5,
416
+ limit: 10,
417
+ fields: 'id',
418
+ include: [
419
+ {
420
+ relation: 'bar',
421
+ },
422
+ ],
423
+ },
424
+ },
425
+ {
426
+ relation: 'baz',
427
+ },
428
+ ]);
429
+ });
430
+
431
+ it('normalizes an array of nested arrays', function () {
432
+ const result = IncludeClauseTool.normalizeIncludeClause([
433
+ ['foo'],
434
+ ['bar', ['baz']],
435
+ ]);
436
+ expect(result).to.be.eql([
437
+ {
438
+ relation: 'foo',
439
+ },
440
+ {
441
+ relation: 'bar',
442
+ },
443
+ {
444
+ relation: 'baz',
445
+ },
446
+ ]);
447
+ });
448
+
449
+ it('normalizes a free-form object with mixed inclusions', function () {
450
+ const result = IncludeClauseTool.normalizeIncludeClause({
451
+ // a string
452
+ foo: 'bar',
453
+ // an array
454
+ baz: ['qux'],
455
+ // a free-form object
456
+ bat: {qwe: 'asd'},
457
+ // an inclusion object
458
+ zxc: {
459
+ relation: 'rty',
460
+ scope: {
461
+ fields: ['id', 'featured'],
462
+ },
463
+ },
464
+ });
465
+ expect(result).to.be.eql([
466
+ // a string
467
+ {
468
+ relation: 'foo',
469
+ scope: {
470
+ include: [
471
+ {
472
+ relation: 'bar',
473
+ },
474
+ ],
475
+ },
476
+ },
477
+ // an array
478
+ {
479
+ relation: 'baz',
480
+ scope: {
481
+ include: [
482
+ {
483
+ relation: 'qux',
484
+ },
485
+ ],
486
+ },
487
+ },
488
+ // a free-form object
489
+ {
490
+ relation: 'bat',
491
+ scope: {
492
+ include: [
493
+ {
494
+ relation: 'qwe',
495
+ scope: {
496
+ include: [
497
+ {
498
+ relation: 'asd',
499
+ },
500
+ ],
501
+ },
502
+ },
503
+ ],
504
+ },
505
+ },
506
+ // an inclusion object
507
+ {
508
+ relation: 'zxc',
509
+ scope: {
510
+ include: [
511
+ {
512
+ relation: 'rty',
513
+ scope: {
514
+ fields: ['id', 'featured'],
515
+ },
516
+ },
517
+ ],
518
+ },
519
+ },
520
+ ]);
521
+ });
522
+
523
+ it('normalizes an array with mixed inclusions', function () {
524
+ const result = IncludeClauseTool.normalizeIncludeClause([
525
+ // a string
526
+ 'foo',
527
+ // a free-form object
528
+ {
529
+ bar: 'baz',
530
+ qux: {
531
+ relation: 'qwe',
532
+ },
533
+ },
534
+ // an inclusion object
535
+ {
536
+ relation: 'asd',
537
+ scope: {
538
+ include: 'zxc',
539
+ },
540
+ },
541
+ // a nested array
542
+ ['rty', 'fgh', ['vbn']],
543
+ ]);
544
+ expect(result).to.be.eql([
545
+ // a string
546
+ {
547
+ relation: 'foo',
548
+ },
549
+ // a free-form object
550
+ {
551
+ relation: 'bar',
552
+ scope: {
553
+ include: [
554
+ {
555
+ relation: 'baz',
556
+ },
557
+ ],
558
+ },
559
+ },
560
+ {
561
+ relation: 'qux',
562
+ scope: {
563
+ include: [
564
+ {
565
+ relation: 'qwe',
566
+ },
567
+ ],
568
+ },
569
+ },
570
+ // an inclusion object
571
+ {
572
+ relation: 'asd',
573
+ scope: {
574
+ include: [
575
+ {
576
+ relation: 'zxc',
577
+ },
578
+ ],
579
+ },
580
+ },
581
+ // a nested array
582
+ {
583
+ relation: 'rty',
584
+ },
585
+ {
586
+ relation: 'fgh',
587
+ },
588
+ {
589
+ relation: 'vbn',
590
+ },
591
+ ]);
592
+ });
593
+
594
+ it('throws an error for unsupported values', function () {
595
+ const validate = v => () => IncludeClauseTool.normalizeIncludeClause(v);
596
+ const createError = v =>
597
+ format(
598
+ 'The provided option "include" should have a value of ' +
599
+ 'following types: String, Object or Array, but %v given.',
600
+ v,
601
+ );
602
+ const testFor = v => {
603
+ const error = createError(v);
604
+ const clauses = [
605
+ v,
606
+ // arrays
607
+ [v],
608
+ [{foo: v}],
609
+ [{foo: [v]}],
610
+ [{foo: {bar: v}}],
611
+ [{foo: {bar: [v]}}],
612
+ [{foo: [{bar: v}]}],
613
+ [{foo: [{bar: [v]}]}],
614
+ [{relation: 'foo', scope: {include: v}}],
615
+ [{relation: 'foo', scope: {include: {bar: v}}}],
616
+ // objects
617
+ {foo: v},
618
+ {foo: [v]},
619
+ {foo: {bar: v}},
620
+ {foo: {bar: [v]}},
621
+ {foo: [{bar: v}]},
622
+ {foo: [{bar: [v]}]},
623
+ {relation: 'foo', scope: {include: v}},
624
+ {relation: 'foo', scope: {include: {bar: v}}},
625
+ ];
626
+ clauses.forEach(c => expect(validate(c)).to.throw(error));
627
+ };
628
+ testFor(10);
629
+ testFor(true);
630
+ testFor(() => undefined);
631
+ });
632
+
633
+ it('throws an error for duplicates', function () {
634
+ const validate = v => () => IncludeClauseTool.normalizeIncludeClause(v);
635
+ const error = 'The provided option "include" has duplicates of "foo".';
636
+ const clauses = [
637
+ ['foo', 'foo'],
638
+ [['foo'], 'foo'],
639
+ ['foo', ['foo']],
640
+ [['foo'], ['foo']],
641
+ ['foo', {foo: 'bar'}],
642
+ [{foo: 'bar'}, 'foo'],
643
+ [{foo: 'bar'}, {foo: 'bar'}],
644
+ [[{foo: 'bar'}], 'foo'],
645
+ ['foo', [{foo: 'bar'}]],
646
+ [[{foo: 'bar'}], [{foo: 'bar'}]],
647
+ ];
648
+ clauses.forEach(c => expect(validate(c)).to.throw(error));
649
+ validate({foo: 'foo'})();
650
+ validate([{foo: 'foo'}])();
651
+ });
652
+ });
653
+ });
@@ -0,0 +1,7 @@
1
+ export * from './filter.js';
2
+ export * from './slice-clause-tool.js';
3
+ export * from './order-clause-tool.js';
4
+ export * from './where-clause-tool.js';
5
+ export * from './fields-clause-tool.js';
6
+ export * from './include-clause-tool.js';
7
+ export * from './operator-clause-tool.js';
@@ -0,0 +1,6 @@
1
+ export * from './slice-clause-tool.js';
2
+ export * from './order-clause-tool.js';
3
+ export * from './where-clause-tool.js';
4
+ export * from './fields-clause-tool.js';
5
+ export * from './include-clause-tool.js';
6
+ export * from './operator-clause-tool.js';