@atscript/db 0.1.147 → 0.1.149

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 (55) hide show
  1. package/dist/{agg-CV7y8nC6.d.cts → agg-42CSpGDR.d.cts} +2 -2
  2. package/dist/{agg-D5DHsAby.d.mts → agg-Wo-smrYV.d.mts} +3 -3
  3. package/dist/agg.cjs +1 -1
  4. package/dist/agg.d.cts +2 -2
  5. package/dist/agg.d.mts +2 -2
  6. package/dist/agg.mjs +1 -1
  7. package/dist/{aggregate-fns-CtsRbZn9.cjs → aggregate-fns-C-UJRobm.cjs} +46 -7
  8. package/dist/{aggregate-fns-C0BymEqa.mjs → aggregate-fns-CyaZyb9I.mjs} +35 -8
  9. package/dist/aggregate-rules-D_bsCpUI.cjs +26 -0
  10. package/dist/aggregate-rules-jdPrxqWa.mjs +15 -0
  11. package/dist/{buckets-DYopfd2Y.d.mts → buckets-CNdTOnei.d.mts} +312 -18
  12. package/dist/{buckets-CjdPipCC.d.cts → buckets-DJiYlMXc.d.cts} +312 -18
  13. package/dist/{column-diff-Dt7EDJsA.cjs → column-diff-CUU4GvYg.cjs} +681 -87
  14. package/dist/{column-diff-CO06iQvI.mjs → column-diff-Cp6ZoyRE.mjs} +678 -96
  15. package/dist/{db-error-D5uilS_A.mjs → db-error-Az85UhTX.mjs} +32 -1
  16. package/dist/{db-error-DTkkeu5b.cjs → db-error-DRQH4sLY.cjs} +55 -0
  17. package/dist/{fk-diff-BtOmL4OW.d.mts → fk-diff-BQ4krij8.d.cts} +1 -1
  18. package/dist/{fk-diff-DLqwVkKG.d.cts → fk-diff-DsaIijVX.d.mts} +1 -1
  19. package/dist/index.cjs +70 -5
  20. package/dist/index.d.cts +58 -13
  21. package/dist/index.d.mts +58 -13
  22. package/dist/index.mjs +64 -6
  23. package/dist/{nested-writer-SqtYJHF0.cjs → nested-writer-BUQvk6QT.cjs} +68 -2
  24. package/dist/{nested-writer-D35UsDBT.mjs → nested-writer-CUBoq1ZO.mjs} +57 -3
  25. package/dist/numeric-operand-B1jKH7x5.mjs +21 -0
  26. package/dist/numeric-operand-DKfiRLYp.cjs +26 -0
  27. package/dist/ops.cjs +1 -1
  28. package/dist/ops.mjs +1 -1
  29. package/dist/plugin.cjs +36 -9
  30. package/dist/plugin.mjs +36 -9
  31. package/dist/rel.cjs +2 -2
  32. package/dist/rel.d.cts +2 -2
  33. package/dist/rel.d.mts +2 -2
  34. package/dist/rel.mjs +2 -2
  35. package/dist/{relation-helpers-C2bLtE-t.d.mts → relation-helpers-Ba0v49sn.d.mts} +1 -1
  36. package/dist/{relation-helpers-DH3LvwLV.d.cts → relation-helpers-kX7jjgME.d.cts} +1 -1
  37. package/dist/{relation-loader-C0qE8xgR.mjs → relation-loader-ByY1Byrl.mjs} +1 -1
  38. package/dist/{relation-loader-BFhVuJ-B.cjs → relation-loader-D8OrdH-r.cjs} +1 -1
  39. package/dist/shared.cjs +3 -0
  40. package/dist/shared.d.cts +12 -1
  41. package/dist/shared.d.mts +12 -1
  42. package/dist/shared.mjs +2 -1
  43. package/dist/sync.cjs +2 -2
  44. package/dist/sync.d.cts +2 -2
  45. package/dist/sync.d.mts +2 -2
  46. package/dist/sync.mjs +2 -2
  47. package/dist/{validator-Clu2q_7z.mjs → validator-BTiIOTKP.mjs} +9 -3
  48. package/dist/{validator-CVS-onRg.cjs → validator-UcuJxHNT.cjs} +8 -2
  49. package/dist/{validator-CMnTI6r7.d.cts → validator-tBNvM1qc.d.cts} +23 -2
  50. package/dist/{validator-CMnTI6r7.d.mts → validator-tBNvM1qc.d.mts} +23 -2
  51. package/dist/validator.cjs +2 -2
  52. package/dist/validator.d.cts +1 -1
  53. package/dist/validator.d.mts +1 -1
  54. package/dist/validator.mjs +2 -2
  55. package/package.json +8 -8
package/dist/plugin.cjs CHANGED
@@ -33,8 +33,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
  enumerable: true
34
34
  }) : target, mod));
35
35
  //#endregion
36
- const require_aggregate_fns = require("./aggregate-fns-CtsRbZn9.cjs");
36
+ const require_aggregate_fns = require("./aggregate-fns-C-UJRobm.cjs");
37
37
  const require_derived_rules = require("./derived-rules-YstgIxG-.cjs");
38
+ const require_numeric_operand = require("./numeric-operand-DKfiRLYp.cjs");
38
39
  require("./consts-BzRfCcH2.cjs");
39
40
  const require_validation_utils = require("./validation-utils-Da2GjobR.cjs");
40
41
  let node_path = require("node:path");
@@ -905,12 +906,6 @@ const EXCLUSIVE_WITH = [
905
906
  "db.json",
906
907
  "db.ignore"
907
908
  ].map((key) => ({ key }));
908
- /** Primitive tags of timestamps (MySQL may store them as native `TIMESTAMP`). */
909
- const TIMESTAMP_TAGS = [
910
- "timestamp",
911
- "created",
912
- "updated"
913
- ];
914
909
  /** The `@db.compute` expression token of a prop, if any. */
915
910
  function computeArg(prop) {
916
911
  return prop?.annotations?.find((a) => a.name === "db.compute")?.args[0];
@@ -936,8 +931,10 @@ function operandProblem(prop, doc) {
936
931
  const leaf = def && (0, _atscript_core.isRef)(def) ? doc.unwindType(def.id, def.chain)?.def : def;
937
932
  const base = require_validation_utils.primitiveBaseType(leaf);
938
933
  if (base === void 0) return void 0;
939
- if (base !== "number") return `is ${base === "decimal" ? "a decimal" : `a ${base}`}`;
940
- if ((0, _atscript_core.isPrimitive)(leaf) && TIMESTAMP_TAGS.some((t) => leaf.tags.has(t))) return "is a timestamp";
934
+ return require_numeric_operand.numericTypeProblem({
935
+ base,
936
+ tags: (0, _atscript_core.isPrimitive)(leaf) ? leaf.tags : void 0
937
+ });
941
938
  }
942
939
  /** VC6 — whether an expression may be NULL (`/` by zero, an optional operand). */
943
940
  function exprNullable(node, props) {
@@ -1086,6 +1083,31 @@ const dbIndexAnnotations = { index: {
1086
1083
  } };
1087
1084
  //#endregion
1088
1085
  //#region src/plugin/annotations/rel.ts
1086
+ /**
1087
+ * X2b: on a `@db.table` a foreign key is a real constraint — one column of a
1088
+ * composite primary key is not unique on its own. Columns that together cover
1089
+ * the whole key (same alias, same target, each naming a top-level key column)
1090
+ * are a valid composite foreign key. Returns whether `token`'s FK is covered
1091
+ * (or the rule does not apply). Cheap checks run before the sibling scan.
1092
+ */
1093
+ function checkCompositeFkCoverage(token, alias, refTypeName, targetStruct, targetProp) {
1094
+ if (targetProp.countAnnotations("db.index.unique") > 0) return true;
1095
+ const pk = [...targetStruct.props.entries()].filter(([, p]) => p.countAnnotations("meta.id") > 0).map(([name]) => name);
1096
+ if (pk.length <= 1) return true;
1097
+ const hostStruct = require_validation_utils.getParentStruct(token);
1098
+ const owner = require_validation_utils.getDbTableOwner(token);
1099
+ if (!hostStruct || owner === void 0 || !isDbTable(owner)) return true;
1100
+ const covered = /* @__PURE__ */ new Set();
1101
+ for (const [, sibling] of hostStruct.props) {
1102
+ if (sibling.countAnnotations("db.rel.FK") === 0) continue;
1103
+ if (require_validation_utils.getAnnotationAlias(sibling, "db.rel.FK") !== alias) continue;
1104
+ const siblingDef = sibling.getDefinition();
1105
+ if (siblingDef && (0, _atscript_core.isRef)(siblingDef) && siblingDef.id === refTypeName) {
1106
+ if (siblingDef.chain.length === 1) covered.add(siblingDef.chain[0].text);
1107
+ }
1108
+ }
1109
+ return pk.every((name) => covered.has(name));
1110
+ }
1089
1111
  const dbRelAnnotations = { rel: {
1090
1112
  FK: new _atscript_core.AnnotationSpec({
1091
1113
  description: "Declares a foreign key reference on this field. The field must use a chain reference type (e.g., `User.id`) whose target is a primary key (`@meta.id`) or unique (`@db.index.unique`) field.\n\n**Dual role:**\n- On a `@db.table` interface, `@db.rel.FK` additionally drives DB-relation semantics — relation loading with `@db.rel.to` / `@db.rel.from`, junction pairing with `@db.rel.via`, etc.\n- On any other interface (value-help sources, WF forms, plain interfaces), `@db.rel.FK` acts purely as the value-help indicator: the client-side picker resolver uses it to decide which fields render a value-help picker. The target's `@db.http.path` (stamped by its readable controller) supplies the picker URL.\n- In `/meta` (and `/meta/form/:name`) the marker is inherited through reference chains: a field declared as `code: Issue.code` where `Issue.code: Dict.code` carries `@db.rel.FK` is served with `ref` pointing at the terminal field (`Dict.code`) and `db.rel.FK: true`, so view fields get the dictionary picker. Runtime metadata is untouched.\n\n**Example:**\n```atscript\n@db.rel.FK\nauthorId: User.id\n\n// With alias (required when multiple FKs point to the same type)\n@db.rel.FK \"author\"\nauthorId: User.id\n```\n",
@@ -1131,6 +1153,11 @@ const dbRelAnnotations = { rel: {
1131
1153
  severity: 1,
1132
1154
  range: token.range
1133
1155
  });
1156
+ if (!checkCompositeFkCoverage(token, alias, refTypeName, struct, targetProp)) errors.push({
1157
+ message: `@db.rel.FK target '${refTypeName}.${chainFields.join(".")}' is one column of a composite primary key — a foreign key must reference a unique column; for value help without a constraint use @ui.valueHelp`,
1158
+ severity: 1,
1159
+ range: token.range
1160
+ });
1134
1161
  const propDef = targetProp.getDefinition();
1135
1162
  if (propDef && (0, _atscript_core.isRef)(propDef)) {
1136
1163
  const propUnwound = targetUnwound.doc.unwindType(propDef.id, propDef.chain);
package/dist/plugin.mjs CHANGED
@@ -1,5 +1,6 @@
1
- import { a as SUPPORTED_AGGREGATE_FNS, i as NULL_WHEN_EMPTY_AGGREGATE_FNS, t as AGG_ANNOTATIONS } from "./aggregate-fns-C0BymEqa.mjs";
1
+ import { i as NULL_WHEN_EMPTY_AGGREGATE_FNS, o as SUPPORTED_AGGREGATE_FNS, t as AGG_ANNOTATIONS } from "./aggregate-fns-CyaZyb9I.mjs";
2
2
  import { n as DERIVED_INCOMPATIBLE, r as JSON_LEAF_TYPES, t as DB_ENTITY_ANNOTATIONS } from "./derived-rules-0sKn4f5C.mjs";
3
+ import { t as numericTypeProblem } from "./numeric-operand-B1jKH7x5.mjs";
3
4
  import "./consts-C_-5_pFq.mjs";
4
5
  import { S as validateSiblingStringField, _ as getParentTypeName, a as hasAnyViewAnnotation, b as validateExclusiveWith, d as viewJoins, f as viewScopeTypes, g as getParentStruct, h as getNavTargetTypeName, i as forEachFieldRef, l as validateQueryScope, m as getDbTableOwner, n as findFKFieldsPointingTo, o as isAliasDecl, p as getAnnotationAlias, r as findViewCycle, s as isDbSourceDecl, t as earlierJoinTargets, u as validateRefArgument, v as primitiveBaseType, x as validateFieldBaseType, y as refActionAnnotation } from "./validation-utils-Dq0uZ7ef.mjs";
5
6
  import path from "node:path";
@@ -869,12 +870,6 @@ const EXCLUSIVE_WITH = [
869
870
  "db.json",
870
871
  "db.ignore"
871
872
  ].map((key) => ({ key }));
872
- /** Primitive tags of timestamps (MySQL may store them as native `TIMESTAMP`). */
873
- const TIMESTAMP_TAGS = [
874
- "timestamp",
875
- "created",
876
- "updated"
877
- ];
878
873
  /** The `@db.compute` expression token of a prop, if any. */
879
874
  function computeArg(prop) {
880
875
  return prop?.annotations?.find((a) => a.name === "db.compute")?.args[0];
@@ -900,8 +895,10 @@ function operandProblem(prop, doc) {
900
895
  const leaf = def && isRef(def) ? doc.unwindType(def.id, def.chain)?.def : def;
901
896
  const base = primitiveBaseType(leaf);
902
897
  if (base === void 0) return void 0;
903
- if (base !== "number") return `is ${base === "decimal" ? "a decimal" : `a ${base}`}`;
904
- if (isPrimitive(leaf) && TIMESTAMP_TAGS.some((t) => leaf.tags.has(t))) return "is a timestamp";
898
+ return numericTypeProblem({
899
+ base,
900
+ tags: isPrimitive(leaf) ? leaf.tags : void 0
901
+ });
905
902
  }
906
903
  /** VC6 — whether an expression may be NULL (`/` by zero, an optional operand). */
907
904
  function exprNullable(node, props) {
@@ -1050,6 +1047,31 @@ const dbIndexAnnotations = { index: {
1050
1047
  } };
1051
1048
  //#endregion
1052
1049
  //#region src/plugin/annotations/rel.ts
1050
+ /**
1051
+ * X2b: on a `@db.table` a foreign key is a real constraint — one column of a
1052
+ * composite primary key is not unique on its own. Columns that together cover
1053
+ * the whole key (same alias, same target, each naming a top-level key column)
1054
+ * are a valid composite foreign key. Returns whether `token`'s FK is covered
1055
+ * (or the rule does not apply). Cheap checks run before the sibling scan.
1056
+ */
1057
+ function checkCompositeFkCoverage(token, alias, refTypeName, targetStruct, targetProp) {
1058
+ if (targetProp.countAnnotations("db.index.unique") > 0) return true;
1059
+ const pk = [...targetStruct.props.entries()].filter(([, p]) => p.countAnnotations("meta.id") > 0).map(([name]) => name);
1060
+ if (pk.length <= 1) return true;
1061
+ const hostStruct = getParentStruct(token);
1062
+ const owner = getDbTableOwner(token);
1063
+ if (!hostStruct || owner === void 0 || !isDbTable(owner)) return true;
1064
+ const covered = /* @__PURE__ */ new Set();
1065
+ for (const [, sibling] of hostStruct.props) {
1066
+ if (sibling.countAnnotations("db.rel.FK") === 0) continue;
1067
+ if (getAnnotationAlias(sibling, "db.rel.FK") !== alias) continue;
1068
+ const siblingDef = sibling.getDefinition();
1069
+ if (siblingDef && isRef(siblingDef) && siblingDef.id === refTypeName) {
1070
+ if (siblingDef.chain.length === 1) covered.add(siblingDef.chain[0].text);
1071
+ }
1072
+ }
1073
+ return pk.every((name) => covered.has(name));
1074
+ }
1053
1075
  const dbRelAnnotations = { rel: {
1054
1076
  FK: new AnnotationSpec({
1055
1077
  description: "Declares a foreign key reference on this field. The field must use a chain reference type (e.g., `User.id`) whose target is a primary key (`@meta.id`) or unique (`@db.index.unique`) field.\n\n**Dual role:**\n- On a `@db.table` interface, `@db.rel.FK` additionally drives DB-relation semantics — relation loading with `@db.rel.to` / `@db.rel.from`, junction pairing with `@db.rel.via`, etc.\n- On any other interface (value-help sources, WF forms, plain interfaces), `@db.rel.FK` acts purely as the value-help indicator: the client-side picker resolver uses it to decide which fields render a value-help picker. The target's `@db.http.path` (stamped by its readable controller) supplies the picker URL.\n- In `/meta` (and `/meta/form/:name`) the marker is inherited through reference chains: a field declared as `code: Issue.code` where `Issue.code: Dict.code` carries `@db.rel.FK` is served with `ref` pointing at the terminal field (`Dict.code`) and `db.rel.FK: true`, so view fields get the dictionary picker. Runtime metadata is untouched.\n\n**Example:**\n```atscript\n@db.rel.FK\nauthorId: User.id\n\n// With alias (required when multiple FKs point to the same type)\n@db.rel.FK \"author\"\nauthorId: User.id\n```\n",
@@ -1095,6 +1117,11 @@ const dbRelAnnotations = { rel: {
1095
1117
  severity: 1,
1096
1118
  range: token.range
1097
1119
  });
1120
+ if (!checkCompositeFkCoverage(token, alias, refTypeName, struct, targetProp)) errors.push({
1121
+ message: `@db.rel.FK target '${refTypeName}.${chainFields.join(".")}' is one column of a composite primary key — a foreign key must reference a unique column; for value help without a constraint use @ui.valueHelp`,
1122
+ severity: 1,
1123
+ range: token.range
1124
+ });
1098
1125
  const propDef = targetProp.getDefinition();
1099
1126
  if (propDef && isRef(propDef)) {
1100
1127
  const propUnwound = targetUnwound.doc.unwindType(propDef.id, propDef.chain);
package/dist/rel.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_nested_writer = require("./nested-writer-SqtYJHF0.cjs");
3
- const require_relation_loader = require("./relation-loader-BFhVuJ-B.cjs");
2
+ const require_nested_writer = require("./nested-writer-BUQvk6QT.cjs");
3
+ const require_relation_loader = require("./relation-loader-D8OrdH-r.cjs");
4
4
  exports.applyPatchNestedTo = require_nested_writer.applyPatchNestedTo;
5
5
  exports.batchInsertNestedFrom = require_nested_writer.batchInsertNestedFrom;
6
6
  exports.batchInsertNestedTo = require_nested_writer.batchInsertNestedTo;
package/dist/rel.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { Fn as TGenericLogger, H as TDbForeignKey, Nt as TWriteTableResolver, Ot as TTableResolver, Rt as TableMetadata, Ut as BaseDbAdapter, X as TDbRelation, m as AtscriptDbWritable, p as AtscriptDbTableLike } from "./buckets-CjdPipCC.cjs";
1
+ import { Jt as BaseDbAdapter, Nt as TTableResolver, Rt as TWriteTableResolver, U as TDbForeignKey, Ut as TableMetadata, Vn as TGenericLogger, et as TDbRelation, h as AtscriptDbWritable, m as AtscriptDbTableLike } from "./buckets-DJiYlMXc.cjs";
2
2
  import { t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.cjs";
3
- import { n as findRemoteFK, r as resolveRelationTargetTable, t as findFKForRelation } from "./relation-helpers-DH3LvwLV.cjs";
3
+ import { n as findRemoteFK, r as resolveRelationTargetTable, t as findFKForRelation } from "./relation-helpers-kX7jjgME.cjs";
4
4
  import { FilterExpr, WithRelation } from "@uniqu/core";
5
5
  import { Validator } from "@atscript/typescript/utils";
6
6
 
package/dist/rel.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { Fn as TGenericLogger, H as TDbForeignKey, Nt as TWriteTableResolver, Ot as TTableResolver, Rt as TableMetadata, Ut as BaseDbAdapter, X as TDbRelation, m as AtscriptDbWritable, p as AtscriptDbTableLike } from "./buckets-DYopfd2Y.mjs";
1
+ import { Jt as BaseDbAdapter, Nt as TTableResolver, Rt as TWriteTableResolver, U as TDbForeignKey, Ut as TableMetadata, Vn as TGenericLogger, et as TDbRelation, h as AtscriptDbWritable, m as AtscriptDbTableLike } from "./buckets-CNdTOnei.mjs";
2
2
  import { t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.mjs";
3
- import { n as findRemoteFK, r as resolveRelationTargetTable, t as findFKForRelation } from "./relation-helpers-C2bLtE-t.mjs";
3
+ import { n as findRemoteFK, r as resolveRelationTargetTable, t as findFKForRelation } from "./relation-helpers-Ba0v49sn.mjs";
4
4
  import { Validator } from "@atscript/typescript/utils";
5
5
  import { FilterExpr, WithRelation } from "@uniqu/core";
6
6
 
package/dist/rel.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { t as loadRelationsImpl } from "./relation-loader-C0qE8xgR.mjs";
2
- import { I as findFKForRelation, L as findRemoteFK, R as resolveRelationTargetTable, a as batchPatchNestedFrom, c as batchReplaceNestedFrom, d as checkDepthOverflow, f as planNestedFromVia, h as validateBatch, i as batchInsertNestedVia, l as batchReplaceNestedTo, m as preValidateNestedFrom, n as batchInsertNestedFrom, o as batchPatchNestedTo, p as planPatchNestedTo, r as batchInsertNestedTo, s as batchPatchNestedVia, t as applyPatchNestedTo, u as batchReplaceNestedVia } from "./nested-writer-D35UsDBT.mjs";
1
+ import { t as loadRelationsImpl } from "./relation-loader-ByY1Byrl.mjs";
2
+ import { L as findFKForRelation, R as findRemoteFK, a as batchPatchNestedFrom, c as batchReplaceNestedFrom, d as checkDepthOverflow, f as planNestedFromVia, h as validateBatch, i as batchInsertNestedVia, l as batchReplaceNestedTo, m as preValidateNestedFrom, n as batchInsertNestedFrom, o as batchPatchNestedTo, p as planPatchNestedTo, r as batchInsertNestedTo, s as batchPatchNestedVia, t as applyPatchNestedTo, u as batchReplaceNestedVia, z as resolveRelationTargetTable } from "./nested-writer-CUBoq1ZO.mjs";
3
3
  export { applyPatchNestedTo, batchInsertNestedFrom, batchInsertNestedTo, batchInsertNestedVia, batchPatchNestedFrom, batchPatchNestedTo, batchPatchNestedVia, batchReplaceNestedFrom, batchReplaceNestedTo, batchReplaceNestedVia, checkDepthOverflow, findFKForRelation, findRemoteFK, loadRelationsImpl, planNestedFromVia, planPatchNestedTo, preValidateNestedFrom, resolveRelationTargetTable, validateBatch };
@@ -1,4 +1,4 @@
1
- import { H as TDbForeignKey, X as TDbRelation } from "./buckets-DYopfd2Y.mjs";
1
+ import { U as TDbForeignKey, et as TDbRelation } from "./buckets-CNdTOnei.mjs";
2
2
  import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
3
3
 
4
4
  //#region src/rel/relation-helpers.d.ts
@@ -1,4 +1,4 @@
1
- import { H as TDbForeignKey, X as TDbRelation } from "./buckets-CjdPipCC.cjs";
1
+ import { U as TDbForeignKey, et as TDbRelation } from "./buckets-DJiYlMXc.cjs";
2
2
  import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
3
3
 
4
4
  //#region src/rel/relation-helpers.d.ts
@@ -1,4 +1,4 @@
1
- import { I as findFKForRelation, L as findRemoteFK, M as relationStaticFilter, P as compositeKey, R as resolveRelationTargetTable, w as andFilters, z as slicePerGroup } from "./nested-writer-D35UsDBT.mjs";
1
+ import { B as slicePerGroup, F as compositeKey, L as findFKForRelation, N as relationStaticFilter, R as findRemoteFK, T as andFilters, z as resolveRelationTargetTable } from "./nested-writer-CUBoq1ZO.mjs";
2
2
  //#region \0rolldown/runtime.js
3
3
  var __defProp = Object.defineProperty;
4
4
  var __exportAll = (all, no_symbols) => {
@@ -1,4 +1,4 @@
1
- const require_nested_writer = require("./nested-writer-SqtYJHF0.cjs");
1
+ const require_nested_writer = require("./nested-writer-BUQvk6QT.cjs");
2
2
  //#region src/rel/relation-loader.ts
3
3
  var relation_loader_exports = /* @__PURE__ */ require("./plugin.cjs").__exportAll({
4
4
  ensureSelectIncludesFields: () => ensureSelectIncludesFields,
package/dist/shared.cjs CHANGED
@@ -1,5 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_aggregate_rules = require("./aggregate-rules-D_bsCpUI.cjs");
2
3
  const require_validation_utils = require("./validation-utils-Da2GjobR.cjs");
4
+ exports.NOT_DIMENSION_REASON = require_aggregate_rules.NOT_DIMENSION_REASON;
3
5
  exports.earlierJoinTargets = require_validation_utils.earlierJoinTargets;
4
6
  exports.findFKFieldsPointingTo = require_validation_utils.findFKFieldsPointingTo;
5
7
  exports.findViewCycle = require_validation_utils.findViewCycle;
@@ -12,6 +14,7 @@ exports.getParentTypeName = require_validation_utils.getParentTypeName;
12
14
  exports.hasAnyViewAnnotation = require_validation_utils.hasAnyViewAnnotation;
13
15
  exports.isAliasDecl = require_validation_utils.isAliasDecl;
14
16
  exports.isDbSourceDecl = require_validation_utils.isDbSourceDecl;
17
+ exports.isStrictAggregateStruct = require_aggregate_rules.isStrictAggregateStruct;
15
18
  exports.joinTargets = require_validation_utils.joinTargets;
16
19
  exports.primitiveBaseType = require_validation_utils.primitiveBaseType;
17
20
  exports.refActionAnnotation = require_validation_utils.refActionAnnotation;
package/dist/shared.d.cts CHANGED
@@ -128,4 +128,15 @@ declare function validateQueryScope(queryToken: Token, scope: TQueryScope, doc:
128
128
  */
129
129
  declare function forEachFieldRef(expr: SemanticQueryExprNode, fn: (ref: SemanticQueryFieldRefNode) => void): void;
130
130
  //#endregion
131
- export { TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, isAliasDecl, isDbSourceDecl, joinTargets, primitiveBaseType, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
131
+ //#region src/shared/aggregate-rules.d.ts
132
+ /** `reason` of a `$groupBy` / bucket rejection for a field outside a strict aggregate table's dimensions. */
133
+ declare const NOT_DIMENSION_REASON = "not a dimension";
134
+ /**
135
+ * Editor-time twin of the runtime `isStrictTable`: a table whose structure
136
+ * declares any `@db.column.dimension` or `@db.column.measure` is strict —
137
+ * only dimensions can be grouped by.
138
+ * @since 0.1.148
139
+ */
140
+ declare function isStrictAggregateStruct(struct: SemanticStructureNode): boolean;
141
+ //#endregion
142
+ export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
package/dist/shared.d.mts CHANGED
@@ -128,4 +128,15 @@ declare function validateQueryScope(queryToken: Token, scope: TQueryScope, doc:
128
128
  */
129
129
  declare function forEachFieldRef(expr: SemanticQueryExprNode, fn: (ref: SemanticQueryFieldRefNode) => void): void;
130
130
  //#endregion
131
- export { TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, isAliasDecl, isDbSourceDecl, joinTargets, primitiveBaseType, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
131
+ //#region src/shared/aggregate-rules.d.ts
132
+ /** `reason` of a `$groupBy` / bucket rejection for a field outside a strict aggregate table's dimensions. */
133
+ declare const NOT_DIMENSION_REASON = "not a dimension";
134
+ /**
135
+ * Editor-time twin of the runtime `isStrictTable`: a table whose structure
136
+ * declares any `@db.column.dimension` or `@db.column.measure` is strict —
137
+ * only dimensions can be grouped by.
138
+ * @since 0.1.148
139
+ */
140
+ declare function isStrictAggregateStruct(struct: SemanticStructureNode): boolean;
141
+ //#endregion
142
+ export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
package/dist/shared.mjs CHANGED
@@ -1,2 +1,3 @@
1
+ import { n as isStrictAggregateStruct, t as NOT_DIMENSION_REASON } from "./aggregate-rules-jdPrxqWa.mjs";
1
2
  import { S as validateSiblingStringField, _ as getParentTypeName, a as hasAnyViewAnnotation, b as validateExclusiveWith, c as joinTargets, d as viewJoins, f as viewScopeTypes, g as getParentStruct, h as getNavTargetTypeName, i as forEachFieldRef, l as validateQueryScope, m as getDbTableOwner, n as findFKFieldsPointingTo, o as isAliasDecl, p as getAnnotationAlias, r as findViewCycle, s as isDbSourceDecl, t as earlierJoinTargets, u as validateRefArgument, v as primitiveBaseType, x as validateFieldBaseType, y as refActionAnnotation } from "./validation-utils-Dq0uZ7ef.mjs";
2
- export { earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, isAliasDecl, isDbSourceDecl, joinTargets, primitiveBaseType, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
3
+ export { NOT_DIMENSION_REASON, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
package/dist/sync.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_db_error = require("./db-error-DTkkeu5b.cjs");
3
- const require_column_diff = require("./column-diff-Dt7EDJsA.cjs");
2
+ const require_db_error = require("./db-error-DRQH4sLY.cjs");
3
+ const require_column_diff = require("./column-diff-CUU4GvYg.cjs");
4
4
  //#region src/schema/table-option-diff.ts
5
5
  /**
6
6
  * Computes the difference between desired and existing table options.
package/dist/sync.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { Dt as TTableOptionDiff, Fn as TGenericLogger, Gt as DbSpace, J as TDbObjectKind, St as TReferencingForeignKey, V as TDbFieldMeta, dt as TExistingForeignKey, ft as TExistingTableOption, lt as TEnsureTableOptions, st as TDerivedChangeReason, xt as TPrimaryKeyChange } from "./buckets-CjdPipCC.cjs";
2
- import { _ as computeTableSnapshot, a as hasForeignKeyChanges, b as snapshotToExistingTableOptions, c as TFieldSnapshot, d as TViewColumnSnapshot, f as TViewJoinSnapshot, g as computeTableHash, h as computeSchemaHash, i as fkKey, l as TForeignKeySnapshot, m as canonicalizeQueryNode, n as computeForeignKeyDiff, o as computeColumnDiff, p as TViewSnapshot, t as TForeignKeyDiff, u as TTableSnapshot, v as computeViewSnapshot, y as snapshotToExistingColumns } from "./fk-diff-DLqwVkKG.cjs";
1
+ import { Dt as TReferencingForeignKey, Et as TPrimaryKeyChange, H as TDbFieldMeta, Mt as TTableOptionDiff, Q as TDbObjectKind, Vn as TGenericLogger, Xt as DbSpace, dt as TDerivedChangeReason, gt as TExistingTableOption, ht as TExistingForeignKey, pt as TEnsureTableOptions } from "./buckets-DJiYlMXc.cjs";
2
+ import { _ as computeTableSnapshot, a as hasForeignKeyChanges, b as snapshotToExistingTableOptions, c as TFieldSnapshot, d as TViewColumnSnapshot, f as TViewJoinSnapshot, g as computeTableHash, h as computeSchemaHash, i as fkKey, l as TForeignKeySnapshot, m as canonicalizeQueryNode, n as computeForeignKeyDiff, o as computeColumnDiff, p as TViewSnapshot, t as TForeignKeyDiff, u as TTableSnapshot, v as computeViewSnapshot, y as snapshotToExistingColumns } from "./fk-diff-BQ4krij8.cjs";
3
3
  import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
4
4
 
5
5
  //#region src/schema/sync-entry.d.ts
package/dist/sync.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { Dt as TTableOptionDiff, Fn as TGenericLogger, Gt as DbSpace, J as TDbObjectKind, St as TReferencingForeignKey, V as TDbFieldMeta, dt as TExistingForeignKey, ft as TExistingTableOption, lt as TEnsureTableOptions, st as TDerivedChangeReason, xt as TPrimaryKeyChange } from "./buckets-DYopfd2Y.mjs";
2
- import { _ as computeTableSnapshot, a as hasForeignKeyChanges, b as snapshotToExistingTableOptions, c as TFieldSnapshot, d as TViewColumnSnapshot, f as TViewJoinSnapshot, g as computeTableHash, h as computeSchemaHash, i as fkKey, l as TForeignKeySnapshot, m as canonicalizeQueryNode, n as computeForeignKeyDiff, o as computeColumnDiff, p as TViewSnapshot, t as TForeignKeyDiff, u as TTableSnapshot, v as computeViewSnapshot, y as snapshotToExistingColumns } from "./fk-diff-BtOmL4OW.mjs";
1
+ import { Dt as TReferencingForeignKey, Et as TPrimaryKeyChange, H as TDbFieldMeta, Mt as TTableOptionDiff, Q as TDbObjectKind, Vn as TGenericLogger, Xt as DbSpace, dt as TDerivedChangeReason, gt as TExistingTableOption, ht as TExistingForeignKey, pt as TEnsureTableOptions } from "./buckets-CNdTOnei.mjs";
2
+ import { _ as computeTableSnapshot, a as hasForeignKeyChanges, b as snapshotToExistingTableOptions, c as TFieldSnapshot, d as TViewColumnSnapshot, f as TViewJoinSnapshot, g as computeTableHash, h as computeSchemaHash, i as fkKey, l as TForeignKeySnapshot, m as canonicalizeQueryNode, n as computeForeignKeyDiff, o as computeColumnDiff, p as TViewSnapshot, t as TForeignKeyDiff, u as TTableSnapshot, v as computeViewSnapshot, y as snapshotToExistingColumns } from "./fk-diff-DsaIijVX.mjs";
3
3
  import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
4
4
 
5
5
  //#region src/schema/sync-entry.d.ts
package/dist/sync.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { r as DbError } from "./db-error-D5uilS_A.mjs";
2
- import { a as computeTableHash, c as snapshotToExistingColumns, d as computeForeignKeyDiff, f as fkColumns, i as computeSchemaHash, l as snapshotToExistingTableOptions, lt as NoopLogger, m as hasForeignKeyChanges, o as computeTableSnapshot, p as fkKey, r as canonicalizeQueryNode, rt as aliasTargetOf, s as computeViewSnapshot, t as computeColumnDiff, u as viewSnapshotSources } from "./column-diff-CO06iQvI.mjs";
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.
@@ -1,5 +1,5 @@
1
- import { i as DepthLimitExceededError } from "./db-error-D5uilS_A.mjs";
2
- import { isDbFieldOp } from "./ops.mjs";
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
- if (isDbFieldOp(value)) {
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-DTkkeu5b.cjs");
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
- if (require_ops.isDbFieldOp(value)) {
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) {
@@ -2,13 +2,19 @@ import { TAtscriptAnnotatedType, TAtscriptTypeArray, TAtscriptTypeObject, TValid
2
2
 
3
3
  //#region src/db-error.d.ts
4
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"
5
11
  /**
6
12
  * The adapter (or the table's wiring) cannot run a relational predicate:
7
13
  * `supportsRelationFilters()` is false for the read/write mode, the related
8
14
  * table lives on a different adapter, or the table was built without a
9
15
  * `DbSpace` (moost-db: 400). @since 0.1.147
10
16
  */
11
- | "REL_FILTER_NOT_SUPPORTED" | "TX_WAIT_TIMEOUT";
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";
12
18
  declare class DbError extends Error {
13
19
  readonly code: DbErrorCode;
14
20
  readonly errors: Array<{
@@ -21,6 +27,14 @@ declare class DbError extends Error {
21
27
  message: string;
22
28
  }>, message?: string);
23
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;
24
38
  /**
25
39
  * Thrown by {@link withOptimisticRetry} when `maxAttempts` is reached
26
40
  * without a successful CAS commit — the target row kept changing under
@@ -55,6 +69,13 @@ declare class CasMismatchError extends DbError {
55
69
  * missing server time zone database — never a malformed query. Since 0.1.132.
56
70
  */
57
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;
58
79
  //#endregion
59
80
  //#region src/patch/patch-types.d.ts
60
81
  interface TArrayPatch<A extends readonly unknown[]> {
@@ -141,4 +162,4 @@ interface ValidationContext {
141
162
  */
142
163
  declare function buildValidationContext(type: TAtscriptAnnotatedType<TAtscriptTypeObject>): ValidationContext;
143
164
  //#endregion
144
- export { buildValidationContext as a, isNavRelation as c, getKeyProps as d, CasExhaustedError as f, bucketTimeZoneUnavailable 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 };
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 };
@@ -2,13 +2,19 @@ import { TAtscriptAnnotatedType, TAtscriptTypeArray, TAtscriptTypeObject, TValid
2
2
 
3
3
  //#region src/db-error.d.ts
4
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"
5
11
  /**
6
12
  * The adapter (or the table's wiring) cannot run a relational predicate:
7
13
  * `supportsRelationFilters()` is false for the read/write mode, the related
8
14
  * table lives on a different adapter, or the table was built without a
9
15
  * `DbSpace` (moost-db: 400). @since 0.1.147
10
16
  */
11
- | "REL_FILTER_NOT_SUPPORTED" | "TX_WAIT_TIMEOUT";
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";
12
18
  declare class DbError extends Error {
13
19
  readonly code: DbErrorCode;
14
20
  readonly errors: Array<{
@@ -21,6 +27,14 @@ declare class DbError extends Error {
21
27
  message: string;
22
28
  }>, message?: string);
23
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;
24
38
  /**
25
39
  * Thrown by {@link withOptimisticRetry} when `maxAttempts` is reached
26
40
  * without a successful CAS commit — the target row kept changing under
@@ -55,6 +69,13 @@ declare class CasMismatchError extends DbError {
55
69
  * missing server time zone database — never a malformed query. Since 0.1.132.
56
70
  */
57
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;
58
79
  //#endregion
59
80
  //#region src/patch/patch-types.d.ts
60
81
  interface TArrayPatch<A extends readonly unknown[]> {
@@ -141,4 +162,4 @@ interface ValidationContext {
141
162
  */
142
163
  declare function buildValidationContext(type: TAtscriptAnnotatedType<TAtscriptTypeObject>): ValidationContext;
143
164
  //#endregion
144
- export { buildValidationContext as a, isNavRelation as c, getKeyProps as d, CasExhaustedError as f, bucketTimeZoneUnavailable 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 };
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,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_db_error = require("./db-error-DTkkeu5b.cjs");
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-CVS-onRg.cjs");
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;
@@ -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-CMnTI6r7.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-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 };
@@ -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-CMnTI6r7.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-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 };
@@ -1,5 +1,5 @@
1
- import { r as DbError } from "./db-error-D5uilS_A.mjs";
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-Clu2q_7z.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-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.147",
3
+ "version": "0.1.149",
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.99",
75
- "@atscript/typescript": "^0.1.99",
76
- "@uniqu/core": "^0.1.12",
77
- "unplugin-atscript": "^0.1.99"
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.99",
81
- "@atscript/typescript": "^0.1.99",
82
- "@uniqu/core": "^0.1.12"
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",