@e22m4u/js-repository 0.8.5 → 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 +27 -23
- package/dist/cjs/index.cjs +746 -325
- package/eslint.config.js +1 -0
- package/package.json +14 -13
- 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 +68 -26
- 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 +26 -10
- package/src/definition/model/properties/property-uniqueness-validator.spec.js +500 -38
- 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
|
@@ -27,42 +27,48 @@ export class HasManyResolver extends Service {
|
|
|
27
27
|
foreignKey,
|
|
28
28
|
scope = undefined,
|
|
29
29
|
) {
|
|
30
|
-
if (!entities || !Array.isArray(entities))
|
|
30
|
+
if (!entities || !Array.isArray(entities)) {
|
|
31
31
|
throw new InvalidArgumentError(
|
|
32
32
|
'The parameter "entities" of HasManyResolver.includeTo requires ' +
|
|
33
33
|
'an Array of Object, but %v was given.',
|
|
34
34
|
entities,
|
|
35
35
|
);
|
|
36
|
-
|
|
36
|
+
}
|
|
37
|
+
if (!sourceName || typeof sourceName !== 'string') {
|
|
37
38
|
throw new InvalidArgumentError(
|
|
38
39
|
'The parameter "sourceName" of HasManyResolver.includeTo requires ' +
|
|
39
40
|
'a non-empty String, but %v was given.',
|
|
40
41
|
sourceName,
|
|
41
42
|
);
|
|
42
|
-
|
|
43
|
+
}
|
|
44
|
+
if (!targetName || typeof targetName !== 'string') {
|
|
43
45
|
throw new InvalidArgumentError(
|
|
44
46
|
'The parameter "targetName" of HasManyResolver.includeTo requires ' +
|
|
45
47
|
'a non-empty String, but %v was given.',
|
|
46
48
|
targetName,
|
|
47
49
|
);
|
|
48
|
-
|
|
50
|
+
}
|
|
51
|
+
if (!relationName || typeof relationName !== 'string') {
|
|
49
52
|
throw new InvalidArgumentError(
|
|
50
53
|
'The parameter "relationName" of HasManyResolver.includeTo requires ' +
|
|
51
54
|
'a non-empty String, but %v was given.',
|
|
52
55
|
relationName,
|
|
53
56
|
);
|
|
54
|
-
|
|
57
|
+
}
|
|
58
|
+
if (!foreignKey || typeof foreignKey !== 'string') {
|
|
55
59
|
throw new InvalidArgumentError(
|
|
56
60
|
'The parameter "foreignKey" of HasManyResolver.includeTo requires ' +
|
|
57
61
|
'a non-empty String, but %v was given.',
|
|
58
62
|
foreignKey,
|
|
59
63
|
);
|
|
60
|
-
|
|
64
|
+
}
|
|
65
|
+
if (scope && (typeof scope !== 'object' || Array.isArray(scope))) {
|
|
61
66
|
throw new InvalidArgumentError(
|
|
62
67
|
'The provided parameter "scope" of HasManyResolver.includeTo ' +
|
|
63
68
|
'should be an Object, but %v was given.',
|
|
64
69
|
scope,
|
|
65
70
|
);
|
|
71
|
+
}
|
|
66
72
|
|
|
67
73
|
const sourcePkPropName =
|
|
68
74
|
this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
|
|
@@ -70,14 +76,17 @@ export class HasManyResolver extends Service {
|
|
|
70
76
|
);
|
|
71
77
|
const sourceIds = [];
|
|
72
78
|
entities.forEach(entity => {
|
|
73
|
-
if (!entity || typeof entity !== 'object' || Array.isArray(entity))
|
|
79
|
+
if (!entity || typeof entity !== 'object' || Array.isArray(entity)) {
|
|
74
80
|
throw new InvalidArgumentError(
|
|
75
81
|
'The parameter "entities" of HasManyResolver.includeTo requires ' +
|
|
76
82
|
'an Array of Object, but %v was given.',
|
|
77
83
|
entity,
|
|
78
84
|
);
|
|
85
|
+
}
|
|
79
86
|
const sourceId = entity[sourcePkPropName];
|
|
80
|
-
if (sourceIds.includes(sourceId))
|
|
87
|
+
if (sourceIds.includes(sourceId)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
81
90
|
sourceIds.push(sourceId);
|
|
82
91
|
});
|
|
83
92
|
|
|
@@ -130,48 +139,55 @@ export class HasManyResolver extends Service {
|
|
|
130
139
|
discriminator,
|
|
131
140
|
scope = undefined,
|
|
132
141
|
) {
|
|
133
|
-
if (!entities || !Array.isArray(entities))
|
|
142
|
+
if (!entities || !Array.isArray(entities)) {
|
|
134
143
|
throw new InvalidArgumentError(
|
|
135
144
|
'The parameter "entities" of HasManyResolver.includePolymorphicTo requires ' +
|
|
136
145
|
'an Array of Object, but %v was given.',
|
|
137
146
|
entities,
|
|
138
147
|
);
|
|
139
|
-
|
|
148
|
+
}
|
|
149
|
+
if (!sourceName || typeof sourceName !== 'string') {
|
|
140
150
|
throw new InvalidArgumentError(
|
|
141
151
|
'The parameter "sourceName" of HasManyResolver.includePolymorphicTo requires ' +
|
|
142
152
|
'a non-empty String, but %v was given.',
|
|
143
153
|
sourceName,
|
|
144
154
|
);
|
|
145
|
-
|
|
155
|
+
}
|
|
156
|
+
if (!targetName || typeof targetName !== 'string') {
|
|
146
157
|
throw new InvalidArgumentError(
|
|
147
158
|
'The parameter "targetName" of HasManyResolver.includePolymorphicTo requires ' +
|
|
148
159
|
'a non-empty String, but %v was given.',
|
|
149
160
|
targetName,
|
|
150
161
|
);
|
|
151
|
-
|
|
162
|
+
}
|
|
163
|
+
if (!relationName || typeof relationName !== 'string') {
|
|
152
164
|
throw new InvalidArgumentError(
|
|
153
165
|
'The parameter "relationName" of HasManyResolver.includePolymorphicTo requires ' +
|
|
154
166
|
'a non-empty String, but %v was given.',
|
|
155
167
|
relationName,
|
|
156
168
|
);
|
|
157
|
-
|
|
169
|
+
}
|
|
170
|
+
if (!foreignKey || typeof foreignKey !== 'string') {
|
|
158
171
|
throw new InvalidArgumentError(
|
|
159
172
|
'The parameter "foreignKey" of HasManyResolver.includePolymorphicTo requires ' +
|
|
160
173
|
'a non-empty String, but %v was given.',
|
|
161
174
|
foreignKey,
|
|
162
175
|
);
|
|
163
|
-
|
|
176
|
+
}
|
|
177
|
+
if (!discriminator || typeof discriminator !== 'string') {
|
|
164
178
|
throw new InvalidArgumentError(
|
|
165
179
|
'The parameter "discriminator" of HasManyResolver.includePolymorphicTo requires ' +
|
|
166
180
|
'a non-empty String, but %v was given.',
|
|
167
181
|
discriminator,
|
|
168
182
|
);
|
|
169
|
-
|
|
183
|
+
}
|
|
184
|
+
if (scope && (typeof scope !== 'object' || Array.isArray(scope))) {
|
|
170
185
|
throw new InvalidArgumentError(
|
|
171
186
|
'The provided parameter "scope" of HasManyResolver.includePolymorphicTo ' +
|
|
172
187
|
'should be an Object, but %v was given.',
|
|
173
188
|
scope,
|
|
174
189
|
);
|
|
190
|
+
}
|
|
175
191
|
|
|
176
192
|
const sourcePkPropName =
|
|
177
193
|
this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
|
|
@@ -179,14 +195,17 @@ export class HasManyResolver extends Service {
|
|
|
179
195
|
);
|
|
180
196
|
const sourceIds = [];
|
|
181
197
|
entities.forEach(entity => {
|
|
182
|
-
if (!entity || typeof entity !== 'object' || Array.isArray(entity))
|
|
198
|
+
if (!entity || typeof entity !== 'object' || Array.isArray(entity)) {
|
|
183
199
|
throw new InvalidArgumentError(
|
|
184
200
|
'The parameter "entities" of HasManyResolver.includePolymorphicTo requires ' +
|
|
185
201
|
'an Array of Object, but %v was given.',
|
|
186
202
|
entity,
|
|
187
203
|
);
|
|
204
|
+
}
|
|
188
205
|
const sourceId = entity[sourcePkPropName];
|
|
189
|
-
if (sourceIds.includes(sourceId))
|
|
206
|
+
if (sourceIds.includes(sourceId)) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
190
209
|
sourceIds.push(sourceId);
|
|
191
210
|
});
|
|
192
211
|
|
|
@@ -240,47 +259,53 @@ export class HasManyResolver extends Service {
|
|
|
240
259
|
targetRelationName,
|
|
241
260
|
scope = undefined,
|
|
242
261
|
) {
|
|
243
|
-
if (!entities || !Array.isArray(entities))
|
|
262
|
+
if (!entities || !Array.isArray(entities)) {
|
|
244
263
|
throw new InvalidArgumentError(
|
|
245
264
|
'The parameter "entities" of HasManyResolver.includePolymorphicByRelationName requires ' +
|
|
246
265
|
'an Array of Object, but %v was given.',
|
|
247
266
|
entities,
|
|
248
267
|
);
|
|
249
|
-
|
|
268
|
+
}
|
|
269
|
+
if (!sourceName || typeof sourceName !== 'string') {
|
|
250
270
|
throw new InvalidArgumentError(
|
|
251
271
|
'The parameter "sourceName" of HasManyResolver.includePolymorphicByRelationName requires ' +
|
|
252
272
|
'a non-empty String, but %v was given.',
|
|
253
273
|
sourceName,
|
|
254
274
|
);
|
|
255
|
-
|
|
275
|
+
}
|
|
276
|
+
if (!targetName || typeof targetName !== 'string') {
|
|
256
277
|
throw new InvalidArgumentError(
|
|
257
278
|
'The parameter "targetName" of HasManyResolver.includePolymorphicByRelationName requires ' +
|
|
258
279
|
'a non-empty String, but %v was given.',
|
|
259
280
|
targetName,
|
|
260
281
|
);
|
|
261
|
-
|
|
282
|
+
}
|
|
283
|
+
if (!relationName || typeof relationName !== 'string') {
|
|
262
284
|
throw new InvalidArgumentError(
|
|
263
285
|
'The parameter "relationName" of HasManyResolver.includePolymorphicByRelationName requires ' +
|
|
264
286
|
'a non-empty String, but %v was given.',
|
|
265
287
|
relationName,
|
|
266
288
|
);
|
|
267
|
-
|
|
289
|
+
}
|
|
290
|
+
if (!targetRelationName || typeof targetRelationName !== 'string') {
|
|
268
291
|
throw new InvalidArgumentError(
|
|
269
292
|
'The parameter "targetRelationName" of HasManyResolver.includePolymorphicByRelationName requires ' +
|
|
270
293
|
'a non-empty String, but %v was given.',
|
|
271
294
|
targetRelationName,
|
|
272
295
|
);
|
|
273
|
-
|
|
296
|
+
}
|
|
297
|
+
if (scope && (typeof scope !== 'object' || Array.isArray(scope))) {
|
|
274
298
|
throw new InvalidArgumentError(
|
|
275
299
|
'The provided parameter "scope" of HasManyResolver.includePolymorphicByRelationName ' +
|
|
276
300
|
'should be an Object, but %v was given.',
|
|
277
301
|
scope,
|
|
278
302
|
);
|
|
303
|
+
}
|
|
279
304
|
|
|
280
305
|
const targetRelationDef = this.getService(
|
|
281
306
|
ModelDefinitionUtils,
|
|
282
307
|
).getRelationDefinitionByName(targetName, targetRelationName);
|
|
283
|
-
if (targetRelationDef.type !== RelationType.BELONGS_TO)
|
|
308
|
+
if (targetRelationDef.type !== RelationType.BELONGS_TO) {
|
|
284
309
|
throw new InvalidArgumentError(
|
|
285
310
|
'The relation %v of the model %v is a polymorphic "hasMany" relation, ' +
|
|
286
311
|
'so it requires the target relation %v to be a polymorphic "belongsTo", ' +
|
|
@@ -290,7 +315,8 @@ export class HasManyResolver extends Service {
|
|
|
290
315
|
targetRelationName,
|
|
291
316
|
targetRelationDef.type,
|
|
292
317
|
);
|
|
293
|
-
|
|
318
|
+
}
|
|
319
|
+
if (!targetRelationDef.polymorphic) {
|
|
294
320
|
throw new InvalidArgumentError(
|
|
295
321
|
'The relation %v of the model %v is a polymorphic "hasMany" relation, ' +
|
|
296
322
|
'so it requires the target relation %v to be a polymorphic too.',
|
|
@@ -298,6 +324,7 @@ export class HasManyResolver extends Service {
|
|
|
298
324
|
sourceName,
|
|
299
325
|
targetRelationName,
|
|
300
326
|
);
|
|
327
|
+
}
|
|
301
328
|
const foreignKey =
|
|
302
329
|
targetRelationDef.foreignKey || `${targetRelationName}Id`;
|
|
303
330
|
const discriminator =
|
|
@@ -27,42 +27,48 @@ export class HasOneResolver extends Service {
|
|
|
27
27
|
foreignKey,
|
|
28
28
|
scope = undefined,
|
|
29
29
|
) {
|
|
30
|
-
if (!entities || !Array.isArray(entities))
|
|
30
|
+
if (!entities || !Array.isArray(entities)) {
|
|
31
31
|
throw new InvalidArgumentError(
|
|
32
32
|
'The parameter "entities" of HasOneResolver.includeTo requires ' +
|
|
33
33
|
'an Array of Object, but %v was given.',
|
|
34
34
|
entities,
|
|
35
35
|
);
|
|
36
|
-
|
|
36
|
+
}
|
|
37
|
+
if (!sourceName || typeof sourceName !== 'string') {
|
|
37
38
|
throw new InvalidArgumentError(
|
|
38
39
|
'The parameter "sourceName" of HasOneResolver.includeTo requires ' +
|
|
39
40
|
'a non-empty String, but %v was given.',
|
|
40
41
|
sourceName,
|
|
41
42
|
);
|
|
42
|
-
|
|
43
|
+
}
|
|
44
|
+
if (!targetName || typeof targetName !== 'string') {
|
|
43
45
|
throw new InvalidArgumentError(
|
|
44
46
|
'The parameter "targetName" of HasOneResolver.includeTo requires ' +
|
|
45
47
|
'a non-empty String, but %v was given.',
|
|
46
48
|
targetName,
|
|
47
49
|
);
|
|
48
|
-
|
|
50
|
+
}
|
|
51
|
+
if (!relationName || typeof relationName !== 'string') {
|
|
49
52
|
throw new InvalidArgumentError(
|
|
50
53
|
'The parameter "relationName" of HasOneResolver.includeTo requires ' +
|
|
51
54
|
'a non-empty String, but %v was given.',
|
|
52
55
|
relationName,
|
|
53
56
|
);
|
|
54
|
-
|
|
57
|
+
}
|
|
58
|
+
if (!foreignKey || typeof foreignKey !== 'string') {
|
|
55
59
|
throw new InvalidArgumentError(
|
|
56
60
|
'The parameter "foreignKey" of HasOneResolver.includeTo requires ' +
|
|
57
61
|
'a non-empty String, but %v was given.',
|
|
58
62
|
foreignKey,
|
|
59
63
|
);
|
|
60
|
-
|
|
64
|
+
}
|
|
65
|
+
if (scope && (typeof scope !== 'object' || Array.isArray(scope))) {
|
|
61
66
|
throw new InvalidArgumentError(
|
|
62
67
|
'The provided parameter "scope" of HasOneResolver.includeTo ' +
|
|
63
68
|
'should be an Object, but %v was given.',
|
|
64
69
|
scope,
|
|
65
70
|
);
|
|
71
|
+
}
|
|
66
72
|
|
|
67
73
|
const sourcePkPropName =
|
|
68
74
|
this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
|
|
@@ -70,14 +76,17 @@ export class HasOneResolver extends Service {
|
|
|
70
76
|
);
|
|
71
77
|
const sourceIds = [];
|
|
72
78
|
entities.forEach(entity => {
|
|
73
|
-
if (!entity || typeof entity !== 'object' || Array.isArray(entity))
|
|
79
|
+
if (!entity || typeof entity !== 'object' || Array.isArray(entity)) {
|
|
74
80
|
throw new InvalidArgumentError(
|
|
75
81
|
'The parameter "entities" of HasOneResolver.includeTo requires ' +
|
|
76
82
|
'an Array of Object, but %v was given.',
|
|
77
83
|
entity,
|
|
78
84
|
);
|
|
85
|
+
}
|
|
79
86
|
const sourceId = entity[sourcePkPropName];
|
|
80
|
-
if (sourceIds.includes(sourceId))
|
|
87
|
+
if (sourceIds.includes(sourceId)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
81
90
|
sourceIds.push(sourceId);
|
|
82
91
|
});
|
|
83
92
|
|
|
@@ -94,7 +103,9 @@ export class HasOneResolver extends Service {
|
|
|
94
103
|
filter.limit = 1;
|
|
95
104
|
promises.push(
|
|
96
105
|
targetRepository.find(filter).then(result => {
|
|
97
|
-
if (result.length)
|
|
106
|
+
if (result.length) {
|
|
107
|
+
targetBySourceId.set(sourceId, result[0]);
|
|
108
|
+
}
|
|
98
109
|
}),
|
|
99
110
|
);
|
|
100
111
|
});
|
|
@@ -127,48 +138,55 @@ export class HasOneResolver extends Service {
|
|
|
127
138
|
discriminator,
|
|
128
139
|
scope = undefined,
|
|
129
140
|
) {
|
|
130
|
-
if (!entities || !Array.isArray(entities))
|
|
141
|
+
if (!entities || !Array.isArray(entities)) {
|
|
131
142
|
throw new InvalidArgumentError(
|
|
132
143
|
'The parameter "entities" of HasOneResolver.includePolymorphicTo requires ' +
|
|
133
144
|
'an Array of Object, but %v was given.',
|
|
134
145
|
entities,
|
|
135
146
|
);
|
|
136
|
-
|
|
147
|
+
}
|
|
148
|
+
if (!sourceName || typeof sourceName !== 'string') {
|
|
137
149
|
throw new InvalidArgumentError(
|
|
138
150
|
'The parameter "sourceName" of HasOneResolver.includePolymorphicTo requires ' +
|
|
139
151
|
'a non-empty String, but %v was given.',
|
|
140
152
|
sourceName,
|
|
141
153
|
);
|
|
142
|
-
|
|
154
|
+
}
|
|
155
|
+
if (!targetName || typeof targetName !== 'string') {
|
|
143
156
|
throw new InvalidArgumentError(
|
|
144
157
|
'The parameter "targetName" of HasOneResolver.includePolymorphicTo requires ' +
|
|
145
158
|
'a non-empty String, but %v was given.',
|
|
146
159
|
targetName,
|
|
147
160
|
);
|
|
148
|
-
|
|
161
|
+
}
|
|
162
|
+
if (!relationName || typeof relationName !== 'string') {
|
|
149
163
|
throw new InvalidArgumentError(
|
|
150
164
|
'The parameter "relationName" of HasOneResolver.includePolymorphicTo requires ' +
|
|
151
165
|
'a non-empty String, but %v was given.',
|
|
152
166
|
relationName,
|
|
153
167
|
);
|
|
154
|
-
|
|
168
|
+
}
|
|
169
|
+
if (!foreignKey || typeof foreignKey !== 'string') {
|
|
155
170
|
throw new InvalidArgumentError(
|
|
156
171
|
'The parameter "foreignKey" of HasOneResolver.includePolymorphicTo requires ' +
|
|
157
172
|
'a non-empty String, but %v was given.',
|
|
158
173
|
foreignKey,
|
|
159
174
|
);
|
|
160
|
-
|
|
175
|
+
}
|
|
176
|
+
if (!discriminator || typeof discriminator !== 'string') {
|
|
161
177
|
throw new InvalidArgumentError(
|
|
162
178
|
'The parameter "discriminator" of HasOneResolver.includePolymorphicTo requires ' +
|
|
163
179
|
'a non-empty String, but %v was given.',
|
|
164
180
|
discriminator,
|
|
165
181
|
);
|
|
166
|
-
|
|
182
|
+
}
|
|
183
|
+
if (scope && (typeof scope !== 'object' || Array.isArray(scope))) {
|
|
167
184
|
throw new InvalidArgumentError(
|
|
168
185
|
'The provided parameter "scope" of HasOneResolver.includePolymorphicTo ' +
|
|
169
186
|
'should be an Object, but %v was given.',
|
|
170
187
|
scope,
|
|
171
188
|
);
|
|
189
|
+
}
|
|
172
190
|
|
|
173
191
|
const sourcePkPropName =
|
|
174
192
|
this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
|
|
@@ -176,14 +194,17 @@ export class HasOneResolver extends Service {
|
|
|
176
194
|
);
|
|
177
195
|
const sourceIds = [];
|
|
178
196
|
entities.forEach(entity => {
|
|
179
|
-
if (!entity || typeof entity !== 'object' || Array.isArray(entity))
|
|
197
|
+
if (!entity || typeof entity !== 'object' || Array.isArray(entity)) {
|
|
180
198
|
throw new InvalidArgumentError(
|
|
181
199
|
'The parameter "entities" of HasOneResolver.includePolymorphicTo requires ' +
|
|
182
200
|
'an Array of Object, but %v was given.',
|
|
183
201
|
entity,
|
|
184
202
|
);
|
|
203
|
+
}
|
|
185
204
|
const sourceId = entity[sourcePkPropName];
|
|
186
|
-
if (sourceIds.includes(sourceId))
|
|
205
|
+
if (sourceIds.includes(sourceId)) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
187
208
|
sourceIds.push(sourceId);
|
|
188
209
|
});
|
|
189
210
|
|
|
@@ -203,7 +224,9 @@ export class HasOneResolver extends Service {
|
|
|
203
224
|
filter.limit = 1;
|
|
204
225
|
promises.push(
|
|
205
226
|
targetRepository.find(filter).then(result => {
|
|
206
|
-
if (result.length)
|
|
227
|
+
if (result.length) {
|
|
228
|
+
targetBySourceId.set(sourceId, result[0]);
|
|
229
|
+
}
|
|
207
230
|
}),
|
|
208
231
|
);
|
|
209
232
|
});
|
|
@@ -234,47 +257,53 @@ export class HasOneResolver extends Service {
|
|
|
234
257
|
targetRelationName,
|
|
235
258
|
scope = undefined,
|
|
236
259
|
) {
|
|
237
|
-
if (!entities || !Array.isArray(entities))
|
|
260
|
+
if (!entities || !Array.isArray(entities)) {
|
|
238
261
|
throw new InvalidArgumentError(
|
|
239
262
|
'The parameter "entities" of HasOneResolver.includePolymorphicByRelationName requires ' +
|
|
240
263
|
'an Array of Object, but %v was given.',
|
|
241
264
|
entities,
|
|
242
265
|
);
|
|
243
|
-
|
|
266
|
+
}
|
|
267
|
+
if (!sourceName || typeof sourceName !== 'string') {
|
|
244
268
|
throw new InvalidArgumentError(
|
|
245
269
|
'The parameter "sourceName" of HasOneResolver.includePolymorphicByRelationName requires ' +
|
|
246
270
|
'a non-empty String, but %v was given.',
|
|
247
271
|
sourceName,
|
|
248
272
|
);
|
|
249
|
-
|
|
273
|
+
}
|
|
274
|
+
if (!targetName || typeof targetName !== 'string') {
|
|
250
275
|
throw new InvalidArgumentError(
|
|
251
276
|
'The parameter "targetName" of HasOneResolver.includePolymorphicByRelationName requires ' +
|
|
252
277
|
'a non-empty String, but %v was given.',
|
|
253
278
|
targetName,
|
|
254
279
|
);
|
|
255
|
-
|
|
280
|
+
}
|
|
281
|
+
if (!relationName || typeof relationName !== 'string') {
|
|
256
282
|
throw new InvalidArgumentError(
|
|
257
283
|
'The parameter "relationName" of HasOneResolver.includePolymorphicByRelationName requires ' +
|
|
258
284
|
'a non-empty String, but %v was given.',
|
|
259
285
|
relationName,
|
|
260
286
|
);
|
|
261
|
-
|
|
287
|
+
}
|
|
288
|
+
if (!targetRelationName || typeof targetRelationName !== 'string') {
|
|
262
289
|
throw new InvalidArgumentError(
|
|
263
290
|
'The parameter "targetRelationName" of HasOneResolver.includePolymorphicByRelationName requires ' +
|
|
264
291
|
'a non-empty String, but %v was given.',
|
|
265
292
|
targetRelationName,
|
|
266
293
|
);
|
|
267
|
-
|
|
294
|
+
}
|
|
295
|
+
if (scope && (typeof scope !== 'object' || Array.isArray(scope))) {
|
|
268
296
|
throw new InvalidArgumentError(
|
|
269
297
|
'The provided parameter "scope" of HasOneResolver.includePolymorphicByRelationName ' +
|
|
270
298
|
'should be an Object, but %v was given.',
|
|
271
299
|
scope,
|
|
272
300
|
);
|
|
301
|
+
}
|
|
273
302
|
|
|
274
303
|
const targetRelationDef = this.getService(
|
|
275
304
|
ModelDefinitionUtils,
|
|
276
305
|
).getRelationDefinitionByName(targetName, targetRelationName);
|
|
277
|
-
if (targetRelationDef.type !== RelationType.BELONGS_TO)
|
|
306
|
+
if (targetRelationDef.type !== RelationType.BELONGS_TO) {
|
|
278
307
|
throw new InvalidArgumentError(
|
|
279
308
|
'The relation %v of the model %v is a polymorphic "hasOne" relation, ' +
|
|
280
309
|
'so it requires the target relation %v to be a polymorphic "belongsTo", ' +
|
|
@@ -284,7 +313,8 @@ export class HasOneResolver extends Service {
|
|
|
284
313
|
targetRelationName,
|
|
285
314
|
targetRelationDef.type,
|
|
286
315
|
);
|
|
287
|
-
|
|
316
|
+
}
|
|
317
|
+
if (!targetRelationDef.polymorphic) {
|
|
288
318
|
throw new InvalidArgumentError(
|
|
289
319
|
'The relation %v of the model %v is a polymorphic "hasOne" relation, ' +
|
|
290
320
|
'so it requires the target relation %v to be a polymorphic too.',
|
|
@@ -292,6 +322,7 @@ export class HasOneResolver extends Service {
|
|
|
292
322
|
sourceName,
|
|
293
323
|
targetRelationName,
|
|
294
324
|
);
|
|
325
|
+
}
|
|
295
326
|
const foreignKey =
|
|
296
327
|
targetRelationDef.foreignKey || `${targetRelationName}Id`;
|
|
297
328
|
const discriminator =
|
|
@@ -27,59 +27,69 @@ export class ReferencesManyResolver extends Service {
|
|
|
27
27
|
foreignKey = undefined,
|
|
28
28
|
scope = undefined,
|
|
29
29
|
) {
|
|
30
|
-
if (!entities || !Array.isArray(entities))
|
|
30
|
+
if (!entities || !Array.isArray(entities)) {
|
|
31
31
|
throw new InvalidArgumentError(
|
|
32
32
|
'The parameter "entities" of ReferencesManyResolver.includeTo requires ' +
|
|
33
33
|
'an Array of Object, but %v was given.',
|
|
34
34
|
entities,
|
|
35
35
|
);
|
|
36
|
-
|
|
36
|
+
}
|
|
37
|
+
if (!sourceName || typeof sourceName !== 'string') {
|
|
37
38
|
throw new InvalidArgumentError(
|
|
38
39
|
'The parameter "sourceName" of ReferencesManyResolver.includeTo requires ' +
|
|
39
40
|
'a non-empty String, but %v was given.',
|
|
40
41
|
sourceName,
|
|
41
42
|
);
|
|
42
|
-
|
|
43
|
+
}
|
|
44
|
+
if (!targetName || typeof targetName !== 'string') {
|
|
43
45
|
throw new InvalidArgumentError(
|
|
44
46
|
'The parameter "targetName" of ReferencesManyResolver.includeTo requires ' +
|
|
45
47
|
'a non-empty String, but %v was given.',
|
|
46
48
|
targetName,
|
|
47
49
|
);
|
|
48
|
-
|
|
50
|
+
}
|
|
51
|
+
if (!relationName || typeof relationName !== 'string') {
|
|
49
52
|
throw new InvalidArgumentError(
|
|
50
53
|
'The parameter "relationName" of ReferencesManyResolver.includeTo requires ' +
|
|
51
54
|
'a non-empty String, but %v was given.',
|
|
52
55
|
relationName,
|
|
53
56
|
);
|
|
54
|
-
|
|
57
|
+
}
|
|
58
|
+
if (foreignKey && typeof foreignKey !== 'string') {
|
|
55
59
|
throw new InvalidArgumentError(
|
|
56
60
|
'The provided parameter "foreignKey" of ReferencesManyResolver.includeTo ' +
|
|
57
61
|
'should be a String, but %v was given.',
|
|
58
62
|
foreignKey,
|
|
59
63
|
);
|
|
60
|
-
|
|
64
|
+
}
|
|
65
|
+
if (scope && (typeof scope !== 'object' || Array.isArray(scope))) {
|
|
61
66
|
throw new InvalidArgumentError(
|
|
62
67
|
'The provided parameter "scope" of ReferencesManyResolver.includeTo ' +
|
|
63
68
|
'should be an Object, but %v was given.',
|
|
64
69
|
scope,
|
|
65
70
|
);
|
|
71
|
+
}
|
|
66
72
|
if (foreignKey == null) {
|
|
67
73
|
const singularRelationName = singularize(relationName);
|
|
68
74
|
foreignKey = `${singularRelationName}Ids`;
|
|
69
75
|
}
|
|
70
76
|
const targetIds = entities.reduce((acc, entity) => {
|
|
71
|
-
if (!entity || typeof entity !== 'object' || Array.isArray(entity))
|
|
77
|
+
if (!entity || typeof entity !== 'object' || Array.isArray(entity)) {
|
|
72
78
|
throw new InvalidArgumentError(
|
|
73
79
|
'The parameter "entities" of ReferencesManyResolver.includeTo requires ' +
|
|
74
80
|
'an Array of Object, but %v was given.',
|
|
75
81
|
entity,
|
|
76
82
|
);
|
|
83
|
+
}
|
|
77
84
|
const ids = entity[foreignKey];
|
|
78
|
-
if (Array.isArray(ids))
|
|
85
|
+
if (Array.isArray(ids)) {
|
|
79
86
|
ids.forEach(id => {
|
|
80
|
-
if (id == null || acc.includes(id))
|
|
87
|
+
if (id == null || acc.includes(id)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
81
90
|
acc.push(id);
|
|
82
91
|
});
|
|
92
|
+
}
|
|
83
93
|
return acc;
|
|
84
94
|
}, []);
|
|
85
95
|
|
|
@@ -102,11 +112,14 @@ export class ReferencesManyResolver extends Service {
|
|
|
102
112
|
entities.forEach(entity => {
|
|
103
113
|
const ids = entity[foreignKey];
|
|
104
114
|
entity[relationName] = [];
|
|
105
|
-
if (Array.isArray(ids))
|
|
115
|
+
if (Array.isArray(ids)) {
|
|
106
116
|
targets.forEach(target => {
|
|
107
117
|
const targetId = target[targetPkPropName];
|
|
108
|
-
if (ids.includes(targetId))
|
|
118
|
+
if (ids.includes(targetId)) {
|
|
119
|
+
entity[relationName].push(target);
|
|
120
|
+
}
|
|
109
121
|
});
|
|
122
|
+
}
|
|
110
123
|
});
|
|
111
124
|
}
|
|
112
125
|
}
|
|
@@ -51,7 +51,9 @@ export class RepositoryRegistry extends Service {
|
|
|
51
51
|
getRepository(modelName) {
|
|
52
52
|
const modelKey = modelNameToModelKey(modelName);
|
|
53
53
|
let repository = this._repositories[modelKey];
|
|
54
|
-
if (repository)
|
|
54
|
+
if (repository) {
|
|
55
|
+
return repository;
|
|
56
|
+
}
|
|
55
57
|
repository = new this._repositoryCtor(this.container, modelName);
|
|
56
58
|
this._repositories[modelKey] = repository;
|
|
57
59
|
return repository;
|
|
@@ -51,11 +51,12 @@ export class Repository extends Service {
|
|
|
51
51
|
this._modelName = modelName;
|
|
52
52
|
const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
|
|
53
53
|
const datasourceName = modelDef.datasource;
|
|
54
|
-
if (!datasourceName)
|
|
54
|
+
if (!datasourceName) {
|
|
55
55
|
throw new InvalidArgumentError(
|
|
56
56
|
'The model %v does not have a specified datasource.',
|
|
57
57
|
modelName,
|
|
58
58
|
);
|
|
59
|
+
}
|
|
59
60
|
this._datasourceName = datasourceName;
|
|
60
61
|
}
|
|
61
62
|
|
package/src/utils/capitalize.js
CHANGED
package/src/utils/clone-deep.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* @returns {*}
|
|
7
7
|
*/
|
|
8
8
|
export function cloneDeep(value) {
|
|
9
|
-
if (!value)
|
|
9
|
+
if (!value) {
|
|
10
|
+
return value;
|
|
11
|
+
} // null, undefined values check
|
|
10
12
|
|
|
11
13
|
const types = [Number, String, Boolean];
|
|
12
14
|
let result;
|
|
@@ -14,7 +16,9 @@ export function cloneDeep(value) {
|
|
|
14
16
|
// normalizing primitives if someone did new String('aaa'),
|
|
15
17
|
// or new Number('444');
|
|
16
18
|
types.forEach(type => {
|
|
17
|
-
if (value instanceof type)
|
|
19
|
+
if (value instanceof type) {
|
|
20
|
+
result = type(value);
|
|
21
|
+
}
|
|
18
22
|
});
|
|
19
23
|
|
|
20
24
|
if (result === undefined) {
|
|
@@ -8,11 +8,12 @@ import {InvalidArgumentError} from '../errors/index.js';
|
|
|
8
8
|
* @returns {object}
|
|
9
9
|
*/
|
|
10
10
|
export function excludeObjectKeys(obj, keys) {
|
|
11
|
-
if (typeof obj !== 'object' || !obj || Array.isArray(obj))
|
|
11
|
+
if (typeof obj !== 'object' || !obj || Array.isArray(obj)) {
|
|
12
12
|
throw new InvalidArgumentError(
|
|
13
13
|
'Cannot exclude keys from a non-Object value, %v was given.',
|
|
14
14
|
obj,
|
|
15
15
|
);
|
|
16
|
+
}
|
|
16
17
|
const result = {...obj};
|
|
17
18
|
keys = Array.isArray(keys) ? keys : [keys];
|
|
18
19
|
keys.forEach(key => delete result[key]);
|