@atscript/db 0.1.132 → 0.1.134

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.
@@ -32,10 +32,12 @@ const NoopLogger = {
32
32
  * moost-db's HTTP gate — so both layers answer with the same wording.
33
33
  * Everything downstream (`collectQueryPaths`, the field mappers,
34
34
  * `UniquSelect`, adapters) assumes normalized input and does not re-check.
35
- * - **Schema** (timestamp-typed source, JSON ancestor, encryption, physical
36
- * filterability) is the path guard's (`guardPath` op `bucket`), mirrored by
37
- * moost-db's capability index; dimensions are the aggregate rules'.
38
- * - **Adapter capability** (`calendarBucketUnits()`) is `guardAggregate`'s
35
+ * - **The source field** (encryption, JSON ancestor, timestamp type,
36
+ * physical filterability, strict-mode dimension, an adapter with calendar
37
+ * buckets) is `bucketSourceVerdict` — ONE function, called by the path
38
+ * guard (`guardPath` op `bucket`) and by moost-db's capability index, so
39
+ * `/meta.fields[P].bucketable` and the core cannot disagree.
40
+ * - **The unit** (`calendarBucketUnits()` lacks it) is `guardAggregate`'s
39
41
  * (`BUCKET_NOT_SUPPORTED`); SQL builders only re-assert the inlined
40
42
  * literals (defense in depth).
41
43
  *
@@ -52,11 +54,14 @@ function resolveCalendarBuckets(controls, fields, aggregate) {
52
54
  return res.buckets;
53
55
  }
54
56
  /**
55
- * Whether a field can be the source of a calendar bucket: a `number` /
56
- * `integer` leaf carrying the `timestamp` tag (`number.timestamp`,
57
- * `.created`, `.updated`) that is not `@db.encrypted`. The type is the
58
- * declaration — no annotation opts a field in. Physical filterability is the
59
- * caller's (the core path guard and moost-db's capability index both add it).
57
+ * Whether a field's TYPE allows it to be the source of a calendar bucket: a
58
+ * `number` / `integer` leaf carrying the `timestamp` tag
59
+ * (`number.timestamp`, `.created`, `.updated`) that is not
60
+ * `@db.encrypted`. The type is the declaration — no annotation opts a field
61
+ * in.
62
+ *
63
+ * @deprecated since 0.1.133 — the type rule alone; use `bucketSourceVerdict`,
64
+ * the full bucket-source rule the core and moost-db apply.
60
65
  */
61
66
  function isBucketableField(fd) {
62
67
  if (fd.encrypted) return false;
@@ -207,6 +212,7 @@ var TableMetadata = class {
207
212
  physicalNames = /* @__PURE__ */ new Set();
208
213
  _built = false;
209
214
  _identifications;
215
+ _alwaysAddressable;
210
216
  _collateMap = /* @__PURE__ */ new Map();
211
217
  _columnFromMap = /* @__PURE__ */ new Map();
212
218
  constructor(nestedObjects) {
@@ -276,6 +282,11 @@ var TableMetadata = class {
276
282
  if (!this.nestedObjects) this._buildLeafIndexes();
277
283
  this._buildIdentifications();
278
284
  this._resolvePreferredId(type);
285
+ this._alwaysAddressable = new Set([
286
+ ...this.primaryKeys,
287
+ ...this.preferredId,
288
+ ...this.originalMetaIdFields
289
+ ]);
279
290
  this._finalizeIndexes();
280
291
  this._collateMap.clear();
281
292
  this._columnFromMap.clear();
@@ -734,6 +745,14 @@ var TableMetadata = class {
734
745
  getIdentifications() {
735
746
  return this._identifications ?? [];
736
747
  }
748
+ /**
749
+ * Fields that always count as visible for row identification (since
750
+ * 0.1.134): primary key, `preferredId` and `@meta.id` fields — see
751
+ * `AtscriptDbReadable.identificationsVisibleTo`.
752
+ */
753
+ getAlwaysAddressable() {
754
+ return this._alwaysAddressable ?? /* @__PURE__ */ new Set();
755
+ }
737
756
  _resolvePreferredId(type) {
738
757
  const preferred = type.metadata.get("db.table.preferredId.uniqueIndex");
739
758
  if (preferred === void 0) {
@@ -1362,8 +1381,10 @@ var RelationalFieldMapper = class extends FieldMappingStrategy {
1362
1381
  * - malformed `$select` computed entries / `$groupBy` entries, calendar
1363
1382
  * buckets outside grouped queries or with a bad unit / zone / alias →
1364
1383
  * `INVALID_QUERY` (the shared normalizer, `resolveCalendarBuckets`)
1365
- * - a calendar bucket over a non-timestamp field → `INVALID_QUERY`; a unit
1366
- * the adapter's `calendarBucketUnits()` lacks → `BUCKET_NOT_SUPPORTED`
1384
+ * - a calendar bucket over a field that is not a bucket source
1385
+ * (`bucketSourceVerdict`) → `INVALID_QUERY`, or `BUCKET_NOT_SUPPORTED`
1386
+ * when the adapter has no calendar buckets at all; a unit the adapter's
1387
+ * `calendarBucketUnits()` lacks → `BUCKET_NOT_SUPPORTED`
1367
1388
  * - every filter / `$sort` / `$select` / `$groupBy` / `$having` / aggregate
1368
1389
  * path must resolve to physical storage on THIS adapter and pass the
1369
1390
  * capability its position (for a filter entry: its predicate class, see
@@ -1450,8 +1471,8 @@ const OP_VERB = {
1450
1471
  aggregate: "aggregate over",
1451
1472
  bucket: "bucket"
1452
1473
  };
1453
- function pathError(path, message) {
1454
- return new require_db_error.DbError("INVALID_QUERY", [{
1474
+ function pathError(path, message, code = "INVALID_QUERY") {
1475
+ return new require_db_error.DbError(code, [{
1455
1476
  path,
1456
1477
  message
1457
1478
  }]);
@@ -1488,6 +1509,16 @@ function sortFieldNames(sort) {
1488
1509
  if (typeof sort === "object") return Object.keys(sort);
1489
1510
  return [];
1490
1511
  }
1512
+ /**
1513
+ * The reason clause for a leaf the adapter cannot filter (value comparison).
1514
+ * @internal Shared wording for moost-db's capability index — not consumer API.
1515
+ */
1516
+ const ADAPTER_FILTER_REASON = "adapter cannot filter on this storage type";
1517
+ /**
1518
+ * The reason clause for an `@db.encrypted` leaf in a comparing / ordering position.
1519
+ * @internal Shared wording for moost-db's capability index — not consumer API.
1520
+ */
1521
+ const ENCRYPTED_REASON = "field is @db.encrypted (ciphertext cannot be compared or ordered)";
1491
1522
  /** The operator each non-`compare` predicate class stands for, in `filterOps` order. */
1492
1523
  const FILTER_PREDICATE_OPS = {
1493
1524
  exists: "$exists",
@@ -1536,6 +1567,52 @@ function narrowerFilterOps(fd, adapter) {
1536
1567
  function acceptedOperatorsHint(ops) {
1537
1568
  return ops.length > 0 ? ` (accepted operators: ${ops.join(", ")})` : "";
1538
1569
  }
1570
+ /**
1571
+ * Strict mode: a table declaring dimensions or measures groups only by
1572
+ * dimensions (a calendar bucket's source included) and aggregates only
1573
+ * measures.
1574
+ */
1575
+ function isStrictTable(table) {
1576
+ return table.dimensions.length > 0 || table.measures.length > 0;
1577
+ }
1578
+ function rejectSource(code, reason) {
1579
+ return {
1580
+ ok: false,
1581
+ code,
1582
+ reason
1583
+ };
1584
+ }
1585
+ /**
1586
+ * Whether the stored leaf `fd` may be the source of a calendar bucket
1587
+ * (since 0.1.133) — every schema and adapter rule, once, for the core path
1588
+ * guard ({@link guardPath} op `bucket`) and moost-db's capability index
1589
+ * (`/meta.fields[P].bucketable` and the HTTP gate) alike. First failing rule
1590
+ * wins, in this order:
1591
+ *
1592
+ * 1. `encrypted` — `@db.encrypted` (ciphertext has no calendar);
1593
+ * 2. `jsonDescendant` — inside a JSON value (`jsonValueAncestor`):
1594
+ * relational adapters cannot address it and nested-object adapters must
1595
+ * not diverge from them;
1596
+ * 3. `notTimestamp` — not a `number.timestamp` leaf;
1597
+ * 4. `notFilterable` — the adapter cannot filter (so cannot group) the storage;
1598
+ * 5. `notDimension` — a strict table ({@link isStrictTable}) and the field
1599
+ * is not a dimension;
1600
+ * 6. `noBuckets` — the adapter reports no `calendarBucketUnits()`.
1601
+ *
1602
+ * Whether the adapter supports the requested UNIT is a per-query rule, not
1603
+ * a field's (the core's `BUCKET_NOT_SUPPORTED`). Caller-specific policy
1604
+ * layers on top: moost-db rejects `@db.writeOnly` sources before asking.
1605
+ */
1606
+ function bucketSourceVerdict(fd, table, adapter) {
1607
+ if (fd.encrypted) return rejectSource("encrypted", ENCRYPTED_REASON);
1608
+ const jsonAncestor = jsonValueAncestor(fd.path, table.jsonValueParents);
1609
+ if (jsonAncestor !== void 0) return rejectSource("jsonDescendant", `inside JSON-stored column "${jsonAncestor}"`);
1610
+ if (!isBucketableField(fd)) return rejectSource("notTimestamp", "not a timestamp field (declare it number.timestamp)");
1611
+ if (!adapter.canFilterField(fd)) return rejectSource("notFilterable", ADAPTER_FILTER_REASON);
1612
+ if (isStrictTable(table) && !table.dimensions.includes(fd.path)) return rejectSource("notDimension", "not a dimension");
1613
+ if (adapter.calendarBucketUnits().size === 0) return rejectSource("noBuckets", "adapter has no calendar buckets");
1614
+ return { ok: true };
1615
+ }
1539
1616
  function collectFilterKeys(filter, push, skip, refs) {
1540
1617
  if (!filter || typeof filter !== "object" || Array.isArray(filter)) return;
1541
1618
  for (const [key, value] of Object.entries(filter)) {
@@ -1662,8 +1739,8 @@ function pathSourceOf(meta) {
1662
1739
  * - a leaf → physical capability (`canSortField` for `$sort`; for a filter
1663
1740
  * entry {@link canFilterLeaf} of its `predicate` class; `canFilterField`
1664
1741
  * for `$groupBy` / `$having` / aggregate `$field`s; `$select` always passes);
1665
- * a calendar-bucket source must also be a timestamp field
1666
- * (`isBucketableField`);
1742
+ * a calendar-bucket source must pass `bucketSourceVerdict` (the rules
1743
+ * moost-db's capability index applies too);
1667
1744
  * - a nested-object parent → only `$select`, and only when it expands to
1668
1745
  * leaf columns (`selectExpansion`);
1669
1746
  * - everything else is rejected.
@@ -1683,17 +1760,15 @@ function guardPath(meta, adapter, path, op, predicate = "compare") {
1683
1760
  if (op === "select") return;
1684
1761
  const fd = meta.descriptorByPath.get(path);
1685
1762
  if (op === "bucket") {
1686
- const jsonAncestor = jsonValueAncestor(path, meta.jsonValueParents);
1687
- if (jsonAncestor !== void 0) throw pathError(path, `Cannot bucket "${path}" — inside JSON-stored column "${jsonAncestor}"`);
1688
- if (!isBucketableField(fd)) throw pathError(path, notTimestampMessage(path));
1689
- if (!adapter.canFilterField(fd)) throw pathError(path, `Cannot bucket "${path}" — adapter cannot filter on this storage type`);
1763
+ const verdict = bucketSourceVerdict(fd, meta, adapter);
1764
+ if (!verdict.ok) throw pathError(path, `Cannot bucket "${path}" — ${verdict.reason}`, verdict.code === "noBuckets" ? "BUCKET_NOT_SUPPORTED" : "INVALID_QUERY");
1690
1765
  return;
1691
1766
  }
1692
1767
  if (op === "sort") {
1693
1768
  if (!adapter.canSortField(fd)) throw pathError(path, `Cannot sort by "${path}" — adapter cannot sort on this storage type`);
1694
1769
  return;
1695
1770
  }
1696
- if (!canFilterLeaf(fd, predicate, adapter)) throw pathError(path, `Cannot ${verb} "${path}" — adapter cannot filter on this storage type${op === "filter" ? acceptedOperatorsHint(narrowerFilterOps(fd, adapter)) : ""}`);
1771
+ if (!canFilterLeaf(fd, predicate, adapter)) throw pathError(path, `Cannot ${verb} "${path}" — ${ADAPTER_FILTER_REASON}${op === "filter" ? acceptedOperatorsHint(narrowerFilterOps(fd, adapter)) : ""}`);
1697
1772
  return;
1698
1773
  }
1699
1774
  case "objectParent":
@@ -1793,13 +1868,10 @@ function guardAggregate(meta, adapter, query, resolved) {
1793
1868
  const having = refs ? checkHavingKeys(refs) : void 0;
1794
1869
  if (having) throw new require_db_error.DbError("INVALID_QUERY", [having]);
1795
1870
  }
1796
- /** The core wording for a bucket over a field that is not `number.timestamp`. */
1797
- function notTimestampMessage(path) {
1798
- return `Cannot bucket "${path}" — not a timestamp field (declare it number.timestamp)`;
1799
- }
1800
1871
  /**
1801
1872
  * Rejects a calendar bucket whose unit this adapter cannot group by
1802
- * (`calendarBucketUnits()`; empty by default) with `BUCKET_NOT_SUPPORTED`,
1873
+ * (`calendarBucketUnits()`; an adapter with none was already answered per
1874
+ * source by `bucketSourceVerdict`) with `BUCKET_NOT_SUPPORTED`,
1803
1875
  * before anything is translated — third-party adapters get a clean 400,
1804
1876
  * never an engine error or a silent fallback.
1805
1877
  */
@@ -2058,6 +2130,19 @@ var AtscriptDbReadable = class {
2058
2130
  return this._meta.getIdentifications();
2059
2131
  }
2060
2132
  /**
2133
+ * The {@link identifications} an id may resolve through when fields are
2134
+ * hidden per request (since 0.1.134): a unique index with a field that
2135
+ * fails `isFieldVisible` is dropped, as if it did not exist. Primary-key,
2136
+ * `preferredId` and `@meta.id` fields always count as visible. Without a
2137
+ * predicate, every identification.
2138
+ */
2139
+ identificationsVisibleTo(isFieldVisible) {
2140
+ const all = this.identifications;
2141
+ if (!isFieldVisible) return all;
2142
+ const always = this._meta.getAlwaysAddressable();
2143
+ return all.filter((ident) => ident.fields.every((f) => always.has(f) || isFieldVisible(f)));
2144
+ }
2145
+ /**
2061
2146
  * Physical column name of the single `@meta.id` field, or `null` when the
2062
2147
  * schema has zero or multiple `@meta.id` fields. Used by adapters to return
2063
2148
  * the user's logical ID instead of the DB-generated one on insert.
@@ -2177,6 +2262,24 @@ var AtscriptDbReadable = class {
2177
2262
  return this._meta.fieldDescriptors;
2178
2263
  }
2179
2264
  /**
2265
+ * The target table of the navigation relation `navField` (since 0.1.134),
2266
+ * resolved through the table resolver this readable was built with (the
2267
+ * `DbSpace`'s). `undefined` when `navField` is not a relation of this table
2268
+ * or no resolver is available (a table constructed without a `DbSpace`).
2269
+ * Top-level relation names only — no dotted paths.
2270
+ *
2271
+ * ```typescript
2272
+ * const users = posts.relatedTable('author')
2273
+ * users?.primaryKeys // ['id']
2274
+ * ```
2275
+ */
2276
+ relatedTable(navField) {
2277
+ this._ensureBuilt();
2278
+ const targetType = this._meta.relations.get(navField)?.targetType();
2279
+ if (!targetType || !this._tableResolver) return;
2280
+ return this._tableResolver(targetType);
2281
+ }
2282
+ /**
2180
2283
  * Resolves whether `path` references a real field — directly via `flatMap`
2181
2284
  * or transitively through a nav relation by recursing into the target
2182
2285
  * table. Defense-in-depth for query-path validation: `flattenAnnotatedType`
@@ -2192,12 +2295,7 @@ var AtscriptDbReadable = class {
2192
2295
  if (dotIdx === -1) return false;
2193
2296
  const head = path.slice(0, dotIdx);
2194
2297
  const tail = path.slice(dotIdx + 1);
2195
- if (!this.navFields.has(head)) return false;
2196
- const relation = this._meta.relations.get(head);
2197
- if (!relation) return false;
2198
- const targetType = relation.targetType();
2199
- if (!targetType || !this._tableResolver) return false;
2200
- const targetTable = this._tableResolver(targetType);
2298
+ const targetTable = this.relatedTable(head);
2201
2299
  if (!targetTable || typeof targetTable.isValidFieldPath !== "function") return false;
2202
2300
  const visited = _visited ?? /* @__PURE__ */ new Set();
2203
2301
  const cycleKey = `${this.tableName}:${head}`;
@@ -2280,10 +2378,11 @@ var AtscriptDbReadable = class {
2280
2378
  * `resolveCalendarBuckets`: shapes, unit, zone, alias, grouping)
2281
2379
  * - Plain fields in $select are a subset of $groupBy
2282
2380
  * - When dimensions/measures are defined (strict mode): $groupBy fields
2283
- * must be dimensions (a calendar bucket's source field included),
2284
- * aggregate $field values must be measures (or '*')
2285
- * - the path guard (a bucket source must be a timestamp field) and the
2286
- * adapter's calendar-bucket units (`BUCKET_NOT_SUPPORTED`)
2381
+ * must be dimensions, aggregate $field values must be measures (or '*')
2382
+ * - the path guard (a bucket source must pass `bucketSourceVerdict` —
2383
+ * timestamp type, no JSON ancestor, a dimension in strict mode, an
2384
+ * adapter with calendar buckets) and the adapter's calendar-bucket units
2385
+ * (`BUCKET_NOT_SUPPORTED`)
2287
2386
  *
2288
2387
  * Translates field names, delegates to adapter.aggregate(),
2289
2388
  * then reverse-maps and applies fromStorage formatters on results.
@@ -2300,11 +2399,11 @@ var AtscriptDbReadable = class {
2300
2399
  }]);
2301
2400
  }
2302
2401
  const { dimensions, measures } = this._meta;
2303
- if (dimensions.length > 0 || measures.length > 0) {
2402
+ if (isStrictTable(this._meta)) {
2304
2403
  const dimSet = new Set(dimensions);
2305
2404
  const measSet = new Set(measures);
2306
- const bucketSource = new Map(buckets.map((b) => [b.alias, b.field]));
2307
- for (const field of $groupBy.map((key) => bucketSource.get(key) ?? key)) if (!dimSet.has(field)) throw new require_db_error.DbError("INVALID_QUERY", [{
2405
+ const bucketAliases = new Set(buckets.map((b) => b.alias));
2406
+ for (const field of $groupBy) if (!dimSet.has(field) && !bucketAliases.has(field)) throw new require_db_error.DbError("INVALID_QUERY", [{
2308
2407
  path: "$groupBy",
2309
2408
  message: `Field "${field}" is not a dimension`
2310
2409
  }]);
@@ -2562,9 +2661,11 @@ var AtscriptDbReadable = class {
2562
2661
  * same identification resolution as {@link findById}. Public so callers can
2563
2662
  * AND-combine the id-filter with a row-level read overlay before issuing
2564
2663
  * `findOne` (avoiding the existence leak that `findById` would cause).
2664
+ * `opts.isFieldVisible` (since 0.1.134) drops unique indexes over hidden
2665
+ * fields — see {@link identificationsVisibleTo}.
2565
2666
  */
2566
- resolveIdFilter(id) {
2567
- return this._resolveIdFilter(id);
2667
+ resolveIdFilter(id, opts) {
2668
+ return this._resolveIdFilter(id, opts);
2568
2669
  }
2569
2670
  /**
2570
2671
  * Resolve an id value into a filter expression.
@@ -2572,9 +2673,10 @@ var AtscriptDbReadable = class {
2572
2673
  * When `preferredId` differs from the PK, scalar ids resolve only against
2573
2674
  * the preferred field (deterministic addressing). Otherwise scalars try PK
2574
2675
  * + every single-field unique index; objects try PK + compound unique
2575
- * indexes.
2676
+ * indexes. With `opts.isFieldVisible`, only the identifications
2677
+ * {@link identificationsVisibleTo} keeps are tried.
2576
2678
  */
2577
- _resolveIdFilter(id) {
2679
+ _resolveIdFilter(id, opts) {
2578
2680
  const pkFields = this.primaryKeys;
2579
2681
  const preferredFields = this.preferredId;
2580
2682
  const isExplicitPreferred = preferredFields.length !== pkFields.length || preferredFields.some((f, i) => f !== pkFields[i]);
@@ -2586,12 +2688,13 @@ var AtscriptDbReadable = class {
2586
2688
  };
2587
2689
  const orFilters = [];
2588
2690
  const idObj = isScalar ? null : id;
2589
- for (const ident of this.identifications) {
2691
+ const identifications = this.identificationsVisibleTo(opts?.isFieldVisible);
2692
+ for (const ident of identifications) {
2590
2693
  if (ident.fields.length !== 1) continue;
2591
2694
  const filter = tryScalarOrField(ident.fields[0]);
2592
2695
  if (filter) orFilters.push(filter);
2593
2696
  }
2594
- if (idObj) for (const ident of this.identifications) {
2697
+ if (idObj) for (const ident of identifications) {
2595
2698
  if (ident.fields.length < 2) continue;
2596
2699
  if (ident.source !== "primaryKey" && orFilters.length > 0) break;
2597
2700
  const filter = this._tryCompoundFilter(ident.fields, idObj);
@@ -3993,7 +4096,7 @@ var AtscriptDbTable = class extends AtscriptDbReadable {
3993
4096
  const data = items[i];
3994
4097
  for (const navField of this._meta.navFields) delete data[navField];
3995
4098
  if (versionColumn !== void 0) assertNoVersionWrites(data, versionColumn);
3996
- const filter = this._extractRecordFilter(data);
4099
+ const filter = this._extractRecordFilter(data, opts);
3997
4100
  const prepared = this._fieldMapper.prepareForWrite(data, this._meta, this.adapter);
3998
4101
  const result = await this.adapter.replaceOne(this._fieldMapper.translateFilter(filter, this._meta), prepared, expectedVersions[i]);
3999
4102
  matchedCount += result.matchedCount;
@@ -4068,7 +4171,7 @@ var AtscriptDbTable = class extends AtscriptDbReadable {
4068
4171
  const expectedVersion = expectedVersions[i];
4069
4172
  const data = { ...payload };
4070
4173
  for (const navField of this._meta.navFields) delete data[navField];
4071
- const filter = this._extractRecordFilter(data);
4174
+ const filter = this._extractRecordFilter(data, opts);
4072
4175
  for (const key of Object.keys(filter)) delete data[key];
4073
4176
  if (versionColumn !== void 0) assertNoVersionWrites(data, versionColumn);
4074
4177
  const translatedFilter = this._fieldMapper.translateFilter(filter, this._meta);
@@ -4202,7 +4305,7 @@ var AtscriptDbTable = class extends AtscriptDbReadable {
4202
4305
  */
4203
4306
  async deleteOne(id, opts) {
4204
4307
  this._ensureBuilt();
4205
- const filter = this._resolveIdFilter(id);
4308
+ const filter = this._resolveIdFilter(id, opts);
4206
4309
  if (!filter) return { deletedCount: 0 };
4207
4310
  const guard = opts?.guard;
4208
4311
  const needsCascade = this._integrity.needsCascade(this._cascadeResolver);
@@ -4376,9 +4479,11 @@ var AtscriptDbTable = class extends AtscriptDbReadable {
4376
4479
  * 2. Single-field unique index — first `@db.index.unique` field found.
4377
4480
  * 3. Compound unique index — first compound unique index whose fields are all present.
4378
4481
  *
4379
- * Throws when no identifying fields can be found.
4482
+ * Throws when no identifying fields can be found. With `isFieldVisible`
4483
+ * (since 0.1.134), a unique index over a hidden field is skipped, as if it
4484
+ * did not exist — see {@link identificationsVisibleTo}.
4380
4485
  */
4381
- _extractRecordFilter(payload) {
4486
+ _extractRecordFilter(payload, opts) {
4382
4487
  const pkFields = this.primaryKeys;
4383
4488
  if (pkFields.length > 0) {
4384
4489
  let allPresent = true;
@@ -4392,17 +4497,15 @@ var AtscriptDbTable = class extends AtscriptDbReadable {
4392
4497
  return filter;
4393
4498
  }
4394
4499
  }
4395
- for (const prop of this.uniqueProps) if (payload[prop] !== void 0) return { [prop]: this._prepareFilterValue(prop, payload[prop]) };
4396
- for (const index of this._meta.indexes.values()) {
4397
- if (index.type !== "unique" || index.fields.length < 2) continue;
4398
- let allPresent = true;
4399
- for (const indexField of index.fields) if (payload[indexField.name] === void 0) {
4400
- allPresent = false;
4401
- break;
4402
- }
4403
- if (allPresent) {
4500
+ const identifications = this.identificationsVisibleTo(opts?.isFieldVisible);
4501
+ const singleFields = /* @__PURE__ */ new Set();
4502
+ for (const ident of identifications) if (ident.source !== "primaryKey" && ident.fields.length === 1) singleFields.add(ident.fields[0]);
4503
+ for (const prop of this.uniqueProps) if (singleFields.has(prop) && payload[prop] !== void 0) return { [prop]: this._prepareFilterValue(prop, payload[prop]) };
4504
+ for (const ident of identifications) {
4505
+ if (ident.source === "primaryKey" || ident.fields.length < 2) continue;
4506
+ if (ident.fields.every((field) => payload[field] !== void 0)) {
4404
4507
  const filter = {};
4405
- for (const indexField of index.fields) filter[indexField.name] = this._prepareFilterValue(indexField.name, payload[indexField.name]);
4508
+ for (const field of ident.fields) filter[field] = this._prepareFilterValue(field, payload[field]);
4406
4509
  return filter;
4407
4510
  }
4408
4511
  }
@@ -4652,6 +4755,12 @@ function isAtscriptDbView(readable) {
4652
4755
  return readable.isView;
4653
4756
  }
4654
4757
  //#endregion
4758
+ Object.defineProperty(exports, "ADAPTER_FILTER_REASON", {
4759
+ enumerable: true,
4760
+ get: function() {
4761
+ return ADAPTER_FILTER_REASON;
4762
+ }
4763
+ });
4655
4764
  Object.defineProperty(exports, "ALL_BUCKET_UNITS", {
4656
4765
  enumerable: true,
4657
4766
  get: function() {
@@ -4694,6 +4803,12 @@ Object.defineProperty(exports, "DocumentFieldMapper", {
4694
4803
  return DocumentFieldMapper;
4695
4804
  }
4696
4805
  });
4806
+ Object.defineProperty(exports, "ENCRYPTED_REASON", {
4807
+ enumerable: true,
4808
+ get: function() {
4809
+ return ENCRYPTED_REASON;
4810
+ }
4811
+ });
4697
4812
  Object.defineProperty(exports, "FieldMappingStrategy", {
4698
4813
  enumerable: true,
4699
4814
  get: function() {
@@ -4754,6 +4869,12 @@ Object.defineProperty(exports, "assertNoVersionWrites", {
4754
4869
  return assertNoVersionWrites;
4755
4870
  }
4756
4871
  });
4872
+ Object.defineProperty(exports, "bucketSourceVerdict", {
4873
+ enumerable: true,
4874
+ get: function() {
4875
+ return bucketSourceVerdict;
4876
+ }
4877
+ });
4757
4878
  Object.defineProperty(exports, "canFilterLeaf", {
4758
4879
  enumerable: true,
4759
4880
  get: function() {
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_db_error = require("./db-error-DTkkeu5b.cjs");
3
- const require_db_view = require("./db-view-CuFAhzwF.cjs");
3
+ const require_db_view = require("./db-view-pgm2dHIo.cjs");
4
4
  const require_validator = require("./validator-BtZbcLN2.cjs");
5
5
  const require_consts = require("./consts-BzRfCcH2.cjs");
6
6
  const require_ops = require("./ops.cjs");
@@ -382,6 +382,7 @@ exports.$remove = require_ops.$remove;
382
382
  exports.$replace = require_ops.$replace;
383
383
  exports.$update = require_ops.$update;
384
384
  exports.$upsert = require_ops.$upsert;
385
+ exports.ADAPTER_FILTER_REASON = require_db_view.ADAPTER_FILTER_REASON;
385
386
  exports.ALL_BUCKET_UNITS = require_db_view.ALL_BUCKET_UNITS;
386
387
  exports.ApplicationIntegrity = require_db_view.ApplicationIntegrity;
387
388
  exports.AtscriptDbReadable = require_db_view.AtscriptDbReadable;
@@ -395,6 +396,7 @@ exports.DbEncryption = DbEncryption;
395
396
  exports.DbError = require_db_error.DbError;
396
397
  exports.DbSpace = DbSpace;
397
398
  exports.DocumentFieldMapper = require_db_view.DocumentFieldMapper;
399
+ exports.ENCRYPTED_REASON = require_db_view.ENCRYPTED_REASON;
398
400
  exports.FieldMappingStrategy = require_db_view.FieldMappingStrategy;
399
401
  exports.IntegrityStrategy = require_db_view.IntegrityStrategy;
400
402
  exports.NativeIntegrity = require_db_view.NativeIntegrity;
@@ -405,6 +407,7 @@ exports.UniquSelect = require_db_view.UniquSelect;
405
407
  exports.acceptedOperatorsHint = require_db_view.acceptedOperatorsHint;
406
408
  exports.assertGeoPoint = require_db_view.assertGeoPoint;
407
409
  exports.assertNoVersionWrites = require_db_view.assertNoVersionWrites;
410
+ exports.bucketSourceVerdict = require_db_view.bucketSourceVerdict;
408
411
  exports.bucketTimeZoneUnavailable = require_db_error.bucketTimeZoneUnavailable;
409
412
  exports.buildDbValidator = require_validator.buildDbValidator;
410
413
  exports.buildValidationContext = require_validator.buildValidationContext;
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
- import { $ as TDbWriteGuardContext, A as TDbActionIntent, At as isGeoPointType, B as TDbIndexField, Bt as NoopLogger, C as PrimaryKeyOf, Ct as TypedWithRelation, D as TCrudOp, Dt as TableMetadata, E as TColumnDiff, Et as WithRelation, F as TDbDefaultValue, Ft as resolveDesignType, G as TDbReferentialAction, H as TDbInsertManyResult, Ht as UniquSelect, I as TDbDeleteResult, It as DbEncryption, J as TDbRemoveGuardContext, K as TDbRelation, L as TDbFieldMeta, Lt as TDbEncryptionOptions, M as TDbActionProcessor, Mt as BaseDbAdapter, N as TDbCollation, Nt as AtscriptDbReadable, O as TCrudPermissions, Ot as findAncestorInSet, P as TDbDefaultFn, Pt as DbResponse, Q as TDbWriteGuard, R as TDbForeignKey, Rt as DocumentFieldMapper, S as OwnPropsOf, St as TWriteTableResolver, T as TCascadeTarget, Tt as UniqueryControls, U as TDbInsertResult, V as TDbIndexType, Vt as TGenericLogger, W as TDbObjectKind, X as TDbUpdateResult, Y as TDbStorageType, Z as TDbWriteAction, _ as FieldOpsFor, _t as TTableOptionDiff, a as jsonValueAncestor, at as TFieldMeta, b as NavPropsOf, bt as TValueFormatterPair, c as AggregateExpr, ct as TIdDescriptor, d as AggregateResult, dt as TMetadataOverrides, et as TDeleteOptions, f as AtscriptDbWritable, ft as TPrimaryKeyChange, g as DbRow, gt as TSyncColumnResult, h as DbQuery, ht as TSearchIndexInfo, i as isJsonValueField, it as TExistingTableOption, j as TDbActionLevel, jt as ALL_BUCKET_UNITS, k as TDbActionInfo, kt as isGeoIndexableType, l as AggregateFn, lt as TIdentification, m as DbPatch, mt as TRelationInfo, n as TResolvedBucket, nt as TExistingColumn, o as resolveCalendarBuckets, ot as TFkLookupResolver, p as DbControls, pt as TReferencingForeignKey, q as TDbRemoveGuard, r as isBucketableField, rt as TExistingForeignKey, s as AggregateControls, st as TFkLookupTarget, t as TBucketFieldSource, tt as TEnsureTableOptions, u as AggregateQuery, ut as TMetaResponse, v as FilterExpr, vt as TTableResolver, w as TCascadeResolver, wt as Uniquery, x as NullableOptional, xt as TWriteOptions, y as FlatOf, yt as TTouchManyOptions, z as TDbIndex, zt as FieldMappingStrategy } from "./buckets-BvoYYQ2Q.cjs";
1
+ import { $ as TDbWriteGuardContext, A as TDbActionIntent, At as isGeoIndexableType, B as TDbIndexField, Bt as FieldMappingStrategy, C as PrimaryKeyOf, Ct as TWriteTableResolver, D as TCrudOp, Dt as WithRelation, E as TColumnDiff, Et as UniqueryControls, F as TDbDefaultValue, Ft as DbResponse, G as TDbReferentialAction, H as TDbInsertManyResult, Ht as TGenericLogger, I as TDbDeleteResult, It as resolveDesignType, J as TDbRemoveGuardContext, K as TDbRelation, L as TDbFieldMeta, Lt as DbEncryption, M as TDbActionProcessor, Mt as ALL_BUCKET_UNITS, N as TDbCollation, Nt as BaseDbAdapter, O as TCrudPermissions, Ot as TableMetadata, P as TDbDefaultFn, Pt as AtscriptDbReadable, Q as TDbWriteGuard, R as TDbForeignKey, Rt as TDbEncryptionOptions, S as OwnPropsOf, St as TWriteOptions, T as TCascadeTarget, Tt as Uniquery, U as TDbInsertResult, Ut as UniquSelect, V as TDbIndexType, Vt as NoopLogger, W as TDbObjectKind, X as TDbUpdateResult, Y as TDbStorageType, Z as TDbWriteAction, _ as FieldOpsFor, _t as TSyncColumnResult, a as jsonValueAncestor, at as TFieldMeta, b as NavPropsOf, bt as TTouchManyOptions, c as AggregateExpr, ct as TIdDescriptor, d as AggregateResult, dt as TMetaResponse, et as TDeleteOptions, f as AtscriptDbWritable, ft as TMetadataOverrides, g as DbRow, gt as TSearchIndexInfo, h as DbQuery, ht as TRelationInfo, i as isJsonValueField, it as TExistingTableOption, j as TDbActionLevel, jt as isGeoPointType, k as TDbActionInfo, kt as findAncestorInSet, l as AggregateFn, lt as TIdResolveOptions, m as DbPatch, mt as TReferencingForeignKey, n as TResolvedBucket, nt as TExistingColumn, o as resolveCalendarBuckets, ot as TFkLookupResolver, p as DbControls, pt as TPrimaryKeyChange, q as TDbRemoveGuard, r as isBucketableField, rt as TExistingForeignKey, s as AggregateControls, st as TFkLookupTarget, t as TBucketFieldSource, tt as TEnsureTableOptions, u as AggregateQuery, ut as TIdentification, v as FilterExpr, vt as TTableOptionDiff, w as TCascadeResolver, wt as TypedWithRelation, x as NullableOptional, xt as TValueFormatterPair, y as FlatOf, yt as TTableResolver, z as TDbIndex, zt as DocumentFieldMapper } from "./buckets-Bo2IcPZ_.cjs";
2
2
  import { _ as separateFieldOps, a as $mul, c as $update, d as TDbFieldOp, f as TFieldOps, g as separateCas, h as reconcileCas, i as $insert, l as $upsert, m as isDbFieldOp, n as $dec, o as $remove, p as getDbFieldOp, r as $inc, s as $replace, t as $cas, u as TDbCas } from "./ops-AqhV7s9o.cjs";
3
3
  import { BucketExpr, BucketUnit, CalendarBucketLabel, ComputedExpr, ResolvedBucket, WeekStart } from "./agg.cjs";
4
- import { a as TViewColumnMapping, c as AtscriptQueryFieldRef, d as TViewJoin, f as TViewPlan, g as NativeIntegrity, h as IntegrityStrategy, i as AtscriptDbView, l as AtscriptQueryNode, m as AtscriptDbTable, n as TAdapterFactory, o as isAtscriptDbView, p as translateQueryTree, r as TDbSpaceOptions, s as AtscriptQueryComparison, t as DbSpace, u as AtscriptRef } from "./db-space-Cslq5Dux.cjs";
4
+ import { a as TViewColumnMapping, c as AtscriptQueryFieldRef, d as TViewJoin, f as TViewPlan, g as NativeIntegrity, h as IntegrityStrategy, i as AtscriptDbView, l as AtscriptQueryNode, m as AtscriptDbTable, n as TAdapterFactory, o as isAtscriptDbView, p as translateQueryTree, r as TDbSpaceOptions, s as AtscriptQueryComparison, t as DbSpace, u as AtscriptRef } from "./db-space-DtGx5HIC.cjs";
5
5
  import { _ as DbErrorCode, a as buildValidationContext, c as isNavRelation, d as TArrayPatch, f as TDbPatch, g as DbError, h as CasMismatchError, l as isEmptyObject, m as CasExhaustedError, n as ValidatorMode, p as getKeyProps, r as buildDbValidator, s as forceNavNonOptional, t as ValidationContext, u as isPlainObject, v as bucketTimeZoneUnavailable } from "./validator-CewfnGZj.cjs";
6
6
  import { n as createDbValidatorPlugin, t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.cjs";
7
7
  import { AggregateQuery as AggregateQuery$1, FilterExpr as FilterExpr$1, FilterVisitor, ResolvedBucket as ResolvedBucket$1, Uniquery as Uniquery$1, computeInsights, isPrimitive, walkFilter } from "@uniqu/core";
@@ -106,8 +106,10 @@ declare class ApplicationIntegrity extends IntegrityStrategy {
106
106
  * - malformed `$select` computed entries / `$groupBy` entries, calendar
107
107
  * buckets outside grouped queries or with a bad unit / zone / alias →
108
108
  * `INVALID_QUERY` (the shared normalizer, `resolveCalendarBuckets`)
109
- * - a calendar bucket over a non-timestamp field → `INVALID_QUERY`; a unit
110
- * the adapter's `calendarBucketUnits()` lacks → `BUCKET_NOT_SUPPORTED`
109
+ * - a calendar bucket over a field that is not a bucket source
110
+ * (`bucketSourceVerdict`) → `INVALID_QUERY`, or `BUCKET_NOT_SUPPORTED`
111
+ * when the adapter has no calendar buckets at all; a unit the adapter's
112
+ * `calendarBucketUnits()` lacks → `BUCKET_NOT_SUPPORTED`
111
113
  * - every filter / `$sort` / `$select` / `$groupBy` / `$having` / aggregate
112
114
  * path must resolve to physical storage on THIS adapter and pass the
113
115
  * capability its position (for a filter entry: its predicate class, see
@@ -159,6 +161,16 @@ interface TFilterRef {
159
161
  path: string;
160
162
  predicate: TFilterPredicate;
161
163
  }
164
+ /**
165
+ * The reason clause for a leaf the adapter cannot filter (value comparison).
166
+ * @internal Shared wording for moost-db's capability index — not consumer API.
167
+ */
168
+ declare const ADAPTER_FILTER_REASON = "adapter cannot filter on this storage type";
169
+ /**
170
+ * The reason clause for an `@db.encrypted` leaf in a comparing / ordering position.
171
+ * @internal Shared wording for moost-db's capability index — not consumer API.
172
+ */
173
+ declare const ENCRYPTED_REASON = "field is @db.encrypted (ciphertext cannot be compared or ordered)";
162
174
  /** The adapter-shaped capability {@link canFilterLeaf} consults (a `BaseDbAdapter` or a readable). */
163
175
  type TFilterCapabilitySource = Pick<BaseDbAdapter, "canFilterField" | "isGeoSearchable">;
164
176
  /** The operator each non-`compare` predicate class stands for, in `filterOps` order. */
@@ -184,6 +196,52 @@ declare function canFilterLeaf(fd: TDbFieldMeta, predicate: TFilterPredicate, ad
184
196
  declare function narrowerFilterOps(fd: TDbFieldMeta, adapter: TFilterCapabilitySource): string[];
185
197
  /** The rejection suffix naming {@link narrowerFilterOps} — `""` when there are none. */
186
198
  declare function acceptedOperatorsHint(ops: readonly string[]): string;
199
+ /**
200
+ * The table side of a {@link bucketSourceVerdict}: `TableMetadata` itself,
201
+ * or moost-db's capability index assembling the same names from a readable.
202
+ */
203
+ interface TBucketSourceTable {
204
+ /** Paths of the `isJsonValueField` descriptors — see `jsonValueAncestor`. */
205
+ jsonValueParents: ReadonlySet<string>;
206
+ /** Declared dimensions / measures — see {@link isStrictTable}. */
207
+ dimensions: readonly string[];
208
+ measures: readonly string[];
209
+ }
210
+ /**
211
+ * {@link bucketSourceVerdict}'s answer. `reason` is the shared clause (no
212
+ * trailing period) both layers put after the dash: the core's
213
+ * `Cannot bucket "P" — <reason>`, moost-db's
214
+ * `Bucketing field "P" is not permitted — <reason>.`
215
+ */
216
+ type TBucketSourceVerdict = {
217
+ ok: true;
218
+ } | {
219
+ ok: false;
220
+ code: "encrypted" | "jsonDescendant" | "notTimestamp" | "notFilterable" | "notDimension" | "noBuckets";
221
+ reason: string;
222
+ };
223
+ /**
224
+ * Whether the stored leaf `fd` may be the source of a calendar bucket
225
+ * (since 0.1.133) — every schema and adapter rule, once, for the core path
226
+ * guard ({@link guardPath} op `bucket`) and moost-db's capability index
227
+ * (`/meta.fields[P].bucketable` and the HTTP gate) alike. First failing rule
228
+ * wins, in this order:
229
+ *
230
+ * 1. `encrypted` — `@db.encrypted` (ciphertext has no calendar);
231
+ * 2. `jsonDescendant` — inside a JSON value (`jsonValueAncestor`):
232
+ * relational adapters cannot address it and nested-object adapters must
233
+ * not diverge from them;
234
+ * 3. `notTimestamp` — not a `number.timestamp` leaf;
235
+ * 4. `notFilterable` — the adapter cannot filter (so cannot group) the storage;
236
+ * 5. `notDimension` — a strict table ({@link isStrictTable}) and the field
237
+ * is not a dimension;
238
+ * 6. `noBuckets` — the adapter reports no `calendarBucketUnits()`.
239
+ *
240
+ * Whether the adapter supports the requested UNIT is a per-query rule, not
241
+ * a field's (the core's `BUCKET_NOT_SUPPORTED`). Caller-specific policy
242
+ * layers on top: moost-db rejects `@db.writeOnly` sources before asking.
243
+ */
244
+ declare function bucketSourceVerdict(fd: TDbFieldMeta, table: TBucketSourceTable, adapter: Pick<BaseDbAdapter, "canFilterField" | "calendarBucketUnits">): TBucketSourceVerdict;
187
245
  /** Every logical path a parsed query references, grouped by position (since 0.1.128). */
188
246
  interface TQueryPathRefs {
189
247
  /**
@@ -268,8 +326,8 @@ declare function classifyQueryPath(source: TQueryPathSource, path: string): {
268
326
  * - a leaf → physical capability (`canSortField` for `$sort`; for a filter
269
327
  * entry {@link canFilterLeaf} of its `predicate` class; `canFilterField`
270
328
  * for `$groupBy` / `$having` / aggregate `$field`s; `$select` always passes);
271
- * a calendar-bucket source must also be a timestamp field
272
- * (`isBucketableField`);
329
+ * a calendar-bucket source must pass `bucketSourceVerdict` (the rules
330
+ * moost-db's capability index applies too);
273
331
  * - a nested-object parent → only `$select`, and only when it expands to
274
332
  * leaf columns (`selectExpansion`);
275
333
  * - everything else is rejected.
@@ -429,4 +487,4 @@ declare function createFailureCollector(what: string): {
429
487
  throwIfAny: () => void;
430
488
  };
431
489
  //#endregion
432
- export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, ALL_BUCKET_UNITS, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptQueryComparison, type AtscriptQueryFieldRef, type AtscriptQueryNode, type AtscriptRef, BaseDbAdapter, type BucketExpr, type BucketUnit, type CalendarBucketLabel, CasExhaustedError, CasMismatchError, type ComputedExpr, DEFAULT_DB_SPACE, type DbControls, DbEncryption, DbError, type DbErrorCode, type DbPatch, type DbQuery, type DbResponse, type DbRow, DbSpace, type DbValidationContext, DocumentFieldMapper, FieldMappingStrategy, type FieldOpsFor, type FilterExpr, type FilterVisitor, type FlatOf, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type NullableOptional, type OwnPropsOf, type PrimaryKeyOf, RelationalFieldMapper, type ResolvedBucket, type TAdapterFactory, type TArrayPatch, type TBucketFieldSource, type TCascadeResolver, type TCascadeTarget, type TColumnDiff, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbCas, type TDbCollation, type TDbDefaultFn, type TDbDefaultValue, type TDbDeleteResult, type TDbEncryptionOptions, type TDbFieldMeta, type TDbFieldOp, type TDbForeignKey, type TDbIndex, type TDbIndexField, type TDbIndexType, type TDbInsertManyResult, type TDbInsertResult, type TDbObjectKind, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbRemoveGuard, type TDbRemoveGuardContext, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateResult, type TDbWriteAction, type TDbWriteGuard, type TDbWriteGuardContext, type TDeleteOptions, type TEnsureTableOptions, type TExistingColumn, type TExistingForeignKey, type TExistingTableOption, type TFieldMeta, type TFieldOps, type TFilterPredicate, type TFilterRef, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TGuardedQuery, type TIdDescriptor, type TIdentification, type TMetaResponse, type TMetadataOverrides, type TPrimaryKeyChange, type TQueryPathKind, type TQueryPathOp, type TQueryPathRefs, type TQueryPathSource, type TReferencingForeignKey, type TRelationInfo, type TResolvedBucket, type TSearchIndexInfo, type TSyncColumnResult, type TTableOptionDiff, type TTableResolver, type TTouchManyOptions, type TValueFormatterPair, type TViewColumnMapping, type TViewJoin, type TViewPlan, type TWriteOptions, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WeekStart, type WithOptimisticRetryOptions, type WithRelation, acceptedOperatorsHint, assertGeoPoint, assertNoVersionWrites, bucketTimeZoneUnavailable, buildDbValidator, buildValidationContext, canFilterLeaf, checkHavingKeys, classifyQueryPath, collectQueryPaths, computeInsights, createDbValidatorPlugin, createFailureCollector, decomposePatch, findAncestorInSet, forceNavNonOptional, getDbFieldOp, getKeyProps, guardAggregate, guardFilter, guardPath, guardPaths, guardQuery, isAtscriptDbView, isBucketableField, isDbFieldOp, isEmptyObject, isGeoIndexableType, isGeoPointType, isJsonValueField, isNavRelation, isPlainObject, isPrimitive, jsonValueAncestor, narrowerFilterOps, reconcileCas, resolveCalendarBuckets, resolveDesignType, separateCas, separateFieldOps, sortFieldNames, translateQueryTree, unsupportedOperatorMessage, walkFilter, withOptimisticRetry };
490
+ export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, ADAPTER_FILTER_REASON, ALL_BUCKET_UNITS, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptQueryComparison, type AtscriptQueryFieldRef, type AtscriptQueryNode, type AtscriptRef, BaseDbAdapter, type BucketExpr, type BucketUnit, type CalendarBucketLabel, CasExhaustedError, CasMismatchError, type ComputedExpr, DEFAULT_DB_SPACE, type DbControls, DbEncryption, DbError, type DbErrorCode, type DbPatch, type DbQuery, type DbResponse, type DbRow, DbSpace, type DbValidationContext, DocumentFieldMapper, ENCRYPTED_REASON, FieldMappingStrategy, type FieldOpsFor, type FilterExpr, type FilterVisitor, type FlatOf, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type NullableOptional, type OwnPropsOf, type PrimaryKeyOf, RelationalFieldMapper, type ResolvedBucket, type TAdapterFactory, type TArrayPatch, type TBucketFieldSource, type TBucketSourceTable, type TBucketSourceVerdict, type TCascadeResolver, type TCascadeTarget, type TColumnDiff, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbCas, type TDbCollation, type TDbDefaultFn, type TDbDefaultValue, type TDbDeleteResult, type TDbEncryptionOptions, type TDbFieldMeta, type TDbFieldOp, type TDbForeignKey, type TDbIndex, type TDbIndexField, type TDbIndexType, type TDbInsertManyResult, type TDbInsertResult, type TDbObjectKind, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbRemoveGuard, type TDbRemoveGuardContext, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateResult, type TDbWriteAction, type TDbWriteGuard, type TDbWriteGuardContext, type TDeleteOptions, type TEnsureTableOptions, type TExistingColumn, type TExistingForeignKey, type TExistingTableOption, type TFieldMeta, type TFieldOps, type TFilterPredicate, type TFilterRef, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TGuardedQuery, type TIdDescriptor, type TIdResolveOptions, type TIdentification, type TMetaResponse, type TMetadataOverrides, type TPrimaryKeyChange, type TQueryPathKind, type TQueryPathOp, type TQueryPathRefs, type TQueryPathSource, type TReferencingForeignKey, type TRelationInfo, type TResolvedBucket, type TSearchIndexInfo, type TSyncColumnResult, type TTableOptionDiff, type TTableResolver, type TTouchManyOptions, type TValueFormatterPair, type TViewColumnMapping, type TViewJoin, type TViewPlan, type TWriteOptions, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WeekStart, type WithOptimisticRetryOptions, type WithRelation, acceptedOperatorsHint, assertGeoPoint, assertNoVersionWrites, bucketSourceVerdict, bucketTimeZoneUnavailable, buildDbValidator, buildValidationContext, canFilterLeaf, checkHavingKeys, classifyQueryPath, collectQueryPaths, computeInsights, createDbValidatorPlugin, createFailureCollector, decomposePatch, findAncestorInSet, forceNavNonOptional, getDbFieldOp, getKeyProps, guardAggregate, guardFilter, guardPath, guardPaths, guardQuery, isAtscriptDbView, isBucketableField, isDbFieldOp, isEmptyObject, isGeoIndexableType, isGeoPointType, isJsonValueField, isNavRelation, isPlainObject, isPrimitive, jsonValueAncestor, narrowerFilterOps, reconcileCas, resolveCalendarBuckets, resolveDesignType, separateCas, separateFieldOps, sortFieldNames, translateQueryTree, unsupportedOperatorMessage, walkFilter, withOptimisticRetry };