@atscript/db 0.1.146 → 0.1.148
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-CV7y8nC6.d.cts → agg-42CSpGDR.d.cts} +2 -2
- package/dist/{agg-D5DHsAby.d.mts → agg-Wo-smrYV.d.mts} +3 -3
- package/dist/agg.cjs +1 -1
- package/dist/agg.d.cts +2 -2
- package/dist/agg.d.mts +2 -2
- package/dist/agg.mjs +1 -1
- package/dist/{aggregate-fns-CGBv3E8S.cjs → aggregate-fns-C-UJRobm.cjs} +52 -5
- package/dist/{aggregate-fns-CfsveE1w.mjs → aggregate-fns-CyaZyb9I.mjs} +35 -6
- package/dist/aggregate-rules-D_bsCpUI.cjs +26 -0
- package/dist/aggregate-rules-jdPrxqWa.mjs +15 -0
- package/dist/{buckets-DRycmhOW.d.mts → buckets-CNdTOnei.d.mts} +832 -33
- package/dist/{buckets-DYFu0eZ8.d.cts → buckets-DJiYlMXc.d.cts} +832 -33
- package/dist/{column-diff-D_Kyuh0S.cjs → column-diff-CUU4GvYg.cjs} +1546 -193
- package/dist/{column-diff-e2oHc71_.mjs → column-diff-Cp6ZoyRE.mjs} +1529 -200
- package/dist/{db-error-D5uilS_A.mjs → db-error-Az85UhTX.mjs} +32 -1
- package/dist/{db-error-DTkkeu5b.cjs → db-error-DRQH4sLY.cjs} +55 -0
- package/dist/{column-diff-Q9UmWn5x.d.mts → fk-diff-BQ4krij8.d.cts} +48 -2
- package/dist/{column-diff-w-Mym_3w.d.cts → fk-diff-DsaIijVX.d.mts} +48 -2
- package/dist/index.cjs +95 -35
- package/dist/index.d.cts +92 -22
- package/dist/index.d.mts +92 -22
- package/dist/index.mjs +65 -35
- package/dist/{nested-writer-xfQwxplL.cjs → nested-writer-BUQvk6QT.cjs} +734 -2
- package/dist/{nested-writer-CnOOAehr.mjs → nested-writer-CUBoq1ZO.mjs} +598 -4
- package/dist/numeric-operand-B1jKH7x5.mjs +21 -0
- package/dist/numeric-operand-DKfiRLYp.cjs +26 -0
- package/dist/ops.cjs +1 -1
- package/dist/ops.mjs +1 -1
- package/dist/plugin.cjs +293 -5
- package/dist/plugin.mjs +294 -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-Ba0v49sn.d.mts} +1 -1
- package/dist/{relation-helpers-BOMm_HUI.d.cts → relation-helpers-kX7jjgME.d.cts} +1 -1
- package/dist/relation-loader-ByY1Byrl.mjs +370 -0
- package/dist/relation-loader-D8OrdH-r.cjs +369 -0
- package/dist/shared.cjs +4 -1
- package/dist/shared.d.cts +16 -4
- package/dist/shared.d.mts +16 -4
- package/dist/shared.mjs +3 -2
- package/dist/sync.cjs +11 -7
- package/dist/sync.d.cts +2 -25
- package/dist/sync.d.mts +2 -25
- package/dist/sync.mjs +11 -7
- 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-Clu2q_7z.mjs → validator-BTiIOTKP.mjs} +9 -3
- package/dist/{validator-CVS-onRg.cjs → validator-UcuJxHNT.cjs} +8 -2
- package/dist/{validator-Bw6ks9Hy.d.mts → validator-tBNvM1qc.d.cts} +31 -7
- package/dist/{validator-Bw6ks9Hy.d.cts → validator-tBNvM1qc.d.mts} +31 -7
- package/dist/validator.cjs +2 -2
- package/dist/validator.d.cts +1 -1
- package/dist/validator.d.mts +1 -1
- package/dist/validator.mjs +2 -2
- package/package.json +8 -8
- package/dist/relation-loader-CBPY6kM7.cjs +0 -461
- package/dist/relation-loader-D9XuXaMv.mjs +0 -462
package/dist/sync.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as DbError } from "./db-error-
|
|
2
|
-
import { a as
|
|
1
|
+
import { r as DbError } from "./db-error-Az85UhTX.mjs";
|
|
2
|
+
import { a as computeTableHash, at as aliasTargetOf, c as snapshotToExistingColumns, d as computeForeignKeyDiff, dt as NoopLogger, f as fkColumns, i as computeSchemaHash, l as snapshotToExistingTableOptions, m as hasForeignKeyChanges, o as computeTableSnapshot, p as fkKey, r as canonicalizeQueryNode, s as computeViewSnapshot, t as computeColumnDiff, u as viewSnapshotSources } from "./column-diff-Cp6ZoyRE.mjs";
|
|
3
3
|
//#region src/schema/table-option-diff.ts
|
|
4
4
|
/**
|
|
5
5
|
* Computes the difference between desired and existing table options.
|
|
@@ -744,7 +744,7 @@ async function executeSyncTable(facts, safe, deps, exec) {
|
|
|
744
744
|
};
|
|
745
745
|
} else {
|
|
746
746
|
if (hasFkChanges && fkDiff && adapter.dropForeignKeys) {
|
|
747
|
-
const keysToDrop = [...fkDiff.removed.map((fk) => fkKey(fk.fields)), ...fkDiff.changed.map((fk) => fkKey(fk.desired.fields))];
|
|
747
|
+
const keysToDrop = [...fkDiff.removed.map((fk) => fkKey(fk.fields)), ...fkDiff.changed.map((fk) => fkKey(fkColumns(fk.desired).fields))];
|
|
748
748
|
if (keysToDrop.length > 0) {
|
|
749
749
|
await adapter.dropForeignKeys(keysToDrop);
|
|
750
750
|
droppedFks.push(...keysToDrop);
|
|
@@ -1610,7 +1610,7 @@ var SchemaSync = class {
|
|
|
1610
1610
|
const fkDiff = facts.fkDiff;
|
|
1611
1611
|
init.status = "alter";
|
|
1612
1612
|
init.fkAdded = fkDiff.added.map((fk) => ({
|
|
1613
|
-
fields: fk.fields,
|
|
1613
|
+
fields: fkColumns(fk).fields,
|
|
1614
1614
|
targetTable: fk.targetTable
|
|
1615
1615
|
}));
|
|
1616
1616
|
init.fkRemoved = fkDiff.removed.map((fk) => ({
|
|
@@ -1618,9 +1618,12 @@ var SchemaSync = class {
|
|
|
1618
1618
|
targetTable: fk.targetTable
|
|
1619
1619
|
}));
|
|
1620
1620
|
init.fkChanged = fkDiff.changed.map((fk) => ({
|
|
1621
|
-
fields: fk.desired.fields,
|
|
1621
|
+
fields: fkColumns(fk.desired).fields,
|
|
1622
1622
|
targetTable: fk.desired.targetTable,
|
|
1623
|
-
details: buildFkChangeDetails(
|
|
1623
|
+
details: buildFkChangeDetails({
|
|
1624
|
+
...fk.desired,
|
|
1625
|
+
targetFields: fkColumns(fk.desired).targetFields
|
|
1626
|
+
}, fk.existing)
|
|
1624
1627
|
}));
|
|
1625
1628
|
}
|
|
1626
1629
|
if (facts.diff?.primaryKeyChanged) facts.populated = await adapter.hasRows(pendingRename ? dbName : void 0) ?? "unknown";
|
|
@@ -1658,7 +1661,7 @@ var SchemaSync = class {
|
|
|
1658
1661
|
addRefusal(refusals, t.name, `Primary key of "${t.name}" changed ${label} but the referencing table "${child.name}" is renamed in the same run (from "${child.pendingRename}") — rename it in a separate run first, then retarget the foreign key and re-run.`);
|
|
1659
1662
|
continue;
|
|
1660
1663
|
}
|
|
1661
|
-
if (!(child !== void 0 && [...child.readable.foreignKeys.values()].some((desired) => desired.targetTable === t.name && fkKey(desired.fields) === fkKey(fk.fields) && fkKey(desired.targetFields) === fkKey(pk.to)))) addRefusal(refusals, t.name, `Primary key of "${t.name}" changed ${label} but "${fk.table}.${fk.fields.join(",")}" still references the old key — retarget the foreign key (or migrate manually) and re-run.`);
|
|
1664
|
+
if (!(child !== void 0 && [...child.readable.foreignKeys.values()].some((desired) => desired.targetTable === t.name && fkKey(fkColumns(desired).fields) === fkKey(fk.fields) && fkKey(fkColumns(desired).targetFields) === fkKey(pk.to)))) addRefusal(refusals, t.name, `Primary key of "${t.name}" changed ${label} but "${fk.table}.${fk.fields.join(",")}" still references the old key — retarget the foreign key (or migrate manually) and re-run.`);
|
|
1662
1665
|
}
|
|
1663
1666
|
for (const f of t.readable.fieldDescriptors) if (!f.ignored && !f.isPrimaryKey && f.defaultValue?.kind === "fn" && f.defaultValue.fn === "increment") addRefusal(refusals, t.name, `"${t.name}.${f.physicalName}" is auto-increment but no longer part of the primary key; auto-increment columns must be primary-key columns.`);
|
|
1664
1667
|
}
|
|
@@ -1673,6 +1676,7 @@ var SchemaSync = class {
|
|
|
1673
1676
|
if (d.viewObjectKinds.get(view.tableName) === "table") addRefusal(refusals, view.tableName, `A physical table "${view.tableName}" exists where managed view "${view.tableName}" is declared — drop or rename it`);
|
|
1674
1677
|
const fns = view.dbAdapter.aggregateFns();
|
|
1675
1678
|
for (const col of view.getViewColumnMappings()) if (col.aggFn && !fns.has(col.aggFn)) addRefusal(refusals, view.tableName, `View "${view.tableName}" field "${col.viewPath}": aggregate "${col.aggFn}" is not supported by this adapter (aggregateFns())`);
|
|
1679
|
+
for (const problem of view.viewCapabilityProblems()) addRefusal(refusals, view.tableName, problem);
|
|
1676
1680
|
for (const source of d.viewSources.get(view.tableName)) if (d.externalTargets.get(source) === false) addRefusal(refusals, view.tableName, `View "${view.tableName}" reads "${source}" which is neither in the sync inventory nor present in the database`);
|
|
1677
1681
|
}
|
|
1678
1682
|
if (!safe) for (const r of d.removed) {
|
|
@@ -344,44 +344,55 @@ function hasAnyViewAnnotation(node) {
|
|
|
344
344
|
return viewAnnotationNames.some((name) => node.countAnnotations(name) > 0);
|
|
345
345
|
}
|
|
346
346
|
/**
|
|
347
|
-
*
|
|
348
|
-
*
|
|
347
|
+
* Every field ref of a backtick argument — a predicate (`queryNode`), an
|
|
348
|
+
* arithmetic expression (`exprNode`) or an ordering (`orderNode`) — in source
|
|
349
|
+
* order. `[]` when the argument did not parse.
|
|
350
|
+
* @since 0.1.147
|
|
351
|
+
*/
|
|
352
|
+
function backtickFieldRefs(token) {
|
|
353
|
+
if (token.queryNode) {
|
|
354
|
+
const refs = [];
|
|
355
|
+
forEachFieldRef(token.queryNode.expression, (ref) => refs.push(ref));
|
|
356
|
+
return refs;
|
|
357
|
+
}
|
|
358
|
+
return (token.exprNode ?? token.orderNode)?.fieldRefs() ?? [];
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Validate that all field refs in a backtick argument (a query, an `expr` or
|
|
362
|
+
* an `order`) are within `scope` — the same {@link TQueryScope} the editor
|
|
363
|
+
* completes (`lsp-scopes`):
|
|
349
364
|
* qualified refs must name one of `scope.allowedTypes`; an unqualified ref
|
|
350
365
|
* (a dotted path included) must be a field of `scope.unqualifiedTarget`, or
|
|
351
366
|
* is rejected outright when that is `null`.
|
|
352
367
|
*
|
|
353
|
-
* @param queryToken - The
|
|
368
|
+
* @param queryToken - The backtick arg token (with `.queryNode`, `.exprNode` or `.orderNode`)
|
|
354
369
|
* @param scope - The scope of the argument
|
|
355
370
|
* @param doc - The document for type lookups
|
|
356
371
|
* @param scopeHint - Replaces the default "expected 'A' or 'B'" tail of the out-of-scope message
|
|
357
372
|
*/
|
|
358
373
|
function validateQueryScope(queryToken, scope, doc, scopeHint) {
|
|
359
374
|
const errors = [];
|
|
360
|
-
const queryNode = queryToken.queryNode;
|
|
361
|
-
if (!queryNode) return errors;
|
|
362
375
|
const { allowedTypes, unqualifiedTarget } = scope;
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
message: `Query references '${typeName}' which is not in scope — ${scopeHint ?? `expected ${allowedTypes.map((t) => `'${t}'`).join(" or ")}`}`,
|
|
368
|
-
severity: 1,
|
|
369
|
-
range: ref.typeRef.range
|
|
370
|
-
});
|
|
371
|
-
} else if (unqualifiedTarget === null) errors.push({
|
|
372
|
-
message: `Unqualified field reference '${ref.fieldRef.text}' — use qualified form (e.g., Type.${ref.fieldRef.text})`,
|
|
376
|
+
for (const ref of backtickFieldRefs(queryToken)) if (ref.typeRef) {
|
|
377
|
+
const typeName = ref.typeRef.text;
|
|
378
|
+
if (!allowedTypes.includes(typeName)) errors.push({
|
|
379
|
+
message: `Query references '${typeName}' which is not in scope — ${scopeHint ?? `expected ${allowedTypes.map((t) => `'${t}'`).join(" or ")}`}`,
|
|
373
380
|
severity: 1,
|
|
374
|
-
range: ref.
|
|
381
|
+
range: ref.typeRef.range
|
|
375
382
|
});
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
severity: 1,
|
|
381
|
-
range: ref.fieldRef.range
|
|
382
|
-
});
|
|
383
|
-
}
|
|
383
|
+
} else if (unqualifiedTarget === null) errors.push({
|
|
384
|
+
message: `Unqualified field reference '${ref.fieldRef.text}' — use qualified form (e.g., Type.${ref.fieldRef.text})`,
|
|
385
|
+
severity: 1,
|
|
386
|
+
range: ref.fieldRef.range
|
|
384
387
|
});
|
|
388
|
+
else {
|
|
389
|
+
const targetDef = doc.unwindType(unqualifiedTarget)?.def;
|
|
390
|
+
if (targetDef && ((0, _atscript_core.isInterface)(targetDef) || (0, _atscript_core.isStructure)(targetDef)) && !doc.unwindType(unqualifiedTarget, ref.fieldRef.text.split("."))) errors.push({
|
|
391
|
+
message: `Field '${ref.fieldRef.text}' does not exist on '${unqualifiedTarget}'`,
|
|
392
|
+
severity: 1,
|
|
393
|
+
range: ref.fieldRef.range
|
|
394
|
+
});
|
|
395
|
+
}
|
|
385
396
|
return errors;
|
|
386
397
|
}
|
|
387
398
|
/**
|
|
@@ -344,44 +344,55 @@ function hasAnyViewAnnotation(node) {
|
|
|
344
344
|
return viewAnnotationNames.some((name) => node.countAnnotations(name) > 0);
|
|
345
345
|
}
|
|
346
346
|
/**
|
|
347
|
-
*
|
|
348
|
-
*
|
|
347
|
+
* Every field ref of a backtick argument — a predicate (`queryNode`), an
|
|
348
|
+
* arithmetic expression (`exprNode`) or an ordering (`orderNode`) — in source
|
|
349
|
+
* order. `[]` when the argument did not parse.
|
|
350
|
+
* @since 0.1.147
|
|
351
|
+
*/
|
|
352
|
+
function backtickFieldRefs(token) {
|
|
353
|
+
if (token.queryNode) {
|
|
354
|
+
const refs = [];
|
|
355
|
+
forEachFieldRef(token.queryNode.expression, (ref) => refs.push(ref));
|
|
356
|
+
return refs;
|
|
357
|
+
}
|
|
358
|
+
return (token.exprNode ?? token.orderNode)?.fieldRefs() ?? [];
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Validate that all field refs in a backtick argument (a query, an `expr` or
|
|
362
|
+
* an `order`) are within `scope` — the same {@link TQueryScope} the editor
|
|
363
|
+
* completes (`lsp-scopes`):
|
|
349
364
|
* qualified refs must name one of `scope.allowedTypes`; an unqualified ref
|
|
350
365
|
* (a dotted path included) must be a field of `scope.unqualifiedTarget`, or
|
|
351
366
|
* is rejected outright when that is `null`.
|
|
352
367
|
*
|
|
353
|
-
* @param queryToken - The
|
|
368
|
+
* @param queryToken - The backtick arg token (with `.queryNode`, `.exprNode` or `.orderNode`)
|
|
354
369
|
* @param scope - The scope of the argument
|
|
355
370
|
* @param doc - The document for type lookups
|
|
356
371
|
* @param scopeHint - Replaces the default "expected 'A' or 'B'" tail of the out-of-scope message
|
|
357
372
|
*/
|
|
358
373
|
function validateQueryScope(queryToken, scope, doc, scopeHint) {
|
|
359
374
|
const errors = [];
|
|
360
|
-
const queryNode = queryToken.queryNode;
|
|
361
|
-
if (!queryNode) return errors;
|
|
362
375
|
const { allowedTypes, unqualifiedTarget } = scope;
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
message: `Query references '${typeName}' which is not in scope — ${scopeHint ?? `expected ${allowedTypes.map((t) => `'${t}'`).join(" or ")}`}`,
|
|
368
|
-
severity: 1,
|
|
369
|
-
range: ref.typeRef.range
|
|
370
|
-
});
|
|
371
|
-
} else if (unqualifiedTarget === null) errors.push({
|
|
372
|
-
message: `Unqualified field reference '${ref.fieldRef.text}' — use qualified form (e.g., Type.${ref.fieldRef.text})`,
|
|
376
|
+
for (const ref of backtickFieldRefs(queryToken)) if (ref.typeRef) {
|
|
377
|
+
const typeName = ref.typeRef.text;
|
|
378
|
+
if (!allowedTypes.includes(typeName)) errors.push({
|
|
379
|
+
message: `Query references '${typeName}' which is not in scope — ${scopeHint ?? `expected ${allowedTypes.map((t) => `'${t}'`).join(" or ")}`}`,
|
|
373
380
|
severity: 1,
|
|
374
|
-
range: ref.
|
|
381
|
+
range: ref.typeRef.range
|
|
375
382
|
});
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
severity: 1,
|
|
381
|
-
range: ref.fieldRef.range
|
|
382
|
-
});
|
|
383
|
-
}
|
|
383
|
+
} else if (unqualifiedTarget === null) errors.push({
|
|
384
|
+
message: `Unqualified field reference '${ref.fieldRef.text}' — use qualified form (e.g., Type.${ref.fieldRef.text})`,
|
|
385
|
+
severity: 1,
|
|
386
|
+
range: ref.fieldRef.range
|
|
384
387
|
});
|
|
388
|
+
else {
|
|
389
|
+
const targetDef = doc.unwindType(unqualifiedTarget)?.def;
|
|
390
|
+
if (targetDef && (isInterface(targetDef) || isStructure(targetDef)) && !doc.unwindType(unqualifiedTarget, ref.fieldRef.text.split("."))) errors.push({
|
|
391
|
+
message: `Field '${ref.fieldRef.text}' does not exist on '${unqualifiedTarget}'`,
|
|
392
|
+
severity: 1,
|
|
393
|
+
range: ref.fieldRef.range
|
|
394
|
+
});
|
|
395
|
+
}
|
|
385
396
|
return errors;
|
|
386
397
|
}
|
|
387
398
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as DepthLimitExceededError } from "./db-error-
|
|
2
|
-
import {
|
|
1
|
+
import { i as DepthLimitExceededError } from "./db-error-Az85UhTX.mjs";
|
|
2
|
+
import { getDbFieldOp } from "./ops.mjs";
|
|
3
3
|
import { flattenAnnotatedType } from "@atscript/typescript/utils";
|
|
4
4
|
//#region src/patch/patch-types.ts
|
|
5
5
|
/**
|
|
@@ -83,7 +83,8 @@ function createDbValidatorPlugin() {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
if (dbCtx.mode === "patch") {
|
|
86
|
-
|
|
86
|
+
const fieldOp = getDbFieldOp(value);
|
|
87
|
+
if (fieldOp) {
|
|
87
88
|
if (def.metadata.has("db.column.derived")) {
|
|
88
89
|
ctx.error("Field operations ($inc/$dec/$mul) are not allowed on a @db.column.derived field — it is computed from its @db.json source; patch the source leaf instead");
|
|
89
90
|
return false;
|
|
@@ -96,6 +97,11 @@ function createDbValidatorPlugin() {
|
|
|
96
97
|
ctx.error("Field operations ($inc/$dec/$mul) can only be applied to numeric fields");
|
|
97
98
|
return false;
|
|
98
99
|
}
|
|
100
|
+
const operand = fieldOp.value;
|
|
101
|
+
if (!Number.isFinite(operand)) {
|
|
102
|
+
ctx.error(`Field operation operand must be a finite number, got ${operand}`);
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
99
105
|
return true;
|
|
100
106
|
}
|
|
101
107
|
if (def.type.kind === "array" && dbCtx.flatMap) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_db_error = require("./db-error-
|
|
1
|
+
const require_db_error = require("./db-error-DRQH4sLY.cjs");
|
|
2
2
|
const require_ops = require("./ops.cjs");
|
|
3
3
|
let _atscript_typescript_utils = require("@atscript/typescript/utils");
|
|
4
4
|
//#region src/patch/patch-types.ts
|
|
@@ -83,7 +83,8 @@ function createDbValidatorPlugin() {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
if (dbCtx.mode === "patch") {
|
|
86
|
-
|
|
86
|
+
const fieldOp = require_ops.getDbFieldOp(value);
|
|
87
|
+
if (fieldOp) {
|
|
87
88
|
if (def.metadata.has("db.column.derived")) {
|
|
88
89
|
ctx.error("Field operations ($inc/$dec/$mul) are not allowed on a @db.column.derived field — it is computed from its @db.json source; patch the source leaf instead");
|
|
89
90
|
return false;
|
|
@@ -96,6 +97,11 @@ function createDbValidatorPlugin() {
|
|
|
96
97
|
ctx.error("Field operations ($inc/$dec/$mul) can only be applied to numeric fields");
|
|
97
98
|
return false;
|
|
98
99
|
}
|
|
100
|
+
const operand = fieldOp.value;
|
|
101
|
+
if (!Number.isFinite(operand)) {
|
|
102
|
+
ctx.error(`Field operation operand must be a finite number, got ${operand}`);
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
99
105
|
return true;
|
|
100
106
|
}
|
|
101
107
|
if (def.type.kind === "array" && dbCtx.flatMap) {
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { TAtscriptAnnotatedType, TAtscriptTypeArray, TAtscriptTypeObject, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
|
|
2
2
|
|
|
3
3
|
//#region src/db-error.d.ts
|
|
4
|
-
type DbErrorCode = "CONFLICT" | "FK_VIOLATION" | "NOT_FOUND" | "CASCADE_CYCLE" | "INVALID_QUERY" | "DEPTH_EXCEEDED" | "VERSION_COLUMN_WRITE" | "CAS_EXHAUSTED" | "CAS_MISMATCH" | "ENC_CONFIG_MISSING" | "ENC_KEY_INVALID" | "ENC_NOT_ENCRYPTED" | "ENC_DECRYPT_FAILED" | "ENC_FIELD_FILTER" | "ENC_FIELD_SORT" | "ENC_FIELD_AGG" | "ENC_FIELD_PATCH_OP" | "GEO_INDEX_MISSING" | "GEO_NOT_SUPPORTED" | "FILTER_TYPE_MISMATCH" /** The adapter's `calendarBucketUnits()` lacks the requested unit (moost-db: 400). */ | "BUCKET_NOT_SUPPORTED" /** The engine cannot resolve the bucket's time zone — a store-configuration condition (moost-db: 501). */ | "BUCKET_TZ_UNAVAILABLE" /** A known aggregate function the adapter's `aggregateFns()` lacks (moost-db: 400). @since 0.1.136 */ | "AGG_FN_NOT_SUPPORTED"
|
|
4
|
+
type DbErrorCode = "CONFLICT" | "FK_VIOLATION" | "NOT_FOUND" | "CASCADE_CYCLE" | "INVALID_QUERY" | "DEPTH_EXCEEDED" | "VERSION_COLUMN_WRITE" | "CAS_EXHAUSTED" | "CAS_MISMATCH" | "ENC_CONFIG_MISSING" | "ENC_KEY_INVALID" | "ENC_NOT_ENCRYPTED" | "ENC_DECRYPT_FAILED" | "ENC_FIELD_FILTER" | "ENC_FIELD_SORT" | "ENC_FIELD_AGG" | "ENC_FIELD_PATCH_OP" | "GEO_INDEX_MISSING" | "GEO_NOT_SUPPORTED" | "FILTER_TYPE_MISMATCH" /** The adapter's `calendarBucketUnits()` lacks the requested unit (moost-db: 400). */ | "BUCKET_NOT_SUPPORTED" /** The engine cannot resolve the bucket's time zone — a store-configuration condition (moost-db: 501). */ | "BUCKET_TZ_UNAVAILABLE" /** A known aggregate function the adapter's `aggregateFns()` lacks (moost-db: 400). @since 0.1.136 */ | "AGG_FN_NOT_SUPPORTED"
|
|
5
|
+
/**
|
|
6
|
+
* The adapter's `supportsAggregateExpressions()` is false and the query uses
|
|
7
|
+
* arithmetic (`{ $expr }`, `{ $fn, $expr }`) in an aggregate `$select`
|
|
8
|
+
* (moost-db: 400). @since 0.1.148
|
|
9
|
+
*/
|
|
10
|
+
| "AGG_EXPR_NOT_SUPPORTED"
|
|
11
|
+
/**
|
|
12
|
+
* The adapter (or the table's wiring) cannot run a relational predicate:
|
|
13
|
+
* `supportsRelationFilters()` is false for the read/write mode, the related
|
|
14
|
+
* table lives on a different adapter, or the table was built without a
|
|
15
|
+
* `DbSpace` (moost-db: 400). @since 0.1.147
|
|
16
|
+
*/
|
|
17
|
+
| "REL_FILTER_NOT_SUPPORTED" /** The `DbSpace` was closed; the table/view handle can no longer be used (moost-db: 503). @since 0.1.148 */ | "SPACE_CLOSED" /** The adapter does not implement `insertManyIgnore` (moost-db: 400). @since 0.1.148 */ | "ON_CONFLICT_NOT_SUPPORTED" | "TX_WAIT_TIMEOUT";
|
|
5
18
|
declare class DbError extends Error {
|
|
6
19
|
readonly code: DbErrorCode;
|
|
7
20
|
readonly errors: Array<{
|
|
@@ -14,6 +27,14 @@ declare class DbError extends Error {
|
|
|
14
27
|
message: string;
|
|
15
28
|
}>, message?: string);
|
|
16
29
|
}
|
|
30
|
+
/** Whether `error` is a `DbError` with code `CONFLICT` (unique / primary-key violation). */
|
|
31
|
+
declare function isConflict(error: unknown): error is DbError;
|
|
32
|
+
/**
|
|
33
|
+
* Collapses the failures of a multi-step shutdown into one `AggregateError`
|
|
34
|
+
* (message lists every failure).
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
declare function aggregateFailure(label: string, errors: unknown[]): AggregateError;
|
|
17
38
|
/**
|
|
18
39
|
* Thrown by {@link withOptimisticRetry} when `maxAttempts` is reached
|
|
19
40
|
* without a successful CAS commit — the target row kept changing under
|
|
@@ -39,11 +60,7 @@ declare class CasMismatchError extends DbError {
|
|
|
39
60
|
/** Keys passed to `touchMany`. */
|
|
40
61
|
readonly expected: number;
|
|
41
62
|
name: string;
|
|
42
|
-
constructor(/** Rows whose primary key + version matched. */
|
|
43
|
-
|
|
44
|
-
matched: number, /** Keys passed to `touchMany`. */
|
|
45
|
-
|
|
46
|
-
expected: number);
|
|
63
|
+
constructor(/** Rows whose primary key + version matched. */matched: number, /** Keys passed to `touchMany`. */expected: number);
|
|
47
64
|
}
|
|
48
65
|
/**
|
|
49
66
|
* The engine cannot resolve a calendar bucket's time zone (`BUCKET_TZ_UNAVAILABLE`,
|
|
@@ -52,6 +69,13 @@ declare class CasMismatchError extends DbError {
|
|
|
52
69
|
* missing server time zone database — never a malformed query. Since 0.1.132.
|
|
53
70
|
*/
|
|
54
71
|
declare function bucketTimeZoneUnavailable(message: string): DbError;
|
|
72
|
+
/**
|
|
73
|
+
* The adapter's `supportsAggregateExpressions()` is false (or its SQL dialect
|
|
74
|
+
* cannot cast to a double) and the query uses arithmetic in an aggregate
|
|
75
|
+
* `$select` (`AGG_EXPR_NOT_SUPPORTED`, `path` `$select`; moost-db: 400).
|
|
76
|
+
* @since 0.1.148
|
|
77
|
+
*/
|
|
78
|
+
declare function aggregateExpressionsNotSupported(): DbError;
|
|
55
79
|
//#endregion
|
|
56
80
|
//#region src/patch/patch-types.d.ts
|
|
57
81
|
interface TArrayPatch<A extends readonly unknown[]> {
|
|
@@ -138,4 +162,4 @@ interface ValidationContext {
|
|
|
138
162
|
*/
|
|
139
163
|
declare function buildValidationContext(type: TAtscriptAnnotatedType<TAtscriptTypeObject>): ValidationContext;
|
|
140
164
|
//#endregion
|
|
141
|
-
export { buildValidationContext as a, isNavRelation as c, getKeyProps as d, CasExhaustedError as f,
|
|
165
|
+
export { aggregateFailure as _, buildValidationContext as a, isNavRelation as c, getKeyProps as d, CasExhaustedError as f, aggregateExpressionsNotSupported as g, DbErrorCode as h, buildPatchPartial as i, TArrayPatch as l, DbError as m, ValidatorMode as n, dbPlugin as o, CasMismatchError as p, buildDbValidator as r, forceNavNonOptional as s, ValidationContext as t, TDbPatch as u, bucketTimeZoneUnavailable as v, isConflict as y };
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { TAtscriptAnnotatedType, TAtscriptTypeArray, TAtscriptTypeObject, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
|
|
2
2
|
|
|
3
3
|
//#region src/db-error.d.ts
|
|
4
|
-
type DbErrorCode = "CONFLICT" | "FK_VIOLATION" | "NOT_FOUND" | "CASCADE_CYCLE" | "INVALID_QUERY" | "DEPTH_EXCEEDED" | "VERSION_COLUMN_WRITE" | "CAS_EXHAUSTED" | "CAS_MISMATCH" | "ENC_CONFIG_MISSING" | "ENC_KEY_INVALID" | "ENC_NOT_ENCRYPTED" | "ENC_DECRYPT_FAILED" | "ENC_FIELD_FILTER" | "ENC_FIELD_SORT" | "ENC_FIELD_AGG" | "ENC_FIELD_PATCH_OP" | "GEO_INDEX_MISSING" | "GEO_NOT_SUPPORTED" | "FILTER_TYPE_MISMATCH" /** The adapter's `calendarBucketUnits()` lacks the requested unit (moost-db: 400). */ | "BUCKET_NOT_SUPPORTED" /** The engine cannot resolve the bucket's time zone — a store-configuration condition (moost-db: 501). */ | "BUCKET_TZ_UNAVAILABLE" /** A known aggregate function the adapter's `aggregateFns()` lacks (moost-db: 400). @since 0.1.136 */ | "AGG_FN_NOT_SUPPORTED"
|
|
4
|
+
type DbErrorCode = "CONFLICT" | "FK_VIOLATION" | "NOT_FOUND" | "CASCADE_CYCLE" | "INVALID_QUERY" | "DEPTH_EXCEEDED" | "VERSION_COLUMN_WRITE" | "CAS_EXHAUSTED" | "CAS_MISMATCH" | "ENC_CONFIG_MISSING" | "ENC_KEY_INVALID" | "ENC_NOT_ENCRYPTED" | "ENC_DECRYPT_FAILED" | "ENC_FIELD_FILTER" | "ENC_FIELD_SORT" | "ENC_FIELD_AGG" | "ENC_FIELD_PATCH_OP" | "GEO_INDEX_MISSING" | "GEO_NOT_SUPPORTED" | "FILTER_TYPE_MISMATCH" /** The adapter's `calendarBucketUnits()` lacks the requested unit (moost-db: 400). */ | "BUCKET_NOT_SUPPORTED" /** The engine cannot resolve the bucket's time zone — a store-configuration condition (moost-db: 501). */ | "BUCKET_TZ_UNAVAILABLE" /** A known aggregate function the adapter's `aggregateFns()` lacks (moost-db: 400). @since 0.1.136 */ | "AGG_FN_NOT_SUPPORTED"
|
|
5
|
+
/**
|
|
6
|
+
* The adapter's `supportsAggregateExpressions()` is false and the query uses
|
|
7
|
+
* arithmetic (`{ $expr }`, `{ $fn, $expr }`) in an aggregate `$select`
|
|
8
|
+
* (moost-db: 400). @since 0.1.148
|
|
9
|
+
*/
|
|
10
|
+
| "AGG_EXPR_NOT_SUPPORTED"
|
|
11
|
+
/**
|
|
12
|
+
* The adapter (or the table's wiring) cannot run a relational predicate:
|
|
13
|
+
* `supportsRelationFilters()` is false for the read/write mode, the related
|
|
14
|
+
* table lives on a different adapter, or the table was built without a
|
|
15
|
+
* `DbSpace` (moost-db: 400). @since 0.1.147
|
|
16
|
+
*/
|
|
17
|
+
| "REL_FILTER_NOT_SUPPORTED" /** The `DbSpace` was closed; the table/view handle can no longer be used (moost-db: 503). @since 0.1.148 */ | "SPACE_CLOSED" /** The adapter does not implement `insertManyIgnore` (moost-db: 400). @since 0.1.148 */ | "ON_CONFLICT_NOT_SUPPORTED" | "TX_WAIT_TIMEOUT";
|
|
5
18
|
declare class DbError extends Error {
|
|
6
19
|
readonly code: DbErrorCode;
|
|
7
20
|
readonly errors: Array<{
|
|
@@ -14,6 +27,14 @@ declare class DbError extends Error {
|
|
|
14
27
|
message: string;
|
|
15
28
|
}>, message?: string);
|
|
16
29
|
}
|
|
30
|
+
/** Whether `error` is a `DbError` with code `CONFLICT` (unique / primary-key violation). */
|
|
31
|
+
declare function isConflict(error: unknown): error is DbError;
|
|
32
|
+
/**
|
|
33
|
+
* Collapses the failures of a multi-step shutdown into one `AggregateError`
|
|
34
|
+
* (message lists every failure).
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
declare function aggregateFailure(label: string, errors: unknown[]): AggregateError;
|
|
17
38
|
/**
|
|
18
39
|
* Thrown by {@link withOptimisticRetry} when `maxAttempts` is reached
|
|
19
40
|
* without a successful CAS commit — the target row kept changing under
|
|
@@ -39,11 +60,7 @@ declare class CasMismatchError extends DbError {
|
|
|
39
60
|
/** Keys passed to `touchMany`. */
|
|
40
61
|
readonly expected: number;
|
|
41
62
|
name: string;
|
|
42
|
-
constructor(/** Rows whose primary key + version matched. */
|
|
43
|
-
|
|
44
|
-
matched: number, /** Keys passed to `touchMany`. */
|
|
45
|
-
|
|
46
|
-
expected: number);
|
|
63
|
+
constructor(/** Rows whose primary key + version matched. */matched: number, /** Keys passed to `touchMany`. */expected: number);
|
|
47
64
|
}
|
|
48
65
|
/**
|
|
49
66
|
* The engine cannot resolve a calendar bucket's time zone (`BUCKET_TZ_UNAVAILABLE`,
|
|
@@ -52,6 +69,13 @@ declare class CasMismatchError extends DbError {
|
|
|
52
69
|
* missing server time zone database — never a malformed query. Since 0.1.132.
|
|
53
70
|
*/
|
|
54
71
|
declare function bucketTimeZoneUnavailable(message: string): DbError;
|
|
72
|
+
/**
|
|
73
|
+
* The adapter's `supportsAggregateExpressions()` is false (or its SQL dialect
|
|
74
|
+
* cannot cast to a double) and the query uses arithmetic in an aggregate
|
|
75
|
+
* `$select` (`AGG_EXPR_NOT_SUPPORTED`, `path` `$select`; moost-db: 400).
|
|
76
|
+
* @since 0.1.148
|
|
77
|
+
*/
|
|
78
|
+
declare function aggregateExpressionsNotSupported(): DbError;
|
|
55
79
|
//#endregion
|
|
56
80
|
//#region src/patch/patch-types.d.ts
|
|
57
81
|
interface TArrayPatch<A extends readonly unknown[]> {
|
|
@@ -138,4 +162,4 @@ interface ValidationContext {
|
|
|
138
162
|
*/
|
|
139
163
|
declare function buildValidationContext(type: TAtscriptAnnotatedType<TAtscriptTypeObject>): ValidationContext;
|
|
140
164
|
//#endregion
|
|
141
|
-
export { buildValidationContext as a, isNavRelation as c, getKeyProps as d, CasExhaustedError as f,
|
|
165
|
+
export { aggregateFailure as _, buildValidationContext as a, isNavRelation as c, getKeyProps as d, CasExhaustedError as f, aggregateExpressionsNotSupported as g, DbErrorCode as h, buildPatchPartial as i, TArrayPatch as l, DbError as m, ValidatorMode as n, dbPlugin as o, CasMismatchError as p, buildDbValidator as r, forceNavNonOptional as s, ValidationContext as t, TDbPatch as u, bucketTimeZoneUnavailable as v, isConflict as y };
|
package/dist/validator.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_db_error = require("./db-error-
|
|
2
|
+
const require_db_error = require("./db-error-DRQH4sLY.cjs");
|
|
3
3
|
const require_object = require("./object-Djg28csK.cjs");
|
|
4
4
|
const require_ops = require("./ops.cjs");
|
|
5
|
-
const require_validator = require("./validator-
|
|
5
|
+
const require_validator = require("./validator-UcuJxHNT.cjs");
|
|
6
6
|
exports.$cas = require_ops.$cas;
|
|
7
7
|
exports.$dec = require_ops.$dec;
|
|
8
8
|
exports.$inc = require_ops.$inc;
|
package/dist/validator.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as $mul, c as $update, d as TDbFieldOp, g as separateCas, h as reconcileCas, i as $insert, l as $upsert, m as isDbFieldOp, n as $dec, o as $remove, r as $inc, s as $replace, t as $cas, u as TDbCas } from "./ops-AqhV7s9o.cjs";
|
|
2
2
|
import { a as isPlainObject, i as isEmptyObject } from "./object-CtPYTIvy.cjs";
|
|
3
|
-
import { a as buildValidationContext, c as isNavRelation, d as getKeyProps, i as buildPatchPartial, l as TArrayPatch, m as DbError, n as ValidatorMode, o as dbPlugin, r as buildDbValidator, s as forceNavNonOptional, t as ValidationContext, u as TDbPatch } from "./validator-
|
|
3
|
+
import { a as buildValidationContext, c as isNavRelation, d as getKeyProps, i as buildPatchPartial, l as TArrayPatch, m as DbError, n as ValidatorMode, o as dbPlugin, r as buildDbValidator, s as forceNavNonOptional, t as ValidationContext, u as TDbPatch } from "./validator-tBNvM1qc.cjs";
|
|
4
4
|
import { n as createDbValidatorPlugin, t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.cjs";
|
|
5
5
|
export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, DbError, type DbValidationContext, type TArrayPatch, type TDbCas, type TDbFieldOp, type TDbPatch, ValidationContext, ValidatorMode, buildDbValidator, buildPatchPartial, buildValidationContext, createDbValidatorPlugin, dbPlugin, forceNavNonOptional, getKeyProps, isDbFieldOp, isEmptyObject, isNavRelation, isPlainObject, reconcileCas, separateCas };
|
package/dist/validator.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as $mul, c as $update, d as TDbFieldOp, g as separateCas, h as reconcileCas, i as $insert, l as $upsert, m as isDbFieldOp, n as $dec, o as $remove, r as $inc, s as $replace, t as $cas, u as TDbCas } from "./ops-AqhV7s9o.mjs";
|
|
2
2
|
import { a as isPlainObject, i as isEmptyObject } from "./object-CtPYTIvy.mjs";
|
|
3
|
-
import { a as buildValidationContext, c as isNavRelation, d as getKeyProps, i as buildPatchPartial, l as TArrayPatch, m as DbError, n as ValidatorMode, o as dbPlugin, r as buildDbValidator, s as forceNavNonOptional, t as ValidationContext, u as TDbPatch } from "./validator-
|
|
3
|
+
import { a as buildValidationContext, c as isNavRelation, d as getKeyProps, i as buildPatchPartial, l as TArrayPatch, m as DbError, n as ValidatorMode, o as dbPlugin, r as buildDbValidator, s as forceNavNonOptional, t as ValidationContext, u as TDbPatch } from "./validator-tBNvM1qc.mjs";
|
|
4
4
|
import { n as createDbValidatorPlugin, t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.mjs";
|
|
5
5
|
export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, DbError, type DbValidationContext, type TArrayPatch, type TDbCas, type TDbFieldOp, type TDbPatch, ValidationContext, ValidatorMode, buildDbValidator, buildPatchPartial, buildValidationContext, createDbValidatorPlugin, dbPlugin, forceNavNonOptional, getKeyProps, isDbFieldOp, isEmptyObject, isNavRelation, isPlainObject, reconcileCas, separateCas };
|
package/dist/validator.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as DbError } from "./db-error-
|
|
1
|
+
import { r as DbError } from "./db-error-Az85UhTX.mjs";
|
|
2
2
|
import { a as isPlainObject, i as isEmptyObject } from "./object-TkiJQ-Dp.mjs";
|
|
3
3
|
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-
|
|
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-BTiIOTKP.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.
|
|
3
|
+
"version": "0.1.148",
|
|
4
4
|
"description": "Database adapter utilities for atscript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"atscript",
|
|
@@ -71,15 +71,15 @@
|
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
|
-
"@atscript/core": "^0.1.
|
|
75
|
-
"@atscript/typescript": "^0.1.
|
|
76
|
-
"@uniqu/core": "^0.1.
|
|
77
|
-
"unplugin-atscript": "^0.1.
|
|
74
|
+
"@atscript/core": "^0.1.100",
|
|
75
|
+
"@atscript/typescript": "^0.1.100",
|
|
76
|
+
"@uniqu/core": "^0.1.13",
|
|
77
|
+
"unplugin-atscript": "^0.1.100"
|
|
78
78
|
},
|
|
79
79
|
"peerDependencies": {
|
|
80
|
-
"@atscript/core": "^0.1.
|
|
81
|
-
"@atscript/typescript": "^0.1.
|
|
82
|
-
"@uniqu/core": "^0.1.
|
|
80
|
+
"@atscript/core": "^0.1.100",
|
|
81
|
+
"@atscript/typescript": "^0.1.100",
|
|
82
|
+
"@uniqu/core": "^0.1.13"
|
|
83
83
|
},
|
|
84
84
|
"scripts": {
|
|
85
85
|
"postinstall": "asc -f dts",
|