@loopback/repository 3.2.1 → 3.5.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 +54 -0
- package/dist/common-types.js +1 -1
- package/dist/common-types.js.map +1 -1
- package/dist/connectors/connector.d.ts +35 -1
- package/dist/decorators/model.decorator.js +2 -1
- package/dist/decorators/model.decorator.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/mixins/repository.mixin.d.ts +11 -11
- package/dist/mixins/repository.mixin.js.map +1 -1
- package/dist/model.d.ts +2 -2
- package/dist/model.js.map +1 -1
- package/dist/relations/belongs-to/{belongs-to-accessor.d.ts → belongs-to.accessor.d.ts} +0 -0
- package/dist/relations/belongs-to/{belongs-to-accessor.js → belongs-to.accessor.js} +2 -2
- package/dist/relations/belongs-to/{belongs-to-accessor.js.map → belongs-to.accessor.js.map} +1 -1
- package/dist/relations/belongs-to/belongs-to.decorator.js +5 -2
- package/dist/relations/belongs-to/belongs-to.decorator.js.map +1 -1
- package/dist/relations/belongs-to/belongs-to.helpers.js +1 -1
- package/dist/relations/belongs-to/belongs-to.helpers.js.map +1 -1
- package/dist/relations/belongs-to/belongs-to.inclusion-resolver.d.ts +1 -1
- package/dist/relations/belongs-to/belongs-to.inclusion-resolver.js +2 -1
- package/dist/relations/belongs-to/belongs-to.inclusion-resolver.js.map +1 -1
- package/dist/relations/belongs-to/belongs-to.repository.d.ts +1 -1
- package/dist/relations/belongs-to/belongs-to.repository.js +2 -2
- package/dist/relations/belongs-to/belongs-to.repository.js.map +1 -1
- package/dist/relations/belongs-to/index.d.ts +1 -1
- package/dist/relations/belongs-to/index.js +1 -1
- package/dist/relations/has-many/has-many-through.helpers.js +1 -1
- package/dist/relations/has-many/has-many-through.helpers.js.map +1 -1
- package/dist/relations/has-many/{has-many-through.inclusion.resolver.d.ts → has-many-through.inclusion-resolver.d.ts} +1 -1
- package/dist/relations/has-many/{has-many-through.inclusion.resolver.js → has-many-through.inclusion-resolver.js} +4 -3
- package/dist/relations/has-many/{has-many-through.inclusion.resolver.js.map → has-many-through.inclusion-resolver.js.map} +1 -1
- package/dist/relations/has-many/{has-many-through-repository.factory.d.ts → has-many-through.repository-factory.d.ts} +0 -0
- package/dist/relations/has-many/{has-many-through-repository.factory.js → has-many-through.repository-factory.js} +2 -2
- package/dist/relations/has-many/{has-many-through-repository.factory.js.map → has-many-through.repository-factory.js.map} +1 -1
- package/dist/relations/has-many/has-many-through.repository.js.map +1 -1
- package/dist/relations/has-many/has-many.helpers.js +1 -1
- package/dist/relations/has-many/has-many.helpers.js.map +1 -1
- package/dist/relations/has-many/has-many.inclusion-resolver.d.ts +1 -1
- package/dist/relations/has-many/has-many.inclusion-resolver.js +3 -2
- package/dist/relations/has-many/has-many.inclusion-resolver.js.map +1 -1
- package/dist/relations/has-many/{has-many-repository.factory.d.ts → has-many.repository-factory.d.ts} +1 -1
- package/dist/relations/has-many/{has-many-repository.factory.js → has-many.repository-factory.js} +2 -2
- package/dist/relations/has-many/has-many.repository-factory.js.map +1 -0
- package/dist/relations/has-many/has-many.repository.d.ts +1 -1
- package/dist/relations/has-many/has-many.repository.js +5 -5
- package/dist/relations/has-many/has-many.repository.js.map +1 -1
- package/dist/relations/has-many/index.d.ts +2 -2
- package/dist/relations/has-many/index.js +2 -2
- package/dist/relations/has-one/has-one.helpers.js +1 -1
- package/dist/relations/has-one/has-one.helpers.js.map +1 -1
- package/dist/relations/has-one/has-one.inclusion-resolver.d.ts +1 -1
- package/dist/relations/has-one/has-one.inclusion-resolver.js +2 -1
- package/dist/relations/has-one/has-one.inclusion-resolver.js.map +1 -1
- package/dist/relations/has-one/{has-one-repository.factory.d.ts → has-one.repository-factory.d.ts} +1 -1
- package/dist/relations/has-one/{has-one-repository.factory.js → has-one.repository-factory.js} +2 -2
- package/dist/relations/has-one/has-one.repository-factory.js.map +1 -0
- package/dist/relations/has-one/index.d.ts +1 -1
- package/dist/relations/has-one/index.js +1 -1
- package/dist/relations/relation.helpers.d.ts +2 -2
- package/dist/relations/relation.helpers.js +9 -11
- package/dist/relations/relation.helpers.js.map +1 -1
- package/dist/relations/relation.types.d.ts +2 -2
- package/dist/repositories/kv.repository.bridge.js.map +1 -1
- package/dist/repositories/legacy-juggler-bridge.d.ts +2 -2
- package/dist/repositories/legacy-juggler-bridge.js.map +1 -1
- package/package.json +19 -19
- package/src/connectors/connector.ts +41 -1
- package/src/define-model-class.ts +3 -4
- package/src/index.ts +5 -0
- package/src/model.ts +2 -2
- package/src/relations/belongs-to/{belongs-to-accessor.ts → belongs-to.accessor.ts} +1 -1
- package/src/relations/belongs-to/belongs-to.decorator.ts +2 -2
- package/src/relations/belongs-to/belongs-to.helpers.ts +1 -1
- package/src/relations/belongs-to/belongs-to.inclusion-resolver.ts +7 -4
- package/src/relations/belongs-to/belongs-to.repository.ts +1 -2
- package/src/relations/belongs-to/index.ts +1 -1
- package/src/relations/has-many/has-many-through.helpers.ts +3 -1
- package/src/relations/has-many/{has-many-through.inclusion.resolver.ts → has-many-through.inclusion-resolver.ts} +8 -11
- package/src/relations/has-many/{has-many-through-repository.factory.ts → has-many-through.repository-factory.ts} +1 -1
- package/src/relations/has-many/has-many.helpers.ts +1 -1
- package/src/relations/has-many/has-many.inclusion-resolver.ts +10 -5
- package/src/relations/has-many/{has-many-repository.factory.ts → has-many.repository-factory.ts} +4 -2
- package/src/relations/has-many/has-many.repository.ts +2 -2
- package/src/relations/has-many/index.ts +2 -2
- package/src/relations/has-one/has-one.helpers.ts +1 -1
- package/src/relations/has-one/has-one.inclusion-resolver.ts +7 -4
- package/src/relations/has-one/{has-one-repository.factory.ts → has-one.repository-factory.ts} +4 -2
- package/src/relations/has-one/index.ts +1 -1
- package/src/relations/relation.helpers.ts +13 -14
- package/src/relations/relation.types.ts +2 -2
- package/src/repositories/kv.repository.bridge.ts +4 -3
- package/src/repositories/legacy-juggler-bridge.ts +7 -2
- package/dist/relations/has-many/has-many-repository.factory.js.map +0 -1
- package/dist/relations/has-one/has-one-repository.factory.js.map +0 -1
|
@@ -12,13 +12,53 @@ import {
|
|
|
12
12
|
} from '../common-types';
|
|
13
13
|
import {Model} from '../model';
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Interfaces adopted by a {@link Connector}.
|
|
17
|
+
*
|
|
18
|
+
* @experimental
|
|
19
|
+
*/
|
|
20
|
+
export namespace ConnectorInterfaces {
|
|
21
|
+
/**
|
|
22
|
+
* Strong relation interfaces adopted by a {@link Connector}
|
|
23
|
+
*
|
|
24
|
+
* @experimental
|
|
25
|
+
*/
|
|
26
|
+
export const enum StrongRelation {
|
|
27
|
+
BELONGS_TO = 'strongBelongsTo',
|
|
28
|
+
HAS_ONE = 'strongHasOne',
|
|
29
|
+
HAS_MANY = 'strongHasMany',
|
|
30
|
+
HAS_MANY_THROUGH = 'strongHasManyThrough',
|
|
31
|
+
HAS_AND_BELONGS_TO_MANY = 'strongHasAndBelongsToMany',
|
|
32
|
+
EMBEDS_ONE = 'strongEmbedsOne',
|
|
33
|
+
EMBEDS_MANY = 'strongEmbedsMany',
|
|
34
|
+
REFERNCES_MANY = 'strongReferencesMany',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Strong query join interfaces adopted by a {@link Connector}
|
|
39
|
+
*
|
|
40
|
+
* @experimental
|
|
41
|
+
*/
|
|
42
|
+
export const enum StrongJoins {
|
|
43
|
+
INNER = 'strongInnerJoin',
|
|
44
|
+
LEFT = 'strongLeftJoin',
|
|
45
|
+
RIGHT = 'strongRightJoin',
|
|
46
|
+
FULL = 'strongFullJoin',
|
|
47
|
+
CARTESIAN = 'strongCartesianJoin',
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
15
51
|
/**
|
|
16
52
|
* Common properties/operations for connectors
|
|
17
53
|
*/
|
|
18
54
|
export interface Connector {
|
|
19
55
|
name: string; // Name/type of the connector
|
|
20
56
|
configModel?: Model; // The configuration model
|
|
21
|
-
interfaces?:
|
|
57
|
+
interfaces?: (
|
|
58
|
+
| string
|
|
59
|
+
| ConnectorInterfaces.StrongRelation
|
|
60
|
+
| ConnectorInterfaces.StrongJoins
|
|
61
|
+
)[]; // A list of interfaces implemented by the connector
|
|
22
62
|
connect(): Promise<void>; // Connect to the underlying system
|
|
23
63
|
disconnect(): Promise<void>; // Disconnect from the underlying system
|
|
24
64
|
ping(): Promise<void>; // Ping the underlying system
|
|
@@ -84,8 +84,7 @@ export type DynamicModelCtor<
|
|
|
84
84
|
Props extends object
|
|
85
85
|
> = {
|
|
86
86
|
/** Model constructor accepting partial model data. */
|
|
87
|
-
new (
|
|
88
|
-
BaseCtor
|
|
89
|
-
> &
|
|
90
|
-
Props;
|
|
87
|
+
new (
|
|
88
|
+
data?: DataObject<PrototypeOf<BaseCtor> & Props>,
|
|
89
|
+
): PrototypeOf<BaseCtor> & Props;
|
|
91
90
|
} & BaseCtor;
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
export * from '@loopback/filter';
|
|
16
16
|
export {JSONSchema7 as JsonSchema} from 'json-schema';
|
|
17
|
+
/**
|
|
18
|
+
* Export the DataSource to avoid TypeScript 4.2's complaint about
|
|
19
|
+
* RepositoryMixin as it references `juggler.DataSource`
|
|
20
|
+
*/
|
|
21
|
+
export {DataSource as JugglerDataSource} from 'loopback-datasource-juggler';
|
|
17
22
|
export * from './common-types';
|
|
18
23
|
export * from './connectors';
|
|
19
24
|
export * from './datasource';
|
package/src/model.ts
CHANGED
|
@@ -309,7 +309,7 @@ function asObject(value: any, options?: Options): any {
|
|
|
309
309
|
/**
|
|
310
310
|
* Base class for models
|
|
311
311
|
*/
|
|
312
|
-
export
|
|
312
|
+
export class Model {
|
|
313
313
|
static get modelName(): string {
|
|
314
314
|
return this.definition?.name || this.name;
|
|
315
315
|
}
|
|
@@ -418,7 +418,7 @@ export abstract class ValueObject extends Model implements Persistable {}
|
|
|
418
418
|
/**
|
|
419
419
|
* Base class for entities which have unique ids
|
|
420
420
|
*/
|
|
421
|
-
export
|
|
421
|
+
export class Entity extends Model implements Persistable {
|
|
422
422
|
/**
|
|
423
423
|
* Get the names of identity properties (primary keys).
|
|
424
424
|
*/
|
|
@@ -16,7 +16,7 @@ import {resolveBelongsToMetadata} from './belongs-to.helpers';
|
|
|
16
16
|
import {createBelongsToInclusionResolver} from './belongs-to.inclusion-resolver';
|
|
17
17
|
import {DefaultBelongsToRepository} from './belongs-to.repository';
|
|
18
18
|
|
|
19
|
-
const debug = debugFactory('loopback:repository:belongs-to
|
|
19
|
+
const debug = debugFactory('loopback:repository:relations:belongs-to:accessor');
|
|
20
20
|
|
|
21
21
|
export interface BelongsToAccessor<Target extends Entity, SourceId> {
|
|
22
22
|
/**
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
import {DecoratorFactory, MetadataInspector} from '@loopback/core';
|
|
7
|
-
import {property} from '../../decorators
|
|
8
|
-
import {Entity, EntityResolver, PropertyDefinition} from '../../model';
|
|
7
|
+
import {property} from '../../decorators';
|
|
9
8
|
import {relation} from '../relation.decorator';
|
|
9
|
+
import {Entity, EntityResolver, PropertyDefinition} from '../../model';
|
|
10
10
|
import {BelongsToDefinition, RelationType} from '../relation.types';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -9,7 +9,7 @@ import {InvalidRelationError} from '../../errors';
|
|
|
9
9
|
import {isTypeResolver} from '../../type-resolver';
|
|
10
10
|
import {BelongsToDefinition, RelationType} from '../relation.types';
|
|
11
11
|
|
|
12
|
-
const debug = debugFactory('loopback:repository:belongs-to
|
|
12
|
+
const debug = debugFactory('loopback:repository:relations:belongs-to:helpers');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Relation definition with optional metadata (e.g. `keyTo`) filled in.
|
|
@@ -3,10 +3,10 @@
|
|
|
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 {Filter, InclusionFilter} from '@loopback/filter';
|
|
6
7
|
import {AnyObject, Options} from '../../common-types';
|
|
7
8
|
import {Entity} from '../../model';
|
|
8
|
-
import {
|
|
9
|
-
import {EntityCrudRepository} from '../../repositories/repository';
|
|
9
|
+
import {EntityCrudRepository} from '../../repositories';
|
|
10
10
|
import {
|
|
11
11
|
deduplicate,
|
|
12
12
|
findByForeignKeys,
|
|
@@ -44,7 +44,7 @@ export function createBelongsToInclusionResolver<
|
|
|
44
44
|
|
|
45
45
|
return async function fetchIncludedModels(
|
|
46
46
|
entities: Entity[],
|
|
47
|
-
inclusion:
|
|
47
|
+
inclusion: InclusionFilter,
|
|
48
48
|
options?: Options,
|
|
49
49
|
): Promise<((Target & TargetRelations) | undefined)[]> {
|
|
50
50
|
if (!entities.length) return [];
|
|
@@ -54,12 +54,15 @@ export function createBelongsToInclusionResolver<
|
|
|
54
54
|
const targetKey = relationMeta.keyTo as StringKeyOf<Target>;
|
|
55
55
|
const dedupedSourceIds = deduplicate(sourceIds);
|
|
56
56
|
|
|
57
|
+
const scope =
|
|
58
|
+
typeof inclusion === 'string' ? {} : (inclusion.scope as Filter<Target>);
|
|
59
|
+
|
|
57
60
|
const targetRepo = await getTargetRepo();
|
|
58
61
|
const targetsFound = await findByForeignKeys(
|
|
59
62
|
targetRepo,
|
|
60
63
|
targetKey,
|
|
61
64
|
dedupedSourceIds.filter(e => e),
|
|
62
|
-
|
|
65
|
+
scope,
|
|
63
66
|
options,
|
|
64
67
|
);
|
|
65
68
|
|
|
@@ -7,8 +7,7 @@ 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';
|
|
10
|
-
import {constrainFilter} from '../../repositories
|
|
11
|
-
import {EntityCrudRepository} from '../../repositories/repository';
|
|
10
|
+
import {constrainFilter, EntityCrudRepository} from '../../repositories';
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* CRUD operations for a target repository of a BelongsTo relation
|
|
@@ -15,7 +15,9 @@ import {
|
|
|
15
15
|
} from '../..';
|
|
16
16
|
import {resolveHasManyMetaHelper} from './has-many.helpers';
|
|
17
17
|
|
|
18
|
-
const debug = debugFactory(
|
|
18
|
+
const debug = debugFactory(
|
|
19
|
+
'loopback:repository:relations:has-many-through:helpers',
|
|
20
|
+
);
|
|
19
21
|
|
|
20
22
|
export type HasManyThroughResolvedDefinition = HasManyDefinition & {
|
|
21
23
|
keyTo: string;
|
|
@@ -3,11 +3,11 @@
|
|
|
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 {Filter,
|
|
6
|
+
import {Filter, InclusionFilter} from '@loopback/filter';
|
|
7
7
|
import debugFactory from 'debug';
|
|
8
8
|
import {AnyObject, Options} from '../../common-types';
|
|
9
9
|
import {Entity} from '../../model';
|
|
10
|
-
import {EntityCrudRepository} from '../../repositories
|
|
10
|
+
import {EntityCrudRepository} from '../../repositories';
|
|
11
11
|
import {
|
|
12
12
|
findByForeignKeys,
|
|
13
13
|
flattenTargetsOfOneToManyRelation,
|
|
@@ -17,7 +17,7 @@ import {Getter, HasManyDefinition, InclusionResolver} from '../relation.types';
|
|
|
17
17
|
import {resolveHasManyMetadata} from './has-many.helpers';
|
|
18
18
|
|
|
19
19
|
const debug = debugFactory(
|
|
20
|
-
'loopback:repository:has-many-through
|
|
20
|
+
'loopback:repository:relations:has-many-through:inclusion-resolver',
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -52,7 +52,7 @@ export function createHasManyThroughInclusionResolver<
|
|
|
52
52
|
|
|
53
53
|
return async function fetchHasManyThroughModels(
|
|
54
54
|
entities: Entity[],
|
|
55
|
-
inclusion:
|
|
55
|
+
inclusion: InclusionFilter,
|
|
56
56
|
options?: Options,
|
|
57
57
|
): Promise<((Target & TargetRelations)[] | undefined)[]> {
|
|
58
58
|
if (!entities.length) return [];
|
|
@@ -104,6 +104,9 @@ export function createHasManyThroughInclusionResolver<
|
|
|
104
104
|
|
|
105
105
|
const result = [];
|
|
106
106
|
|
|
107
|
+
const scope =
|
|
108
|
+
typeof inclusion === 'string' ? {} : (inclusion.scope as Filter<Target>);
|
|
109
|
+
|
|
107
110
|
// convert from through entities to the target entities
|
|
108
111
|
for (const entityList of throughResult) {
|
|
109
112
|
if (entityList) {
|
|
@@ -115,13 +118,7 @@ export function createHasManyThroughInclusionResolver<
|
|
|
115
118
|
Target,
|
|
116
119
|
TargetRelations,
|
|
117
120
|
StringKeyOf<Target>
|
|
118
|
-
>(
|
|
119
|
-
targetRepo,
|
|
120
|
-
targetKey,
|
|
121
|
-
(targetIds as unknown) as [],
|
|
122
|
-
inclusion.scope as Filter<Target>,
|
|
123
|
-
options,
|
|
124
|
-
);
|
|
121
|
+
>(targetRepo, targetKey, (targetIds as unknown) as [], scope, options);
|
|
125
122
|
result.push(targetEntityList);
|
|
126
123
|
} else {
|
|
127
124
|
// no entities found, add undefined to results
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
getTargetKeysFromThroughModels,
|
|
20
20
|
resolveHasManyThroughMetadata,
|
|
21
21
|
} from './has-many-through.helpers';
|
|
22
|
-
import {createHasManyThroughInclusionResolver} from './has-many-through.inclusion
|
|
22
|
+
import {createHasManyThroughInclusionResolver} from './has-many-through.inclusion-resolver';
|
|
23
23
|
import {
|
|
24
24
|
DefaultHasManyThroughRepository,
|
|
25
25
|
HasManyThroughRepository,
|
|
@@ -9,7 +9,7 @@ import {InvalidRelationError} from '../../errors';
|
|
|
9
9
|
import {isTypeResolver} from '../../type-resolver';
|
|
10
10
|
import {HasManyDefinition, RelationType} from '../relation.types';
|
|
11
11
|
|
|
12
|
-
const debug = debugFactory('loopback:repository:has-many
|
|
12
|
+
const debug = debugFactory('loopback:repository:relations:has-many:helpers');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Relation definition with optional metadata (e.g. `keyTo`) filled in.
|
|
@@ -3,11 +3,11 @@
|
|
|
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 {Filter,
|
|
6
|
+
import {Filter, InclusionFilter} from '@loopback/filter';
|
|
7
7
|
import debugFactory from 'debug';
|
|
8
8
|
import {AnyObject, Options} from '../../common-types';
|
|
9
9
|
import {Entity} from '../../model';
|
|
10
|
-
import {EntityCrudRepository} from '../../repositories
|
|
10
|
+
import {EntityCrudRepository} from '../../repositories';
|
|
11
11
|
import {
|
|
12
12
|
findByForeignKeys,
|
|
13
13
|
flattenTargetsOfOneToManyRelation,
|
|
@@ -16,7 +16,9 @@ import {
|
|
|
16
16
|
import {Getter, HasManyDefinition, InclusionResolver} from '../relation.types';
|
|
17
17
|
import {resolveHasManyMetadata} from './has-many.helpers';
|
|
18
18
|
|
|
19
|
-
const debug = debugFactory(
|
|
19
|
+
const debug = debugFactory(
|
|
20
|
+
'loopback:repository:relations:has-many:inclusion-resolver',
|
|
21
|
+
);
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* Creates InclusionResolver for HasMany relation.
|
|
@@ -42,7 +44,7 @@ export function createHasManyInclusionResolver<
|
|
|
42
44
|
|
|
43
45
|
return async function fetchHasManyModels(
|
|
44
46
|
entities: Entity[],
|
|
45
|
-
inclusion:
|
|
47
|
+
inclusion: InclusionFilter,
|
|
46
48
|
options?: Options,
|
|
47
49
|
): Promise<((Target & TargetRelations)[] | undefined)[]> {
|
|
48
50
|
if (!entities.length) return [];
|
|
@@ -60,12 +62,15 @@ export function createHasManyInclusionResolver<
|
|
|
60
62
|
sourceIds.map(i => typeof i),
|
|
61
63
|
);
|
|
62
64
|
|
|
65
|
+
const scope =
|
|
66
|
+
typeof inclusion === 'string' ? {} : (inclusion.scope as Filter<Target>);
|
|
67
|
+
|
|
63
68
|
const targetRepo = await getTargetRepo();
|
|
64
69
|
const targetsFound = await findByForeignKeys(
|
|
65
70
|
targetRepo,
|
|
66
71
|
targetKey,
|
|
67
72
|
sourceIds,
|
|
68
|
-
|
|
73
|
+
scope,
|
|
69
74
|
options,
|
|
70
75
|
);
|
|
71
76
|
|
package/src/relations/has-many/{has-many-repository.factory.ts → has-many.repository-factory.ts}
RENAMED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import debugFactory from 'debug';
|
|
7
7
|
import {DataObject} from '../../common-types';
|
|
8
8
|
import {Entity} from '../../model';
|
|
9
|
-
import {EntityCrudRepository} from '../../repositories
|
|
9
|
+
import {EntityCrudRepository} from '../../repositories';
|
|
10
10
|
import {Getter, HasManyDefinition, InclusionResolver} from '../relation.types';
|
|
11
11
|
import {resolveHasManyMetadata} from './has-many.helpers';
|
|
12
12
|
import {createHasManyInclusionResolver} from './has-many.inclusion-resolver';
|
|
@@ -15,7 +15,9 @@ import {
|
|
|
15
15
|
HasManyRepository,
|
|
16
16
|
} from './has-many.repository';
|
|
17
17
|
|
|
18
|
-
const debug = debugFactory(
|
|
18
|
+
const debug = debugFactory(
|
|
19
|
+
'loopback:repository:relations:has-many:repository-factory',
|
|
20
|
+
);
|
|
19
21
|
|
|
20
22
|
export interface HasManyRepositoryFactory<
|
|
21
23
|
Target extends Entity,
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
constrainDataObject,
|
|
12
12
|
constrainFilter,
|
|
13
13
|
constrainWhere,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
EntityCrudRepository,
|
|
15
|
+
} from '../../repositories';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* CRUD operations for a target repository of a HasMany relation
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// This file is licensed under the MIT License.
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
|
-
export * from './has-many-
|
|
7
|
-
export * from './has-many-through-
|
|
6
|
+
export * from './has-many.repository-factory';
|
|
7
|
+
export * from './has-many-through.repository-factory';
|
|
8
8
|
export * from './has-many-through.repository';
|
|
9
9
|
export * from './has-many.decorator';
|
|
10
10
|
export * from './has-many.inclusion-resolver';
|
|
@@ -9,7 +9,7 @@ import {InvalidRelationError} from '../../errors';
|
|
|
9
9
|
import {isTypeResolver} from '../../type-resolver';
|
|
10
10
|
import {HasOneDefinition, RelationType} from '../relation.types';
|
|
11
11
|
|
|
12
|
-
const debug = debugFactory('loopback:repository:has-one
|
|
12
|
+
const debug = debugFactory('loopback:repository:relations:has-one:helpers');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Relation definition with optional metadata (e.g. `keyTo`) filled in.
|
|
@@ -3,10 +3,10 @@
|
|
|
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 {Filter,
|
|
6
|
+
import {Filter, InclusionFilter} from '@loopback/filter';
|
|
7
7
|
import {AnyObject, Options} from '../../common-types';
|
|
8
8
|
import {Entity} from '../../model';
|
|
9
|
-
import {EntityCrudRepository} from '../../repositories
|
|
9
|
+
import {EntityCrudRepository} from '../../repositories';
|
|
10
10
|
import {
|
|
11
11
|
findByForeignKeys,
|
|
12
12
|
flattenTargetsOfOneToOneRelation,
|
|
@@ -39,7 +39,7 @@ export function createHasOneInclusionResolver<
|
|
|
39
39
|
|
|
40
40
|
return async function fetchHasOneModel(
|
|
41
41
|
entities: Entity[],
|
|
42
|
-
inclusion:
|
|
42
|
+
inclusion: InclusionFilter,
|
|
43
43
|
options?: Options,
|
|
44
44
|
): Promise<((Target & TargetRelations) | undefined)[]> {
|
|
45
45
|
if (!entities.length) return [];
|
|
@@ -48,12 +48,15 @@ export function createHasOneInclusionResolver<
|
|
|
48
48
|
const sourceIds = entities.map(e => (e as AnyObject)[sourceKey]);
|
|
49
49
|
const targetKey = relationMeta.keyTo as StringKeyOf<Target>;
|
|
50
50
|
|
|
51
|
+
const scope =
|
|
52
|
+
typeof inclusion === 'string' ? {} : (inclusion.scope as Filter<Target>);
|
|
53
|
+
|
|
51
54
|
const targetRepo = await getTargetRepo();
|
|
52
55
|
const targetsFound = await findByForeignKeys(
|
|
53
56
|
targetRepo,
|
|
54
57
|
targetKey,
|
|
55
58
|
sourceIds,
|
|
56
|
-
|
|
59
|
+
scope,
|
|
57
60
|
options,
|
|
58
61
|
);
|
|
59
62
|
|
package/src/relations/has-one/{has-one-repository.factory.ts → has-one.repository-factory.ts}
RENAMED
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
import debugFactory from 'debug';
|
|
7
7
|
import {DataObject} from '../../common-types';
|
|
8
8
|
import {Entity} from '../../model';
|
|
9
|
-
import {EntityCrudRepository} from '../../repositories
|
|
9
|
+
import {EntityCrudRepository} from '../../repositories';
|
|
10
10
|
import {Getter, HasOneDefinition, InclusionResolver} from '../relation.types';
|
|
11
11
|
import {resolveHasOneMetadata} from './has-one.helpers';
|
|
12
12
|
import {createHasOneInclusionResolver} from './has-one.inclusion-resolver';
|
|
13
13
|
import {DefaultHasOneRepository, HasOneRepository} from './has-one.repository';
|
|
14
14
|
|
|
15
|
-
const debug = debugFactory(
|
|
15
|
+
const debug = debugFactory(
|
|
16
|
+
'loopback:repository:relations:has-one:repository-factory',
|
|
17
|
+
);
|
|
16
18
|
|
|
17
19
|
export interface HasOneRepositoryFactory<
|
|
18
20
|
Target extends Entity,
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
import assert from 'assert';
|
|
7
7
|
import debugFactory from 'debug';
|
|
8
|
-
import _ from 'lodash';
|
|
8
|
+
import _, {cloneDeep} from 'lodash';
|
|
9
9
|
import {
|
|
10
10
|
AnyObject,
|
|
11
11
|
Entity,
|
|
12
12
|
EntityCrudRepository,
|
|
13
13
|
Filter,
|
|
14
14
|
FilterBuilder,
|
|
15
|
-
|
|
15
|
+
InclusionFilter,
|
|
16
16
|
Options,
|
|
17
17
|
Where,
|
|
18
18
|
} from '..';
|
|
@@ -39,17 +39,11 @@ export async function findByForeignKeys<
|
|
|
39
39
|
options?: Options,
|
|
40
40
|
): Promise<(Target & TargetRelations)[]> {
|
|
41
41
|
let value;
|
|
42
|
+
scope = cloneDeep(scope);
|
|
42
43
|
|
|
43
44
|
if (Array.isArray(fkValues)) {
|
|
44
45
|
if (fkValues.length === 0) return [];
|
|
45
|
-
value =
|
|
46
|
-
fkValues.length === 1
|
|
47
|
-
? fkValues[0]
|
|
48
|
-
: {
|
|
49
|
-
// Create a copy to prevent query coercion algorithm
|
|
50
|
-
// inside connectors from modifying the original values
|
|
51
|
-
inq: [...fkValues],
|
|
52
|
-
};
|
|
46
|
+
value = fkValues.length === 1 ? fkValues[0] : {inq: fkValues};
|
|
53
47
|
} else {
|
|
54
48
|
value = fkValues;
|
|
55
49
|
}
|
|
@@ -84,9 +78,11 @@ export async function includeRelatedModels<
|
|
|
84
78
|
>(
|
|
85
79
|
targetRepository: EntityCrudRepository<T, unknown, Relations>,
|
|
86
80
|
entities: T[],
|
|
87
|
-
include?:
|
|
81
|
+
include?: InclusionFilter[],
|
|
88
82
|
options?: Options,
|
|
89
83
|
): Promise<(T & Relations)[]> {
|
|
84
|
+
entities = cloneDeep(entities);
|
|
85
|
+
include = cloneDeep(include);
|
|
90
86
|
const result = entities as (T & Relations)[];
|
|
91
87
|
if (!include) return result;
|
|
92
88
|
|
|
@@ -108,7 +104,10 @@ export async function includeRelatedModels<
|
|
|
108
104
|
}
|
|
109
105
|
|
|
110
106
|
const resolveTasks = include.map(async inclusionFilter => {
|
|
111
|
-
const relationName =
|
|
107
|
+
const relationName =
|
|
108
|
+
typeof inclusionFilter === 'string'
|
|
109
|
+
? inclusionFilter
|
|
110
|
+
: inclusionFilter.relation;
|
|
112
111
|
const resolver = targetRepository.inclusionResolvers.get(relationName)!;
|
|
113
112
|
const targets = await resolver(entities, inclusionFilter, options);
|
|
114
113
|
|
|
@@ -131,9 +130,9 @@ export async function includeRelatedModels<
|
|
|
131
130
|
*/
|
|
132
131
|
function isInclusionAllowed<T extends Entity, Relations extends object = {}>(
|
|
133
132
|
targetRepository: EntityCrudRepository<T, unknown, Relations>,
|
|
134
|
-
include:
|
|
133
|
+
include: InclusionFilter,
|
|
135
134
|
): boolean {
|
|
136
|
-
const relationName = include.relation;
|
|
135
|
+
const relationName = typeof include === 'string' ? include : include.relation;
|
|
137
136
|
if (!relationName) {
|
|
138
137
|
debug('isInclusionAllowed for %j? No: missing relation name', include);
|
|
139
138
|
return false;
|
|
@@ -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 {
|
|
6
|
+
import {InclusionFilter} from '@loopback/filter';
|
|
7
7
|
import {Options} from '../common-types';
|
|
8
8
|
import {Entity} from '../model';
|
|
9
9
|
import {TypeResolver} from '../type-resolver';
|
|
@@ -172,7 +172,7 @@ export type InclusionResolver<S extends Entity, T extends Entity> = (
|
|
|
172
172
|
/**
|
|
173
173
|
* Inclusion requested by the user (e.g. scope constraints to apply).
|
|
174
174
|
*/
|
|
175
|
-
inclusion:
|
|
175
|
+
inclusion: InclusionFilter,
|
|
176
176
|
/**
|
|
177
177
|
* Generic options object, e.g. carrying the Transaction object.
|
|
178
178
|
*/
|
|
@@ -53,9 +53,10 @@ export class DefaultKeyValueRepository<T extends Model>
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
async get(key: string, options?: Options): Promise<T> {
|
|
56
|
-
const val = this.kvModelClass.get(
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
const val = this.kvModelClass.get(
|
|
57
|
+
key,
|
|
58
|
+
options,
|
|
59
|
+
) as legacy.PromiseOrVoid<legacy.ModelData>;
|
|
59
60
|
const result = await ensurePromise(val);
|
|
60
61
|
return this.toEntity(result);
|
|
61
62
|
}
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
import {Getter} from '@loopback/core';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Filter,
|
|
9
|
+
FilterExcludingWhere,
|
|
10
|
+
InclusionFilter,
|
|
11
|
+
Where,
|
|
12
|
+
} from '@loopback/filter';
|
|
8
13
|
import assert from 'assert';
|
|
9
14
|
import legacy from 'loopback-datasource-juggler';
|
|
10
15
|
import {
|
|
@@ -695,7 +700,7 @@ export class DefaultCrudRepository<
|
|
|
695
700
|
*/
|
|
696
701
|
protected async includeRelatedModels(
|
|
697
702
|
entities: T[],
|
|
698
|
-
include?:
|
|
703
|
+
include?: InclusionFilter[],
|
|
699
704
|
options?: Options,
|
|
700
705
|
): Promise<(T & Relations)[]> {
|
|
701
706
|
return includeRelatedModels<T, Relations>(this, entities, include, options);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"has-many-repository.factory.js","sourceRoot":"","sources":["../../../src/relations/has-many/has-many-repository.factory.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,oCAAoC;AACpC,+CAA+C;AAC/C,gEAAgE;;;;AAEhE,0DAAiC;AAKjC,yDAA0D;AAC1D,+EAA6E;AAC7E,+DAG+B;AAE/B,MAAM,KAAK,GAAG,eAAY,CAAC,iDAAiD,CAAC,CAAC;AAiB9E;;;;;;;;;;;;GAYG;AACH,SAAgB,8BAA8B,CAK5C,gBAAmC,EACnC,sBAAsE;IAEtE,MAAM,IAAI,GAAG,yCAAsB,CAAC,gBAAgB,CAAC,CAAC;IACtD,KAAK,CAAC,wCAAwC,EAAE,IAAI,CAAC,CAAC;IACtD,MAAM,MAAM,GAAqD,UAC/D,OAAuB;QAEvB,8DAA8D;QAC9D,MAAM,UAAU,GAAQ,EAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,EAAC,CAAC;QAChD,OAAO,IAAI,8CAAwB,CAIjC,sBAAsB,EAAE,UAAgC,CAAC,CAAC;IAC9D,CAAC,CAAC;IACF,MAAM,CAAC,iBAAiB,GAAG,4DAA8B,CACvD,IAAI,EACJ,sBAAsB,CACvB,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AA1BD,wEA0BC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"has-one-repository.factory.js","sourceRoot":"","sources":["../../../src/relations/has-one/has-one-repository.factory.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,oCAAoC;AACpC,+CAA+C;AAC/C,gEAAgE;;;;AAEhE,0DAAiC;AAKjC,uDAAwD;AACxD,6EAA2E;AAC3E,6DAA+E;AAE/E,MAAM,KAAK,GAAG,eAAY,CAAC,gDAAgD,CAAC,CAAC;AAgB7E;;;;;;;;;;;;GAYG;AACH,SAAgB,6BAA6B,CAK3C,gBAAkC,EAClC,sBAAsE;IAEtE,MAAM,IAAI,GAAG,uCAAqB,CAAC,gBAAgB,CAAC,CAAC;IACrD,KAAK,CAAC,uCAAuC,EAAE,IAAI,CAAC,CAAC;IACrD,MAAM,MAAM,GAAoD,UAC9D,OAAuB;QAEvB,8DAA8D;QAC9D,MAAM,UAAU,GAAQ,EAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,EAAC,CAAC;QAChD,OAAO,IAAI,4CAAuB,CAIhC,sBAAsB,EAAE,UAAgC,CAAC,CAAC;IAC9D,CAAC,CAAC;IACF,MAAM,CAAC,iBAAiB,GAAG,0DAA6B,CACtD,IAAI,EACJ,sBAAsB,CACvB,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AA1BD,sEA0BC"}
|