@atscript/db 0.1.39 → 0.1.41
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/README.md +18 -18
- package/dist/agg.cjs +8 -3
- package/dist/agg.d.cts +7 -0
- package/dist/agg.d.mts +7 -0
- package/dist/agg.mjs +7 -3
- package/dist/control-DRgryKeg.cjs +14 -0
- package/dist/{control_as-bjmwe24C.mjs → control-IANbnfjG.mjs} +6 -18
- package/dist/db-readable-BQQzfguJ.d.cts +1249 -0
- package/dist/db-readable-Bbr4CjMb.d.mts +1249 -0
- package/dist/db-space-BUrQ5BFm.d.mts +309 -0
- package/dist/db-space-Vxpcnyt5.d.cts +309 -0
- package/dist/db-validator-plugin-07kDiis2.d.cts +22 -0
- package/dist/db-validator-plugin-CiqsHTI_.d.mts +22 -0
- package/dist/db-view-CMI9TOo1.cjs +3096 -0
- package/dist/db-view-Esy2fDxw.mjs +2995 -0
- package/dist/index.cjs +95 -2801
- package/dist/index.d.cts +137 -0
- package/dist/index.d.mts +137 -0
- package/dist/index.mjs +55 -2761
- package/dist/{nested-writer-BkqL7cp3.cjs → nested-writer-BDXsDMPP.cjs} +196 -150
- package/dist/{nested-writer-NEN51mnR.mjs → nested-writer-Dmm1gbZV.mjs} +118 -70
- package/dist/ops-BdRAFLKY.d.mts +67 -0
- package/dist/ops-DXJ4Zw0P.d.cts +67 -0
- package/dist/ops.cjs +123 -0
- package/dist/ops.d.cts +2 -0
- package/dist/ops.d.mts +2 -0
- package/dist/ops.mjs +112 -0
- package/dist/plugin.cjs +90 -109
- package/dist/plugin.d.cts +6 -0
- package/dist/plugin.d.mts +6 -0
- package/dist/plugin.mjs +29 -49
- package/dist/rel.cjs +20 -20
- package/dist/rel.d.cts +119 -0
- package/dist/rel.d.mts +119 -0
- package/dist/rel.mjs +4 -5
- package/dist/{relation-helpers-guFL_oRf.cjs → relation-helpers-BYvsE1tR.cjs} +26 -22
- package/dist/{relation-helpers-DyBIlQnB.mjs → relation-helpers-CLasawQq.mjs} +11 -6
- package/dist/{relation-loader-Dv7qXYq7.mjs → relation-loader-BEOTXNcq.mjs} +63 -43
- package/dist/{relation-loader-CpnDRf9k.cjs → relation-loader-CRC5LcqM.cjs} +74 -49
- package/dist/shared.cjs +13 -13
- package/dist/{shared.d.ts → shared.d.cts} +14 -13
- package/dist/shared.d.mts +71 -0
- package/dist/shared.mjs +2 -3
- package/dist/sync.cjs +300 -252
- package/dist/sync.d.cts +369 -0
- package/dist/sync.d.mts +369 -0
- package/dist/sync.mjs +284 -233
- package/dist/{validation-utils-DEoCMmEb.cjs → validation-utils-DVJDijnB.cjs} +141 -109
- package/dist/{validation-utils-DhR_mtKa.mjs → validation-utils-DhjIjP1-.mjs} +71 -37
- package/package.json +30 -29
- package/LICENSE +0 -21
- package/dist/agg-BJFJ3dFQ.mjs +0 -8
- package/dist/agg-DnUWAOK8.cjs +0 -14
- package/dist/agg.d.ts +0 -13
- package/dist/chunk-CrpGerW8.cjs +0 -31
- package/dist/control_as-BFPERAF_.cjs +0 -28
- package/dist/index.d.ts +0 -1706
- package/dist/logger-B7oxCfLQ.mjs +0 -12
- package/dist/logger-Dt2v_-wb.cjs +0 -18
- package/dist/plugin.d.ts +0 -5
- package/dist/rel.d.ts +0 -1305
- package/dist/relation-loader-D4mTw6yH.cjs +0 -4
- package/dist/relation-loader-Ggy1ujwR.mjs +0 -4
- package/dist/sync.d.ts +0 -1878
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { n as findRemoteFK, r as resolveRelationTargetTable, t as findFKForRelation } from "./relation-helpers-CLasawQq.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({ loadRelationsImpl: () => loadRelationsImpl });
|
|
16
|
+
/**
|
|
17
|
+
* Loads related data for `$with` relations and attaches them to result rows.
|
|
18
|
+
*/
|
|
4
19
|
async function loadRelationsImpl(rows, withRelations, host) {
|
|
5
20
|
if (rows.length === 0 || withRelations.length === 0) return;
|
|
6
21
|
if (host.adapter.supportsNativeRelations()) return host.adapter.loadRelations(rows, withRelations, host._meta.relations, host._meta.foreignKeys, host._tableResolver);
|
|
@@ -18,13 +33,12 @@ async function loadRelationsImpl(rows, withRelations, host) {
|
|
|
18
33
|
host.logger.warn(`Could not resolve table for relation "${relName}" — skipping`);
|
|
19
34
|
continue;
|
|
20
35
|
}
|
|
21
|
-
const filter = withRel.filter && Object.keys(withRel.filter).length > 0 ? withRel.filter :
|
|
36
|
+
const filter = withRel.filter && Object.keys(withRel.filter).length > 0 ? withRel.filter : void 0;
|
|
22
37
|
const flatRel = withRel;
|
|
23
|
-
const
|
|
24
|
-
const controls = { ...nested };
|
|
38
|
+
const controls = { ...withRel.controls || {} };
|
|
25
39
|
if (flatRel.$sort && !controls.$sort) controls.$sort = flatRel.$sort;
|
|
26
|
-
if (flatRel.$limit !== null && flatRel.$limit !==
|
|
27
|
-
if (flatRel.$skip !== null && flatRel.$skip !==
|
|
40
|
+
if (flatRel.$limit !== null && flatRel.$limit !== void 0 && (controls.$limit === null || controls.$limit === void 0)) controls.$limit = flatRel.$limit;
|
|
41
|
+
if (flatRel.$skip !== null && flatRel.$skip !== void 0 && (controls.$skip === null || controls.$skip === void 0)) controls.$skip = flatRel.$skip;
|
|
28
42
|
if (flatRel.$select && !controls.$select) controls.$select = flatRel.$select;
|
|
29
43
|
if (flatRel.$with && !controls.$with) controls.$with = flatRel.$with;
|
|
30
44
|
const relQuery = {
|
|
@@ -37,13 +51,13 @@ async function loadRelationsImpl(rows, withRelations, host) {
|
|
|
37
51
|
targetTable,
|
|
38
52
|
relQuery
|
|
39
53
|
}, host));
|
|
40
|
-
else if (relation.direction === "via") tasks.push(loadViaRelation(rows, {
|
|
54
|
+
else if (relation.direction === "via") tasks.push(loadViaRelation(rows, {
|
|
41
55
|
relName,
|
|
42
56
|
relation,
|
|
43
57
|
targetTable,
|
|
44
58
|
relQuery
|
|
45
59
|
}, host));
|
|
46
|
-
else tasks.push(loadFromRelation(rows, {
|
|
60
|
+
else tasks.push(loadFromRelation(rows, {
|
|
47
61
|
relName,
|
|
48
62
|
relation,
|
|
49
63
|
targetTable,
|
|
@@ -54,7 +68,8 @@ else tasks.push(loadFromRelation(rows, {
|
|
|
54
68
|
}
|
|
55
69
|
/**
|
|
56
70
|
* Loads a `@db.rel.to` relation (FK is on this table).
|
|
57
|
-
*/
|
|
71
|
+
*/
|
|
72
|
+
async function loadToRelation(rows, opts, host) {
|
|
58
73
|
const { relName, relation, targetTable, relQuery } = opts;
|
|
59
74
|
const fkEntry = findFKForRelation(relation, host._meta.foreignKeys);
|
|
60
75
|
if (!fkEntry) return;
|
|
@@ -70,13 +85,12 @@ else tasks.push(loadFromRelation(rows, {
|
|
|
70
85
|
const inFilter = { [targetField]: { $in: fkValues } };
|
|
71
86
|
const targetFilter = relQuery.filter ? { $and: [inFilter, relQuery.filter] } : inFilter;
|
|
72
87
|
const controls = ensureSelectIncludesFields(relQuery.controls, targetFields);
|
|
73
|
-
const related = await targetTable.findMany({
|
|
74
|
-
filter: targetFilter,
|
|
75
|
-
controls
|
|
76
|
-
});
|
|
77
88
|
assignSingle({
|
|
78
89
|
rows,
|
|
79
|
-
related
|
|
90
|
+
related: await targetTable.findMany({
|
|
91
|
+
filter: targetFilter,
|
|
92
|
+
controls
|
|
93
|
+
}),
|
|
80
94
|
localField,
|
|
81
95
|
remoteField: targetField,
|
|
82
96
|
relName
|
|
@@ -88,14 +102,15 @@ else tasks.push(loadFromRelation(rows, {
|
|
|
88
102
|
targetTable,
|
|
89
103
|
relQuery
|
|
90
104
|
});
|
|
91
|
-
const index = new Map();
|
|
105
|
+
const index = /* @__PURE__ */ new Map();
|
|
92
106
|
for (const item of related) index.set(compositeKey(targetFields, item), item);
|
|
93
107
|
for (const row of rows) row[relName] = index.get(compositeKey(localFields, row)) ?? null;
|
|
94
108
|
}
|
|
95
109
|
}
|
|
96
110
|
/**
|
|
97
111
|
* Loads a `@db.rel.from` relation (FK is on the target table).
|
|
98
|
-
*/
|
|
112
|
+
*/
|
|
113
|
+
async function loadFromRelation(rows, opts, host) {
|
|
99
114
|
const { relName, relation, targetTable, relQuery } = opts;
|
|
100
115
|
const remoteFK = findRemoteFK(targetTable, host.tableName, relation.alias);
|
|
101
116
|
if (!remoteFK) {
|
|
@@ -123,7 +138,7 @@ else tasks.push(loadFromRelation(rows, {
|
|
|
123
138
|
remoteField,
|
|
124
139
|
relName
|
|
125
140
|
});
|
|
126
|
-
else assignSingle({
|
|
141
|
+
else assignSingle({
|
|
127
142
|
rows,
|
|
128
143
|
related,
|
|
129
144
|
localField,
|
|
@@ -138,7 +153,7 @@ else assignSingle({
|
|
|
138
153
|
relQuery
|
|
139
154
|
});
|
|
140
155
|
if (relation.isArray) {
|
|
141
|
-
const groups = new Map();
|
|
156
|
+
const groups = /* @__PURE__ */ new Map();
|
|
142
157
|
for (const item of related) {
|
|
143
158
|
const key = compositeKey(remoteFields, item);
|
|
144
159
|
let group = groups.get(key);
|
|
@@ -150,7 +165,7 @@ else assignSingle({
|
|
|
150
165
|
}
|
|
151
166
|
for (const row of rows) row[relName] = groups.get(compositeKey(localFields, row)) ?? [];
|
|
152
167
|
} else {
|
|
153
|
-
const index = new Map();
|
|
168
|
+
const index = /* @__PURE__ */ new Map();
|
|
154
169
|
for (const item of related) {
|
|
155
170
|
const key = compositeKey(remoteFields, item);
|
|
156
171
|
if (!index.has(key)) index.set(key, item);
|
|
@@ -161,7 +176,8 @@ else assignSingle({
|
|
|
161
176
|
}
|
|
162
177
|
/**
|
|
163
178
|
* Loads a `@db.rel.via` relation (M:N through a junction table).
|
|
164
|
-
*/
|
|
179
|
+
*/
|
|
180
|
+
async function loadViaRelation(rows, opts, host) {
|
|
165
181
|
const { relName, relation, targetTable, relQuery } = opts;
|
|
166
182
|
if (!relation.viaType || !host._tableResolver) return;
|
|
167
183
|
const junctionType = relation.viaType();
|
|
@@ -197,7 +213,7 @@ else assignSingle({
|
|
|
197
213
|
junctionTargetFields,
|
|
198
214
|
junctionTable
|
|
199
215
|
});
|
|
200
|
-
else await loadViaCompositeKey(rows, {
|
|
216
|
+
else await loadViaCompositeKey(rows, {
|
|
201
217
|
relName,
|
|
202
218
|
relation,
|
|
203
219
|
targetTable,
|
|
@@ -237,9 +253,9 @@ async function loadViaSingleKey(rows, opts) {
|
|
|
237
253
|
filter: targetFilter,
|
|
238
254
|
controls
|
|
239
255
|
});
|
|
240
|
-
const targetIndex = new Map();
|
|
256
|
+
const targetIndex = /* @__PURE__ */ new Map();
|
|
241
257
|
for (const item of targetRows) targetIndex.set(String(item[targetPKField]), item);
|
|
242
|
-
const groups = new Map();
|
|
258
|
+
const groups = /* @__PURE__ */ new Map();
|
|
243
259
|
for (const jRow of junctionRows) {
|
|
244
260
|
const localKey = String(jRow[junctionLocalField]);
|
|
245
261
|
const targetKey = String(jRow[junctionTargetField]);
|
|
@@ -265,7 +281,7 @@ async function loadViaCompositeKey(rows, opts) {
|
|
|
265
281
|
let valid = true;
|
|
266
282
|
for (let i = 0; i < localPKFields.length; i++) {
|
|
267
283
|
const val = row[localPKFields[i]];
|
|
268
|
-
if (val === null || val ===
|
|
284
|
+
if (val === null || val === void 0) {
|
|
269
285
|
valid = false;
|
|
270
286
|
break;
|
|
271
287
|
}
|
|
@@ -287,7 +303,7 @@ async function loadViaCompositeKey(rows, opts) {
|
|
|
287
303
|
return;
|
|
288
304
|
}
|
|
289
305
|
const targetOrFilters = [];
|
|
290
|
-
const seenTargets = new Set();
|
|
306
|
+
const seenTargets = /* @__PURE__ */ new Set();
|
|
291
307
|
for (const jRow of junctionRows) {
|
|
292
308
|
const key = compositeKey(junctionTargetFields, jRow);
|
|
293
309
|
if (seenTargets.has(key)) continue;
|
|
@@ -302,9 +318,9 @@ async function loadViaCompositeKey(rows, opts) {
|
|
|
302
318
|
filter: finalFilter,
|
|
303
319
|
controls: relQuery.controls
|
|
304
320
|
});
|
|
305
|
-
const targetIndex = new Map();
|
|
321
|
+
const targetIndex = /* @__PURE__ */ new Map();
|
|
306
322
|
for (const item of targetRows) targetIndex.set(compositeKey(targetPKFields, item), item);
|
|
307
|
-
const groups = new Map();
|
|
323
|
+
const groups = /* @__PURE__ */ new Map();
|
|
308
324
|
for (const jRow of junctionRows) {
|
|
309
325
|
const localKey = compositeKey(junctionLocalFields, jRow);
|
|
310
326
|
const targetKey = compositeKey(junctionTargetFields, jRow);
|
|
@@ -325,7 +341,8 @@ async function loadViaCompositeKey(rows, opts) {
|
|
|
325
341
|
/**
|
|
326
342
|
* If controls include an array-style $select, ensure the given join fields
|
|
327
343
|
* are present so that FK matching works after the query returns.
|
|
328
|
-
*/
|
|
344
|
+
*/
|
|
345
|
+
function ensureSelectIncludesFields(controls, fields) {
|
|
329
346
|
if (!controls) return controls;
|
|
330
347
|
const sel = controls.$select;
|
|
331
348
|
if (!Array.isArray(sel)) return controls;
|
|
@@ -341,21 +358,23 @@ function compositeKey(fields, obj) {
|
|
|
341
358
|
for (let i = 0; i < fields.length; i++) {
|
|
342
359
|
if (i > 0) key += "\0\0";
|
|
343
360
|
const v = obj[fields[i]];
|
|
344
|
-
key += v === null || v ===
|
|
361
|
+
key += v === null || v === void 0 ? "\0" : String(v);
|
|
345
362
|
}
|
|
346
363
|
return key;
|
|
347
364
|
}
|
|
348
|
-
/** Collects unique non-null values for a field across rows. */
|
|
349
|
-
|
|
365
|
+
/** Collects unique non-null values for a field across rows. */
|
|
366
|
+
function collectUniqueValues(rows, field) {
|
|
367
|
+
const set = /* @__PURE__ */ new Set();
|
|
350
368
|
for (const row of rows) {
|
|
351
369
|
const v = row[field];
|
|
352
|
-
if (v !== null && v !==
|
|
370
|
+
if (v !== null && v !== void 0) set.add(v);
|
|
353
371
|
}
|
|
354
372
|
return [...set];
|
|
355
373
|
}
|
|
356
|
-
/** Assigns related items grouped by FK value (one-to-many). */
|
|
374
|
+
/** Assigns related items grouped by FK value (one-to-many). */
|
|
375
|
+
function assignGrouped(opts) {
|
|
357
376
|
const { rows, related, localField, remoteField, relName } = opts;
|
|
358
|
-
const groups = new Map();
|
|
377
|
+
const groups = /* @__PURE__ */ new Map();
|
|
359
378
|
for (const item of related) {
|
|
360
379
|
const key = item[remoteField];
|
|
361
380
|
let group = groups.get(key);
|
|
@@ -367,18 +386,20 @@ function compositeKey(fields, obj) {
|
|
|
367
386
|
}
|
|
368
387
|
for (const row of rows) row[relName] = groups.get(row[localField]) ?? [];
|
|
369
388
|
}
|
|
370
|
-
/** Assigns related items by FK value (many-to-one / one-to-one). */
|
|
389
|
+
/** Assigns related items by FK value (many-to-one / one-to-one). */
|
|
390
|
+
function assignSingle(opts) {
|
|
371
391
|
const { rows, related, localField, remoteField, relName } = opts;
|
|
372
|
-
const index = new Map();
|
|
392
|
+
const index = /* @__PURE__ */ new Map();
|
|
373
393
|
for (const item of related) {
|
|
374
394
|
const key = item[remoteField];
|
|
375
395
|
if (!index.has(key)) index.set(key, item);
|
|
376
396
|
}
|
|
377
397
|
for (const row of rows) row[relName] = index.get(row[localField]) ?? null;
|
|
378
398
|
}
|
|
379
|
-
/** Batch query for composite FK. */
|
|
399
|
+
/** Batch query for composite FK. */
|
|
400
|
+
function queryCompositeFK(rows, opts) {
|
|
380
401
|
const { localFields, targetFields, targetTable, relQuery } = opts;
|
|
381
|
-
const seen = new Set();
|
|
402
|
+
const seen = /* @__PURE__ */ new Set();
|
|
382
403
|
const orFilters = [];
|
|
383
404
|
for (const row of rows) {
|
|
384
405
|
const key = compositeKey(localFields, row);
|
|
@@ -388,7 +409,7 @@ function compositeKey(fields, obj) {
|
|
|
388
409
|
let valid = true;
|
|
389
410
|
for (let i = 0; i < localFields.length; i++) {
|
|
390
411
|
const val = row[localFields[i]];
|
|
391
|
-
if (val === null || val ===
|
|
412
|
+
if (val === null || val === void 0) {
|
|
392
413
|
valid = false;
|
|
393
414
|
break;
|
|
394
415
|
}
|
|
@@ -404,6 +425,5 @@ function compositeKey(fields, obj) {
|
|
|
404
425
|
controls: relQuery.controls
|
|
405
426
|
});
|
|
406
427
|
}
|
|
407
|
-
|
|
408
428
|
//#endregion
|
|
409
|
-
export { loadRelationsImpl };
|
|
429
|
+
export { relation_loader_exports as n, loadRelationsImpl as t };
|
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
const require_relation_helpers = require("./relation-helpers-BYvsE1tR.cjs");
|
|
14
|
+
//#region src/rel/relation-loader.ts
|
|
15
|
+
var relation_loader_exports = /* @__PURE__ */ __exportAll({ loadRelationsImpl: () => loadRelationsImpl });
|
|
16
|
+
/**
|
|
17
|
+
* Loads related data for `$with` relations and attaches them to result rows.
|
|
18
|
+
*/
|
|
5
19
|
async function loadRelationsImpl(rows, withRelations, host) {
|
|
6
20
|
if (rows.length === 0 || withRelations.length === 0) return;
|
|
7
21
|
if (host.adapter.supportsNativeRelations()) return host.adapter.loadRelations(rows, withRelations, host._meta.relations, host._meta.foreignKeys, host._tableResolver);
|
|
@@ -19,13 +33,12 @@ async function loadRelationsImpl(rows, withRelations, host) {
|
|
|
19
33
|
host.logger.warn(`Could not resolve table for relation "${relName}" — skipping`);
|
|
20
34
|
continue;
|
|
21
35
|
}
|
|
22
|
-
const filter = withRel.filter && Object.keys(withRel.filter).length > 0 ? withRel.filter :
|
|
36
|
+
const filter = withRel.filter && Object.keys(withRel.filter).length > 0 ? withRel.filter : void 0;
|
|
23
37
|
const flatRel = withRel;
|
|
24
|
-
const
|
|
25
|
-
const controls = { ...nested };
|
|
38
|
+
const controls = { ...withRel.controls || {} };
|
|
26
39
|
if (flatRel.$sort && !controls.$sort) controls.$sort = flatRel.$sort;
|
|
27
|
-
if (flatRel.$limit !== null && flatRel.$limit !==
|
|
28
|
-
if (flatRel.$skip !== null && flatRel.$skip !==
|
|
40
|
+
if (flatRel.$limit !== null && flatRel.$limit !== void 0 && (controls.$limit === null || controls.$limit === void 0)) controls.$limit = flatRel.$limit;
|
|
41
|
+
if (flatRel.$skip !== null && flatRel.$skip !== void 0 && (controls.$skip === null || controls.$skip === void 0)) controls.$skip = flatRel.$skip;
|
|
29
42
|
if (flatRel.$select && !controls.$select) controls.$select = flatRel.$select;
|
|
30
43
|
if (flatRel.$with && !controls.$with) controls.$with = flatRel.$with;
|
|
31
44
|
const relQuery = {
|
|
@@ -38,13 +51,13 @@ async function loadRelationsImpl(rows, withRelations, host) {
|
|
|
38
51
|
targetTable,
|
|
39
52
|
relQuery
|
|
40
53
|
}, host));
|
|
41
|
-
else if (relation.direction === "via") tasks.push(loadViaRelation(rows, {
|
|
54
|
+
else if (relation.direction === "via") tasks.push(loadViaRelation(rows, {
|
|
42
55
|
relName,
|
|
43
56
|
relation,
|
|
44
57
|
targetTable,
|
|
45
58
|
relQuery
|
|
46
59
|
}, host));
|
|
47
|
-
else tasks.push(loadFromRelation(rows, {
|
|
60
|
+
else tasks.push(loadFromRelation(rows, {
|
|
48
61
|
relName,
|
|
49
62
|
relation,
|
|
50
63
|
targetTable,
|
|
@@ -55,7 +68,8 @@ else tasks.push(loadFromRelation(rows, {
|
|
|
55
68
|
}
|
|
56
69
|
/**
|
|
57
70
|
* Loads a `@db.rel.to` relation (FK is on this table).
|
|
58
|
-
*/
|
|
71
|
+
*/
|
|
72
|
+
async function loadToRelation(rows, opts, host) {
|
|
59
73
|
const { relName, relation, targetTable, relQuery } = opts;
|
|
60
74
|
const fkEntry = require_relation_helpers.findFKForRelation(relation, host._meta.foreignKeys);
|
|
61
75
|
if (!fkEntry) return;
|
|
@@ -71,13 +85,12 @@ else tasks.push(loadFromRelation(rows, {
|
|
|
71
85
|
const inFilter = { [targetField]: { $in: fkValues } };
|
|
72
86
|
const targetFilter = relQuery.filter ? { $and: [inFilter, relQuery.filter] } : inFilter;
|
|
73
87
|
const controls = ensureSelectIncludesFields(relQuery.controls, targetFields);
|
|
74
|
-
const related = await targetTable.findMany({
|
|
75
|
-
filter: targetFilter,
|
|
76
|
-
controls
|
|
77
|
-
});
|
|
78
88
|
assignSingle({
|
|
79
89
|
rows,
|
|
80
|
-
related
|
|
90
|
+
related: await targetTable.findMany({
|
|
91
|
+
filter: targetFilter,
|
|
92
|
+
controls
|
|
93
|
+
}),
|
|
81
94
|
localField,
|
|
82
95
|
remoteField: targetField,
|
|
83
96
|
relName
|
|
@@ -89,14 +102,15 @@ else tasks.push(loadFromRelation(rows, {
|
|
|
89
102
|
targetTable,
|
|
90
103
|
relQuery
|
|
91
104
|
});
|
|
92
|
-
const index = new Map();
|
|
105
|
+
const index = /* @__PURE__ */ new Map();
|
|
93
106
|
for (const item of related) index.set(compositeKey(targetFields, item), item);
|
|
94
107
|
for (const row of rows) row[relName] = index.get(compositeKey(localFields, row)) ?? null;
|
|
95
108
|
}
|
|
96
109
|
}
|
|
97
110
|
/**
|
|
98
111
|
* Loads a `@db.rel.from` relation (FK is on the target table).
|
|
99
|
-
*/
|
|
112
|
+
*/
|
|
113
|
+
async function loadFromRelation(rows, opts, host) {
|
|
100
114
|
const { relName, relation, targetTable, relQuery } = opts;
|
|
101
115
|
const remoteFK = require_relation_helpers.findRemoteFK(targetTable, host.tableName, relation.alias);
|
|
102
116
|
if (!remoteFK) {
|
|
@@ -124,7 +138,7 @@ else tasks.push(loadFromRelation(rows, {
|
|
|
124
138
|
remoteField,
|
|
125
139
|
relName
|
|
126
140
|
});
|
|
127
|
-
else assignSingle({
|
|
141
|
+
else assignSingle({
|
|
128
142
|
rows,
|
|
129
143
|
related,
|
|
130
144
|
localField,
|
|
@@ -139,7 +153,7 @@ else assignSingle({
|
|
|
139
153
|
relQuery
|
|
140
154
|
});
|
|
141
155
|
if (relation.isArray) {
|
|
142
|
-
const groups = new Map();
|
|
156
|
+
const groups = /* @__PURE__ */ new Map();
|
|
143
157
|
for (const item of related) {
|
|
144
158
|
const key = compositeKey(remoteFields, item);
|
|
145
159
|
let group = groups.get(key);
|
|
@@ -151,7 +165,7 @@ else assignSingle({
|
|
|
151
165
|
}
|
|
152
166
|
for (const row of rows) row[relName] = groups.get(compositeKey(localFields, row)) ?? [];
|
|
153
167
|
} else {
|
|
154
|
-
const index = new Map();
|
|
168
|
+
const index = /* @__PURE__ */ new Map();
|
|
155
169
|
for (const item of related) {
|
|
156
170
|
const key = compositeKey(remoteFields, item);
|
|
157
171
|
if (!index.has(key)) index.set(key, item);
|
|
@@ -162,7 +176,8 @@ else assignSingle({
|
|
|
162
176
|
}
|
|
163
177
|
/**
|
|
164
178
|
* Loads a `@db.rel.via` relation (M:N through a junction table).
|
|
165
|
-
*/
|
|
179
|
+
*/
|
|
180
|
+
async function loadViaRelation(rows, opts, host) {
|
|
166
181
|
const { relName, relation, targetTable, relQuery } = opts;
|
|
167
182
|
if (!relation.viaType || !host._tableResolver) return;
|
|
168
183
|
const junctionType = relation.viaType();
|
|
@@ -198,7 +213,7 @@ else assignSingle({
|
|
|
198
213
|
junctionTargetFields,
|
|
199
214
|
junctionTable
|
|
200
215
|
});
|
|
201
|
-
else await loadViaCompositeKey(rows, {
|
|
216
|
+
else await loadViaCompositeKey(rows, {
|
|
202
217
|
relName,
|
|
203
218
|
relation,
|
|
204
219
|
targetTable,
|
|
@@ -238,9 +253,9 @@ async function loadViaSingleKey(rows, opts) {
|
|
|
238
253
|
filter: targetFilter,
|
|
239
254
|
controls
|
|
240
255
|
});
|
|
241
|
-
const targetIndex = new Map();
|
|
256
|
+
const targetIndex = /* @__PURE__ */ new Map();
|
|
242
257
|
for (const item of targetRows) targetIndex.set(String(item[targetPKField]), item);
|
|
243
|
-
const groups = new Map();
|
|
258
|
+
const groups = /* @__PURE__ */ new Map();
|
|
244
259
|
for (const jRow of junctionRows) {
|
|
245
260
|
const localKey = String(jRow[junctionLocalField]);
|
|
246
261
|
const targetKey = String(jRow[junctionTargetField]);
|
|
@@ -266,7 +281,7 @@ async function loadViaCompositeKey(rows, opts) {
|
|
|
266
281
|
let valid = true;
|
|
267
282
|
for (let i = 0; i < localPKFields.length; i++) {
|
|
268
283
|
const val = row[localPKFields[i]];
|
|
269
|
-
if (val === null || val ===
|
|
284
|
+
if (val === null || val === void 0) {
|
|
270
285
|
valid = false;
|
|
271
286
|
break;
|
|
272
287
|
}
|
|
@@ -288,7 +303,7 @@ async function loadViaCompositeKey(rows, opts) {
|
|
|
288
303
|
return;
|
|
289
304
|
}
|
|
290
305
|
const targetOrFilters = [];
|
|
291
|
-
const seenTargets = new Set();
|
|
306
|
+
const seenTargets = /* @__PURE__ */ new Set();
|
|
292
307
|
for (const jRow of junctionRows) {
|
|
293
308
|
const key = compositeKey(junctionTargetFields, jRow);
|
|
294
309
|
if (seenTargets.has(key)) continue;
|
|
@@ -303,9 +318,9 @@ async function loadViaCompositeKey(rows, opts) {
|
|
|
303
318
|
filter: finalFilter,
|
|
304
319
|
controls: relQuery.controls
|
|
305
320
|
});
|
|
306
|
-
const targetIndex = new Map();
|
|
321
|
+
const targetIndex = /* @__PURE__ */ new Map();
|
|
307
322
|
for (const item of targetRows) targetIndex.set(compositeKey(targetPKFields, item), item);
|
|
308
|
-
const groups = new Map();
|
|
323
|
+
const groups = /* @__PURE__ */ new Map();
|
|
309
324
|
for (const jRow of junctionRows) {
|
|
310
325
|
const localKey = compositeKey(junctionLocalFields, jRow);
|
|
311
326
|
const targetKey = compositeKey(junctionTargetFields, jRow);
|
|
@@ -326,7 +341,8 @@ async function loadViaCompositeKey(rows, opts) {
|
|
|
326
341
|
/**
|
|
327
342
|
* If controls include an array-style $select, ensure the given join fields
|
|
328
343
|
* are present so that FK matching works after the query returns.
|
|
329
|
-
*/
|
|
344
|
+
*/
|
|
345
|
+
function ensureSelectIncludesFields(controls, fields) {
|
|
330
346
|
if (!controls) return controls;
|
|
331
347
|
const sel = controls.$select;
|
|
332
348
|
if (!Array.isArray(sel)) return controls;
|
|
@@ -342,21 +358,23 @@ function compositeKey(fields, obj) {
|
|
|
342
358
|
for (let i = 0; i < fields.length; i++) {
|
|
343
359
|
if (i > 0) key += "\0\0";
|
|
344
360
|
const v = obj[fields[i]];
|
|
345
|
-
key += v === null || v ===
|
|
361
|
+
key += v === null || v === void 0 ? "\0" : String(v);
|
|
346
362
|
}
|
|
347
363
|
return key;
|
|
348
364
|
}
|
|
349
|
-
/** Collects unique non-null values for a field across rows. */
|
|
350
|
-
|
|
365
|
+
/** Collects unique non-null values for a field across rows. */
|
|
366
|
+
function collectUniqueValues(rows, field) {
|
|
367
|
+
const set = /* @__PURE__ */ new Set();
|
|
351
368
|
for (const row of rows) {
|
|
352
369
|
const v = row[field];
|
|
353
|
-
if (v !== null && v !==
|
|
370
|
+
if (v !== null && v !== void 0) set.add(v);
|
|
354
371
|
}
|
|
355
372
|
return [...set];
|
|
356
373
|
}
|
|
357
|
-
/** Assigns related items grouped by FK value (one-to-many). */
|
|
374
|
+
/** Assigns related items grouped by FK value (one-to-many). */
|
|
375
|
+
function assignGrouped(opts) {
|
|
358
376
|
const { rows, related, localField, remoteField, relName } = opts;
|
|
359
|
-
const groups = new Map();
|
|
377
|
+
const groups = /* @__PURE__ */ new Map();
|
|
360
378
|
for (const item of related) {
|
|
361
379
|
const key = item[remoteField];
|
|
362
380
|
let group = groups.get(key);
|
|
@@ -368,18 +386,20 @@ function compositeKey(fields, obj) {
|
|
|
368
386
|
}
|
|
369
387
|
for (const row of rows) row[relName] = groups.get(row[localField]) ?? [];
|
|
370
388
|
}
|
|
371
|
-
/** Assigns related items by FK value (many-to-one / one-to-one). */
|
|
389
|
+
/** Assigns related items by FK value (many-to-one / one-to-one). */
|
|
390
|
+
function assignSingle(opts) {
|
|
372
391
|
const { rows, related, localField, remoteField, relName } = opts;
|
|
373
|
-
const index = new Map();
|
|
392
|
+
const index = /* @__PURE__ */ new Map();
|
|
374
393
|
for (const item of related) {
|
|
375
394
|
const key = item[remoteField];
|
|
376
395
|
if (!index.has(key)) index.set(key, item);
|
|
377
396
|
}
|
|
378
397
|
for (const row of rows) row[relName] = index.get(row[localField]) ?? null;
|
|
379
398
|
}
|
|
380
|
-
/** Batch query for composite FK. */
|
|
399
|
+
/** Batch query for composite FK. */
|
|
400
|
+
function queryCompositeFK(rows, opts) {
|
|
381
401
|
const { localFields, targetFields, targetTable, relQuery } = opts;
|
|
382
|
-
const seen = new Set();
|
|
402
|
+
const seen = /* @__PURE__ */ new Set();
|
|
383
403
|
const orFilters = [];
|
|
384
404
|
for (const row of rows) {
|
|
385
405
|
const key = compositeKey(localFields, row);
|
|
@@ -389,7 +409,7 @@ function compositeKey(fields, obj) {
|
|
|
389
409
|
let valid = true;
|
|
390
410
|
for (let i = 0; i < localFields.length; i++) {
|
|
391
411
|
const val = row[localFields[i]];
|
|
392
|
-
if (val === null || val ===
|
|
412
|
+
if (val === null || val === void 0) {
|
|
393
413
|
valid = false;
|
|
394
414
|
break;
|
|
395
415
|
}
|
|
@@ -405,11 +425,16 @@ function compositeKey(fields, obj) {
|
|
|
405
425
|
controls: relQuery.controls
|
|
406
426
|
});
|
|
407
427
|
}
|
|
408
|
-
|
|
409
428
|
//#endregion
|
|
410
|
-
Object.defineProperty(exports,
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
});
|
|
429
|
+
Object.defineProperty(exports, "loadRelationsImpl", {
|
|
430
|
+
enumerable: true,
|
|
431
|
+
get: function() {
|
|
432
|
+
return loadRelationsImpl;
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
Object.defineProperty(exports, "relation_loader_exports", {
|
|
436
|
+
enumerable: true,
|
|
437
|
+
get: function() {
|
|
438
|
+
return relation_loader_exports;
|
|
439
|
+
}
|
|
440
|
+
});
|
package/dist/shared.cjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.findFKFieldsPointingTo = require_validation_utils.findFKFieldsPointingTo
|
|
4
|
-
exports.getAnnotationAlias = require_validation_utils.getAnnotationAlias
|
|
5
|
-
exports.getDbTableOwner = require_validation_utils.getDbTableOwner
|
|
6
|
-
exports.getNavTargetTypeName = require_validation_utils.getNavTargetTypeName
|
|
7
|
-
exports.getParentStruct = require_validation_utils.getParentStruct
|
|
8
|
-
exports.getParentTypeName = require_validation_utils.getParentTypeName
|
|
9
|
-
exports.hasAnyViewAnnotation = require_validation_utils.hasAnyViewAnnotation
|
|
10
|
-
exports.refActionAnnotation = require_validation_utils.refActionAnnotation
|
|
11
|
-
exports.validateFieldBaseType = require_validation_utils.validateFieldBaseType
|
|
12
|
-
exports.validateQueryScope = require_validation_utils.validateQueryScope
|
|
13
|
-
exports.validateRefArgument = require_validation_utils.validateRefArgument
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_validation_utils = require("./validation-utils-DVJDijnB.cjs");
|
|
3
|
+
exports.findFKFieldsPointingTo = require_validation_utils.findFKFieldsPointingTo;
|
|
4
|
+
exports.getAnnotationAlias = require_validation_utils.getAnnotationAlias;
|
|
5
|
+
exports.getDbTableOwner = require_validation_utils.getDbTableOwner;
|
|
6
|
+
exports.getNavTargetTypeName = require_validation_utils.getNavTargetTypeName;
|
|
7
|
+
exports.getParentStruct = require_validation_utils.getParentStruct;
|
|
8
|
+
exports.getParentTypeName = require_validation_utils.getParentTypeName;
|
|
9
|
+
exports.hasAnyViewAnnotation = require_validation_utils.hasAnyViewAnnotation;
|
|
10
|
+
exports.refActionAnnotation = require_validation_utils.refActionAnnotation;
|
|
11
|
+
exports.validateFieldBaseType = require_validation_utils.validateFieldBaseType;
|
|
12
|
+
exports.validateQueryScope = require_validation_utils.validateQueryScope;
|
|
13
|
+
exports.validateRefArgument = require_validation_utils.validateRefArgument;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AnnotationSpec, AtscriptDoc, SemanticInterfaceNode, SemanticNode, SemanticPropNode, SemanticStructureNode, TMessages, Token } from "@atscript/core";
|
|
2
2
|
|
|
3
|
+
//#region src/shared/annotation-utils.d.ts
|
|
3
4
|
/**
|
|
4
5
|
* Traverse from annotation token → prop → structure → interface
|
|
5
6
|
* to check if the parent interface has @db.table.
|
|
@@ -30,22 +31,23 @@ declare function getAnnotationAlias(prop: SemanticNode, annotationName: string):
|
|
|
30
31
|
* Factory for @db.rel.onDelete / @db.rel.onUpdate — identical validation logic,
|
|
31
32
|
* only the annotation name and description verb differ.
|
|
32
33
|
*/
|
|
33
|
-
declare function refActionAnnotation(name:
|
|
34
|
-
|
|
34
|
+
declare function refActionAnnotation(name: "onDelete" | "onUpdate"): AnnotationSpec;
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/shared/validation-utils.d.ts
|
|
35
37
|
/**
|
|
36
38
|
* Validate a ref annotation argument against the document's type registry.
|
|
37
39
|
* Returns diagnostic messages for unknown types or fields.
|
|
38
40
|
*/
|
|
39
41
|
declare function validateRefArgument(token: Token, doc: AtscriptDoc, options?: {
|
|
40
|
-
|
|
42
|
+
requireDbTable?: boolean;
|
|
41
43
|
}): TMessages;
|
|
42
44
|
interface TFKFieldMatch {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
name: string;
|
|
46
|
+
prop: SemanticPropNode;
|
|
47
|
+
chainRef: {
|
|
48
|
+
type: string;
|
|
49
|
+
field: string;
|
|
50
|
+
};
|
|
49
51
|
}
|
|
50
52
|
/**
|
|
51
53
|
* Find all `@db.rel.FK` fields on a type that reference `targetTypeName`.
|
|
@@ -65,6 +67,5 @@ declare function hasAnyViewAnnotation(node: SemanticNode): boolean;
|
|
|
65
67
|
* @param doc - The document for type lookups
|
|
66
68
|
*/
|
|
67
69
|
declare function validateQueryScope(queryToken: Token, allowedTypes: string[], unqualifiedTarget: string | null, doc: AtscriptDoc): TMessages;
|
|
68
|
-
|
|
69
|
-
export { findFKFieldsPointingTo, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, refActionAnnotation, validateFieldBaseType, validateQueryScope, validateRefArgument };
|
|
70
|
-
export type { TFKFieldMatch };
|
|
70
|
+
//#endregion
|
|
71
|
+
export { TFKFieldMatch, findFKFieldsPointingTo, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, refActionAnnotation, validateFieldBaseType, validateQueryScope, validateRefArgument };
|