@atscript/db 0.1.146 → 0.1.147
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/dist/agg.cjs +1 -1
- package/dist/agg.d.cts +1 -1
- package/dist/agg.d.mts +1 -1
- package/dist/agg.mjs +1 -1
- package/dist/{aggregate-fns-CfsveE1w.mjs → aggregate-fns-C0BymEqa.mjs} +3 -1
- package/dist/{aggregate-fns-CGBv3E8S.cjs → aggregate-fns-CtsRbZn9.cjs} +8 -0
- package/dist/{buckets-DYFu0eZ8.d.cts → buckets-CjdPipCC.d.cts} +522 -17
- package/dist/{buckets-DRycmhOW.d.mts → buckets-DYopfd2Y.d.mts} +522 -17
- package/dist/{column-diff-e2oHc71_.mjs → column-diff-CO06iQvI.mjs} +862 -115
- package/dist/{column-diff-D_Kyuh0S.cjs → column-diff-Dt7EDJsA.cjs} +872 -113
- package/dist/{column-diff-Q9UmWn5x.d.mts → fk-diff-BtOmL4OW.d.mts} +48 -2
- package/dist/{column-diff-w-Mym_3w.d.cts → fk-diff-DLqwVkKG.d.cts} +48 -2
- package/dist/index.cjs +28 -33
- package/dist/index.d.cts +40 -15
- package/dist/index.d.mts +40 -15
- package/dist/index.mjs +5 -33
- package/dist/{nested-writer-CnOOAehr.mjs → nested-writer-D35UsDBT.mjs} +542 -2
- package/dist/{nested-writer-xfQwxplL.cjs → nested-writer-SqtYJHF0.cjs} +666 -0
- package/dist/plugin.cjs +266 -5
- package/dist/plugin.mjs +267 -6
- package/dist/rel.cjs +2 -2
- package/dist/rel.d.cts +2 -2
- package/dist/rel.d.mts +2 -2
- package/dist/rel.mjs +2 -2
- package/dist/{relation-helpers-B-0NRKat.d.mts → relation-helpers-C2bLtE-t.d.mts} +1 -1
- package/dist/{relation-helpers-BOMm_HUI.d.cts → relation-helpers-DH3LvwLV.d.cts} +1 -1
- package/dist/relation-loader-BFhVuJ-B.cjs +369 -0
- package/dist/relation-loader-C0qE8xgR.mjs +370 -0
- package/dist/shared.cjs +1 -1
- package/dist/shared.d.cts +4 -3
- package/dist/shared.d.mts +4 -3
- package/dist/shared.mjs +1 -1
- package/dist/sync.cjs +10 -6
- package/dist/sync.d.cts +2 -25
- package/dist/sync.d.mts +2 -25
- package/dist/sync.mjs +10 -6
- package/dist/{validation-utils-DOsB4e6G.cjs → validation-utils-Da2GjobR.cjs} +35 -24
- package/dist/{validation-utils-CMR4fe2M.mjs → validation-utils-Dq0uZ7ef.mjs} +35 -24
- package/dist/{validator-Bw6ks9Hy.d.mts → validator-CMnTI6r7.d.cts} +9 -6
- package/dist/{validator-Bw6ks9Hy.d.cts → validator-CMnTI6r7.d.mts} +9 -6
- package/dist/validator.d.cts +1 -1
- package/dist/validator.d.mts +1 -1
- package/package.json +8 -8
- package/dist/relation-loader-CBPY6kM7.cjs +0 -461
- package/dist/relation-loader-D9XuXaMv.mjs +0 -462
|
@@ -1,462 +0,0 @@
|
|
|
1
|
-
import { C as findRemoteFK, S as findFKForRelation, w as resolveRelationTargetTable } from "./nested-writer-CnOOAehr.mjs";
|
|
2
|
-
//#region \0rolldown/runtime.js
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __exportAll = (all, no_symbols) => {
|
|
5
|
-
let target = {};
|
|
6
|
-
for (var name in all) __defProp(target, name, {
|
|
7
|
-
get: all[name],
|
|
8
|
-
enumerable: true
|
|
9
|
-
});
|
|
10
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
11
|
-
return target;
|
|
12
|
-
};
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/rel/relation-loader.ts
|
|
15
|
-
var relation_loader_exports = /* @__PURE__ */ __exportAll({
|
|
16
|
-
ensureSelectIncludesFields: () => ensureSelectIncludesFields,
|
|
17
|
-
loadRelationsImpl: () => loadRelationsImpl
|
|
18
|
-
});
|
|
19
|
-
/**
|
|
20
|
-
* Loads related data for `$with` relations and attaches them to result rows.
|
|
21
|
-
*/
|
|
22
|
-
async function loadRelationsImpl(rows, withRelations, host) {
|
|
23
|
-
if (rows.length === 0 || withRelations.length === 0) return;
|
|
24
|
-
if (host.adapter.supportsNativeRelations()) return host.adapter.loadRelations(rows, withRelations, host._meta.relations, host._meta.foreignKeys, host._tableResolver);
|
|
25
|
-
if (!host._tableResolver) return;
|
|
26
|
-
const tasks = [];
|
|
27
|
-
for (const withRel of withRelations) {
|
|
28
|
-
const relName = withRel.name;
|
|
29
|
-
if (relName.includes(".")) continue;
|
|
30
|
-
const relation = host._meta.relations.get(relName);
|
|
31
|
-
if (!relation) throw new Error(`Unknown relation "${relName}" in $with. Available relations: ${[...host._meta.relations.keys()].join(", ") || "(none)"}`);
|
|
32
|
-
const targetType = relation.targetType();
|
|
33
|
-
if (!targetType) continue;
|
|
34
|
-
const targetTable = host._tableResolver(targetType);
|
|
35
|
-
if (!targetTable) {
|
|
36
|
-
host.logger.warn(`Could not resolve table for relation "${relName}" — skipping`);
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
const filter = withRel.filter && Object.keys(withRel.filter).length > 0 ? withRel.filter : void 0;
|
|
40
|
-
const flatRel = withRel;
|
|
41
|
-
const controls = { ...withRel.controls || {} };
|
|
42
|
-
if (flatRel.$sort && !controls.$sort) controls.$sort = flatRel.$sort;
|
|
43
|
-
if (flatRel.$limit !== null && flatRel.$limit !== void 0 && (controls.$limit === null || controls.$limit === void 0)) controls.$limit = flatRel.$limit;
|
|
44
|
-
if (flatRel.$skip !== null && flatRel.$skip !== void 0 && (controls.$skip === null || controls.$skip === void 0)) controls.$skip = flatRel.$skip;
|
|
45
|
-
if (flatRel.$select && !controls.$select) controls.$select = flatRel.$select;
|
|
46
|
-
if (flatRel.$with && !controls.$with) controls.$with = flatRel.$with;
|
|
47
|
-
const relQuery = {
|
|
48
|
-
filter,
|
|
49
|
-
controls
|
|
50
|
-
};
|
|
51
|
-
if (relation.direction === "to") tasks.push(loadToRelation(rows, {
|
|
52
|
-
relName,
|
|
53
|
-
relation,
|
|
54
|
-
targetTable,
|
|
55
|
-
relQuery
|
|
56
|
-
}, host));
|
|
57
|
-
else if (relation.direction === "via") tasks.push(loadViaRelation(rows, {
|
|
58
|
-
relName,
|
|
59
|
-
relation,
|
|
60
|
-
targetTable,
|
|
61
|
-
relQuery
|
|
62
|
-
}, host));
|
|
63
|
-
else tasks.push(loadFromRelation(rows, {
|
|
64
|
-
relName,
|
|
65
|
-
relation,
|
|
66
|
-
targetTable,
|
|
67
|
-
relQuery
|
|
68
|
-
}, host));
|
|
69
|
-
}
|
|
70
|
-
await Promise.all(tasks);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Loads a `@db.rel.to` relation (FK is on this table).
|
|
74
|
-
*/
|
|
75
|
-
async function loadToRelation(rows, opts, host) {
|
|
76
|
-
const { relName, relation, targetTable, relQuery } = opts;
|
|
77
|
-
const fkEntry = findFKForRelation(relation, host._meta.foreignKeys);
|
|
78
|
-
if (!fkEntry) return;
|
|
79
|
-
const { localFields, targetFields } = fkEntry;
|
|
80
|
-
if (localFields.length === 1) {
|
|
81
|
-
const localField = localFields[0];
|
|
82
|
-
const targetField = targetFields[0];
|
|
83
|
-
const fkValues = collectUniqueValues(rows, localField);
|
|
84
|
-
if (fkValues.length === 0) {
|
|
85
|
-
for (const row of rows) row[relName] = null;
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
const inFilter = { [targetField]: { $in: fkValues } };
|
|
89
|
-
const targetFilter = relQuery.filter ? { $and: [inFilter, relQuery.filter] } : inFilter;
|
|
90
|
-
const controls = ensureSelectIncludesFields(relQuery.controls, targetFields);
|
|
91
|
-
assignSingle({
|
|
92
|
-
rows,
|
|
93
|
-
related: await targetTable.findMany({
|
|
94
|
-
filter: targetFilter,
|
|
95
|
-
controls
|
|
96
|
-
}),
|
|
97
|
-
localField,
|
|
98
|
-
remoteField: targetField,
|
|
99
|
-
relName
|
|
100
|
-
});
|
|
101
|
-
} else {
|
|
102
|
-
const related = await queryCompositeFK(rows, {
|
|
103
|
-
localFields,
|
|
104
|
-
targetFields,
|
|
105
|
-
targetTable,
|
|
106
|
-
relQuery
|
|
107
|
-
});
|
|
108
|
-
const index = /* @__PURE__ */ new Map();
|
|
109
|
-
for (const item of related) index.set(compositeKey(targetFields, item), item);
|
|
110
|
-
for (const row of rows) row[relName] = index.get(compositeKey(localFields, row)) ?? null;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Loads a `@db.rel.from` relation (FK is on the target table).
|
|
115
|
-
*/
|
|
116
|
-
async function loadFromRelation(rows, opts, host) {
|
|
117
|
-
const { relName, relation, targetTable, relQuery } = opts;
|
|
118
|
-
const remoteFK = findRemoteFK(targetTable, host.tableName, relation.alias);
|
|
119
|
-
if (!remoteFK) {
|
|
120
|
-
host.logger.warn(`Could not find FK on target table for relation "${relName}"`);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const localFields = remoteFK.targetFields;
|
|
124
|
-
const remoteFields = remoteFK.fields;
|
|
125
|
-
if (localFields.length === 1) {
|
|
126
|
-
const localField = localFields[0];
|
|
127
|
-
const remoteField = remoteFields[0];
|
|
128
|
-
const pkValues = collectUniqueValues(rows, localField);
|
|
129
|
-
if (pkValues.length === 0) return;
|
|
130
|
-
const inFilter = { [remoteField]: { $in: pkValues } };
|
|
131
|
-
const targetFilter = relQuery.filter ? { $and: [inFilter, relQuery.filter] } : inFilter;
|
|
132
|
-
const controls = ensureSelectIncludesFields(relQuery.controls, remoteFields);
|
|
133
|
-
const related = await targetTable.findMany({
|
|
134
|
-
filter: targetFilter,
|
|
135
|
-
controls
|
|
136
|
-
});
|
|
137
|
-
if (relation.isArray) assignGrouped({
|
|
138
|
-
rows,
|
|
139
|
-
related,
|
|
140
|
-
localField,
|
|
141
|
-
remoteField,
|
|
142
|
-
relName
|
|
143
|
-
});
|
|
144
|
-
else assignSingle({
|
|
145
|
-
rows,
|
|
146
|
-
related,
|
|
147
|
-
localField,
|
|
148
|
-
remoteField,
|
|
149
|
-
relName
|
|
150
|
-
});
|
|
151
|
-
} else {
|
|
152
|
-
const related = await queryCompositeFK(rows, {
|
|
153
|
-
localFields,
|
|
154
|
-
targetFields: remoteFields,
|
|
155
|
-
targetTable,
|
|
156
|
-
relQuery
|
|
157
|
-
});
|
|
158
|
-
if (relation.isArray) {
|
|
159
|
-
const groups = /* @__PURE__ */ new Map();
|
|
160
|
-
for (const item of related) {
|
|
161
|
-
const key = compositeKey(remoteFields, item);
|
|
162
|
-
let group = groups.get(key);
|
|
163
|
-
if (!group) {
|
|
164
|
-
group = [];
|
|
165
|
-
groups.set(key, group);
|
|
166
|
-
}
|
|
167
|
-
group.push(item);
|
|
168
|
-
}
|
|
169
|
-
for (const row of rows) row[relName] = groups.get(compositeKey(localFields, row)) ?? [];
|
|
170
|
-
} else {
|
|
171
|
-
const index = /* @__PURE__ */ new Map();
|
|
172
|
-
for (const item of related) {
|
|
173
|
-
const key = compositeKey(remoteFields, item);
|
|
174
|
-
if (!index.has(key)) index.set(key, item);
|
|
175
|
-
}
|
|
176
|
-
for (const row of rows) row[relName] = index.get(compositeKey(localFields, row)) ?? null;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Loads a `@db.rel.via` relation (M:N through a junction table).
|
|
182
|
-
*/
|
|
183
|
-
async function loadViaRelation(rows, opts, host) {
|
|
184
|
-
const { relName, relation, targetTable, relQuery } = opts;
|
|
185
|
-
if (!relation.viaType || !host._tableResolver) return;
|
|
186
|
-
const junctionType = relation.viaType();
|
|
187
|
-
if (!junctionType) return;
|
|
188
|
-
const junctionTable = host._tableResolver(junctionType);
|
|
189
|
-
if (!junctionTable) {
|
|
190
|
-
host.logger.warn(`Could not resolve junction table for via relation "${relName}"`);
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
const fkToThis = findRemoteFK(junctionTable, host.tableName);
|
|
194
|
-
if (!fkToThis) {
|
|
195
|
-
host.logger.warn(`Could not find FK on junction table pointing to "${host.tableName}" for via relation "${relName}"`);
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
const targetTableName = resolveRelationTargetTable(relation);
|
|
199
|
-
const fkToTarget = findRemoteFK(junctionTable, targetTableName);
|
|
200
|
-
if (!fkToTarget) {
|
|
201
|
-
host.logger.warn(`Could not find FK on junction table pointing to target "${targetTableName}" for via relation "${relName}"`);
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
const localPKFields = fkToThis.targetFields;
|
|
205
|
-
const junctionLocalFields = fkToThis.fields;
|
|
206
|
-
const targetPKFields = fkToTarget.targetFields;
|
|
207
|
-
const junctionTargetFields = fkToTarget.fields;
|
|
208
|
-
if (localPKFields.length === 1) await loadViaSingleKey(rows, {
|
|
209
|
-
relName,
|
|
210
|
-
relation,
|
|
211
|
-
targetTable,
|
|
212
|
-
relQuery,
|
|
213
|
-
localPKFields,
|
|
214
|
-
junctionLocalFields,
|
|
215
|
-
targetPKFields,
|
|
216
|
-
junctionTargetFields,
|
|
217
|
-
junctionTable
|
|
218
|
-
});
|
|
219
|
-
else await loadViaCompositeKey(rows, {
|
|
220
|
-
relName,
|
|
221
|
-
relation,
|
|
222
|
-
targetTable,
|
|
223
|
-
relQuery,
|
|
224
|
-
localPKFields,
|
|
225
|
-
junctionLocalFields,
|
|
226
|
-
targetPKFields,
|
|
227
|
-
junctionTargetFields,
|
|
228
|
-
junctionTable
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
async function loadViaSingleKey(rows, opts) {
|
|
232
|
-
const { relName, relation, targetTable, relQuery, localPKFields, junctionLocalFields, targetPKFields, junctionTargetFields, junctionTable } = opts;
|
|
233
|
-
const localField = localPKFields[0];
|
|
234
|
-
const junctionLocalField = junctionLocalFields[0];
|
|
235
|
-
const junctionTargetField = junctionTargetFields[0];
|
|
236
|
-
const targetPKField = targetPKFields[0];
|
|
237
|
-
const pkValues = collectUniqueValues(rows, localField);
|
|
238
|
-
if (pkValues.length === 0) {
|
|
239
|
-
for (const row of rows) row[relName] = [];
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const junctionFilter = { [junctionLocalField]: { $in: pkValues } };
|
|
243
|
-
const junctionRows = await junctionTable.findMany({
|
|
244
|
-
filter: junctionFilter,
|
|
245
|
-
controls: { $select: [junctionLocalField, junctionTargetField] }
|
|
246
|
-
});
|
|
247
|
-
if (junctionRows.length === 0) {
|
|
248
|
-
for (const row of rows) row[relName] = relation.isArray ? [] : null;
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
const targetFKValues = collectUniqueValues(junctionRows, junctionTargetField);
|
|
252
|
-
const inFilter = { [targetPKField]: { $in: targetFKValues } };
|
|
253
|
-
const targetFilter = relQuery.filter ? { $and: [inFilter, relQuery.filter] } : inFilter;
|
|
254
|
-
const controls = ensureSelectIncludesFields(relQuery.controls, targetPKFields);
|
|
255
|
-
const targetRows = await targetTable.findMany({
|
|
256
|
-
filter: targetFilter,
|
|
257
|
-
controls
|
|
258
|
-
});
|
|
259
|
-
const targetIndex = /* @__PURE__ */ new Map();
|
|
260
|
-
for (const item of targetRows) targetIndex.set(String(item[targetPKField]), item);
|
|
261
|
-
const groups = /* @__PURE__ */ new Map();
|
|
262
|
-
for (const jRow of junctionRows) {
|
|
263
|
-
const localKey = String(jRow[junctionLocalField]);
|
|
264
|
-
const targetKey = String(jRow[junctionTargetField]);
|
|
265
|
-
const target = targetIndex.get(targetKey);
|
|
266
|
-
if (!target) continue;
|
|
267
|
-
let group = groups.get(localKey);
|
|
268
|
-
if (!group) {
|
|
269
|
-
group = [];
|
|
270
|
-
groups.set(localKey, group);
|
|
271
|
-
}
|
|
272
|
-
group.push(target);
|
|
273
|
-
}
|
|
274
|
-
for (const row of rows) {
|
|
275
|
-
const key = String(row[localField]);
|
|
276
|
-
row[relName] = relation.isArray ? groups.get(key) ?? [] : groups.get(key)?.[0] ?? null;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
async function loadViaCompositeKey(rows, opts) {
|
|
280
|
-
const { relName, relation, targetTable, relQuery, localPKFields, junctionLocalFields, targetPKFields, junctionTargetFields, junctionTable } = opts;
|
|
281
|
-
const orFilters = [];
|
|
282
|
-
for (const row of rows) {
|
|
283
|
-
const condition = {};
|
|
284
|
-
let valid = true;
|
|
285
|
-
for (let i = 0; i < localPKFields.length; i++) {
|
|
286
|
-
const val = row[localPKFields[i]];
|
|
287
|
-
if (val === null || val === void 0) {
|
|
288
|
-
valid = false;
|
|
289
|
-
break;
|
|
290
|
-
}
|
|
291
|
-
condition[junctionLocalFields[i]] = val;
|
|
292
|
-
}
|
|
293
|
-
if (valid) orFilters.push(condition);
|
|
294
|
-
}
|
|
295
|
-
if (orFilters.length === 0) {
|
|
296
|
-
for (const row of rows) row[relName] = relation.isArray ? [] : null;
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
const junctionFilter = orFilters.length === 1 ? orFilters[0] : { $or: orFilters };
|
|
300
|
-
const junctionRows = await junctionTable.findMany({
|
|
301
|
-
filter: junctionFilter,
|
|
302
|
-
controls: { $select: [...junctionLocalFields, ...junctionTargetFields] }
|
|
303
|
-
});
|
|
304
|
-
if (junctionRows.length === 0) {
|
|
305
|
-
for (const row of rows) row[relName] = relation.isArray ? [] : null;
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
const targetOrFilters = [];
|
|
309
|
-
const seenTargets = /* @__PURE__ */ new Set();
|
|
310
|
-
for (const jRow of junctionRows) {
|
|
311
|
-
const key = compositeKey(junctionTargetFields, jRow);
|
|
312
|
-
if (seenTargets.has(key)) continue;
|
|
313
|
-
seenTargets.add(key);
|
|
314
|
-
const condition = {};
|
|
315
|
-
for (let i = 0; i < junctionTargetFields.length; i++) condition[targetPKFields[i]] = jRow[junctionTargetFields[i]];
|
|
316
|
-
targetOrFilters.push(condition);
|
|
317
|
-
}
|
|
318
|
-
const targetBaseFilter = targetOrFilters.length === 1 ? targetOrFilters[0] : { $or: targetOrFilters };
|
|
319
|
-
const finalFilter = relQuery.filter ? { $and: [targetBaseFilter, relQuery.filter] } : targetBaseFilter;
|
|
320
|
-
const controls = ensureSelectIncludesFields(relQuery.controls, targetPKFields);
|
|
321
|
-
const targetRows = await targetTable.findMany({
|
|
322
|
-
filter: finalFilter,
|
|
323
|
-
controls
|
|
324
|
-
});
|
|
325
|
-
const targetIndex = /* @__PURE__ */ new Map();
|
|
326
|
-
for (const item of targetRows) targetIndex.set(compositeKey(targetPKFields, item), item);
|
|
327
|
-
const groups = /* @__PURE__ */ new Map();
|
|
328
|
-
for (const jRow of junctionRows) {
|
|
329
|
-
const localKey = compositeKey(junctionLocalFields, jRow);
|
|
330
|
-
const targetKey = compositeKey(junctionTargetFields, jRow);
|
|
331
|
-
const target = targetIndex.get(targetKey);
|
|
332
|
-
if (!target) continue;
|
|
333
|
-
let group = groups.get(localKey);
|
|
334
|
-
if (!group) {
|
|
335
|
-
group = [];
|
|
336
|
-
groups.set(localKey, group);
|
|
337
|
-
}
|
|
338
|
-
group.push(target);
|
|
339
|
-
}
|
|
340
|
-
for (const row of rows) {
|
|
341
|
-
const key = compositeKey(localPKFields, row);
|
|
342
|
-
row[relName] = relation.isArray ? groups.get(key) ?? [] : groups.get(key)?.[0] ?? null;
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Ensure the given join fields survive the user's $select on a $with relation
|
|
347
|
-
* read. Without this, the JS-side join would key off undefined and silently
|
|
348
|
-
* return empty relations.
|
|
349
|
-
*
|
|
350
|
-
* - Array $select: append missing FK fields.
|
|
351
|
-
* - Include-mode object $select (any value is 1/true, or empty object): set
|
|
352
|
-
* missing FK fields to 1.
|
|
353
|
-
* - Exclude-mode object $select: leave alone — FK survives by default. If the
|
|
354
|
-
* FK is explicitly excluded, throw rather than silently override user intent.
|
|
355
|
-
*/
|
|
356
|
-
function ensureSelectIncludesFields(controls, fields) {
|
|
357
|
-
if (!controls) return controls;
|
|
358
|
-
const sel = controls.$select;
|
|
359
|
-
if (sel === void 0 || sel === null) return controls;
|
|
360
|
-
if (Array.isArray(sel)) {
|
|
361
|
-
const augmented = [...sel];
|
|
362
|
-
for (const f of fields) if (!augmented.includes(f)) augmented.push(f);
|
|
363
|
-
return {
|
|
364
|
-
...controls,
|
|
365
|
-
$select: augmented
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
if (typeof sel === "object") {
|
|
369
|
-
const selObj = sel;
|
|
370
|
-
const isInclude = Object.keys(selObj).length === 0 || Object.values(selObj).some((v) => v === 1 || v === true);
|
|
371
|
-
const augmented = { ...selObj };
|
|
372
|
-
let mutated = false;
|
|
373
|
-
for (const f of fields) {
|
|
374
|
-
const v = augmented[f];
|
|
375
|
-
if (v === 0 || v === false) throw new Error(`Cannot exclude join column "${f}" from $select on $with relation`);
|
|
376
|
-
if (v === void 0 && isInclude) {
|
|
377
|
-
augmented[f] = 1;
|
|
378
|
-
mutated = true;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
return mutated ? {
|
|
382
|
-
...controls,
|
|
383
|
-
$select: augmented
|
|
384
|
-
} : controls;
|
|
385
|
-
}
|
|
386
|
-
return controls;
|
|
387
|
-
}
|
|
388
|
-
function compositeKey(fields, obj) {
|
|
389
|
-
let key = "";
|
|
390
|
-
for (let i = 0; i < fields.length; i++) {
|
|
391
|
-
if (i > 0) key += "\0\0";
|
|
392
|
-
const v = obj[fields[i]];
|
|
393
|
-
key += v === null || v === void 0 ? "\0" : String(v);
|
|
394
|
-
}
|
|
395
|
-
return key;
|
|
396
|
-
}
|
|
397
|
-
/** Collects unique non-null values for a field across rows. */
|
|
398
|
-
function collectUniqueValues(rows, field) {
|
|
399
|
-
const set = /* @__PURE__ */ new Set();
|
|
400
|
-
for (const row of rows) {
|
|
401
|
-
const v = row[field];
|
|
402
|
-
if (v !== null && v !== void 0) set.add(v);
|
|
403
|
-
}
|
|
404
|
-
return [...set];
|
|
405
|
-
}
|
|
406
|
-
/** Assigns related items grouped by FK value (one-to-many). */
|
|
407
|
-
function assignGrouped(opts) {
|
|
408
|
-
const { rows, related, localField, remoteField, relName } = opts;
|
|
409
|
-
const groups = /* @__PURE__ */ new Map();
|
|
410
|
-
for (const item of related) {
|
|
411
|
-
const key = item[remoteField];
|
|
412
|
-
let group = groups.get(key);
|
|
413
|
-
if (!group) {
|
|
414
|
-
group = [];
|
|
415
|
-
groups.set(key, group);
|
|
416
|
-
}
|
|
417
|
-
group.push(item);
|
|
418
|
-
}
|
|
419
|
-
for (const row of rows) row[relName] = groups.get(row[localField]) ?? [];
|
|
420
|
-
}
|
|
421
|
-
/** Assigns related items by FK value (many-to-one / one-to-one). */
|
|
422
|
-
function assignSingle(opts) {
|
|
423
|
-
const { rows, related, localField, remoteField, relName } = opts;
|
|
424
|
-
const index = /* @__PURE__ */ new Map();
|
|
425
|
-
for (const item of related) {
|
|
426
|
-
const key = item[remoteField];
|
|
427
|
-
if (!index.has(key)) index.set(key, item);
|
|
428
|
-
}
|
|
429
|
-
for (const row of rows) row[relName] = index.get(row[localField]) ?? null;
|
|
430
|
-
}
|
|
431
|
-
/** Batch query for composite FK. */
|
|
432
|
-
function queryCompositeFK(rows, opts) {
|
|
433
|
-
const { localFields, targetFields, targetTable, relQuery } = opts;
|
|
434
|
-
const seen = /* @__PURE__ */ new Set();
|
|
435
|
-
const orFilters = [];
|
|
436
|
-
for (const row of rows) {
|
|
437
|
-
const key = compositeKey(localFields, row);
|
|
438
|
-
if (seen.has(key)) continue;
|
|
439
|
-
seen.add(key);
|
|
440
|
-
const condition = {};
|
|
441
|
-
let valid = true;
|
|
442
|
-
for (let i = 0; i < localFields.length; i++) {
|
|
443
|
-
const val = row[localFields[i]];
|
|
444
|
-
if (val === null || val === void 0) {
|
|
445
|
-
valid = false;
|
|
446
|
-
break;
|
|
447
|
-
}
|
|
448
|
-
condition[targetFields[i]] = val;
|
|
449
|
-
}
|
|
450
|
-
if (valid) orFilters.push(condition);
|
|
451
|
-
}
|
|
452
|
-
if (orFilters.length === 0) return Promise.resolve([]);
|
|
453
|
-
const baseFilter = orFilters.length === 1 ? orFilters[0] : { $or: orFilters };
|
|
454
|
-
const targetFilter = relQuery.filter ? { $and: [baseFilter, relQuery.filter] } : baseFilter;
|
|
455
|
-
const controls = ensureSelectIncludesFields(relQuery.controls, targetFields);
|
|
456
|
-
return targetTable.findMany({
|
|
457
|
-
filter: targetFilter,
|
|
458
|
-
controls
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
//#endregion
|
|
462
|
-
export { relation_loader_exports as n, loadRelationsImpl as t };
|