1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | Object.defineProperty(exports, "__esModule", { value: true });
|
7 | exports.createHasManyThroughInclusionResolver = void 0;
|
8 | const tslib_1 = require("tslib");
|
9 | const debug_1 = tslib_1.__importDefault(require("debug"));
|
10 | const __1 = require("../..");
|
11 | const relation_helpers_1 = require("../relation.helpers");
|
12 | const has_many_through_helpers_1 = require("./has-many-through.helpers");
|
13 | const debug = (0, debug_1.default)('loopback:repository:relations:has-many-through:inclusion-resolver');
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | function createHasManyThroughInclusionResolver(meta, getThroughRepo, getTargetRepoDict) {
|
27 | const relationMeta = (0, has_many_through_helpers_1.resolveHasManyThroughMetadata)(meta);
|
28 | return async function fetchHasManyThroughModels(entities, inclusion, options) {
|
29 | if (!relationMeta.through) {
|
30 | throw new Error(`relationMeta.through must be defined on ${relationMeta}`);
|
31 | }
|
32 | if (!entities.length)
|
33 | return [];
|
34 | debug('Fetching target models for entities:', entities);
|
35 | debug('Relation metadata:', relationMeta);
|
36 | const sourceKey = relationMeta.keyFrom;
|
37 | const sourceIds = entities.map(e => e[sourceKey]);
|
38 | const targetKey = relationMeta.keyTo;
|
39 | if (!relationMeta.through) {
|
40 | throw new Error(`relationMeta.through must be defined on ${relationMeta}`);
|
41 | }
|
42 | const throughKeyTo = relationMeta.through.keyTo;
|
43 | const throughKeyFrom = relationMeta.through.keyFrom;
|
44 | debug('Parameters:', {
|
45 | sourceKey,
|
46 | sourceIds,
|
47 | targetKey,
|
48 | throughKeyTo,
|
49 | throughKeyFrom,
|
50 | });
|
51 | debug('sourceId types', sourceIds.map(i => typeof i));
|
52 | const throughRepo = await getThroughRepo();
|
53 |
|
54 | const throughFound = await (0, relation_helpers_1.findByForeignKeys)(throughRepo, throughKeyFrom, sourceIds, {},
|
55 | options);
|
56 | const throughResult = (0, relation_helpers_1.flattenTargetsOfOneToManyRelation)(sourceIds, throughFound, throughKeyFrom);
|
57 | const scope = typeof inclusion === 'string' ? {} : inclusion.scope;
|
58 |
|
59 | const targetDiscriminator = relationMeta.through.polymorphic
|
60 | ? relationMeta.through.polymorphic.discriminator
|
61 | : undefined;
|
62 | if (targetDiscriminator) {
|
63 |
|
64 | const throughArrayByTargetType = {};
|
65 | for (const throughArray of throughResult) {
|
66 | if (throughArray) {
|
67 | for (const throughItem of throughArray) {
|
68 | const targetType = String(throughItem[targetDiscriminator]);
|
69 | if (!getTargetRepoDict[targetType]) {
|
70 | throw new __1.InvalidPolymorphismError(targetType, String(targetDiscriminator));
|
71 | }
|
72 | if (!throughArrayByTargetType[targetType]) {
|
73 | throughArrayByTargetType[targetType] = [];
|
74 | }
|
75 | throughArrayByTargetType[targetType].push(throughItem);
|
76 | }
|
77 | }
|
78 | }
|
79 |
|
80 | const targetOfTypes = {};
|
81 | for (const targetType of Object.keys(throughArrayByTargetType)) {
|
82 | const targetIds = throughArrayByTargetType[targetType].map(throughItem => throughItem[throughKeyTo]);
|
83 | const targetRepo = await getTargetRepoDict[targetType]();
|
84 | const targetEntityList = await (0, relation_helpers_1.findByForeignKeys)(targetRepo, targetKey, targetIds, scope, options);
|
85 | targetOfTypes[targetType] = targetEntityList;
|
86 | }
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 | const allTargetsOfThrough = [];
|
106 | for (const throughArray of throughResult) {
|
107 | if (throughArray && throughArray.length > 0) {
|
108 | const currentTargetThroughArray = [];
|
109 | for (const throughItem of throughArray) {
|
110 | const itemToAdd = targetOfTypes[String(throughItem[targetDiscriminator])].shift();
|
111 | if (itemToAdd) {
|
112 | currentTargetThroughArray.push(itemToAdd);
|
113 | }
|
114 | }
|
115 | allTargetsOfThrough.push(currentTargetThroughArray);
|
116 | }
|
117 | else {
|
118 | allTargetsOfThrough.push(undefined);
|
119 | }
|
120 | }
|
121 | return allTargetsOfThrough;
|
122 | }
|
123 | else {
|
124 | const targetRepo = await getTargetRepoDict[relationMeta.target().name]();
|
125 | const result = [];
|
126 |
|
127 | for (const entityList of throughResult) {
|
128 | if (entityList) {
|
129 |
|
130 | const targetIds = entityList.map(entity => entity[throughKeyTo]);
|
131 |
|
132 | const targetEntityList = await (0, relation_helpers_1.findByForeignKeys)(targetRepo, targetKey, targetIds, scope, {
|
133 | ...options,
|
134 | isThroughModelInclude: true,
|
135 | });
|
136 | result.push(targetEntityList);
|
137 | }
|
138 | else {
|
139 |
|
140 | result.push(entityList);
|
141 | }
|
142 | }
|
143 | debug('fetchHasManyThroughModels result', result);
|
144 | return result;
|
145 | }
|
146 | };
|
147 | }
|
148 | exports.createHasManyThroughInclusionResolver = createHasManyThroughInclusionResolver;
|
149 |
|
\ | No newline at end of file |