@atscript/db 0.1.154 → 0.1.156

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 (35) hide show
  1. package/dist/agg.d.cts +1 -1
  2. package/dist/agg.d.mts +1 -1
  3. package/dist/{buckets-CBKL_ZWE.d.mts → buckets-8mG67Mtw.d.mts} +168 -16
  4. package/dist/{buckets-jy8BfswO.d.cts → buckets-B4T_alUe.d.cts} +168 -16
  5. package/dist/{column-diff-DAIAq6XR.mjs → column-diff-DR1glykD.mjs} +419 -75
  6. package/dist/{column-diff-qnzx1o3c.cjs → column-diff-DpeUbhEI.cjs} +430 -74
  7. package/dist/{fk-diff-BIJ8l_hF.d.mts → fk-diff-5gX42hBt.d.mts} +2 -1
  8. package/dist/{fk-diff-D1mrLMjU.d.cts → fk-diff-BWdQ7kRZ.d.cts} +2 -1
  9. package/dist/index.cjs +3 -3
  10. package/dist/index.d.cts +15 -9
  11. package/dist/index.d.mts +15 -9
  12. package/dist/index.mjs +3 -3
  13. package/dist/plugin.cjs +21 -4
  14. package/dist/plugin.mjs +21 -4
  15. package/dist/rel.d.cts +2 -2
  16. package/dist/rel.d.mts +2 -2
  17. package/dist/{relation-helpers-BUsxNNGU.d.mts → relation-helpers-17_2f5hX.d.mts} +1 -1
  18. package/dist/{relation-helpers-D_8bydc2.d.cts → relation-helpers-BLBrLQYi.d.cts} +1 -1
  19. package/dist/{search-fields-DBIZKwyb.mjs → search-fields-CE8cmj9X.mjs} +1 -0
  20. package/dist/{search-fields-DwrsJUC1.cjs → search-fields-CT_UZ9fg.cjs} +1 -0
  21. package/dist/shared.cjs +2 -1
  22. package/dist/shared.d.cts +10 -3
  23. package/dist/shared.d.mts +10 -3
  24. package/dist/shared.mjs +2 -2
  25. package/dist/sync.cjs +317 -35
  26. package/dist/sync.d.cts +34 -5
  27. package/dist/sync.d.mts +34 -5
  28. package/dist/sync.mjs +317 -35
  29. package/dist/{validation-utils-DqZAH6aT.mjs → validation-utils-BGjqc2jU.mjs} +24 -6
  30. package/dist/{validation-utils-debIYpq0.cjs → validation-utils-CtLNlBtB.cjs} +29 -5
  31. package/dist/{validator-BACewoRj.mjs → validator-B3fPJjS1.mjs} +178 -10
  32. package/dist/{validator-BxWwh3wf.cjs → validator-B4YDLUkj.cjs} +201 -9
  33. package/dist/validator.cjs +1 -1
  34. package/dist/validator.mjs +1 -1
  35. package/package.json +6 -6
@@ -1,4 +1,4 @@
1
- import { A as TColumnDiff, Cn as AtscriptDbReadable, U as TDbFieldMeta, V as TDbDefaultValue, W as TDbForeignKey, _t as TExistingColumn, at as TDbStorageType, dn as AtscriptQueryFieldRef, fn as AtscriptQueryNode, ht as TDerivedColumn, nn as AtscriptDbView, yt as TExistingTableOption, z as TDbCollation } from "./buckets-CBKL_ZWE.mjs";
1
+ import { A as TColumnDiff, B as TDbDefaultFn, En as AtscriptDbReadable, U as TDbFieldMeta, V as TDbDefaultValue, W as TDbForeignKey, _t as TExistingColumn, an as AtscriptDbView, at as TDbStorageType, hn as AtscriptQueryNode, ht as TDerivedColumn, mn as AtscriptQueryFieldRef, yt as TExistingTableOption, z as TDbCollation } from "./buckets-8mG67Mtw.mjs";
2
2
 
3
3
  //#region src/schema/schema-hash.d.ts
4
4
  interface TFieldSnapshot {
@@ -225,6 +225,7 @@ declare function isColumnTypeChanged(existingType: string, expectedType: string)
225
225
  */
226
226
  declare function computeColumnDiff(desired: readonly TDbFieldMeta[], existing: TExistingColumn[], typeMapper?: (field: TDbFieldMeta) => string, opts?: {
227
227
  snapshot?: TTableSnapshot | null;
228
+ nativeDefaultFns?: ReadonlySet<TDbDefaultFn>;
228
229
  }): TColumnDiff;
229
230
  //#endregion
230
231
  //#region src/schema/fk-diff.d.ts
@@ -1,4 +1,4 @@
1
- import { A as TColumnDiff, Cn as AtscriptDbReadable, U as TDbFieldMeta, V as TDbDefaultValue, W as TDbForeignKey, _t as TExistingColumn, at as TDbStorageType, dn as AtscriptQueryFieldRef, fn as AtscriptQueryNode, ht as TDerivedColumn, nn as AtscriptDbView, yt as TExistingTableOption, z as TDbCollation } from "./buckets-jy8BfswO.cjs";
1
+ import { A as TColumnDiff, B as TDbDefaultFn, En as AtscriptDbReadable, U as TDbFieldMeta, V as TDbDefaultValue, W as TDbForeignKey, _t as TExistingColumn, an as AtscriptDbView, at as TDbStorageType, hn as AtscriptQueryNode, ht as TDerivedColumn, mn as AtscriptQueryFieldRef, yt as TExistingTableOption, z as TDbCollation } from "./buckets-B4T_alUe.cjs";
2
2
 
3
3
  //#region src/schema/schema-hash.d.ts
4
4
  interface TFieldSnapshot {
@@ -225,6 +225,7 @@ declare function isColumnTypeChanged(existingType: string, expectedType: string)
225
225
  */
226
226
  declare function computeColumnDiff(desired: readonly TDbFieldMeta[], existing: TExistingColumn[], typeMapper?: (field: TDbFieldMeta) => string, opts?: {
227
227
  snapshot?: TTableSnapshot | null;
228
+ nativeDefaultFns?: ReadonlySet<TDbDefaultFn>;
228
229
  }): TColumnDiff;
229
230
  //#endregion
230
231
  //#region src/schema/fk-diff.d.ts
package/dist/index.cjs CHANGED
@@ -1,13 +1,13 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_db_error = require("./db-error-JcfJqqpk.cjs");
3
- const require_column_diff = require("./column-diff-qnzx1o3c.cjs");
3
+ const require_column_diff = require("./column-diff-DpeUbhEI.cjs");
4
4
  const require_aggregate_fns = require("./aggregate-fns-DFtKAv7Q.cjs");
5
5
  const require_nested_writer = require("./nested-writer-Bl1SZS7x.cjs");
6
- const require_search_fields = require("./search-fields-DwrsJUC1.cjs");
6
+ const require_validator = require("./validator-B4YDLUkj.cjs");
7
+ const require_search_fields = require("./search-fields-CT_UZ9fg.cjs");
7
8
  const require_object = require("./object-Djg28csK.cjs");
8
9
  const require_consts = require("./consts-BzRfCcH2.cjs");
9
10
  const require_ops = require("./ops.cjs");
10
- const require_validator = require("./validator-BxWwh3wf.cjs");
11
11
  let _atscript_typescript_utils = require("@atscript/typescript/utils");
12
12
  let _uniqu_core = require("@uniqu/core");
13
13
  let node_crypto = require("node:crypto");
package/dist/index.d.cts CHANGED
@@ -1,11 +1,11 @@
1
- import { $ as TDbInsertResult, $t as DbSpace, A as TColumnDiff, An as TRelationFilterJunction, At as TReferencingForeignKey, B as TDbDefaultFn, Bn as TDbEncryptionOptions, Bt as TWriteOptions, C as NavPropsOf, Cn as AtscriptDbReadable, Ct as TIdDescriptor, D as PrimaryKeyOf, Dn as REL_FILTER_MAX_NODES, Dt as TMetaResponse, E as OwnPropsOf, En as REL_FILTER_MAX_DEPTH, Et as TInsertOptions, F as TDbActionLevel, Fn as forEachResolvedRelation, Ft as TTableOptionDiff, G as TDbIndex, Gn as TGenericLogger, Gt as WithRelation, H as TDbDeleteResult, Hn as FieldMappingStrategy, Ht as TypedWithRelation, I as TDbActionProcessor, In as hasRelationOp, It as TTableResolver, J as TDbInsertIgnoreOptions, Jn as TRowOrderKey, Jt as isGeoPointType, K as TDbIndexField, Kn as TExprAggregate, Kt as TableMetadata, L as TDbActionTargetSummary, Ln as isResolvedRelationFilter, Lt as TTouchManyOptions, M as TCrudPermissions, Mn as TRelationStaticFilter, Mt as TRowResolveOptions, N as TDbActionInfo, Nn as andFilters, Nt as TSearchIndexInfo, O as TCascadeResolver, On as ResolvedRelationFilter, Ot as TMetadataOverrides, P as TDbActionIntent, Pn as containsRelationFilter, Pt as TSyncColumnResult, Q as TDbInsertManyResult, Qt as TViewCapability, R as TDbAvailableActions, Rn as relationStaticFilter, Rt as TValueFormatterPair, S as FlatOf, Sn as TCascadePin, St as TFkLookupTarget, T as NullsPlacement, Tn as resolveDesignType, Tt as TIdentification, U as TDbFieldMeta, Un as TReadControls, Ut as Uniquery, V as TDbDefaultValue, Vn as DocumentFieldMapper, Vt as TWriteTableResolver, W as TDbForeignKey, Wn as NoopLogger, Wt as UniqueryControls, X as TDbInsertIgnoreSlot, Xt as ALL_VIEW_CAPABILITIES, Y as TDbInsertIgnoreResult, Yn as UniquSelect, Yt as ALL_BUCKET_UNITS, Z as TDbInsertManyIgnoreResult, Zt as BaseDbAdapter, _ as DbPatch, _n as isFieldRef, _t as TExistingColumn, a as isJsonValueField, an as isViewType, at as TDbStorageType, b as FieldOpsFor, bn as IntegrityStrategy, bt as TFieldMeta, c as resolveCalendarBuckets, cn as AtscriptExprNode, ct as TDbWriteAction, d as AggregateFn, dn as AtscriptQueryFieldRef, dt as TDbWriteGuard, en as TAdapterFactory, et as TDbObjectKind, f as AggregateQuery, fn as AtscriptQueryNode, ft as TDbWriteGuardContext, g as DbControls, gn as evaluateExpr, gt as TEnsureTableOptions, h as AtscriptDbWritable, hn as TViewPlan, ht as TDerivedColumn, i as isBucketableField, in as isAtscriptDbView, it as TDbRemoveGuardContext, j as TCrudOp, jn as TRelationFilterTable, jt as TRelationInfo, k as TCascadeTarget, kn as TRelGuardState, kt as TPrimaryKeyChange, l as AggregateControls, ln as AtscriptOrderItem, lt as TDbWriteCheck, mn as TViewJoin, mt as TDerivedChangeReason, n as TComputedSelect, nn as AtscriptDbView, nt as TDbRelation, o as jsonValueAncestor, on as TViewReadPlan, ot as TDbUpdateOptions, p as AggregateResult, pn as AtscriptRef, pt as TDeleteOptions, q as TDbIndexType, qn as TFirstLast, qt as isGeoIndexableType, r as TResolvedBucket, rn as TViewColumnMapping, rt as TDbRemoveGuard, s as normalizeComputedSelect, sn as aliasTargetOf, st as TDbUpdateResult, t as TBucketFieldSource, tn as TDbSpaceOptions, tt as TDbReferentialAction, u as AggregateExpr, un as AtscriptQueryComparison, ut as TDbWriteCheckContext, v as DbQuery, vn as translateQueryTree, vt as TExistingForeignKey, w as NullableOptional, wn as DbResponse, wt as TIdResolveOptions, x as FilterExpr, xn as NativeIntegrity, xt as TFkLookupResolver, y as DbRow, yn as AtscriptDbTable, yt as TExistingTableOption, z as TDbCollation, zn as DbEncryption, zt as TViewJsonType } from "./buckets-jy8BfswO.cjs";
1
+ import { $ as TDbInsertResult, $t as ALL_VIEW_CAPABILITIES, A as TColumnDiff, An as REL_FILTER_MAX_NODES, At as TPrimaryKeyChange, B as TDbDefaultFn, Bn as isResolvedRelationFilter, Bt as TValueFormatterPair, C as NavPropsOf, Cn as IntegrityStrategy, Ct as TIdDescriptor, D as PrimaryKeyOf, Dn as DbResponse, Dt as TJsonCopyTarget, E as OwnPropsOf, En as AtscriptDbReadable, Et as TInsertOptions, F as TDbActionLevel, Fn as TRelationStaticFilter, Ft as TSyncColumnResult, G as TDbIndex, Gn as FieldMappingStrategy, Gt as Uniquery, H as TDbDeleteResult, Hn as DbEncryption, Ht as TWriteOptions, I as TDbActionProcessor, In as andFilters, It as TSyncIndexesOptions, J as TDbInsertIgnoreOptions, Jn as TGenericLogger, Jt as TableMetadata, K as TDbIndexField, Kn as TReadControls, Kt as UniqueryControls, L as TDbActionTargetSummary, Ln as containsRelationFilter, Lt as TTableOptionDiff, M as TCrudPermissions, Mn as TRelGuardState, Mt as TRelationInfo, N as TDbActionInfo, Nn as TRelationFilterJunction, Nt as TRowResolveOptions, O as TCascadeResolver, On as resolveDesignType, Ot as TMetaResponse, P as TDbActionIntent, Pn as TRelationFilterTable, Pt as TSearchIndexInfo, Q as TDbInsertManyResult, Qn as UniquSelect, Qt as ALL_BUCKET_UNITS, R as TDbAvailableActions, Rn as forEachResolvedRelation, Rt as TTableResolver, S as FlatOf, Sn as AtscriptDbTable, St as TFkLookupTarget, T as NullsPlacement, Tn as TCascadePin, Tt as TIdentification, U as TDbFieldMeta, Un as TDbEncryptionOptions, Ut as TWriteTableResolver, V as TDbDefaultValue, Vn as relationStaticFilter, Vt as TViewJsonType, W as TDbForeignKey, Wn as DocumentFieldMapper, Wt as TypedWithRelation, X as TDbInsertIgnoreSlot, Xn as TFirstLast, Xt as isGeoPointType, Y as TDbInsertIgnoreResult, Yn as TExprAggregate, Yt as isGeoIndexableType, Z as TDbInsertManyIgnoreResult, Zn as TRowOrderKey, Zt as TPathPresence, _ as DbPatch, _n as TViewJoin, _t as TExistingColumn, a as isJsonValueField, an as AtscriptDbView, at as TDbStorageType, b as FieldOpsFor, bn as isFieldRef, bt as TFieldMeta, c as resolveCalendarBuckets, cn as isViewType, ct as TDbWriteAction, d as AggregateFn, dn as AtscriptExprNode, dt as TDbWriteGuard, en as BaseDbAdapter, et as TDbObjectKind, f as AggregateQuery, fn as AtscriptOrderItem, ft as TDbWriteGuardContext, g as DbControls, gn as AtscriptRef, gt as TEnsureTableOptions, h as AtscriptDbWritable, hn as AtscriptQueryNode, ht as TDerivedColumn, i as isBucketableField, in as TDbSpaceOptions, it as TDbRemoveGuardContext, j as TCrudOp, jn as ResolvedRelationFilter, jt as TReferencingForeignKey, k as TCascadeTarget, kn as REL_FILTER_MAX_DEPTH, kt as TMetadataOverrides, l as AggregateControls, ln as TViewReadPlan, lt as TDbWriteCheck, mn as AtscriptQueryFieldRef, mt as TDerivedChangeReason, n as TComputedSelect, nn as DbSpace, nt as TDbRelation, o as jsonValueAncestor, on as TViewColumnMapping, ot as TDbUpdateOptions, p as AggregateResult, pn as AtscriptQueryComparison, pt as TDeleteOptions, q as TDbIndexType, qn as NoopLogger, qt as WithRelation, r as TResolvedBucket, rn as TAdapterFactory, rt as TDbRemoveGuard, s as normalizeComputedSelect, sn as isAtscriptDbView, st as TDbUpdateResult, t as TBucketFieldSource, tn as TViewCapability, tt as TDbReferentialAction, u as AggregateExpr, un as aliasTargetOf, ut as TDbWriteCheckContext, v as DbQuery, vn as TViewPlan, vt as TExistingForeignKey, w as NullableOptional, wn as NativeIntegrity, wt as TIdResolveOptions, x as FilterExpr, xn as translateQueryTree, xt as TFkLookupResolver, y as DbRow, yn as evaluateExpr, yt as TExistingTableOption, z as TDbCollation, zn as hasRelationOp, zt as TTouchManyOptions } from "./buckets-B4T_alUe.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 { a as isPlainObject, i as isEmptyObject, n as findAncestorInSet, o as selfOrAncestor, r as getPath, t as deletePath } from "./object-CtPYTIvy.cjs";
4
4
  import { c as CalendarBucketLabel, d as WeekStart, g as ALL_AGGREGATE_FNS, l as ComputedExpr, o as BucketExpr, s as BucketUnit, u as ResolvedBucket } from "./agg-42CSpGDR.cjs";
5
5
  import { _ as aggregateFailure, a as buildValidationContext, b as isRetryableDbError, c as isNavRelation, d as getKeyProps, f as CasExhaustedError, g as aggregateExpressionsNotSupported, h as DbErrorCode, l as TArrayPatch, m as DbError, n as ValidatorMode, p as CasMismatchError, r as buildDbValidator, s as forceNavNonOptional, t as ValidationContext, u as TDbPatch, v as bucketTimeZoneUnavailable, y as isConflict } from "./validator-B3xlbrWf.cjs";
6
6
  import { n as createDbValidatorPlugin, t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.cjs";
7
- import { r as fkColumns, s as isColumnTypeChanged } from "./fk-diff-D1mrLMjU.cjs";
8
- import { i as tableNameOf } from "./relation-helpers-D_8bydc2.cjs";
7
+ import { r as fkColumns, s as isColumnTypeChanged } from "./fk-diff-BWdQ7kRZ.cjs";
8
+ import { i as tableNameOf } from "./relation-helpers-BLBrLQYi.cjs";
9
9
  import { AggregateQuery as AggregateQuery$1, FilterExpr as FilterExpr$1, FilterVisitor, RELATION_OPS, RelationOp, RelationOp as RelationOp$1, ResolvedRowOrderKey, ResolvedSelectExpr, Uniquery as Uniquery$1, computeInsights, isPrimitive, isRelationOp, walkFilter } from "@uniqu/core";
10
10
  import { AtscriptExprNode as AtscriptExprNode$1, TAtscriptAnnotatedType } from "@atscript/typescript/utils";
11
11
 
@@ -177,6 +177,11 @@ type TFilterPredicate = "compare" | "geo" | "exists" | "relation";
177
177
  interface TFilterRef {
178
178
  path: string;
179
179
  predicate: TFilterPredicate;
180
+ /**
181
+ * The entry only tests presence (`null`, `$eq` / `$ne: null`, `$exists`)
182
+ * — the one filter a stored object accepts (since 0.1.155).
183
+ */
184
+ nullTest?: boolean;
180
185
  /**
181
186
  * `relation` entries: each operator with its operand (a filter on the
182
187
  * related table, not walked here). @since 0.1.147
@@ -386,7 +391,7 @@ declare function classifyQueryPath(source: TQueryPathSource, path: string): {
386
391
  * `FieldCapabilityIndex`, with `$with` hints and leaf lists) is what clients
387
392
  * see and is authoritative — the HTTP gate always answers first.
388
393
  */
389
- declare function guardPath(meta: TableMetadata, adapter: BaseDbAdapter, path: string, op: TQueryPathOp, predicate?: TFilterPredicate): void;
394
+ declare function guardPath(meta: TableMetadata, adapter: BaseDbAdapter, path: string, op: TQueryPathOp, predicate?: TFilterPredicate, nullTest?: boolean): void;
390
395
  /**
391
396
  * Core backstop for every read / aggregate / mutation-filter entry point:
392
397
  * each referenced path (see {@link collectQueryPaths}) must exist on THIS
@@ -636,10 +641,11 @@ declare function assertNoVersionWrites(data: Record<string, unknown>, versionCol
636
641
  * Whether a logical (pre-decomposition) patch writes ONLY version-exempt
637
642
  * fields (`@db.column.version.exempt`). `data` has nav fields, filter keys and
638
643
  * derived fields removed and `$cas` separated. Mirrors `flattenPatchPayload`
639
- * (keep the two side by side): PK keys are skipped; an exempt path (or one
640
- * under an exempt ancestor) is covered whatever its value (scalar, field op,
641
- * array ops, object); a non-exempt merge-strategy object recurses (only the
642
- * supplied children are written); anything else is a non-exempt write.
644
+ * (keep the two side by side): PK keys and `@db.onUpdate.now` fields are
645
+ * skipped; an exempt path (or one under an exempt ancestor) is covered
646
+ * whatever its value (scalar, field op, array ops, object); a non-exempt
647
+ * merge-strategy object recurses (only the supplied children are written);
648
+ * anything else is a non-exempt write.
643
649
  * True iff at least one key is covered and none is not.
644
650
  * @since 0.1.150
645
651
  */
@@ -686,4 +692,4 @@ declare function createFailureCollector(what: string): {
686
692
  */
687
693
  declare function numericOperandProblem(fd: TDbFieldMeta): string | undefined;
688
694
  //#endregion
689
- export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, ADAPTER_FILTER_REASON, ALL_AGGREGATE_FNS, ALL_BUCKET_UNITS, ALL_VIEW_CAPABILITIES, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptExprNode, type AtscriptOrderItem, 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, INTEGER_REGEX_OP, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type NullableOptional, type NullsPlacement, type OwnPropsOf, type PrimaryKeyOf, RELATION_OPS, REL_FILTER_MAX_DEPTH, REL_FILTER_MAX_NODES, type RelationOp, RelationalFieldMapper, type ResolvedBucket, ResolvedRelationFilter, 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 TDbActionTargetSummary, type TDbAvailableActions, 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 TDbInsertIgnoreOptions, type TDbInsertIgnoreResult, type TDbInsertIgnoreSlot, type TDbInsertManyIgnoreResult, type TDbInsertManyResult, type TDbInsertResult, type TDbObjectKind, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbRemoveGuard, type TDbRemoveGuardContext, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateOptions, type TDbUpdateResult, type TDbWriteAction, type TDbWriteCheck, type TDbWriteCheckContext, type TDbWriteGuard, type TDbWriteGuardContext, type TDeleteOptions, type TDerivedChangeReason, type TDerivedColumn, type TEnsureTableOptions, type TExistingColumn, type TExistingForeignKey, type TExistingTableOption, type TExprAggregate, type TFieldMeta, type TFieldOps, type TFilterPredicate, type TFilterRef, type TFirstLast, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TGroupSourceVerdict, type TGuardedQuery, type TIdDescriptor, type TIdResolveOptions, type TIdentification, type TInsertOptions, type TMetaResponse, type TMetadataOverrides, type TPrimaryKeyChange, type TQueryPathKind, type TQueryPathOp, type TQueryPathRefs, type TQueryPathSource, type TReadColumnsKind, type TReadControls, type TReferencingForeignKey, type TRelationFilterJunction, type TRelationFilterTable, type TRelationInfo, type TRelationStaticFilter, type TResolvedBucket, type TRowOrderKey, type TRowResolveOptions, type TSearchIndexInfo, type TSearchMemberKind, type TSyncColumnResult, type TTableOptionDiff, type TTableResolver, type TTouchManyOptions, type TValueFormatterPair, type TViewCapability, type TViewColumnMapping, type TViewJoin, type TViewJsonType, type TViewPlan, type TViewReadPlan, type TWriteOptions, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WeekStart, type WithOptimisticRetryOptions, type WithRelation, acceptedOperatorsHint, aggregateExpressionsNotSupported, aggregateFailure, aliasTargetOf, andFilters, assertGeoPoint, assertNoVersionWrites, bucketSourceVerdict, bucketTimeZoneUnavailable, buildDbValidator, buildValidationContext, canFilterLeaf, checkHavingKeys, classifyQueryPath, collectQueryPaths, computeInsights, containsRelationFilter, createDbValidatorPlugin, createFailureCollector, decomposePatch, defaultFulltextIndex, deletePath, describeFulltext, evaluateExpr, findAncestorInSet, fkColumns, forEachResolvedRelation, forceNavNonOptional, geoIndexNotFoundMessage, getDbFieldOp, getKeyProps, getPath, groupSourceVerdict, guardAggregate, guardFilter, guardPath, guardPaths, guardQuery, hasRelationOp, isAtscriptDbView, isBucketableField, isColumnTypeChanged, isConflict, isDbEntityType, isDbFieldOp, isEmptyObject, isFieldRef, isGeoIndexableType, isGeoPointType, isJsonValueField, isNavRelation, isPlainObject, isPrimitive, isRelationOp, isResolvedRelationFilter, isRetryableDbError, isVersionExemptPatch, isViewType, jsonValueAncestor, narrowerFilterOps, normalizeComputedSelect, numericOperandProblem, queryReadColumns, reconcileCas, relationStaticFilter, resolveCalendarBuckets, resolveDesignType, searchIndexNotFoundMessage, searchMemberKind, searchTermInteger, selfOrAncestor, separateCas, separateFieldOps, sortFieldNames, splitFulltextFields, tableNameOf, translateQueryTree, uniqueKeyTuple, unsupportedOperatorMessage, vectorIndexNotFoundMessage, walkFilter, withOptimisticRetry };
695
+ export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, ADAPTER_FILTER_REASON, ALL_AGGREGATE_FNS, ALL_BUCKET_UNITS, ALL_VIEW_CAPABILITIES, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptExprNode, type AtscriptOrderItem, 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, INTEGER_REGEX_OP, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type NullableOptional, type NullsPlacement, type OwnPropsOf, type PrimaryKeyOf, RELATION_OPS, REL_FILTER_MAX_DEPTH, REL_FILTER_MAX_NODES, type RelationOp, RelationalFieldMapper, type ResolvedBucket, ResolvedRelationFilter, 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 TDbActionTargetSummary, type TDbAvailableActions, 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 TDbInsertIgnoreOptions, type TDbInsertIgnoreResult, type TDbInsertIgnoreSlot, type TDbInsertManyIgnoreResult, type TDbInsertManyResult, type TDbInsertResult, type TDbObjectKind, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbRemoveGuard, type TDbRemoveGuardContext, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateOptions, type TDbUpdateResult, type TDbWriteAction, type TDbWriteCheck, type TDbWriteCheckContext, type TDbWriteGuard, type TDbWriteGuardContext, type TDeleteOptions, type TDerivedChangeReason, type TDerivedColumn, type TEnsureTableOptions, type TExistingColumn, type TExistingForeignKey, type TExistingTableOption, type TExprAggregate, type TFieldMeta, type TFieldOps, type TFilterPredicate, type TFilterRef, type TFirstLast, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TGroupSourceVerdict, type TGuardedQuery, type TIdDescriptor, type TIdResolveOptions, type TIdentification, type TInsertOptions, type TJsonCopyTarget, type TMetaResponse, type TMetadataOverrides, type TPathPresence, type TPrimaryKeyChange, type TQueryPathKind, type TQueryPathOp, type TQueryPathRefs, type TQueryPathSource, type TReadColumnsKind, type TReadControls, type TReferencingForeignKey, type TRelationFilterJunction, type TRelationFilterTable, type TRelationInfo, type TRelationStaticFilter, type TResolvedBucket, type TRowOrderKey, type TRowResolveOptions, type TSearchIndexInfo, type TSearchMemberKind, type TSyncColumnResult, type TSyncIndexesOptions, type TTableOptionDiff, type TTableResolver, type TTouchManyOptions, type TValueFormatterPair, type TViewCapability, type TViewColumnMapping, type TViewJoin, type TViewJsonType, type TViewPlan, type TViewReadPlan, type TWriteOptions, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WeekStart, type WithOptimisticRetryOptions, type WithRelation, acceptedOperatorsHint, aggregateExpressionsNotSupported, aggregateFailure, aliasTargetOf, andFilters, assertGeoPoint, assertNoVersionWrites, bucketSourceVerdict, bucketTimeZoneUnavailable, buildDbValidator, buildValidationContext, canFilterLeaf, checkHavingKeys, classifyQueryPath, collectQueryPaths, computeInsights, containsRelationFilter, createDbValidatorPlugin, createFailureCollector, decomposePatch, defaultFulltextIndex, deletePath, describeFulltext, evaluateExpr, findAncestorInSet, fkColumns, forEachResolvedRelation, forceNavNonOptional, geoIndexNotFoundMessage, getDbFieldOp, getKeyProps, getPath, groupSourceVerdict, guardAggregate, guardFilter, guardPath, guardPaths, guardQuery, hasRelationOp, isAtscriptDbView, isBucketableField, isColumnTypeChanged, isConflict, isDbEntityType, isDbFieldOp, isEmptyObject, isFieldRef, isGeoIndexableType, isGeoPointType, isJsonValueField, isNavRelation, isPlainObject, isPrimitive, isRelationOp, isResolvedRelationFilter, isRetryableDbError, isVersionExemptPatch, isViewType, jsonValueAncestor, narrowerFilterOps, normalizeComputedSelect, numericOperandProblem, queryReadColumns, reconcileCas, relationStaticFilter, resolveCalendarBuckets, resolveDesignType, searchIndexNotFoundMessage, searchMemberKind, searchTermInteger, selfOrAncestor, separateCas, separateFieldOps, sortFieldNames, splitFulltextFields, tableNameOf, translateQueryTree, uniqueKeyTuple, unsupportedOperatorMessage, vectorIndexNotFoundMessage, walkFilter, withOptimisticRetry };
package/dist/index.d.mts CHANGED
@@ -1,11 +1,11 @@
1
- import { $ as TDbInsertResult, $t as DbSpace, A as TColumnDiff, An as TRelationFilterJunction, At as TReferencingForeignKey, B as TDbDefaultFn, Bn as TDbEncryptionOptions, Bt as TWriteOptions, C as NavPropsOf, Cn as AtscriptDbReadable, Ct as TIdDescriptor, D as PrimaryKeyOf, Dn as REL_FILTER_MAX_NODES, Dt as TMetaResponse, E as OwnPropsOf, En as REL_FILTER_MAX_DEPTH, Et as TInsertOptions, F as TDbActionLevel, Fn as forEachResolvedRelation, Ft as TTableOptionDiff, G as TDbIndex, Gn as TGenericLogger, Gt as WithRelation, H as TDbDeleteResult, Hn as FieldMappingStrategy, Ht as TypedWithRelation, I as TDbActionProcessor, In as hasRelationOp, It as TTableResolver, J as TDbInsertIgnoreOptions, Jn as TRowOrderKey, Jt as isGeoPointType, K as TDbIndexField, Kn as TExprAggregate, Kt as TableMetadata, L as TDbActionTargetSummary, Ln as isResolvedRelationFilter, Lt as TTouchManyOptions, M as TCrudPermissions, Mn as TRelationStaticFilter, Mt as TRowResolveOptions, N as TDbActionInfo, Nn as andFilters, Nt as TSearchIndexInfo, O as TCascadeResolver, On as ResolvedRelationFilter, Ot as TMetadataOverrides, P as TDbActionIntent, Pn as containsRelationFilter, Pt as TSyncColumnResult, Q as TDbInsertManyResult, Qt as TViewCapability, R as TDbAvailableActions, Rn as relationStaticFilter, Rt as TValueFormatterPair, S as FlatOf, Sn as TCascadePin, St as TFkLookupTarget, T as NullsPlacement, Tn as resolveDesignType, Tt as TIdentification, U as TDbFieldMeta, Un as TReadControls, Ut as Uniquery, V as TDbDefaultValue, Vn as DocumentFieldMapper, Vt as TWriteTableResolver, W as TDbForeignKey, Wn as NoopLogger, Wt as UniqueryControls, X as TDbInsertIgnoreSlot, Xt as ALL_VIEW_CAPABILITIES, Y as TDbInsertIgnoreResult, Yn as UniquSelect, Yt as ALL_BUCKET_UNITS, Z as TDbInsertManyIgnoreResult, Zt as BaseDbAdapter, _ as DbPatch, _n as isFieldRef, _t as TExistingColumn, a as isJsonValueField, an as isViewType, at as TDbStorageType, b as FieldOpsFor, bn as IntegrityStrategy, bt as TFieldMeta, c as resolveCalendarBuckets, cn as AtscriptExprNode, ct as TDbWriteAction, d as AggregateFn, dn as AtscriptQueryFieldRef, dt as TDbWriteGuard, en as TAdapterFactory, et as TDbObjectKind, f as AggregateQuery, fn as AtscriptQueryNode, ft as TDbWriteGuardContext, g as DbControls, gn as evaluateExpr, gt as TEnsureTableOptions, h as AtscriptDbWritable, hn as TViewPlan, ht as TDerivedColumn, i as isBucketableField, in as isAtscriptDbView, it as TDbRemoveGuardContext, j as TCrudOp, jn as TRelationFilterTable, jt as TRelationInfo, k as TCascadeTarget, kn as TRelGuardState, kt as TPrimaryKeyChange, l as AggregateControls, ln as AtscriptOrderItem, lt as TDbWriteCheck, mn as TViewJoin, mt as TDerivedChangeReason, n as TComputedSelect, nn as AtscriptDbView, nt as TDbRelation, o as jsonValueAncestor, on as TViewReadPlan, ot as TDbUpdateOptions, p as AggregateResult, pn as AtscriptRef, pt as TDeleteOptions, q as TDbIndexType, qn as TFirstLast, qt as isGeoIndexableType, r as TResolvedBucket, rn as TViewColumnMapping, rt as TDbRemoveGuard, s as normalizeComputedSelect, sn as aliasTargetOf, st as TDbUpdateResult, t as TBucketFieldSource, tn as TDbSpaceOptions, tt as TDbReferentialAction, u as AggregateExpr, un as AtscriptQueryComparison, ut as TDbWriteCheckContext, v as DbQuery, vn as translateQueryTree, vt as TExistingForeignKey, w as NullableOptional, wn as DbResponse, wt as TIdResolveOptions, x as FilterExpr, xn as NativeIntegrity, xt as TFkLookupResolver, y as DbRow, yn as AtscriptDbTable, yt as TExistingTableOption, z as TDbCollation, zn as DbEncryption, zt as TViewJsonType } from "./buckets-CBKL_ZWE.mjs";
1
+ import { $ as TDbInsertResult, $t as ALL_VIEW_CAPABILITIES, A as TColumnDiff, An as REL_FILTER_MAX_NODES, At as TPrimaryKeyChange, B as TDbDefaultFn, Bn as isResolvedRelationFilter, Bt as TValueFormatterPair, C as NavPropsOf, Cn as IntegrityStrategy, Ct as TIdDescriptor, D as PrimaryKeyOf, Dn as DbResponse, Dt as TJsonCopyTarget, E as OwnPropsOf, En as AtscriptDbReadable, Et as TInsertOptions, F as TDbActionLevel, Fn as TRelationStaticFilter, Ft as TSyncColumnResult, G as TDbIndex, Gn as FieldMappingStrategy, Gt as Uniquery, H as TDbDeleteResult, Hn as DbEncryption, Ht as TWriteOptions, I as TDbActionProcessor, In as andFilters, It as TSyncIndexesOptions, J as TDbInsertIgnoreOptions, Jn as TGenericLogger, Jt as TableMetadata, K as TDbIndexField, Kn as TReadControls, Kt as UniqueryControls, L as TDbActionTargetSummary, Ln as containsRelationFilter, Lt as TTableOptionDiff, M as TCrudPermissions, Mn as TRelGuardState, Mt as TRelationInfo, N as TDbActionInfo, Nn as TRelationFilterJunction, Nt as TRowResolveOptions, O as TCascadeResolver, On as resolveDesignType, Ot as TMetaResponse, P as TDbActionIntent, Pn as TRelationFilterTable, Pt as TSearchIndexInfo, Q as TDbInsertManyResult, Qn as UniquSelect, Qt as ALL_BUCKET_UNITS, R as TDbAvailableActions, Rn as forEachResolvedRelation, Rt as TTableResolver, S as FlatOf, Sn as AtscriptDbTable, St as TFkLookupTarget, T as NullsPlacement, Tn as TCascadePin, Tt as TIdentification, U as TDbFieldMeta, Un as TDbEncryptionOptions, Ut as TWriteTableResolver, V as TDbDefaultValue, Vn as relationStaticFilter, Vt as TViewJsonType, W as TDbForeignKey, Wn as DocumentFieldMapper, Wt as TypedWithRelation, X as TDbInsertIgnoreSlot, Xn as TFirstLast, Xt as isGeoPointType, Y as TDbInsertIgnoreResult, Yn as TExprAggregate, Yt as isGeoIndexableType, Z as TDbInsertManyIgnoreResult, Zn as TRowOrderKey, Zt as TPathPresence, _ as DbPatch, _n as TViewJoin, _t as TExistingColumn, a as isJsonValueField, an as AtscriptDbView, at as TDbStorageType, b as FieldOpsFor, bn as isFieldRef, bt as TFieldMeta, c as resolveCalendarBuckets, cn as isViewType, ct as TDbWriteAction, d as AggregateFn, dn as AtscriptExprNode, dt as TDbWriteGuard, en as BaseDbAdapter, et as TDbObjectKind, f as AggregateQuery, fn as AtscriptOrderItem, ft as TDbWriteGuardContext, g as DbControls, gn as AtscriptRef, gt as TEnsureTableOptions, h as AtscriptDbWritable, hn as AtscriptQueryNode, ht as TDerivedColumn, i as isBucketableField, in as TDbSpaceOptions, it as TDbRemoveGuardContext, j as TCrudOp, jn as ResolvedRelationFilter, jt as TReferencingForeignKey, k as TCascadeTarget, kn as REL_FILTER_MAX_DEPTH, kt as TMetadataOverrides, l as AggregateControls, ln as TViewReadPlan, lt as TDbWriteCheck, mn as AtscriptQueryFieldRef, mt as TDerivedChangeReason, n as TComputedSelect, nn as DbSpace, nt as TDbRelation, o as jsonValueAncestor, on as TViewColumnMapping, ot as TDbUpdateOptions, p as AggregateResult, pn as AtscriptQueryComparison, pt as TDeleteOptions, q as TDbIndexType, qn as NoopLogger, qt as WithRelation, r as TResolvedBucket, rn as TAdapterFactory, rt as TDbRemoveGuard, s as normalizeComputedSelect, sn as isAtscriptDbView, st as TDbUpdateResult, t as TBucketFieldSource, tn as TViewCapability, tt as TDbReferentialAction, u as AggregateExpr, un as aliasTargetOf, ut as TDbWriteCheckContext, v as DbQuery, vn as TViewPlan, vt as TExistingForeignKey, w as NullableOptional, wn as NativeIntegrity, wt as TIdResolveOptions, x as FilterExpr, xn as translateQueryTree, xt as TFkLookupResolver, y as DbRow, yn as evaluateExpr, yt as TExistingTableOption, z as TDbCollation, zn as hasRelationOp, zt as TTouchManyOptions } from "./buckets-8mG67Mtw.mjs";
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.mjs";
3
3
  import { a as isPlainObject, i as isEmptyObject, n as findAncestorInSet, o as selfOrAncestor, r as getPath, t as deletePath } from "./object-CtPYTIvy.mjs";
4
4
  import { c as CalendarBucketLabel, d as WeekStart, g as ALL_AGGREGATE_FNS, l as ComputedExpr, o as BucketExpr, s as BucketUnit, u as ResolvedBucket } from "./agg-Wo-smrYV.mjs";
5
5
  import { _ as aggregateFailure, a as buildValidationContext, b as isRetryableDbError, c as isNavRelation, d as getKeyProps, f as CasExhaustedError, g as aggregateExpressionsNotSupported, h as DbErrorCode, l as TArrayPatch, m as DbError, n as ValidatorMode, p as CasMismatchError, r as buildDbValidator, s as forceNavNonOptional, t as ValidationContext, u as TDbPatch, v as bucketTimeZoneUnavailable, y as isConflict } from "./validator-B3xlbrWf.mjs";
6
6
  import { n as createDbValidatorPlugin, t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.mjs";
7
- import { r as fkColumns, s as isColumnTypeChanged } from "./fk-diff-BIJ8l_hF.mjs";
8
- import { i as tableNameOf } from "./relation-helpers-BUsxNNGU.mjs";
7
+ import { r as fkColumns, s as isColumnTypeChanged } from "./fk-diff-5gX42hBt.mjs";
8
+ import { i as tableNameOf } from "./relation-helpers-17_2f5hX.mjs";
9
9
  import { AtscriptExprNode as AtscriptExprNode$1, TAtscriptAnnotatedType } from "@atscript/typescript/utils";
10
10
  import { AggregateQuery as AggregateQuery$1, FilterExpr as FilterExpr$1, FilterVisitor, RELATION_OPS, RelationOp, RelationOp as RelationOp$1, ResolvedRowOrderKey, ResolvedSelectExpr, Uniquery as Uniquery$1, computeInsights, isPrimitive, isRelationOp, walkFilter } from "@uniqu/core";
11
11
 
@@ -177,6 +177,11 @@ type TFilterPredicate = "compare" | "geo" | "exists" | "relation";
177
177
  interface TFilterRef {
178
178
  path: string;
179
179
  predicate: TFilterPredicate;
180
+ /**
181
+ * The entry only tests presence (`null`, `$eq` / `$ne: null`, `$exists`)
182
+ * — the one filter a stored object accepts (since 0.1.155).
183
+ */
184
+ nullTest?: boolean;
180
185
  /**
181
186
  * `relation` entries: each operator with its operand (a filter on the
182
187
  * related table, not walked here). @since 0.1.147
@@ -386,7 +391,7 @@ declare function classifyQueryPath(source: TQueryPathSource, path: string): {
386
391
  * `FieldCapabilityIndex`, with `$with` hints and leaf lists) is what clients
387
392
  * see and is authoritative — the HTTP gate always answers first.
388
393
  */
389
- declare function guardPath(meta: TableMetadata, adapter: BaseDbAdapter, path: string, op: TQueryPathOp, predicate?: TFilterPredicate): void;
394
+ declare function guardPath(meta: TableMetadata, adapter: BaseDbAdapter, path: string, op: TQueryPathOp, predicate?: TFilterPredicate, nullTest?: boolean): void;
390
395
  /**
391
396
  * Core backstop for every read / aggregate / mutation-filter entry point:
392
397
  * each referenced path (see {@link collectQueryPaths}) must exist on THIS
@@ -636,10 +641,11 @@ declare function assertNoVersionWrites(data: Record<string, unknown>, versionCol
636
641
  * Whether a logical (pre-decomposition) patch writes ONLY version-exempt
637
642
  * fields (`@db.column.version.exempt`). `data` has nav fields, filter keys and
638
643
  * derived fields removed and `$cas` separated. Mirrors `flattenPatchPayload`
639
- * (keep the two side by side): PK keys are skipped; an exempt path (or one
640
- * under an exempt ancestor) is covered whatever its value (scalar, field op,
641
- * array ops, object); a non-exempt merge-strategy object recurses (only the
642
- * supplied children are written); anything else is a non-exempt write.
644
+ * (keep the two side by side): PK keys and `@db.onUpdate.now` fields are
645
+ * skipped; an exempt path (or one under an exempt ancestor) is covered
646
+ * whatever its value (scalar, field op, array ops, object); a non-exempt
647
+ * merge-strategy object recurses (only the supplied children are written);
648
+ * anything else is a non-exempt write.
643
649
  * True iff at least one key is covered and none is not.
644
650
  * @since 0.1.150
645
651
  */
@@ -686,4 +692,4 @@ declare function createFailureCollector(what: string): {
686
692
  */
687
693
  declare function numericOperandProblem(fd: TDbFieldMeta): string | undefined;
688
694
  //#endregion
689
- export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, ADAPTER_FILTER_REASON, ALL_AGGREGATE_FNS, ALL_BUCKET_UNITS, ALL_VIEW_CAPABILITIES, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptExprNode, type AtscriptOrderItem, 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, INTEGER_REGEX_OP, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type NullableOptional, type NullsPlacement, type OwnPropsOf, type PrimaryKeyOf, RELATION_OPS, REL_FILTER_MAX_DEPTH, REL_FILTER_MAX_NODES, type RelationOp, RelationalFieldMapper, type ResolvedBucket, ResolvedRelationFilter, 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 TDbActionTargetSummary, type TDbAvailableActions, 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 TDbInsertIgnoreOptions, type TDbInsertIgnoreResult, type TDbInsertIgnoreSlot, type TDbInsertManyIgnoreResult, type TDbInsertManyResult, type TDbInsertResult, type TDbObjectKind, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbRemoveGuard, type TDbRemoveGuardContext, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateOptions, type TDbUpdateResult, type TDbWriteAction, type TDbWriteCheck, type TDbWriteCheckContext, type TDbWriteGuard, type TDbWriteGuardContext, type TDeleteOptions, type TDerivedChangeReason, type TDerivedColumn, type TEnsureTableOptions, type TExistingColumn, type TExistingForeignKey, type TExistingTableOption, type TExprAggregate, type TFieldMeta, type TFieldOps, type TFilterPredicate, type TFilterRef, type TFirstLast, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TGroupSourceVerdict, type TGuardedQuery, type TIdDescriptor, type TIdResolveOptions, type TIdentification, type TInsertOptions, type TMetaResponse, type TMetadataOverrides, type TPrimaryKeyChange, type TQueryPathKind, type TQueryPathOp, type TQueryPathRefs, type TQueryPathSource, type TReadColumnsKind, type TReadControls, type TReferencingForeignKey, type TRelationFilterJunction, type TRelationFilterTable, type TRelationInfo, type TRelationStaticFilter, type TResolvedBucket, type TRowOrderKey, type TRowResolveOptions, type TSearchIndexInfo, type TSearchMemberKind, type TSyncColumnResult, type TTableOptionDiff, type TTableResolver, type TTouchManyOptions, type TValueFormatterPair, type TViewCapability, type TViewColumnMapping, type TViewJoin, type TViewJsonType, type TViewPlan, type TViewReadPlan, type TWriteOptions, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WeekStart, type WithOptimisticRetryOptions, type WithRelation, acceptedOperatorsHint, aggregateExpressionsNotSupported, aggregateFailure, aliasTargetOf, andFilters, assertGeoPoint, assertNoVersionWrites, bucketSourceVerdict, bucketTimeZoneUnavailable, buildDbValidator, buildValidationContext, canFilterLeaf, checkHavingKeys, classifyQueryPath, collectQueryPaths, computeInsights, containsRelationFilter, createDbValidatorPlugin, createFailureCollector, decomposePatch, defaultFulltextIndex, deletePath, describeFulltext, evaluateExpr, findAncestorInSet, fkColumns, forEachResolvedRelation, forceNavNonOptional, geoIndexNotFoundMessage, getDbFieldOp, getKeyProps, getPath, groupSourceVerdict, guardAggregate, guardFilter, guardPath, guardPaths, guardQuery, hasRelationOp, isAtscriptDbView, isBucketableField, isColumnTypeChanged, isConflict, isDbEntityType, isDbFieldOp, isEmptyObject, isFieldRef, isGeoIndexableType, isGeoPointType, isJsonValueField, isNavRelation, isPlainObject, isPrimitive, isRelationOp, isResolvedRelationFilter, isRetryableDbError, isVersionExemptPatch, isViewType, jsonValueAncestor, narrowerFilterOps, normalizeComputedSelect, numericOperandProblem, queryReadColumns, reconcileCas, relationStaticFilter, resolveCalendarBuckets, resolveDesignType, searchIndexNotFoundMessage, searchMemberKind, searchTermInteger, selfOrAncestor, separateCas, separateFieldOps, sortFieldNames, splitFulltextFields, tableNameOf, translateQueryTree, uniqueKeyTuple, unsupportedOperatorMessage, vectorIndexNotFoundMessage, walkFilter, withOptimisticRetry };
695
+ export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, ADAPTER_FILTER_REASON, ALL_AGGREGATE_FNS, ALL_BUCKET_UNITS, ALL_VIEW_CAPABILITIES, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptExprNode, type AtscriptOrderItem, 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, INTEGER_REGEX_OP, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type NullableOptional, type NullsPlacement, type OwnPropsOf, type PrimaryKeyOf, RELATION_OPS, REL_FILTER_MAX_DEPTH, REL_FILTER_MAX_NODES, type RelationOp, RelationalFieldMapper, type ResolvedBucket, ResolvedRelationFilter, 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 TDbActionTargetSummary, type TDbAvailableActions, 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 TDbInsertIgnoreOptions, type TDbInsertIgnoreResult, type TDbInsertIgnoreSlot, type TDbInsertManyIgnoreResult, type TDbInsertManyResult, type TDbInsertResult, type TDbObjectKind, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbRemoveGuard, type TDbRemoveGuardContext, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateOptions, type TDbUpdateResult, type TDbWriteAction, type TDbWriteCheck, type TDbWriteCheckContext, type TDbWriteGuard, type TDbWriteGuardContext, type TDeleteOptions, type TDerivedChangeReason, type TDerivedColumn, type TEnsureTableOptions, type TExistingColumn, type TExistingForeignKey, type TExistingTableOption, type TExprAggregate, type TFieldMeta, type TFieldOps, type TFilterPredicate, type TFilterRef, type TFirstLast, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TGroupSourceVerdict, type TGuardedQuery, type TIdDescriptor, type TIdResolveOptions, type TIdentification, type TInsertOptions, type TJsonCopyTarget, type TMetaResponse, type TMetadataOverrides, type TPathPresence, type TPrimaryKeyChange, type TQueryPathKind, type TQueryPathOp, type TQueryPathRefs, type TQueryPathSource, type TReadColumnsKind, type TReadControls, type TReferencingForeignKey, type TRelationFilterJunction, type TRelationFilterTable, type TRelationInfo, type TRelationStaticFilter, type TResolvedBucket, type TRowOrderKey, type TRowResolveOptions, type TSearchIndexInfo, type TSearchMemberKind, type TSyncColumnResult, type TSyncIndexesOptions, type TTableOptionDiff, type TTableResolver, type TTouchManyOptions, type TValueFormatterPair, type TViewCapability, type TViewColumnMapping, type TViewJoin, type TViewJsonType, type TViewPlan, type TViewReadPlan, type TWriteOptions, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WeekStart, type WithOptimisticRetryOptions, type WithRelation, acceptedOperatorsHint, aggregateExpressionsNotSupported, aggregateFailure, aliasTargetOf, andFilters, assertGeoPoint, assertNoVersionWrites, bucketSourceVerdict, bucketTimeZoneUnavailable, buildDbValidator, buildValidationContext, canFilterLeaf, checkHavingKeys, classifyQueryPath, collectQueryPaths, computeInsights, containsRelationFilter, createDbValidatorPlugin, createFailureCollector, decomposePatch, defaultFulltextIndex, deletePath, describeFulltext, evaluateExpr, findAncestorInSet, fkColumns, forEachResolvedRelation, forceNavNonOptional, geoIndexNotFoundMessage, getDbFieldOp, getKeyProps, getPath, groupSourceVerdict, guardAggregate, guardFilter, guardPath, guardPaths, guardQuery, hasRelationOp, isAtscriptDbView, isBucketableField, isColumnTypeChanged, isConflict, isDbEntityType, isDbFieldOp, isEmptyObject, isFieldRef, isGeoIndexableType, isGeoPointType, isJsonValueField, isNavRelation, isPlainObject, isPrimitive, isRelationOp, isResolvedRelationFilter, isRetryableDbError, isVersionExemptPatch, isViewType, jsonValueAncestor, narrowerFilterOps, normalizeComputedSelect, numericOperandProblem, queryReadColumns, reconcileCas, relationStaticFilter, resolveCalendarBuckets, resolveDesignType, searchIndexNotFoundMessage, searchMemberKind, searchTermInteger, selfOrAncestor, separateCas, separateFieldOps, sortFieldNames, splitFulltextFields, tableNameOf, translateQueryTree, uniqueKeyTuple, unsupportedOperatorMessage, vectorIndexNotFoundMessage, walkFilter, withOptimisticRetry };
package/dist/index.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  import { a as aggregateExpressionsNotSupported, c as isConflict, l as isRetryableDbError, n as CasMismatchError, o as aggregateFailure, r as DbError, s as bucketTimeZoneUnavailable, t as CasExhaustedError, u as spaceClosedError } from "./db-error-eSsQX7rt.mjs";
2
- import { $ as DocumentFieldMapper, A as resolveDesignType, B as checkHavingKeys, C as ALL_BUCKET_UNITS, D as IntegrityStrategy, E as createFailureCollector, F as ENCRYPTED_REASON, G as guardFilter, H as collectQueryPaths, I as acceptedOperatorsHint, J as guardQuery, K as guardPath, L as assertGeoPoint, M as searchIndexNotFoundMessage, N as vectorIndexNotFoundMessage, O as NativeIntegrity, P as ADAPTER_FILTER_REASON, Q as RelationalFieldMapper, R as bucketSourceVerdict, S as ApplicationIntegrity, T as BaseDbAdapter, U as groupSourceVerdict, V as classifyQueryPath, W as guardAggregate, X as sortFieldNames, Y as narrowerFilterOps, Z as unsupportedOperatorMessage, _ as isViewType, _t as NoopLogger, at as describeFulltext, b as assertNoVersionWrites, ct as TableMetadata, dt as aliasTargetOf, et as FieldMappingStrategy, f as fkColumns, ft as isBucketableField, g as isAtscriptDbView, gt as resolveCalendarBuckets, h as AtscriptDbView, ht as normalizeComputedSelect, it as defaultFulltextIndex, j as geoIndexNotFoundMessage, k as AtscriptDbReadable, lt as isGeoIndexableType, mt as jsonValueAncestor, n as isColumnTypeChanged, nt as numericOperandProblem, ot as searchTermInteger, pt as isJsonValueField, q as guardPaths, rt as INTEGER_REGEX_OP, st as splitFulltextFields, tt as UniquSelect, ut as isGeoPointType, v as AtscriptDbTable, w as ALL_VIEW_CAPABILITIES, x as decomposePatch, y as isVersionExemptPatch, z as canFilterLeaf } from "./column-diff-DAIAq6XR.mjs";
2
+ import { $ as RelationalFieldMapper, A as AtscriptDbReadable, B as canFilterLeaf, C as ApplicationIntegrity, D as createFailureCollector, E as BaseDbAdapter, F as ADAPTER_FILTER_REASON, G as guardAggregate, H as classifyQueryPath, I as ENCRYPTED_REASON, J as guardPaths, K as guardFilter, L as acceptedOperatorsHint, M as geoIndexNotFoundMessage, N as searchIndexNotFoundMessage, O as IntegrityStrategy, P as vectorIndexNotFoundMessage, Q as unsupportedOperatorMessage, R as assertGeoPoint, S as decomposePatch, T as ALL_VIEW_CAPABILITIES, U as collectQueryPaths, V as checkHavingKeys, W as groupSourceVerdict, X as narrowerFilterOps, Y as guardQuery, Z as sortFieldNames, _ as isAtscriptDbView, _t as normalizeComputedSelect, at as defaultFulltextIndex, b as isVersionExemptPatch, ct as splitFulltextFields, dt as isGeoPointType, et as DocumentFieldMapper, g as AtscriptDbView, gt as jsonValueAncestor, ht as isJsonValueField, it as INTEGER_REGEX_OP, j as resolveDesignType, k as NativeIntegrity, lt as TableMetadata, mt as isBucketableField, n as isColumnTypeChanged, nt as UniquSelect, ot as describeFulltext, p as fkColumns, pt as aliasTargetOf, q as guardPath, rt as numericOperandProblem, st as searchTermInteger, tt as FieldMappingStrategy, ut as isGeoIndexableType, v as isViewType, vt as resolveCalendarBuckets, w as ALL_BUCKET_UNITS, x as assertNoVersionWrites, y as AtscriptDbTable, yt as NoopLogger, z as bucketSourceVerdict } from "./column-diff-DR1glykD.mjs";
3
3
  import { n as ALL_AGGREGATE_FNS } from "./aggregate-fns-B_sgl4mB.mjs";
4
4
  import { A as hasRelationOp, C as REL_FILTER_MAX_DEPTH, D as containsRelationFilter, E as andFilters, G as evaluateExpr, H as tableNameOf, K as isFieldRef, P as relationStaticFilter, S as uniqueKeyTuple, T as ResolvedRelationFilter, j as isResolvedRelationFilter, k as forEachResolvedRelation, q as translateQueryTree, w as REL_FILTER_MAX_NODES } from "./nested-writer-BOj_c_lI.mjs";
5
- import { i as DB_ENTITY_ANNOTATIONS, n as searchMemberKind } from "./search-fields-DBIZKwyb.mjs";
5
+ import { a as forceNavNonOptional, c as getKeyProps, o as isNavRelation, r as buildValidationContext, s as createDbValidatorPlugin, t as buildDbValidator } from "./validator-B3fPJjS1.mjs";
6
+ import { i as DB_ENTITY_ANNOTATIONS, n as searchMemberKind } from "./search-fields-CE8cmj9X.mjs";
6
7
  import { a as isPlainObject, i as isEmptyObject, n as findAncestorInSet, o as selfOrAncestor, r as getPath, t as deletePath } from "./object-TkiJQ-Dp.mjs";
7
8
  import { t as DEFAULT_DB_SPACE } from "./consts-C_-5_pFq.mjs";
8
9
  import { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, getDbFieldOp, isDbFieldOp, reconcileCas, separateCas, separateFieldOps } from "./ops.mjs";
9
- import { a as forceNavNonOptional, c as getKeyProps, o as isNavRelation, r as buildValidationContext, s as createDbValidatorPlugin, t as buildDbValidator } from "./validator-BACewoRj.mjs";
10
10
  import { isAnnotatedType } from "@atscript/typescript/utils";
11
11
  import { RELATION_OPS, computeInsights, isPrimitive, isRelationOp, walkFilter } from "@uniqu/core";
12
12
  import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
package/dist/plugin.cjs CHANGED
@@ -34,9 +34,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
34
  }) : target, mod));
35
35
  //#endregion
36
36
  const require_aggregate_fns = require("./aggregate-fns-DFtKAv7Q.cjs");
37
- const require_search_fields = require("./search-fields-DwrsJUC1.cjs");
37
+ const require_search_fields = require("./search-fields-CT_UZ9fg.cjs");
38
38
  require("./consts-BzRfCcH2.cjs");
39
- const require_validation_utils = require("./validation-utils-debIYpq0.cjs");
39
+ const require_validation_utils = require("./validation-utils-CtLNlBtB.cjs");
40
40
  let node_path = require("node:path");
41
41
  node_path = __toESM(node_path, 1);
42
42
  let node_url = require("node:url");
@@ -873,6 +873,21 @@ const dbColumnAnnotations = {
873
873
  }
874
874
  })
875
875
  },
876
+ onUpdate: { now: new _atscript_core.AnnotationSpec({
877
+ description: "Sets the field to the current time (epoch ms) on every update: patches (`updateOne`, `bulkUpdate`, `updateMany`, HTTP `PATCH`) and replaces (`replaceOne`, `bulkReplace`, `replaceMany`, HTTP `PUT`). The value is written by the SDK in the same statement on every adapter and overrides a value the payload carries. Inserts are not affected — combine with `@db.default.now` (`number.timestamp.updated` applies both). Writes outside the SDK (raw SQL) do not set it.\n\n**Example:**\n```atscript\n@db.default.now\n@db.onUpdate.now\nupdatedAt: number.timestamp\n```\n",
878
+ nodeType: ["prop"],
879
+ passedWhenReferred: false,
880
+ validate(token, args, doc) {
881
+ const errors = require_validation_utils.validateFieldBaseType(token, doc, "@db.onUpdate.now", "number");
882
+ const field = token.parentNode;
883
+ for (const [name, why] of [["meta.id", "the primary key identifies the row and is never updated"], ["db.column.version", "the version column is adapter-managed"]]) if (field.countAnnotations(name) > 0) errors.push({
884
+ message: `@db.onUpdate.now cannot coexist with @${name} — ${why}`,
885
+ severity: 1,
886
+ range: token.range
887
+ });
888
+ return errors;
889
+ }
890
+ }) },
876
891
  json: new _atscript_core.AnnotationSpec({
877
892
  description: "Forces a field to be stored as a single JSON column instead of being flattened into separate columns. Use on nested object fields that should remain as JSON in the database.\n\n**Example:**\n```atscript\n@db.json\nmetadata: { key: string, value: string }\n```\n",
878
893
  nodeType: ["prop"],
@@ -925,6 +940,7 @@ const dbColumnAnnotations = {
925
940
  ["db.column.version", "the OCC filter needs cleartext equality"],
926
941
  ["db.default.increment", "engine-side defaults bypass the encryption transform"],
927
942
  ["db.default.now", "engine-side defaults bypass the encryption transform"],
943
+ ["db.onUpdate.now", "the update time is set after the encryption transform"],
928
944
  ["db.mongo.search.text", "Atlas Search over ciphertext is impossible"],
929
945
  ["db.mongo.search.autocomplete", "Atlas Search over ciphertext is impossible"]
930
946
  ]) if (field.countAnnotations(name) > 0) errors.push({
@@ -1701,7 +1717,7 @@ const dbSearchAnnotations = { search: {
1701
1717
  * read sorts by it without a `$nulls` entry for it.
1702
1718
  */
1703
1719
  const dbSortAnnotations = { sort: { nulls: new _atscript_core.AnnotationSpec({
1704
- description: "Default **NULL placement** when a read sorts by this field and the request names none (`$nulls` control, URL suffix `$sort=-closedAt:last`).\n\n- **`'first'`** — rows where the field is NULL (or missing) come before every value, in both sort directions\n- **`'last'`** — they come after every value, in both directions\n\nWithout it (and without `$nulls`) NULL placement is the database's own: first in ascending order on SQLite, MySQL, MongoDB and the in-memory adapter, last on PostgreSQL. Applies to `$sort` and to the `$rowOrder` of `first()` / `last()`. Only optional fields can be NULL — on a required table field it has no effect. On PostgreSQL, MySQL and MongoDB a placement the engine does not produce natively costs the index its ORDER BY (a sort step instead).\n\n**Example:**\n```atscript\n@db.sort.nulls 'last'\nclosedAt?: number.timestamp\n```\n",
1720
+ description: "Default **NULL placement** when a read sorts by this field and the request names none (`$nulls` control, URL suffix `$sort=-closedAt:last`).\n\n- **`'first'`** — rows where the field is NULL (or missing) come before every value, in both sort directions\n- **`'last'`** — they come after every value, in both directions\n\nWithout it (and without `$nulls`) NULL placement is the database's own: first in ascending order on SQLite, MySQL, MongoDB and the in-memory adapter, last on PostgreSQL. Applies to `$sort` and to the `$rowOrder` of `first()` / `last()`. Only optional and `| null` fields can be NULL — on another required table field it has no effect. On PostgreSQL, MySQL and MongoDB a placement the engine does not produce natively costs the index its ORDER BY (a sort step instead).\n\n**Example:**\n```atscript\n@db.sort.nulls 'last'\nclosedAt?: number.timestamp\n```\n",
1705
1721
  nodeType: ["prop"],
1706
1722
  passedWhenReferred: false,
1707
1723
  multiple: false,
@@ -1736,7 +1752,7 @@ const dbSortAnnotations = { sort: { nulls: new _atscript_core.AnnotationSpec({
1736
1752
  return errors;
1737
1753
  }
1738
1754
  const owner = require_validation_utils.getDbTableOwner(token);
1739
- if (!field.has("optional") && owner && owner.countAnnotations("db.table") > 0 && field.ownerNode?.ownerNode === owner) fail("@db.sort.nulls on a required field has no effect — the field is never NULL; make it optional (field?: …) or remove the annotation", 2);
1755
+ if (!field.has("optional") && !require_validation_utils.isNullableUnion(def, doc) && owner && owner.countAnnotations("db.table") > 0 && field.ownerNode?.ownerNode === owner) fail("@db.sort.nulls on a required field has no effect — the field is never NULL; make it optional (field?: …) or remove the annotation", 2);
1740
1756
  return errors;
1741
1757
  }
1742
1758
  }) } };
@@ -2319,6 +2335,7 @@ const dbPlugin = (options) => ({
2319
2335
  index: dbIndexAnnotations.index,
2320
2336
  column: dbColumnAnnotations.column,
2321
2337
  default: dbColumnAnnotations.default,
2338
+ onUpdate: dbColumnAnnotations.onUpdate,
2322
2339
  json: dbColumnAnnotations.json,
2323
2340
  ignore: dbColumnAnnotations.ignore,
2324
2341
  encrypted: dbColumnAnnotations.encrypted,
package/dist/plugin.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { i as NULL_WHEN_EMPTY_AGGREGATE_FNS, o as SUPPORTED_AGGREGATE_FNS, t as AGG_ANNOTATIONS } from "./aggregate-fns-B_sgl4mB.mjs";
2
- import { a as DERIVED_INCOMPATIBLE, i as DB_ENTITY_ANNOTATIONS, o as JSON_LEAF_TYPES, r as numericTypeProblem } from "./search-fields-DBIZKwyb.mjs";
2
+ import { a as DERIVED_INCOMPATIBLE, i as DB_ENTITY_ANNOTATIONS, o as JSON_LEAF_TYPES, r as numericTypeProblem } from "./search-fields-CE8cmj9X.mjs";
3
3
  import "./consts-C_-5_pFq.mjs";
4
- import { C as validateFieldBaseType, S as validateExclusiveWith, _ as getParentTypeName, a as hasAnyViewAnnotation, b as refActionAnnotation, 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 integerMemberIndexProblem, w as validateSiblingStringField, x as searchFieldVerdict, y as primitiveBaseType } from "./validation-utils-DqZAH6aT.mjs";
4
+ import { C as validateExclusiveWith, S as searchFieldVerdict, T as validateSiblingStringField, _ as getParentTypeName, a as hasAnyViewAnnotation, b as primitiveBaseType, 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 integerMemberIndexProblem, w as validateFieldBaseType, x as refActionAnnotation, y as isNullableUnion } from "./validation-utils-BGjqc2jU.mjs";
5
5
  import path from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { AnnotationSpec, DEFAULT_FORMAT, getFieldsForType, isArray, isInterface, isPrimitive, isProp, isQueryComparison, isQueryLogical, isRef, isStructure } from "@atscript/core";
@@ -837,6 +837,21 @@ const dbColumnAnnotations = {
837
837
  }
838
838
  })
839
839
  },
840
+ onUpdate: { now: new AnnotationSpec({
841
+ description: "Sets the field to the current time (epoch ms) on every update: patches (`updateOne`, `bulkUpdate`, `updateMany`, HTTP `PATCH`) and replaces (`replaceOne`, `bulkReplace`, `replaceMany`, HTTP `PUT`). The value is written by the SDK in the same statement on every adapter and overrides a value the payload carries. Inserts are not affected — combine with `@db.default.now` (`number.timestamp.updated` applies both). Writes outside the SDK (raw SQL) do not set it.\n\n**Example:**\n```atscript\n@db.default.now\n@db.onUpdate.now\nupdatedAt: number.timestamp\n```\n",
842
+ nodeType: ["prop"],
843
+ passedWhenReferred: false,
844
+ validate(token, args, doc) {
845
+ const errors = validateFieldBaseType(token, doc, "@db.onUpdate.now", "number");
846
+ const field = token.parentNode;
847
+ for (const [name, why] of [["meta.id", "the primary key identifies the row and is never updated"], ["db.column.version", "the version column is adapter-managed"]]) if (field.countAnnotations(name) > 0) errors.push({
848
+ message: `@db.onUpdate.now cannot coexist with @${name} — ${why}`,
849
+ severity: 1,
850
+ range: token.range
851
+ });
852
+ return errors;
853
+ }
854
+ }) },
840
855
  json: new AnnotationSpec({
841
856
  description: "Forces a field to be stored as a single JSON column instead of being flattened into separate columns. Use on nested object fields that should remain as JSON in the database.\n\n**Example:**\n```atscript\n@db.json\nmetadata: { key: string, value: string }\n```\n",
842
857
  nodeType: ["prop"],
@@ -889,6 +904,7 @@ const dbColumnAnnotations = {
889
904
  ["db.column.version", "the OCC filter needs cleartext equality"],
890
905
  ["db.default.increment", "engine-side defaults bypass the encryption transform"],
891
906
  ["db.default.now", "engine-side defaults bypass the encryption transform"],
907
+ ["db.onUpdate.now", "the update time is set after the encryption transform"],
892
908
  ["db.mongo.search.text", "Atlas Search over ciphertext is impossible"],
893
909
  ["db.mongo.search.autocomplete", "Atlas Search over ciphertext is impossible"]
894
910
  ]) if (field.countAnnotations(name) > 0) errors.push({
@@ -1665,7 +1681,7 @@ const dbSearchAnnotations = { search: {
1665
1681
  * read sorts by it without a `$nulls` entry for it.
1666
1682
  */
1667
1683
  const dbSortAnnotations = { sort: { nulls: new AnnotationSpec({
1668
- description: "Default **NULL placement** when a read sorts by this field and the request names none (`$nulls` control, URL suffix `$sort=-closedAt:last`).\n\n- **`'first'`** — rows where the field is NULL (or missing) come before every value, in both sort directions\n- **`'last'`** — they come after every value, in both directions\n\nWithout it (and without `$nulls`) NULL placement is the database's own: first in ascending order on SQLite, MySQL, MongoDB and the in-memory adapter, last on PostgreSQL. Applies to `$sort` and to the `$rowOrder` of `first()` / `last()`. Only optional fields can be NULL — on a required table field it has no effect. On PostgreSQL, MySQL and MongoDB a placement the engine does not produce natively costs the index its ORDER BY (a sort step instead).\n\n**Example:**\n```atscript\n@db.sort.nulls 'last'\nclosedAt?: number.timestamp\n```\n",
1684
+ description: "Default **NULL placement** when a read sorts by this field and the request names none (`$nulls` control, URL suffix `$sort=-closedAt:last`).\n\n- **`'first'`** — rows where the field is NULL (or missing) come before every value, in both sort directions\n- **`'last'`** — they come after every value, in both directions\n\nWithout it (and without `$nulls`) NULL placement is the database's own: first in ascending order on SQLite, MySQL, MongoDB and the in-memory adapter, last on PostgreSQL. Applies to `$sort` and to the `$rowOrder` of `first()` / `last()`. Only optional and `| null` fields can be NULL — on another required table field it has no effect. On PostgreSQL, MySQL and MongoDB a placement the engine does not produce natively costs the index its ORDER BY (a sort step instead).\n\n**Example:**\n```atscript\n@db.sort.nulls 'last'\nclosedAt?: number.timestamp\n```\n",
1669
1685
  nodeType: ["prop"],
1670
1686
  passedWhenReferred: false,
1671
1687
  multiple: false,
@@ -1700,7 +1716,7 @@ const dbSortAnnotations = { sort: { nulls: new AnnotationSpec({
1700
1716
  return errors;
1701
1717
  }
1702
1718
  const owner = getDbTableOwner(token);
1703
- if (!field.has("optional") && owner && owner.countAnnotations("db.table") > 0 && field.ownerNode?.ownerNode === owner) fail("@db.sort.nulls on a required field has no effect — the field is never NULL; make it optional (field?: …) or remove the annotation", 2);
1719
+ if (!field.has("optional") && !isNullableUnion(def, doc) && owner && owner.countAnnotations("db.table") > 0 && field.ownerNode?.ownerNode === owner) fail("@db.sort.nulls on a required field has no effect — the field is never NULL; make it optional (field?: …) or remove the annotation", 2);
1704
1720
  return errors;
1705
1721
  }
1706
1722
  }) } };
@@ -2283,6 +2299,7 @@ const dbPlugin = (options) => ({
2283
2299
  index: dbIndexAnnotations.index,
2284
2300
  column: dbColumnAnnotations.column,
2285
2301
  default: dbColumnAnnotations.default,
2302
+ onUpdate: dbColumnAnnotations.onUpdate,
2286
2303
  json: dbColumnAnnotations.json,
2287
2304
  ignore: dbColumnAnnotations.ignore,
2288
2305
  encrypted: dbColumnAnnotations.encrypted,
package/dist/rel.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { Gn as TGenericLogger, It as TTableResolver, Kt as TableMetadata, Vt as TWriteTableResolver, W as TDbForeignKey, Zt as BaseDbAdapter, h as AtscriptDbWritable, m as AtscriptDbTableLike, nt as TDbRelation } from "./buckets-jy8BfswO.cjs";
1
+ import { Jn as TGenericLogger, Jt as TableMetadata, Rt as TTableResolver, Ut as TWriteTableResolver, W as TDbForeignKey, en as BaseDbAdapter, h as AtscriptDbWritable, m as AtscriptDbTableLike, nt as TDbRelation } from "./buckets-B4T_alUe.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-D_8bydc2.cjs";
3
+ import { n as findRemoteFK, r as resolveRelationTargetTable, t as findFKForRelation } from "./relation-helpers-BLBrLQYi.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 { Gn as TGenericLogger, It as TTableResolver, Kt as TableMetadata, Vt as TWriteTableResolver, W as TDbForeignKey, Zt as BaseDbAdapter, h as AtscriptDbWritable, m as AtscriptDbTableLike, nt as TDbRelation } from "./buckets-CBKL_ZWE.mjs";
1
+ import { Jn as TGenericLogger, Jt as TableMetadata, Rt as TTableResolver, Ut as TWriteTableResolver, W as TDbForeignKey, en as BaseDbAdapter, h as AtscriptDbWritable, m as AtscriptDbTableLike, nt as TDbRelation } from "./buckets-8mG67Mtw.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-BUsxNNGU.mjs";
3
+ import { n as findRemoteFK, r as resolveRelationTargetTable, t as findFKForRelation } from "./relation-helpers-17_2f5hX.mjs";
4
4
  import { Validator } from "@atscript/typescript/utils";
5
5
  import { FilterExpr, WithRelation } from "@uniqu/core";
6
6
 
@@ -1,4 +1,4 @@
1
- import { W as TDbForeignKey, nt as TDbRelation } from "./buckets-CBKL_ZWE.mjs";
1
+ import { W as TDbForeignKey, nt as TDbRelation } from "./buckets-8mG67Mtw.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 { W as TDbForeignKey, nt as TDbRelation } from "./buckets-jy8BfswO.cjs";
1
+ import { W as TDbForeignKey, nt as TDbRelation } from "./buckets-B4T_alUe.cjs";
2
2
  import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
3
3
 
4
4
  //#region src/rel/relation-helpers.d.ts
@@ -29,6 +29,7 @@ const DERIVED_INCOMPATIBLE = [
29
29
  ["db.default.increment", "the value is computed, never defaulted"],
30
30
  ["db.default.uuid", "the value is computed, never defaulted"],
31
31
  ["db.default.now", "the value is computed, never defaulted"],
32
+ ["db.onUpdate.now", "a derived column is never written"],
32
33
  ["db.column.version", "the version column is adapter-managed"],
33
34
  ["db.column.version.exempt", "a derived column is never written"],
34
35
  ["db.encrypted", "the value is a cleartext extraction of its source"],
@@ -29,6 +29,7 @@ const DERIVED_INCOMPATIBLE = [
29
29
  ["db.default.increment", "the value is computed, never defaulted"],
30
30
  ["db.default.uuid", "the value is computed, never defaulted"],
31
31
  ["db.default.now", "the value is computed, never defaulted"],
32
+ ["db.onUpdate.now", "a derived column is never written"],
32
33
  ["db.column.version", "the version column is adapter-managed"],
33
34
  ["db.column.version.exempt", "a derived column is never written"],
34
35
  ["db.encrypted", "the value is a cleartext extraction of its source"],
package/dist/shared.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_aggregate_rules = require("./aggregate-rules-D_bsCpUI.cjs");
3
- const require_validation_utils = require("./validation-utils-debIYpq0.cjs");
3
+ const require_validation_utils = require("./validation-utils-CtLNlBtB.cjs");
4
4
  exports.NOT_DIMENSION_REASON = require_aggregate_rules.NOT_DIMENSION_REASON;
5
5
  exports.earlierJoinTargets = require_validation_utils.earlierJoinTargets;
6
6
  exports.findFKFieldsPointingTo = require_validation_utils.findFKFieldsPointingTo;
@@ -15,6 +15,7 @@ exports.hasAnyViewAnnotation = require_validation_utils.hasAnyViewAnnotation;
15
15
  exports.integerMemberIndexProblem = require_validation_utils.integerMemberIndexProblem;
16
16
  exports.isAliasDecl = require_validation_utils.isAliasDecl;
17
17
  exports.isDbSourceDecl = require_validation_utils.isDbSourceDecl;
18
+ exports.isNullableUnion = require_validation_utils.isNullableUnion;
18
19
  exports.isStrictAggregateStruct = require_aggregate_rules.isStrictAggregateStruct;
19
20
  exports.joinTargets = require_validation_utils.joinTargets;
20
21
  exports.primitiveBaseType = require_validation_utils.primitiveBaseType;
package/dist/shared.d.cts CHANGED
@@ -8,6 +8,12 @@ declare function validateExclusiveWith(token: Token, selfName: string, others: A
8
8
  }>): TMessages;
9
9
  /** Primitive base type (`string`, `number`, `decimal`, …) of a resolved definition, if it is a primitive. */
10
10
  declare function primitiveBaseType(def: SemanticNode | undefined): string | undefined;
11
+ /**
12
+ * Whether a definition is a union with a `null` member — `T | null`, or a
13
+ * ref to an alias of one (compile-time mirror of the runtime nullable union,
14
+ * since 0.1.155).
15
+ */
16
+ declare function isNullableUnion(def: SemanticNode | undefined, doc: AtscriptDoc, depth?: number): boolean;
11
17
  /**
12
18
  * Whether a prop takes part in `$search` as text or as an integer, or why it
13
19
  * cannot (compile-time mirror of the runtime `searchMemberKind`). Anything
@@ -22,8 +28,9 @@ declare function searchFieldVerdict(field: SemanticNode, doc: AtscriptDoc): {
22
28
  /**
23
29
  * Why an integer fulltext member is not index-backed (its exact-number match
24
30
  * would scan — or fail on MongoDB next to `$text`), or `undefined`. Backed:
25
- * `_id`, the first `@meta.id` of the type, or the first field (in declaration
26
- * order) of a `@db.index.plain` / `@db.index.unique` group.
31
+ * `_id` or the first `@meta.id` of an interface's own fields (an inline
32
+ * nested object's are no key of the row, like at runtime), or the first field
33
+ * (in declaration order) of a `@db.index.plain` / `@db.index.unique` group.
27
34
  */
28
35
  declare function integerMemberIndexProblem(token: Token): string | undefined;
29
36
  /** Asserts `args[0]` names a sibling property whose primitive base type is `string`. */
@@ -157,4 +164,4 @@ declare const NOT_DIMENSION_REASON = "not a dimension";
157
164
  */
158
165
  declare function isStrictAggregateStruct(struct: SemanticStructureNode): boolean;
159
166
  //#endregion
160
- export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, integerMemberIndexProblem, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, searchFieldVerdict, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
167
+ export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, integerMemberIndexProblem, isAliasDecl, isDbSourceDecl, isNullableUnion, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, searchFieldVerdict, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
package/dist/shared.d.mts CHANGED
@@ -8,6 +8,12 @@ declare function validateExclusiveWith(token: Token, selfName: string, others: A
8
8
  }>): TMessages;
9
9
  /** Primitive base type (`string`, `number`, `decimal`, …) of a resolved definition, if it is a primitive. */
10
10
  declare function primitiveBaseType(def: SemanticNode | undefined): string | undefined;
11
+ /**
12
+ * Whether a definition is a union with a `null` member — `T | null`, or a
13
+ * ref to an alias of one (compile-time mirror of the runtime nullable union,
14
+ * since 0.1.155).
15
+ */
16
+ declare function isNullableUnion(def: SemanticNode | undefined, doc: AtscriptDoc, depth?: number): boolean;
11
17
  /**
12
18
  * Whether a prop takes part in `$search` as text or as an integer, or why it
13
19
  * cannot (compile-time mirror of the runtime `searchMemberKind`). Anything
@@ -22,8 +28,9 @@ declare function searchFieldVerdict(field: SemanticNode, doc: AtscriptDoc): {
22
28
  /**
23
29
  * Why an integer fulltext member is not index-backed (its exact-number match
24
30
  * would scan — or fail on MongoDB next to `$text`), or `undefined`. Backed:
25
- * `_id`, the first `@meta.id` of the type, or the first field (in declaration
26
- * order) of a `@db.index.plain` / `@db.index.unique` group.
31
+ * `_id` or the first `@meta.id` of an interface's own fields (an inline
32
+ * nested object's are no key of the row, like at runtime), or the first field
33
+ * (in declaration order) of a `@db.index.plain` / `@db.index.unique` group.
27
34
  */
28
35
  declare function integerMemberIndexProblem(token: Token): string | undefined;
29
36
  /** Asserts `args[0]` names a sibling property whose primitive base type is `string`. */
@@ -157,4 +164,4 @@ declare const NOT_DIMENSION_REASON = "not a dimension";
157
164
  */
158
165
  declare function isStrictAggregateStruct(struct: SemanticStructureNode): boolean;
159
166
  //#endregion
160
- export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, integerMemberIndexProblem, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, searchFieldVerdict, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
167
+ export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, integerMemberIndexProblem, isAliasDecl, isDbSourceDecl, isNullableUnion, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, searchFieldVerdict, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
package/dist/shared.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  import { n as isStrictAggregateStruct, t as NOT_DIMENSION_REASON } from "./aggregate-rules-jdPrxqWa.mjs";
2
- import { C as validateFieldBaseType, S as validateExclusiveWith, _ as getParentTypeName, a as hasAnyViewAnnotation, b as refActionAnnotation, 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 integerMemberIndexProblem, w as validateSiblingStringField, x as searchFieldVerdict, y as primitiveBaseType } from "./validation-utils-DqZAH6aT.mjs";
3
- export { NOT_DIMENSION_REASON, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, integerMemberIndexProblem, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, searchFieldVerdict, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
2
+ import { C as validateExclusiveWith, S as searchFieldVerdict, T as validateSiblingStringField, _ as getParentTypeName, a as hasAnyViewAnnotation, b as primitiveBaseType, 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 integerMemberIndexProblem, w as validateFieldBaseType, x as refActionAnnotation, y as isNullableUnion } from "./validation-utils-BGjqc2jU.mjs";
3
+ export { NOT_DIMENSION_REASON, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, integerMemberIndexProblem, isAliasDecl, isDbSourceDecl, isNullableUnion, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, searchFieldVerdict, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };