@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,364 @@
1
+ import {Service} from '@e22m4u/js-service';
2
+ import {RelationType} from '../definition/index.js';
3
+ import {HasOneResolver} from '../relations/index.js';
4
+ import {HasManyResolver} from '../relations/index.js';
5
+ import {WhereClauseTool} from './where-clause-tool.js';
6
+ import {OrderClauseTool} from './order-clause-tool.js';
7
+ import {SliceClauseTool} from './slice-clause-tool.js';
8
+ import {InvalidArgumentError} from '../errors/index.js';
9
+ import {BelongsToResolver} from '../relations/index.js';
10
+ import {FieldsClauseTool} from './fields-clause-tool.js';
11
+ import {ModelDefinitionUtils} from '../definition/index.js';
12
+ import {ReferencesManyResolver} from '../relations/index.js';
13
+
14
+ /**
15
+ * Include clause tool.
16
+ *
17
+ * @typedef {string|string[]|object|object[]} IncludeClause
18
+ */
19
+ export class IncludeClauseTool extends Service {
20
+ /**
21
+ * Include to.
22
+ *
23
+ * @param {object[]} entities
24
+ * @param {string} modelName
25
+ * @param {IncludeClause|undefined} clause
26
+ * @returns {Promise<void>}
27
+ */
28
+ async includeTo(entities, modelName, clause) {
29
+ clause = IncludeClauseTool.normalizeIncludeClause(clause);
30
+ const promises = [];
31
+ clause.forEach(inclusion => {
32
+ const relDef = this.getService(
33
+ ModelDefinitionUtils,
34
+ ).getRelationDefinitionByName(modelName, inclusion.relation);
35
+ switch (relDef.type) {
36
+ // BELONGS_TO
37
+ case RelationType.BELONGS_TO:
38
+ if (relDef.polymorphic) {
39
+ promises.push(
40
+ this.getService(BelongsToResolver).includePolymorphicTo(
41
+ entities,
42
+ modelName,
43
+ inclusion.relation,
44
+ relDef.foreignKey,
45
+ relDef.discriminator,
46
+ inclusion.scope,
47
+ ),
48
+ );
49
+ } else {
50
+ promises.push(
51
+ this.getService(BelongsToResolver).includeTo(
52
+ entities,
53
+ modelName,
54
+ relDef.model,
55
+ inclusion.relation,
56
+ relDef.foreignKey,
57
+ inclusion.scope,
58
+ ),
59
+ );
60
+ }
61
+ break;
62
+ // HAS_ONE
63
+ case RelationType.HAS_ONE:
64
+ if (relDef.polymorphic && typeof relDef.polymorphic === 'string') {
65
+ promises.push(
66
+ this.getService(HasOneResolver).includePolymorphicByRelationName(
67
+ entities,
68
+ modelName,
69
+ relDef.model,
70
+ inclusion.relation,
71
+ relDef.polymorphic,
72
+ inclusion.scope,
73
+ ),
74
+ );
75
+ } else if (relDef.polymorphic) {
76
+ promises.push(
77
+ this.getService(HasOneResolver).includePolymorphicTo(
78
+ entities,
79
+ modelName,
80
+ relDef.model,
81
+ inclusion.relation,
82
+ relDef.foreignKey,
83
+ relDef.discriminator,
84
+ inclusion.scope,
85
+ ),
86
+ );
87
+ } else {
88
+ promises.push(
89
+ this.getService(HasOneResolver).includeTo(
90
+ entities,
91
+ modelName,
92
+ relDef.model,
93
+ inclusion.relation,
94
+ relDef.foreignKey,
95
+ inclusion.scope,
96
+ ),
97
+ );
98
+ }
99
+ break;
100
+ // HAS_MANY
101
+ case RelationType.HAS_MANY:
102
+ if (relDef.polymorphic && typeof relDef.polymorphic === 'string') {
103
+ promises.push(
104
+ this.getService(HasManyResolver).includePolymorphicByRelationName(
105
+ entities,
106
+ modelName,
107
+ relDef.model,
108
+ inclusion.relation,
109
+ relDef.polymorphic,
110
+ inclusion.scope,
111
+ ),
112
+ );
113
+ } else if (relDef.polymorphic) {
114
+ promises.push(
115
+ this.getService(HasManyResolver).includePolymorphicTo(
116
+ entities,
117
+ modelName,
118
+ relDef.model,
119
+ inclusion.relation,
120
+ relDef.foreignKey,
121
+ relDef.discriminator,
122
+ inclusion.scope,
123
+ ),
124
+ );
125
+ } else {
126
+ promises.push(
127
+ this.getService(HasManyResolver).includeTo(
128
+ entities,
129
+ modelName,
130
+ relDef.model,
131
+ inclusion.relation,
132
+ relDef.foreignKey,
133
+ inclusion.scope,
134
+ ),
135
+ );
136
+ }
137
+ break;
138
+ case RelationType.REFERENCES_MANY:
139
+ promises.push(
140
+ this.getService(ReferencesManyResolver).includeTo(
141
+ entities,
142
+ modelName,
143
+ relDef.model,
144
+ inclusion.relation,
145
+ relDef.foreignKey,
146
+ inclusion.scope,
147
+ ),
148
+ );
149
+ break;
150
+ default:
151
+ throw new InvalidArgumentError(
152
+ 'The relation type %v does not have an inclusion resolver.',
153
+ relDef.type,
154
+ );
155
+ }
156
+ });
157
+ await Promise.all(promises);
158
+ }
159
+
160
+ /**
161
+ * Validate include clause.
162
+ *
163
+ * @param {IncludeClause|undefined} clause
164
+ */
165
+ static validateIncludeClause(clause) {
166
+ if (!clause) {
167
+ // empty
168
+ } else if (typeof clause === 'string') {
169
+ // string
170
+ } else if (Array.isArray(clause)) {
171
+ // array
172
+ const relNames = [];
173
+ clause.flat().forEach(el => {
174
+ this.validateIncludeClause(el);
175
+ if (typeof el === 'string') {
176
+ relNames.push(el);
177
+ } else if (typeof el === 'object') {
178
+ Object.keys(el).forEach(key => {
179
+ if (Object.prototype.hasOwnProperty.call(el, key))
180
+ relNames.push(key);
181
+ });
182
+ }
183
+ });
184
+ // duplicates checking
185
+ const duplicateNames = relNames.filter(
186
+ (name, i) => relNames.indexOf(name) !== i,
187
+ );
188
+ if (duplicateNames.length)
189
+ throw new InvalidArgumentError(
190
+ 'The provided option "include" has duplicates of %v.',
191
+ duplicateNames[0],
192
+ );
193
+ } else if (typeof clause === 'object') {
194
+ // object
195
+ if ('relation' in clause) {
196
+ // {relation: 'name', scope: {}}
197
+ if (!clause.relation || typeof clause.relation !== 'string')
198
+ throw new InvalidArgumentError(
199
+ 'The provided option "relation" should be ' +
200
+ 'a non-empty String, but %v given.',
201
+ clause.relation,
202
+ );
203
+ if ('scope' in clause && clause) this.validateScopeClause(clause.scope);
204
+ } else {
205
+ // {foo: 'bar', 'baz': ['qux'], ...}
206
+ Object.keys(clause).forEach(key => {
207
+ if (!Object.prototype.hasOwnProperty.call(clause, key)) return;
208
+ this.validateIncludeClause(clause[key]);
209
+ });
210
+ }
211
+ } else {
212
+ // unknown.
213
+ throw new InvalidArgumentError(
214
+ 'The provided option "include" should have a value of ' +
215
+ 'following types: String, Object or Array, but %v given.',
216
+ clause,
217
+ );
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Validate scope clause.
223
+ *
224
+ * @param {object|undefined} clause
225
+ */
226
+ static validateScopeClause(clause) {
227
+ if (!clause) return;
228
+ if (typeof clause !== 'object' || Array.isArray(clause))
229
+ throw new InvalidArgumentError(
230
+ 'The provided option "scope" should be an Object, but %v given.',
231
+ clause,
232
+ );
233
+ if ('where' in clause && clause.where)
234
+ WhereClauseTool.validateWhereClause(clause.where);
235
+ if ('order' in clause && clause.order)
236
+ OrderClauseTool.validateOrderClause(clause.order);
237
+ if ('skip' in clause && clause.skip)
238
+ SliceClauseTool.validateSkipClause(clause.skip);
239
+ if ('limit' in clause && clause.limit)
240
+ SliceClauseTool.validateLimitClause(clause.limit);
241
+ if ('fields' in clause && clause.fields)
242
+ FieldsClauseTool.validateFieldsClause(clause.fields);
243
+ if ('include' in clause && clause.include)
244
+ IncludeClauseTool.validateIncludeClause(clause.include);
245
+ }
246
+
247
+ /**
248
+ * Normalize include clause.
249
+ *
250
+ * @param {IncludeClause|undefined} clause
251
+ * @returns {object[]}
252
+ */
253
+ static normalizeIncludeClause(clause) {
254
+ let result = [];
255
+ if (!clause) {
256
+ // empty
257
+ return result;
258
+ } else if (typeof clause === 'string') {
259
+ // string
260
+ result.push({relation: clause});
261
+ } 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
+ }
272
+ result = [...result, ...el];
273
+ });
274
+ // duplicates checking
275
+ const relNames = result.map(v => v.relation);
276
+ const duplicateNames = relNames.filter(
277
+ (name, i) => relNames.indexOf(name) !== i,
278
+ );
279
+ if (duplicateNames.length)
280
+ throw new InvalidArgumentError(
281
+ 'The provided option "include" has duplicates of %v.',
282
+ duplicateNames[0],
283
+ );
284
+ } else if (typeof clause === 'object') {
285
+ // object
286
+ if ('relation' in clause) {
287
+ // {relation: 'name', scope: {...}}
288
+ if (!clause.relation || typeof clause.relation !== 'string')
289
+ throw new InvalidArgumentError(
290
+ 'The provided option "relation" should be ' +
291
+ 'a non-empty String, but %v given.',
292
+ clause.relation,
293
+ );
294
+ const normalized = {relation: clause.relation};
295
+ const scope = this.normalizeScopeClause(clause.scope);
296
+ if (scope) normalized.scope = scope;
297
+ result.push(normalized);
298
+ } else {
299
+ // {foo: 'bar', baz: ['qux'], ...}
300
+ Object.keys(clause).forEach(key => {
301
+ if (!Object.prototype.hasOwnProperty.call(clause, key)) return;
302
+ const normalized = {relation: key};
303
+ const include = this.normalizeIncludeClause(clause[key]);
304
+ if (include.length) normalized.scope = {include};
305
+ result.push(normalized);
306
+ });
307
+ }
308
+ } else {
309
+ // unknown
310
+ throw new InvalidArgumentError(
311
+ 'The provided option "include" should have a value of ' +
312
+ 'following types: String, Object or Array, but %v given.',
313
+ clause,
314
+ );
315
+ }
316
+ return result;
317
+ }
318
+
319
+ /**
320
+ * Normalize scope clause.
321
+ *
322
+ * @param {object|undefined} clause
323
+ * @returns {object|undefined}
324
+ */
325
+ static normalizeScopeClause(clause) {
326
+ if (!clause) return;
327
+ if (typeof clause !== 'object' || Array.isArray(clause))
328
+ throw new InvalidArgumentError(
329
+ 'The provided option "scope" should be an Object, but %v given.',
330
+ clause,
331
+ );
332
+ const result = {};
333
+ // {where: ...}
334
+ if ('where' in clause && clause.where) {
335
+ WhereClauseTool.validateWhereClause(clause.where);
336
+ result.where = clause.where;
337
+ }
338
+ // {order: ...}
339
+ if ('order' in clause && clause.order) {
340
+ OrderClauseTool.validateOrderClause(clause.order);
341
+ result.order = clause.order;
342
+ }
343
+ // {skip: ...}
344
+ if ('skip' in clause && clause.skip) {
345
+ SliceClauseTool.validateSkipClause(clause.skip);
346
+ result.skip = clause.skip;
347
+ }
348
+ // {limit: ...}
349
+ if ('limit' in clause && clause.limit) {
350
+ SliceClauseTool.validateLimitClause(clause.limit);
351
+ result.limit = clause.limit;
352
+ }
353
+ // {fields: ...}
354
+ if ('fields' in clause && clause.fields) {
355
+ FieldsClauseTool.validateFieldsClause(clause.fields);
356
+ result.fields = clause.fields;
357
+ }
358
+ // {include: ...}
359
+ if ('include' in clause && clause.include)
360
+ result.include = this.normalizeIncludeClause(clause.include);
361
+ if (Object.keys(result).length) return result;
362
+ return undefined;
363
+ }
364
+ }