@loopback/repository 2.6.0 → 2.10.0
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/CHANGELOG.md +63 -0
- package/README.md +1 -1
- package/dist/decorators/metadata.d.ts +1 -1
- package/dist/decorators/metadata.js +6 -6
- package/dist/decorators/metadata.js.map +1 -1
- package/dist/decorators/model.decorator.d.ts +1 -1
- package/dist/decorators/model.decorator.js +10 -10
- package/dist/decorators/model.decorator.js.map +1 -1
- package/dist/decorators/repository.decorator.js +4 -4
- package/dist/decorators/repository.decorator.js.map +1 -1
- package/dist/define-model-class.d.ts +2 -2
- package/dist/mixins/repository.mixin.d.ts +23 -12
- package/dist/mixins/repository.mixin.js +13 -7
- package/dist/mixins/repository.mixin.js.map +1 -1
- package/dist/model.d.ts +19 -2
- package/dist/model.js +46 -2
- package/dist/model.js.map +1 -1
- package/dist/query.d.ts +30 -0
- package/dist/query.js +50 -0
- package/dist/query.js.map +1 -1
- package/dist/relations/belongs-to/belongs-to.decorator.js +2 -2
- package/dist/relations/belongs-to/belongs-to.decorator.js.map +1 -1
- package/dist/relations/belongs-to/belongs-to.helpers.d.ts +1 -0
- package/dist/relations/belongs-to/belongs-to.helpers.js +13 -6
- package/dist/relations/belongs-to/belongs-to.helpers.js.map +1 -1
- package/dist/relations/belongs-to/belongs-to.repository.d.ts +1 -1
- package/dist/relations/has-many/has-many-through-repository.factory.d.ts +11 -0
- package/dist/relations/has-many/has-many-through-repository.factory.js +31 -0
- package/dist/relations/has-many/has-many-through-repository.factory.js.map +1 -0
- package/dist/relations/has-many/has-many-through.helpers.d.ts +122 -14
- package/dist/relations/has-many/has-many-through.helpers.js +153 -20
- package/dist/relations/has-many/has-many-through.helpers.js.map +1 -1
- package/dist/relations/has-many/has-many-through.repository.d.ts +39 -2
- package/dist/relations/has-many/has-many-through.repository.js +87 -0
- package/dist/relations/has-many/has-many-through.repository.js.map +1 -1
- package/dist/relations/has-many/has-many.helpers.js +2 -1
- package/dist/relations/has-many/has-many.helpers.js.map +1 -1
- package/dist/relations/has-many/has-many.repository.d.ts +1 -1
- package/dist/relations/has-many/index.d.ts +4 -2
- package/dist/relations/has-many/index.js +4 -2
- package/dist/relations/has-many/index.js.map +1 -1
- package/dist/relations/has-one/has-one.helpers.js +2 -1
- package/dist/relations/has-one/has-one.helpers.js.map +1 -1
- package/dist/relations/has-one/has-one.repository.d.ts +1 -1
- package/dist/relations/relation.decorator.js +6 -6
- package/dist/relations/relation.decorator.js.map +1 -1
- package/dist/relations/relation.types.d.ts +2 -2
- package/dist/relations/relation.types.js +2 -2
- package/dist/relations/relation.types.js.map +1 -1
- package/dist/repositories/constraint-utils.d.ts +10 -0
- package/dist/repositories/constraint-utils.js +16 -1
- package/dist/repositories/constraint-utils.js.map +1 -1
- package/dist/repositories/legacy-juggler-bridge.d.ts +33 -2
- package/dist/repositories/legacy-juggler-bridge.js +34 -0
- package/dist/repositories/legacy-juggler-bridge.js.map +1 -1
- package/package.json +15 -13
- package/src/decorators/metadata.ts +1 -1
- package/src/decorators/model.decorator.ts +1 -1
- package/src/decorators/repository.decorator.ts +1 -1
- package/src/define-model-class.ts +2 -2
- package/src/mixins/repository.mixin.ts +8 -2
- package/src/model.ts +64 -4
- package/src/query.ts +55 -0
- package/src/relations/belongs-to/belongs-to.decorator.ts +1 -1
- package/src/relations/belongs-to/belongs-to.helpers.ts +19 -8
- package/src/relations/belongs-to/belongs-to.repository.ts +1 -1
- package/src/relations/has-many/has-many-through-repository.factory.ts +104 -0
- package/src/relations/has-many/has-many-through.helpers.ts +182 -21
- package/src/relations/has-many/has-many-through.repository.ts +191 -2
- package/src/relations/has-many/has-many.helpers.ts +1 -2
- package/src/relations/has-many/has-many.repository.ts +1 -1
- package/src/relations/has-many/index.ts +4 -2
- package/src/relations/has-one/has-one.helpers.ts +1 -2
- package/src/relations/has-one/has-one.repository.ts +1 -1
- package/src/relations/relation.decorator.ts +1 -1
- package/src/relations/relation.types.ts +2 -2
- package/src/repositories/constraint-utils.ts +17 -0
- package/src/repositories/legacy-juggler-bridge.ts +59 -1
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loopback/repository",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.10.0",
|
|
4
|
+
"description": "Define and implement a common set of interfaces for interacting with databases",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=10"
|
|
8
|
+
"node": ">=10.16"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"acceptance": "lb-mocha \"dist/__tests__/acceptance/**/*.js\"",
|
|
@@ -18,22 +18,24 @@
|
|
|
18
18
|
"author": "IBM Corp.",
|
|
19
19
|
"copyright.owner": "IBM Corp.",
|
|
20
20
|
"license": "MIT",
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
21
24
|
"devDependencies": {
|
|
22
|
-
"@loopback/build": "^
|
|
23
|
-
"@loopback/eslint-config": "^8.0.
|
|
24
|
-
"@loopback/testlab": "^3.1
|
|
25
|
+
"@loopback/build": "^6.1.1",
|
|
26
|
+
"@loopback/eslint-config": "^8.0.4",
|
|
27
|
+
"@loopback/testlab": "^3.2.1",
|
|
25
28
|
"@types/bson": "^4.0.2",
|
|
26
|
-
"@types/json-schema": "^7.0.
|
|
27
|
-
"@types/lodash": "^4.14.
|
|
28
|
-
"@types/node": "^10.17.
|
|
29
|
+
"@types/json-schema": "^7.0.5",
|
|
30
|
+
"@types/lodash": "^4.14.157",
|
|
31
|
+
"@types/node": "^10.17.27",
|
|
29
32
|
"bson": "4.0.4"
|
|
30
33
|
},
|
|
31
34
|
"dependencies": {
|
|
32
|
-
"@loopback/
|
|
33
|
-
"@loopback/core": "^2.7.1",
|
|
35
|
+
"@loopback/core": "^2.9.2",
|
|
34
36
|
"@types/debug": "^4.1.5",
|
|
35
37
|
"debug": "^4.1.1",
|
|
36
|
-
"lodash": "^4.17.
|
|
38
|
+
"lodash": "^4.17.19",
|
|
37
39
|
"loopback-datasource-juggler": "^4.21.2",
|
|
38
40
|
"tslib": "^2.0.0"
|
|
39
41
|
},
|
|
@@ -48,5 +50,5 @@
|
|
|
48
50
|
"url": "https://github.com/strongloop/loopback-next.git",
|
|
49
51
|
"directory": "packages/repository"
|
|
50
52
|
},
|
|
51
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "5538896411bb56467ae52670a29d1aec1690be74"
|
|
52
54
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// This file is licensed under the MIT License.
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
|
-
import {InspectionOptions, MetadataInspector} from '@loopback/
|
|
6
|
+
import {InspectionOptions, MetadataInspector} from '@loopback/core';
|
|
7
7
|
import {ModelDefinition, RelationDefinitionMap} from '../model';
|
|
8
8
|
import {RELATIONS_KEY} from '../relations';
|
|
9
9
|
import {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// This file is licensed under the MIT License.
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
|
-
import {Context, inject, Injection} from '@loopback/
|
|
6
|
+
import {Context, inject, Injection} from '@loopback/core';
|
|
7
7
|
import assert from 'assert';
|
|
8
8
|
import {Class} from '../common-types';
|
|
9
9
|
import {DataSource} from '../datasource';
|
|
@@ -79,10 +79,10 @@ export function defineModelClass<
|
|
|
79
79
|
export type DynamicModelCtor<
|
|
80
80
|
BaseCtor extends typeof Model,
|
|
81
81
|
Props extends object
|
|
82
|
-
> =
|
|
82
|
+
> = {
|
|
83
83
|
/** Model constructor accepting partial model data. */
|
|
84
84
|
new (data?: DataObject<PrototypeOf<BaseCtor> & Props>): PrototypeOf<
|
|
85
85
|
BaseCtor
|
|
86
86
|
> &
|
|
87
87
|
Props;
|
|
88
|
-
};
|
|
88
|
+
} & BaseCtor;
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
BindingFromClassOptions,
|
|
9
9
|
BindingScope,
|
|
10
10
|
createBindingFromClass,
|
|
11
|
-
} from '@loopback/
|
|
11
|
+
} from '@loopback/core';
|
|
12
12
|
import {
|
|
13
13
|
Application,
|
|
14
14
|
Component,
|
|
@@ -27,7 +27,7 @@ const debug = debugFactory('loopback:repository:mixin');
|
|
|
27
27
|
|
|
28
28
|
// FIXME(rfeng): Workaround for https://github.com/microsoft/rushstack/pull/1867
|
|
29
29
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
30
|
-
import * as loopbackContext from '@loopback/
|
|
30
|
+
import * as loopbackContext from '@loopback/core';
|
|
31
31
|
import * as loopbackCore from '@loopback/core';
|
|
32
32
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
33
33
|
|
|
@@ -44,6 +44,12 @@ import * as loopbackCore from '@loopback/core';
|
|
|
44
44
|
* Please note: the members in the mixin function are documented in a dummy class
|
|
45
45
|
* called <a href="#RepositoryMixinDoc">RepositoryMixinDoc</a>
|
|
46
46
|
*
|
|
47
|
+
* @param superClass - Application class
|
|
48
|
+
* @returns A new class that extends the super class with repository related
|
|
49
|
+
* methods
|
|
50
|
+
*
|
|
51
|
+
* @typeParam T - Type of the application class as the target for the mixin
|
|
52
|
+
*
|
|
47
53
|
*/
|
|
48
54
|
export function RepositoryMixin<T extends MixinTarget<Application>>(
|
|
49
55
|
superClass: T,
|
package/src/model.ts
CHANGED
|
@@ -4,8 +4,14 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
import {AnyObject, DataObject, Options, PrototypeOf} from './common-types';
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import {
|
|
8
|
+
BelongsToDefinition,
|
|
9
|
+
HasManyDefinition,
|
|
10
|
+
HasOneDefinition,
|
|
11
|
+
JsonSchema,
|
|
12
|
+
RelationMetadata,
|
|
13
|
+
RelationType,
|
|
14
|
+
} from './index';
|
|
9
15
|
import {TypeResolver} from './type-resolver';
|
|
10
16
|
import {Type} from './types';
|
|
11
17
|
|
|
@@ -145,6 +151,60 @@ export class ModelDefinition {
|
|
|
145
151
|
return this;
|
|
146
152
|
}
|
|
147
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Define a new belongsTo relation.
|
|
156
|
+
* @param name - The name of the belongsTo relation.
|
|
157
|
+
* @param definition - The definition of the belongsTo relation.
|
|
158
|
+
*/
|
|
159
|
+
belongsTo(
|
|
160
|
+
name: string,
|
|
161
|
+
definition: Omit<BelongsToDefinition, 'name' | 'type' | 'targetsMany'>,
|
|
162
|
+
): this {
|
|
163
|
+
const meta: BelongsToDefinition = {
|
|
164
|
+
...definition,
|
|
165
|
+
name,
|
|
166
|
+
type: RelationType.belongsTo,
|
|
167
|
+
targetsMany: false,
|
|
168
|
+
};
|
|
169
|
+
return this.addRelation(meta);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Define a new hasOne relation.
|
|
174
|
+
* @param name - The name of the hasOne relation.
|
|
175
|
+
* @param definition - The definition of the hasOne relation.
|
|
176
|
+
*/
|
|
177
|
+
hasOne(
|
|
178
|
+
name: string,
|
|
179
|
+
definition: Omit<HasOneDefinition, 'name' | 'type' | 'targetsMany'>,
|
|
180
|
+
): this {
|
|
181
|
+
const meta: HasOneDefinition = {
|
|
182
|
+
...definition,
|
|
183
|
+
name,
|
|
184
|
+
type: RelationType.hasOne,
|
|
185
|
+
targetsMany: false,
|
|
186
|
+
};
|
|
187
|
+
return this.addRelation(meta);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Define a new hasMany relation.
|
|
192
|
+
* @param name - The name of the hasMany relation.
|
|
193
|
+
* @param definition - The definition of the hasMany relation.
|
|
194
|
+
*/
|
|
195
|
+
hasMany(
|
|
196
|
+
name: string,
|
|
197
|
+
definition: Omit<HasManyDefinition, 'name' | 'type' | 'targetsMany'>,
|
|
198
|
+
): this {
|
|
199
|
+
const meta: HasManyDefinition = {
|
|
200
|
+
...definition,
|
|
201
|
+
name,
|
|
202
|
+
type: RelationType.hasMany,
|
|
203
|
+
targetsMany: true,
|
|
204
|
+
};
|
|
205
|
+
return this.addRelation(meta);
|
|
206
|
+
}
|
|
207
|
+
|
|
148
208
|
/**
|
|
149
209
|
* Get an array of names of ID properties, which are specified in
|
|
150
210
|
* the model settings or properties with `id` attribute.
|
|
@@ -216,7 +276,7 @@ function asObject(value: any, options?: Options): any {
|
|
|
216
276
|
*/
|
|
217
277
|
export abstract class Model {
|
|
218
278
|
static get modelName(): string {
|
|
219
|
-
return
|
|
279
|
+
return this.definition?.name || this.name;
|
|
220
280
|
}
|
|
221
281
|
|
|
222
282
|
static definition: ModelDefinition;
|
|
@@ -268,7 +328,7 @@ export abstract class Model {
|
|
|
268
328
|
const def = (this.constructor as typeof Model).definition;
|
|
269
329
|
const obj: AnyObject = {};
|
|
270
330
|
|
|
271
|
-
if (options
|
|
331
|
+
if (options?.ignoreUnknownProperties === false) {
|
|
272
332
|
const hiddenProperties: string[] = def?.settings.hiddenProperties || [];
|
|
273
333
|
for (const p in this) {
|
|
274
334
|
if (!hiddenProperties.includes(p)) {
|
package/src/query.ts
CHANGED
|
@@ -442,6 +442,61 @@ export class WhereBuilder<MT extends object = AnyObject> {
|
|
|
442
442
|
return this;
|
|
443
443
|
}
|
|
444
444
|
|
|
445
|
+
/**
|
|
446
|
+
* Add a `like` condition
|
|
447
|
+
* @param key - Property name
|
|
448
|
+
* @param val - Regexp condition
|
|
449
|
+
*/
|
|
450
|
+
like<K extends KeyOf<MT>>(key: K, val: MT[K]): this {
|
|
451
|
+
const w: Where<MT> = {};
|
|
452
|
+
w[key] = {like: val};
|
|
453
|
+
return this.add(w);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Add a `nlike` condition
|
|
458
|
+
* @param key - Property name
|
|
459
|
+
* @param val - Regexp condition
|
|
460
|
+
*/
|
|
461
|
+
nlike<K extends KeyOf<MT>>(key: K, val: MT[K]): this {
|
|
462
|
+
const w: Where<MT> = {};
|
|
463
|
+
w[key] = {nlike: val};
|
|
464
|
+
return this.add(w);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Add a `ilike` condition
|
|
469
|
+
* @param key - Property name
|
|
470
|
+
* @param val - Regexp condition
|
|
471
|
+
*/
|
|
472
|
+
ilike<K extends KeyOf<MT>>(key: K, val: MT[K]): this {
|
|
473
|
+
const w: Where<MT> = {};
|
|
474
|
+
w[key] = {ilike: val};
|
|
475
|
+
return this.add(w);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Add a `nilike` condition
|
|
480
|
+
* @param key - Property name
|
|
481
|
+
* @param val - Regexp condition
|
|
482
|
+
*/
|
|
483
|
+
nilike<K extends KeyOf<MT>>(key: K, val: MT[K]): this {
|
|
484
|
+
const w: Where<MT> = {};
|
|
485
|
+
w[key] = {nilike: val};
|
|
486
|
+
return this.add(w);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Add a `regexp` condition
|
|
491
|
+
* @param key - Property name
|
|
492
|
+
* @param val - Regexp condition
|
|
493
|
+
*/
|
|
494
|
+
regexp<K extends KeyOf<MT>>(key: K, val: string | RegExp): this {
|
|
495
|
+
const w: Where<MT> = {};
|
|
496
|
+
w[key] = {regexp: val};
|
|
497
|
+
return this.add(w);
|
|
498
|
+
}
|
|
499
|
+
|
|
445
500
|
/**
|
|
446
501
|
* Get the where object
|
|
447
502
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// This file is licensed under the MIT License.
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
|
-
import {MetadataInspector} from '@loopback/
|
|
6
|
+
import {MetadataInspector} from '@loopback/core';
|
|
7
7
|
import {property} from '../../decorators/model.decorator';
|
|
8
8
|
import {Entity, EntityResolver, PropertyDefinition} from '../../model';
|
|
9
9
|
import {relation} from '../relation.decorator';
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
import debugFactory from 'debug';
|
|
7
|
+
import {camelCase} from 'lodash';
|
|
7
8
|
import {InvalidRelationError} from '../../errors';
|
|
8
9
|
import {isTypeResolver} from '../../type-resolver';
|
|
9
10
|
import {BelongsToDefinition, RelationType} from '../relation.types';
|
|
@@ -14,7 +15,10 @@ const debug = debugFactory('loopback:repository:belongs-to-helpers');
|
|
|
14
15
|
* Relation definition with optional metadata (e.g. `keyTo`) filled in.
|
|
15
16
|
* @internal
|
|
16
17
|
*/
|
|
17
|
-
export type BelongsToResolvedDefinition = BelongsToDefinition & {
|
|
18
|
+
export type BelongsToResolvedDefinition = BelongsToDefinition & {
|
|
19
|
+
keyFrom: string;
|
|
20
|
+
keyTo: string;
|
|
21
|
+
};
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
24
|
* Resolves given belongsTo metadata if target is specified to be a resolver.
|
|
@@ -34,11 +38,6 @@ export function resolveBelongsToMetadata(relationMeta: BelongsToDefinition) {
|
|
|
34
38
|
throw new InvalidRelationError(reason, relationMeta);
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
if (!relationMeta.keyFrom) {
|
|
38
|
-
const reason = 'keyFrom is required';
|
|
39
|
-
throw new InvalidRelationError(reason, relationMeta);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
41
|
const sourceModel = relationMeta.source;
|
|
43
42
|
if (!sourceModel || !sourceModel.modelName) {
|
|
44
43
|
const reason = 'source model must be defined';
|
|
@@ -49,12 +48,24 @@ export function resolveBelongsToMetadata(relationMeta: BelongsToDefinition) {
|
|
|
49
48
|
const targetName = targetModel.modelName;
|
|
50
49
|
debug('Resolved model %s from given metadata: %o', targetName, targetModel);
|
|
51
50
|
|
|
51
|
+
let keyFrom;
|
|
52
|
+
if (
|
|
53
|
+
relationMeta.keyFrom &&
|
|
54
|
+
relationMeta.source.definition.properties[relationMeta.keyFrom]
|
|
55
|
+
) {
|
|
56
|
+
keyFrom = relationMeta.keyFrom;
|
|
57
|
+
} else {
|
|
58
|
+
keyFrom = camelCase(targetName + '_id');
|
|
59
|
+
}
|
|
60
|
+
|
|
52
61
|
const targetProperties = targetModel.definition.properties;
|
|
53
62
|
debug('relation metadata from %o: %o', targetName, targetProperties);
|
|
54
63
|
|
|
55
64
|
if (relationMeta.keyTo && targetProperties[relationMeta.keyTo]) {
|
|
56
65
|
// The explicit cast is needed because of a limitation of type inference
|
|
57
|
-
return relationMeta
|
|
66
|
+
return Object.assign(relationMeta, {
|
|
67
|
+
keyFrom,
|
|
68
|
+
}) as BelongsToResolvedDefinition;
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
const targetPrimaryKey = targetModel.definition.idProperties()[0];
|
|
@@ -63,5 +74,5 @@ export function resolveBelongsToMetadata(relationMeta: BelongsToDefinition) {
|
|
|
63
74
|
throw new InvalidRelationError(reason, relationMeta);
|
|
64
75
|
}
|
|
65
76
|
|
|
66
|
-
return Object.assign(relationMeta, {keyTo: targetPrimaryKey});
|
|
77
|
+
return Object.assign(relationMeta, {keyFrom, keyTo: targetPrimaryKey});
|
|
67
78
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// This file is licensed under the MIT License.
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
|
-
import {Getter} from '@loopback/
|
|
6
|
+
import {Getter} from '@loopback/core';
|
|
7
7
|
import {DataObject, Options} from '../../common-types';
|
|
8
8
|
import {EntityNotFoundError} from '../../errors';
|
|
9
9
|
import {Entity} from '../../model';
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2020. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/repository
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
import {
|
|
6
|
+
DataObject,
|
|
7
|
+
Entity,
|
|
8
|
+
EntityCrudRepository,
|
|
9
|
+
Getter,
|
|
10
|
+
HasManyDefinition,
|
|
11
|
+
} from '../..';
|
|
12
|
+
import {
|
|
13
|
+
createTargetConstraintFromThrough,
|
|
14
|
+
createThroughConstraintFromSource,
|
|
15
|
+
createThroughConstraintFromTarget,
|
|
16
|
+
getTargetIdsFromTargetModels,
|
|
17
|
+
getTargetKeysFromThroughModels,
|
|
18
|
+
resolveHasManyThroughMetadata,
|
|
19
|
+
} from './has-many-through.helpers';
|
|
20
|
+
import {
|
|
21
|
+
DefaultHasManyThroughRepository,
|
|
22
|
+
HasManyThroughRepository,
|
|
23
|
+
} from './has-many-through.repository';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* a factory to generate hasManyThrough repository class.
|
|
27
|
+
*
|
|
28
|
+
* Warning: The hasManyThrough interface is experimental and is subject to change.
|
|
29
|
+
* If backwards-incompatible changes are made, a new major version may not be
|
|
30
|
+
* released.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
export type HasManyThroughRepositoryFactory<
|
|
34
|
+
TargetEntity extends Entity,
|
|
35
|
+
TargetID,
|
|
36
|
+
ThroughEntity extends Entity,
|
|
37
|
+
SourceID
|
|
38
|
+
> = (
|
|
39
|
+
fkValue: SourceID,
|
|
40
|
+
) => HasManyThroughRepository<TargetEntity, TargetID, ThroughEntity>;
|
|
41
|
+
|
|
42
|
+
export function createHasManyThroughRepositoryFactory<
|
|
43
|
+
Target extends Entity,
|
|
44
|
+
TargetID,
|
|
45
|
+
Through extends Entity,
|
|
46
|
+
ThroughID,
|
|
47
|
+
SourceID
|
|
48
|
+
>(
|
|
49
|
+
relationMetadata: HasManyDefinition,
|
|
50
|
+
targetRepositoryGetter: Getter<EntityCrudRepository<Target, TargetID>>,
|
|
51
|
+
throughRepositoryGetter: Getter<EntityCrudRepository<Through, ThroughID>>,
|
|
52
|
+
): HasManyThroughRepositoryFactory<Target, TargetID, Through, SourceID> {
|
|
53
|
+
const meta = resolveHasManyThroughMetadata(relationMetadata);
|
|
54
|
+
const result = function (fkValue: SourceID) {
|
|
55
|
+
function getTargetConstraintFromThroughModels(
|
|
56
|
+
throughInstances: Through[],
|
|
57
|
+
): DataObject<Target> {
|
|
58
|
+
return createTargetConstraintFromThrough<Target, Through>(
|
|
59
|
+
meta,
|
|
60
|
+
throughInstances,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function getTargetKeys(throughInstances: Through[]): TargetID[] {
|
|
64
|
+
return getTargetKeysFromThroughModels(meta, throughInstances);
|
|
65
|
+
}
|
|
66
|
+
function getThroughConstraintFromSource(): DataObject<Through> {
|
|
67
|
+
const constraint: DataObject<Through> = createThroughConstraintFromSource<
|
|
68
|
+
Through,
|
|
69
|
+
SourceID
|
|
70
|
+
>(meta, fkValue);
|
|
71
|
+
return constraint;
|
|
72
|
+
}
|
|
73
|
+
function getTargetIds(targetInstances: Target[]): TargetID[] {
|
|
74
|
+
return getTargetIdsFromTargetModels(meta, targetInstances);
|
|
75
|
+
}
|
|
76
|
+
function getThroughConstraintFromTarget(
|
|
77
|
+
fkValues: TargetID[],
|
|
78
|
+
): DataObject<Through> {
|
|
79
|
+
const constraint: DataObject<Through> = createThroughConstraintFromTarget<
|
|
80
|
+
Through,
|
|
81
|
+
TargetID
|
|
82
|
+
>(meta, fkValues);
|
|
83
|
+
return constraint;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return new DefaultHasManyThroughRepository<
|
|
87
|
+
Target,
|
|
88
|
+
TargetID,
|
|
89
|
+
EntityCrudRepository<Target, TargetID>,
|
|
90
|
+
Through,
|
|
91
|
+
ThroughID,
|
|
92
|
+
EntityCrudRepository<Through, ThroughID>
|
|
93
|
+
>(
|
|
94
|
+
targetRepositoryGetter,
|
|
95
|
+
throughRepositoryGetter,
|
|
96
|
+
getTargetConstraintFromThroughModels,
|
|
97
|
+
getTargetKeys,
|
|
98
|
+
getThroughConstraintFromSource,
|
|
99
|
+
getTargetIds,
|
|
100
|
+
getThroughConstraintFromTarget,
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
return result;
|
|
104
|
+
}
|