@atscript/db 0.1.154 → 0.1.155

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.
Files changed (33) hide show
  1. package/dist/agg.d.cts +1 -1
  2. package/dist/agg.d.mts +1 -1
  3. package/dist/{buckets-jy8BfswO.d.cts → buckets-DcWm3SLt.d.cts} +120 -10
  4. package/dist/{buckets-CBKL_ZWE.d.mts → buckets-goCoky8v.d.mts} +120 -10
  5. package/dist/{column-diff-DAIAq6XR.mjs → column-diff-C68V_eYM.mjs} +346 -65
  6. package/dist/{column-diff-qnzx1o3c.cjs → column-diff-DMkGYAGM.cjs} +357 -64
  7. package/dist/{fk-diff-BIJ8l_hF.d.mts → fk-diff-BYLNWoF9.d.mts} +2 -1
  8. package/dist/{fk-diff-D1mrLMjU.d.cts → fk-diff-DblOPBLS.d.cts} +2 -1
  9. package/dist/index.cjs +2 -2
  10. package/dist/index.d.cts +10 -5
  11. package/dist/index.d.mts +10 -5
  12. package/dist/index.mjs +2 -2
  13. package/dist/plugin.cjs +3 -3
  14. package/dist/plugin.mjs +3 -3
  15. package/dist/rel.d.cts +2 -2
  16. package/dist/rel.d.mts +2 -2
  17. package/dist/{relation-helpers-BUsxNNGU.d.mts → relation-helpers-B9MVBrtx.d.mts} +1 -1
  18. package/dist/{relation-helpers-D_8bydc2.d.cts → relation-helpers-D9kMFfum.d.cts} +1 -1
  19. package/dist/shared.cjs +2 -1
  20. package/dist/shared.d.cts +10 -3
  21. package/dist/shared.d.mts +10 -3
  22. package/dist/shared.mjs +2 -2
  23. package/dist/sync.cjs +288 -30
  24. package/dist/sync.d.cts +34 -5
  25. package/dist/sync.d.mts +34 -5
  26. package/dist/sync.mjs +288 -30
  27. package/dist/{validation-utils-DqZAH6aT.mjs → validation-utils-DxHIqa36.mjs} +23 -5
  28. package/dist/{validation-utils-debIYpq0.cjs → validation-utils-_PA7iSLm.cjs} +28 -4
  29. package/dist/{validator-BACewoRj.mjs → validator-BC3nwFi4.mjs} +178 -10
  30. package/dist/{validator-BxWwh3wf.cjs → validator-DHwSyBej.cjs} +201 -9
  31. package/dist/validator.cjs +1 -1
  32. package/dist/validator.mjs +1 -1
  33. package/package.json +6 -6
@@ -1,6 +1,110 @@
1
1
  import { i as DepthLimitExceededError } from "./db-error-eSsQX7rt.mjs";
2
2
  import { getDbFieldOp } from "./ops.mjs";
3
3
  import { createAnnotatedTypeNode, flattenAnnotatedType } from "@atscript/typescript/utils";
4
+ //#region src/shared/union-shape.ts
5
+ /** `null` / `undefined` as a type: a union member that only adds NULL. */
6
+ function isNullishType(type) {
7
+ const def = type.type;
8
+ return def.kind === "" && (def.designType === "null" || def.designType === "undefined");
9
+ }
10
+ /**
11
+ * The value members of a union — nested unions expanded (a flat-union entry
12
+ * of `flattenAnnotatedType` holds the prop's own union besides its members,
13
+ * an alias member may be a union itself), `null` / `undefined` left out,
14
+ * each member once. `nullable`: a `null` / `undefined` member was left out.
15
+ */
16
+ function unionValueMembers(type) {
17
+ const members = /* @__PURE__ */ new Set();
18
+ let nullable = false;
19
+ const visit = (t, depth) => {
20
+ if (t.type.kind === "union" && depth < 8) for (const item of t.type.items) visit(item, depth + 1);
21
+ else if (isNullishType(t)) nullable = true;
22
+ else members.add(t);
23
+ };
24
+ visit(type, 0);
25
+ return {
26
+ members: [...members],
27
+ nullable
28
+ };
29
+ }
30
+ /**
31
+ * The one value member of a union (`T | null` → `T`), or `undefined` when
32
+ * `type` is no union or has several value members. A column of a nullable
33
+ * union is the column `T` alone would get (its type tags, size, precision).
34
+ */
35
+ function soleUnionMember(type) {
36
+ if (type.type.kind !== "union") return void 0;
37
+ const { members } = unionValueMembers(type);
38
+ return members.length === 1 ? members[0] : void 0;
39
+ }
40
+ /**
41
+ * The `T` of a field typed `T | null` whose db annotations (`@db.default.now`
42
+ * of `number.timestamp.created`) describe the field's column like those of a
43
+ * field typed `T` — {@link soleUnionMember}, except for a reference to another
44
+ * field (`closedAt: Order.closedAt`): it shares that field's union, whose db
45
+ * annotations stay with the referenced field.
46
+ */
47
+ function columnUnionBase(type) {
48
+ return type.ref?.field ? void 0 : soleUnionMember(type);
49
+ }
50
+ const RANK = {
51
+ required: 0,
52
+ nullable: 1,
53
+ partial: 2
54
+ };
55
+ function weaker(a, b) {
56
+ return RANK[a] >= RANK[b] ? a : b;
57
+ }
58
+ /**
59
+ * The {@link TPathPresence} of the dot-path `path` below the object type
60
+ * `root`, or `undefined` when the path crosses an array or a tuple (its
61
+ * elements' fields are no columns of their own on relational storage;
62
+ * callers keep the field's own `optional` there).
63
+ */
64
+ function pathPresence(root, path) {
65
+ return presenceAt(root, path.split("."), 0);
66
+ }
67
+ function presenceAt(type, segs, i) {
68
+ const def = type.type;
69
+ switch (def.kind) {
70
+ case "union": {
71
+ let result = "required";
72
+ for (const item of def.items) {
73
+ if (isNullishType(item)) {
74
+ result = weaker(result, "nullable");
75
+ continue;
76
+ }
77
+ const member = presenceAt(item, segs, i);
78
+ if (member === void 0) return void 0;
79
+ result = weaker(result, member);
80
+ }
81
+ return result;
82
+ }
83
+ case "intersection": {
84
+ let result = "partial";
85
+ for (const item of def.items) {
86
+ const member = presenceAt(item, segs, i);
87
+ if (member === void 0) return void 0;
88
+ if (RANK[member] < RANK[result]) result = member;
89
+ }
90
+ return result;
91
+ }
92
+ case "object": {
93
+ if (i === segs.length) return "required";
94
+ const prop = def.props.get(segs[i]);
95
+ if (!prop) return "partial";
96
+ const rest = presenceAt(prop, segs, i + 1);
97
+ if (rest === void 0) return void 0;
98
+ return prop.optional ? weaker(rest, "nullable") : rest;
99
+ }
100
+ case "array":
101
+ case "tuple": return i === segs.length ? "required" : void 0;
102
+ default:
103
+ if (i < segs.length) return "partial";
104
+ return isNullishType(type) ? "nullable" : "required";
105
+ }
106
+ }
107
+ //#endregion
4
108
  //#region src/patch/patch-types.ts
5
109
  /**
6
110
  * Extracts `@expect.array.key` properties from an array-of-objects type.
@@ -50,6 +154,73 @@ function markComplexItems(def) {
50
154
  if (kind === "union" || kind === "tuple" || kind === "intersection") for (const item of def.type.items) complexItems.add(item);
51
155
  }
52
156
  /**
157
+ * Per validation context: the paths (array indices as `*`) of the tuples and
158
+ * the unions of several types the validator visited. Which item a field
159
+ * below one belongs to is not known when defaults are applied, so its
160
+ * default is not filled (`AtscriptDbTable._applyDefaults`) — and the field
161
+ * is not optional on insert either.
162
+ */
163
+ const ambiguousPaths = /* @__PURE__ */ new WeakMap();
164
+ /** `items.3.at` → `items.*.at` */
165
+ function schemaPath(path) {
166
+ return path.replace(/(^|\.)\d+(?=\.|$)/g, "$1*");
167
+ }
168
+ function markAmbiguous(dbCtx, def, path) {
169
+ const kind = def.type.kind;
170
+ if (kind === "tuple" || kind === "union" && !soleUnionMember(def)) {
171
+ let paths = ambiguousPaths.get(dbCtx);
172
+ if (!paths) ambiguousPaths.set(dbCtx, paths = /* @__PURE__ */ new Set());
173
+ paths.add(schemaPath(path));
174
+ }
175
+ }
176
+ /** Whether `path` lies below a tuple or a union of several types (see {@link ambiguousPaths}). */
177
+ function belowAmbiguous(dbCtx, path) {
178
+ const paths = ambiguousPaths.get(dbCtx);
179
+ if (!paths) return false;
180
+ const schema = schemaPath(path);
181
+ for (let dot = schema.lastIndexOf("."); dot !== -1; dot = schema.lastIndexOf(".", dot - 1)) if (paths.has(schema.slice(0, dot))) return true;
182
+ return false;
183
+ }
184
+ /** Per validated root type: schema path → whether it lies below a tuple / union of several types. */
185
+ const ambiguousByRoot = /* @__PURE__ */ new WeakMap();
186
+ /**
187
+ * {@link belowAmbiguous} read from the type itself: walks `path` from `root`
188
+ * (the validator's own type) and answers whether a tuple or a union of
189
+ * several types lies on the way. The visit-based answer misses a union the
190
+ * plugin was not consulted for — a caller that runs this plugin only for
191
+ * absent values (a form's server-managed check) never shows it the union
192
+ * holding the value.
193
+ */
194
+ function pathBelowAmbiguous(root, path) {
195
+ let cache = ambiguousByRoot.get(root);
196
+ if (!cache) ambiguousByRoot.set(root, cache = /* @__PURE__ */ new Map());
197
+ const schema = schemaPath(path);
198
+ let answer = cache.get(schema);
199
+ if (answer === void 0) {
200
+ answer = false;
201
+ let type = root;
202
+ for (const seg of schema.split(".")) {
203
+ if (type.type.kind === "union") {
204
+ const member = soleUnionMember(type);
205
+ if (!member) {
206
+ answer = true;
207
+ break;
208
+ }
209
+ type = member;
210
+ }
211
+ const kind = type.type.kind;
212
+ if (kind === "tuple") {
213
+ answer = true;
214
+ break;
215
+ }
216
+ type = kind === "array" ? seg === "*" ? type.type.of : void 0 : kind === "object" ? type.type.props.get(seg) : void 0;
217
+ if (!type) break;
218
+ }
219
+ cache.set(schema, answer);
220
+ }
221
+ return answer;
222
+ }
223
+ /**
53
224
  * Validator plugin for database operations.
54
225
  *
55
226
  * Handles navigation field constraints and delegates to the standard validator
@@ -65,6 +236,7 @@ function createDbValidatorPlugin() {
65
236
  const dbCtx = ctx.context;
66
237
  if (!dbCtx) return;
67
238
  markComplexItems(def);
239
+ markAmbiguous(dbCtx, def, ctx.path);
68
240
  if (def.type.tags?.has("geoPoint") && value !== void 0 && value !== null) {
69
241
  if (!Array.isArray(value) || value.length !== 2 || typeof value[0] !== "number" || typeof value[1] !== "number" || !Number.isFinite(value[0]) || !Number.isFinite(value[1])) {
70
242
  ctx.error("Expected a [lng, lat] tuple of two finite numbers (GeoJSON order)");
@@ -86,10 +258,13 @@ function createDbValidatorPlugin() {
86
258
  if (isTo || isFrom || isVia) return handleNavField(ctx, def, value, dbCtx, isTo, isFrom, isVia);
87
259
  if (value === void 0 && (dbCtx.mode === "insert" || dbCtx.mode === "replace") && !complexItems.has(def)) {
88
260
  const meta = def.metadata;
89
- const serverManaged = meta.has("db.default") || meta.has("db.default.increment") || meta.has("db.default.uuid") || meta.has("db.default.now") || meta.has("db.column.version") || meta.has("db.column.derived");
261
+ const baseMeta = columnUnionBase(def)?.metadata;
262
+ const defaulted = !(belowAmbiguous(dbCtx, ctx.path) || pathBelowAmbiguous(ctx.root, ctx.path));
263
+ const has = (key) => defaulted && (meta.has(key) || baseMeta?.has(key) === true);
264
+ const serverManaged = has("db.default") || has("db.default.increment") || has("db.default.uuid") || has("db.default.now") || meta.has("db.column.version") || meta.has("db.column.derived");
90
265
  const hasFK = meta.has("db.rel.FK");
91
266
  if (serverManaged || hasFK) {
92
- if (dbCtx.mode === "replace" && meta.has("meta.id") && !isInsideNavField(ctx.path, dbCtx.navFields)) return;
267
+ if (dbCtx.mode === "replace" && meta.has("meta.id") && !ctx.path.includes(".")) return;
93
268
  return true;
94
269
  }
95
270
  }
@@ -149,13 +324,6 @@ function isFieldOpAllowed(path, flatMap, navFields) {
149
324
  }
150
325
  return true;
151
326
  }
152
- /** Returns true if the given path is nested inside a navigation field. */
153
- function isInsideNavField(path, navFields) {
154
- if (!navFields) return false;
155
- let pos = path.length;
156
- while ((pos = path.lastIndexOf(".", pos - 1)) !== -1) if (navFields.has(path.slice(0, pos))) return true;
157
- return false;
158
- }
159
327
  function handleNavField(ctx, def, value, dbCtx, isTo, isFrom, isVia) {
160
328
  const dotIdx = ctx.path.lastIndexOf(".");
161
329
  const fieldName = dotIdx === -1 ? ctx.path : ctx.path.slice(dotIdx + 1);
@@ -437,4 +605,4 @@ function buildValidationContext(type) {
437
605
  };
438
606
  }
439
607
  //#endregion
440
- export { forceNavNonOptional as a, getKeyProps as c, dbPlugin as i, buildPatchPartial as n, isNavRelation as o, buildValidationContext as r, createDbValidatorPlugin as s, buildDbValidator as t };
608
+ export { forceNavNonOptional as a, getKeyProps as c, soleUnionMember as d, unionValueMembers as f, dbPlugin as i, columnUnionBase as l, buildPatchPartial as n, isNavRelation as o, buildValidationContext as r, createDbValidatorPlugin as s, buildDbValidator as t, pathPresence as u };
@@ -1,6 +1,110 @@
1
1
  const require_db_error = require("./db-error-JcfJqqpk.cjs");
2
2
  const require_ops = require("./ops.cjs");
3
3
  let _atscript_typescript_utils = require("@atscript/typescript/utils");
4
+ //#region src/shared/union-shape.ts
5
+ /** `null` / `undefined` as a type: a union member that only adds NULL. */
6
+ function isNullishType(type) {
7
+ const def = type.type;
8
+ return def.kind === "" && (def.designType === "null" || def.designType === "undefined");
9
+ }
10
+ /**
11
+ * The value members of a union — nested unions expanded (a flat-union entry
12
+ * of `flattenAnnotatedType` holds the prop's own union besides its members,
13
+ * an alias member may be a union itself), `null` / `undefined` left out,
14
+ * each member once. `nullable`: a `null` / `undefined` member was left out.
15
+ */
16
+ function unionValueMembers(type) {
17
+ const members = /* @__PURE__ */ new Set();
18
+ let nullable = false;
19
+ const visit = (t, depth) => {
20
+ if (t.type.kind === "union" && depth < 8) for (const item of t.type.items) visit(item, depth + 1);
21
+ else if (isNullishType(t)) nullable = true;
22
+ else members.add(t);
23
+ };
24
+ visit(type, 0);
25
+ return {
26
+ members: [...members],
27
+ nullable
28
+ };
29
+ }
30
+ /**
31
+ * The one value member of a union (`T | null` → `T`), or `undefined` when
32
+ * `type` is no union or has several value members. A column of a nullable
33
+ * union is the column `T` alone would get (its type tags, size, precision).
34
+ */
35
+ function soleUnionMember(type) {
36
+ if (type.type.kind !== "union") return void 0;
37
+ const { members } = unionValueMembers(type);
38
+ return members.length === 1 ? members[0] : void 0;
39
+ }
40
+ /**
41
+ * The `T` of a field typed `T | null` whose db annotations (`@db.default.now`
42
+ * of `number.timestamp.created`) describe the field's column like those of a
43
+ * field typed `T` — {@link soleUnionMember}, except for a reference to another
44
+ * field (`closedAt: Order.closedAt`): it shares that field's union, whose db
45
+ * annotations stay with the referenced field.
46
+ */
47
+ function columnUnionBase(type) {
48
+ return type.ref?.field ? void 0 : soleUnionMember(type);
49
+ }
50
+ const RANK = {
51
+ required: 0,
52
+ nullable: 1,
53
+ partial: 2
54
+ };
55
+ function weaker(a, b) {
56
+ return RANK[a] >= RANK[b] ? a : b;
57
+ }
58
+ /**
59
+ * The {@link TPathPresence} of the dot-path `path` below the object type
60
+ * `root`, or `undefined` when the path crosses an array or a tuple (its
61
+ * elements' fields are no columns of their own on relational storage;
62
+ * callers keep the field's own `optional` there).
63
+ */
64
+ function pathPresence(root, path) {
65
+ return presenceAt(root, path.split("."), 0);
66
+ }
67
+ function presenceAt(type, segs, i) {
68
+ const def = type.type;
69
+ switch (def.kind) {
70
+ case "union": {
71
+ let result = "required";
72
+ for (const item of def.items) {
73
+ if (isNullishType(item)) {
74
+ result = weaker(result, "nullable");
75
+ continue;
76
+ }
77
+ const member = presenceAt(item, segs, i);
78
+ if (member === void 0) return void 0;
79
+ result = weaker(result, member);
80
+ }
81
+ return result;
82
+ }
83
+ case "intersection": {
84
+ let result = "partial";
85
+ for (const item of def.items) {
86
+ const member = presenceAt(item, segs, i);
87
+ if (member === void 0) return void 0;
88
+ if (RANK[member] < RANK[result]) result = member;
89
+ }
90
+ return result;
91
+ }
92
+ case "object": {
93
+ if (i === segs.length) return "required";
94
+ const prop = def.props.get(segs[i]);
95
+ if (!prop) return "partial";
96
+ const rest = presenceAt(prop, segs, i + 1);
97
+ if (rest === void 0) return void 0;
98
+ return prop.optional ? weaker(rest, "nullable") : rest;
99
+ }
100
+ case "array":
101
+ case "tuple": return i === segs.length ? "required" : void 0;
102
+ default:
103
+ if (i < segs.length) return "partial";
104
+ return isNullishType(type) ? "nullable" : "required";
105
+ }
106
+ }
107
+ //#endregion
4
108
  //#region src/patch/patch-types.ts
5
109
  /**
6
110
  * Extracts `@expect.array.key` properties from an array-of-objects type.
@@ -50,6 +154,73 @@ function markComplexItems(def) {
50
154
  if (kind === "union" || kind === "tuple" || kind === "intersection") for (const item of def.type.items) complexItems.add(item);
51
155
  }
52
156
  /**
157
+ * Per validation context: the paths (array indices as `*`) of the tuples and
158
+ * the unions of several types the validator visited. Which item a field
159
+ * below one belongs to is not known when defaults are applied, so its
160
+ * default is not filled (`AtscriptDbTable._applyDefaults`) — and the field
161
+ * is not optional on insert either.
162
+ */
163
+ const ambiguousPaths = /* @__PURE__ */ new WeakMap();
164
+ /** `items.3.at` → `items.*.at` */
165
+ function schemaPath(path) {
166
+ return path.replace(/(^|\.)\d+(?=\.|$)/g, "$1*");
167
+ }
168
+ function markAmbiguous(dbCtx, def, path) {
169
+ const kind = def.type.kind;
170
+ if (kind === "tuple" || kind === "union" && !soleUnionMember(def)) {
171
+ let paths = ambiguousPaths.get(dbCtx);
172
+ if (!paths) ambiguousPaths.set(dbCtx, paths = /* @__PURE__ */ new Set());
173
+ paths.add(schemaPath(path));
174
+ }
175
+ }
176
+ /** Whether `path` lies below a tuple or a union of several types (see {@link ambiguousPaths}). */
177
+ function belowAmbiguous(dbCtx, path) {
178
+ const paths = ambiguousPaths.get(dbCtx);
179
+ if (!paths) return false;
180
+ const schema = schemaPath(path);
181
+ for (let dot = schema.lastIndexOf("."); dot !== -1; dot = schema.lastIndexOf(".", dot - 1)) if (paths.has(schema.slice(0, dot))) return true;
182
+ return false;
183
+ }
184
+ /** Per validated root type: schema path → whether it lies below a tuple / union of several types. */
185
+ const ambiguousByRoot = /* @__PURE__ */ new WeakMap();
186
+ /**
187
+ * {@link belowAmbiguous} read from the type itself: walks `path` from `root`
188
+ * (the validator's own type) and answers whether a tuple or a union of
189
+ * several types lies on the way. The visit-based answer misses a union the
190
+ * plugin was not consulted for — a caller that runs this plugin only for
191
+ * absent values (a form's server-managed check) never shows it the union
192
+ * holding the value.
193
+ */
194
+ function pathBelowAmbiguous(root, path) {
195
+ let cache = ambiguousByRoot.get(root);
196
+ if (!cache) ambiguousByRoot.set(root, cache = /* @__PURE__ */ new Map());
197
+ const schema = schemaPath(path);
198
+ let answer = cache.get(schema);
199
+ if (answer === void 0) {
200
+ answer = false;
201
+ let type = root;
202
+ for (const seg of schema.split(".")) {
203
+ if (type.type.kind === "union") {
204
+ const member = soleUnionMember(type);
205
+ if (!member) {
206
+ answer = true;
207
+ break;
208
+ }
209
+ type = member;
210
+ }
211
+ const kind = type.type.kind;
212
+ if (kind === "tuple") {
213
+ answer = true;
214
+ break;
215
+ }
216
+ type = kind === "array" ? seg === "*" ? type.type.of : void 0 : kind === "object" ? type.type.props.get(seg) : void 0;
217
+ if (!type) break;
218
+ }
219
+ cache.set(schema, answer);
220
+ }
221
+ return answer;
222
+ }
223
+ /**
53
224
  * Validator plugin for database operations.
54
225
  *
55
226
  * Handles navigation field constraints and delegates to the standard validator
@@ -65,6 +236,7 @@ function createDbValidatorPlugin() {
65
236
  const dbCtx = ctx.context;
66
237
  if (!dbCtx) return;
67
238
  markComplexItems(def);
239
+ markAmbiguous(dbCtx, def, ctx.path);
68
240
  if (def.type.tags?.has("geoPoint") && value !== void 0 && value !== null) {
69
241
  if (!Array.isArray(value) || value.length !== 2 || typeof value[0] !== "number" || typeof value[1] !== "number" || !Number.isFinite(value[0]) || !Number.isFinite(value[1])) {
70
242
  ctx.error("Expected a [lng, lat] tuple of two finite numbers (GeoJSON order)");
@@ -86,10 +258,13 @@ function createDbValidatorPlugin() {
86
258
  if (isTo || isFrom || isVia) return handleNavField(ctx, def, value, dbCtx, isTo, isFrom, isVia);
87
259
  if (value === void 0 && (dbCtx.mode === "insert" || dbCtx.mode === "replace") && !complexItems.has(def)) {
88
260
  const meta = def.metadata;
89
- const serverManaged = meta.has("db.default") || meta.has("db.default.increment") || meta.has("db.default.uuid") || meta.has("db.default.now") || meta.has("db.column.version") || meta.has("db.column.derived");
261
+ const baseMeta = columnUnionBase(def)?.metadata;
262
+ const defaulted = !(belowAmbiguous(dbCtx, ctx.path) || pathBelowAmbiguous(ctx.root, ctx.path));
263
+ const has = (key) => defaulted && (meta.has(key) || baseMeta?.has(key) === true);
264
+ const serverManaged = has("db.default") || has("db.default.increment") || has("db.default.uuid") || has("db.default.now") || meta.has("db.column.version") || meta.has("db.column.derived");
90
265
  const hasFK = meta.has("db.rel.FK");
91
266
  if (serverManaged || hasFK) {
92
- if (dbCtx.mode === "replace" && meta.has("meta.id") && !isInsideNavField(ctx.path, dbCtx.navFields)) return;
267
+ if (dbCtx.mode === "replace" && meta.has("meta.id") && !ctx.path.includes(".")) return;
93
268
  return true;
94
269
  }
95
270
  }
@@ -149,13 +324,6 @@ function isFieldOpAllowed(path, flatMap, navFields) {
149
324
  }
150
325
  return true;
151
326
  }
152
- /** Returns true if the given path is nested inside a navigation field. */
153
- function isInsideNavField(path, navFields) {
154
- if (!navFields) return false;
155
- let pos = path.length;
156
- while ((pos = path.lastIndexOf(".", pos - 1)) !== -1) if (navFields.has(path.slice(0, pos))) return true;
157
- return false;
158
- }
159
327
  function handleNavField(ctx, def, value, dbCtx, isTo, isFrom, isVia) {
160
328
  const dotIdx = ctx.path.lastIndexOf(".");
161
329
  const fieldName = dotIdx === -1 ? ctx.path : ctx.path.slice(dotIdx + 1);
@@ -455,6 +623,12 @@ Object.defineProperty(exports, "buildValidationContext", {
455
623
  return buildValidationContext;
456
624
  }
457
625
  });
626
+ Object.defineProperty(exports, "columnUnionBase", {
627
+ enumerable: true,
628
+ get: function() {
629
+ return columnUnionBase;
630
+ }
631
+ });
458
632
  Object.defineProperty(exports, "createDbValidatorPlugin", {
459
633
  enumerable: true,
460
634
  get: function() {
@@ -485,3 +659,21 @@ Object.defineProperty(exports, "isNavRelation", {
485
659
  return isNavRelation;
486
660
  }
487
661
  });
662
+ Object.defineProperty(exports, "pathPresence", {
663
+ enumerable: true,
664
+ get: function() {
665
+ return pathPresence;
666
+ }
667
+ });
668
+ Object.defineProperty(exports, "soleUnionMember", {
669
+ enumerable: true,
670
+ get: function() {
671
+ return soleUnionMember;
672
+ }
673
+ });
674
+ Object.defineProperty(exports, "unionValueMembers", {
675
+ enumerable: true,
676
+ get: function() {
677
+ return unionValueMembers;
678
+ }
679
+ });
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_db_error = require("./db-error-JcfJqqpk.cjs");
3
+ const require_validator = require("./validator-DHwSyBej.cjs");
3
4
  const require_object = require("./object-Djg28csK.cjs");
4
5
  const require_ops = require("./ops.cjs");
5
- const require_validator = require("./validator-BxWwh3wf.cjs");
6
6
  exports.$cas = require_ops.$cas;
7
7
  exports.$dec = require_ops.$dec;
8
8
  exports.$inc = require_ops.$inc;
@@ -1,5 +1,5 @@
1
1
  import { r as DbError } from "./db-error-eSsQX7rt.mjs";
2
+ import { a as forceNavNonOptional, c as getKeyProps, i as dbPlugin, n as buildPatchPartial, o as isNavRelation, r as buildValidationContext, s as createDbValidatorPlugin, t as buildDbValidator } from "./validator-BC3nwFi4.mjs";
2
3
  import { a as isPlainObject, i as isEmptyObject } from "./object-TkiJQ-Dp.mjs";
3
4
  import { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, isDbFieldOp, reconcileCas, separateCas } from "./ops.mjs";
4
- import { a as forceNavNonOptional, c as getKeyProps, i as dbPlugin, n as buildPatchPartial, o as isNavRelation, r as buildValidationContext, s as createDbValidatorPlugin, t as buildDbValidator } from "./validator-BACewoRj.mjs";
5
5
  export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, DbError, buildDbValidator, buildPatchPartial, buildValidationContext, createDbValidatorPlugin, dbPlugin, forceNavNonOptional, getKeyProps, isDbFieldOp, isEmptyObject, isNavRelation, isPlainObject, reconcileCas, separateCas };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/db",
3
- "version": "0.1.154",
3
+ "version": "0.1.155",
4
4
  "description": "Database adapter utilities for atscript.",
5
5
  "keywords": [
6
6
  "atscript",
@@ -71,14 +71,14 @@
71
71
  "access": "public"
72
72
  },
73
73
  "devDependencies": {
74
- "@atscript/core": "^0.1.103",
75
- "@atscript/typescript": "^0.1.103",
74
+ "@atscript/core": "^0.1.105",
75
+ "@atscript/typescript": "^0.1.105",
76
76
  "@uniqu/core": "^0.1.15",
77
- "unplugin-atscript": "^0.1.103"
77
+ "unplugin-atscript": "^0.1.105"
78
78
  },
79
79
  "peerDependencies": {
80
- "@atscript/core": "^0.1.103",
81
- "@atscript/typescript": "^0.1.103",
80
+ "@atscript/core": "^0.1.105",
81
+ "@atscript/typescript": "^0.1.105",
82
82
  "@uniqu/core": "^0.1.15"
83
83
  },
84
84
  "scripts": {