UNPKG

2.79 kBPlain TextView Raw
1// Copyright IBM Corp. and LoopBack contributors 2018,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
6import debugFactory from 'debug';
7import {DataObject} from '../../common-types';
8import {Entity} from '../../model';
9import {EntityCrudRepository} from '../../repositories';
10import {Getter, HasManyDefinition, InclusionResolver} from '../relation.types';
11import {resolveHasManyMetadata} from './has-many.helpers';
12import {createHasManyInclusionResolver} from './has-many.inclusion-resolver';
13import {
14 DefaultHasManyRepository,
15 HasManyRepository,
16} from './has-many.repository';
17
18const debug = debugFactory(
19 'loopback:repository:relations:has-many:repository-factory',
20);
21
22export interface HasManyRepositoryFactory<
23 Target extends Entity,
24 ForeignKeyType,
25> {
26 /**
27 * Invoke the function to obtain HasManyRepository.
28 */
29 (fkValue: ForeignKeyType): HasManyRepository<Target>;
30
31 /**
32 * Use `resolver` property to obtain an InclusionResolver for this relation.
33 */
34 inclusionResolver: InclusionResolver<Entity, Target>;
35}
36
37/**
38 * Enforces a constraint on a repository based on a relationship contract
39 * between models. For example, if a Customer model is related to an Order model
40 * via a HasMany relation, then, the relational repository returned by the
41 * factory function would be constrained by a Customer model instance's id(s).
42 *
43 * @param relationMetadata - The relation metadata used to describe the
44 * relationship and determine how to apply the constraint.
45 * @param targetRepositoryGetter - The repository which represents the target model of a
46 * relation attached to a datasource.
47 * @returns The factory function which accepts a foreign key value to constrain
48 * the given target repository
49 */
50export function createHasManyRepositoryFactory<
51 Target extends Entity,
52 TargetID,
53 ForeignKeyType,
54>(
55 relationMetadata: HasManyDefinition,
56 targetRepositoryGetter: Getter<EntityCrudRepository<Target, TargetID>>,
57): HasManyRepositoryFactory<Target, ForeignKeyType> {
58 const meta = resolveHasManyMetadata(relationMetadata);
59 debug('Resolved HasMany relation metadata: %o', meta);
60 const result: HasManyRepositoryFactory<Target, ForeignKeyType> = function (
61 fkValue: ForeignKeyType,
62 ) {
63 // eslint-disable-next-line @typescript-eslint/no-explicit-any
64 const constraint: any = {[meta.keyTo]: fkValue};
65 return new DefaultHasManyRepository<
66 Target,
67 TargetID,
68 EntityCrudRepository<Target, TargetID>
69 >(targetRepositoryGetter, constraint as DataObject<Target>);
70 };
71 result.inclusionResolver = createHasManyInclusionResolver(
72 meta,
73 targetRepositoryGetter,
74 );
75 return result;
76}