@atscript/db 0.1.164 → 0.1.165

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/agg.cjs +1 -1
  2. package/dist/agg.d.cts +1 -1
  3. package/dist/agg.d.mts +1 -1
  4. package/dist/agg.mjs +1 -1
  5. package/dist/{aggregate-fns-DupYzFD7.cjs → aggregate-fns-CNtrSxGH.cjs} +1 -1
  6. package/dist/{aggregate-fns-DsS9UQVB.mjs → aggregate-fns-CmtSNIHm.mjs} +1 -1
  7. package/dist/{buckets-B8UOod-v.d.cts → buckets-BDxKfCNo.d.cts} +143 -13
  8. package/dist/{buckets-CHyspjYP.d.mts → buckets-CHUgky8T.d.mts} +143 -13
  9. package/dist/{column-diff-BfNIlMwX.mjs → column-diff-9pF0d8JP.mjs} +354 -31
  10. package/dist/{column-diff-BIGX3sRH.cjs → column-diff-DjeUj9kb.cjs} +371 -30
  11. package/dist/control-B5BJypqL.cjs +16 -0
  12. package/dist/control-CevYIJC4.mjs +16 -0
  13. package/dist/{db-error-hraC12B9.mjs → db-error-BMy4-OWq.mjs} +23 -1
  14. package/dist/{db-error-B_DRL1E9.d.cts → db-error-DQUw2cED.d.cts} +65 -9
  15. package/dist/{db-error-B_DRL1E9.d.mts → db-error-DQUw2cED.d.mts} +65 -9
  16. package/dist/{db-error-DmF1_xrz.cjs → db-error-G3sgvL87.cjs} +28 -0
  17. package/dist/{fk-diff-BNGawZi9.d.cts → fk-diff-DSM7O7hs.d.cts} +1 -1
  18. package/dist/{fk-diff-rj9N2QLw.d.mts → fk-diff-Dapr5Dk-.d.mts} +1 -1
  19. package/dist/index.cjs +17 -11
  20. package/dist/index.d.cts +38 -12
  21. package/dist/index.d.mts +38 -12
  22. package/dist/index.mjs +14 -12
  23. package/dist/{nested-writer-ClUX0DB0.mjs → nested-writer-BraWjS8a.mjs} +177 -26
  24. package/dist/{nested-writer-yCy6wGuN.cjs → nested-writer-DOvdbYG-.cjs} +194 -31
  25. package/dist/ops.cjs +1 -1
  26. package/dist/ops.mjs +1 -1
  27. package/dist/plugin.cjs +15 -12
  28. package/dist/plugin.mjs +15 -12
  29. package/dist/rel.cjs +2 -2
  30. package/dist/rel.d.cts +2 -2
  31. package/dist/rel.d.mts +2 -2
  32. package/dist/rel.mjs +2 -2
  33. package/dist/{relation-helpers-DloMywNs.d.cts → relation-helpers-C4UNWYQu.d.cts} +1 -1
  34. package/dist/{relation-helpers-zwt19E7r.d.mts → relation-helpers-hdbuqwjV.d.mts} +1 -1
  35. package/dist/{relation-loader-Qv3LrQ42.mjs → relation-loader-BOEVhcBe.mjs} +1 -1
  36. package/dist/{relation-loader-DujL_Mh9.cjs → relation-loader-BrkakVF_.cjs} +1 -1
  37. package/dist/shared.cjs +3 -1
  38. package/dist/shared.d.cts +13 -2
  39. package/dist/shared.d.mts +13 -2
  40. package/dist/shared.mjs +2 -2
  41. package/dist/sync.cjs +107 -25
  42. package/dist/sync.d.cts +53 -6
  43. package/dist/sync.d.mts +53 -6
  44. package/dist/sync.mjs +107 -25
  45. package/dist/{validator-DK9Ijpo7.cjs → validator-D7E7T0Oy.cjs} +1 -1
  46. package/dist/{validator-DuDWsIdQ.mjs → validator-UpgPhwvH.mjs} +1 -1
  47. package/dist/validator.cjs +2 -2
  48. package/dist/validator.d.cts +1 -1
  49. package/dist/validator.d.mts +1 -1
  50. package/dist/validator.mjs +2 -2
  51. package/dist/{view-validation-BiDLCYMw.cjs → view-validation-C0UVLx_H.cjs} +38 -10
  52. package/dist/{view-validation-BcgDq7M9.mjs → view-validation-KW77xIKn.mjs} +28 -12
  53. package/package.json +6 -6
  54. package/dist/control-D5cQmzFj.mjs +0 -14
  55. package/dist/control-jIVU2hkf.cjs +0 -14
package/dist/agg.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_aggregate_fns = require("./aggregate-fns-DupYzFD7.cjs");
2
+ const require_aggregate_fns = require("./aggregate-fns-CNtrSxGH.cjs");
3
3
  let _uniqu_core = require("@uniqu/core");
4
4
  //#region src/agg.ts
5
5
  /**
package/dist/agg.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- import { r as TResolvedBucket } from "./buckets-B8UOod-v.cjs";
1
+ import { r as TResolvedBucket } from "./buckets-BDxKfCNo.cjs";
2
2
  import { _ as TDbAggregateFn, a as AggregateResult, c as CalendarBucketLabel, d as WeekStart, f as isAggregateExpr, h as resolveAlias, i as AggregateQuery, l as ComputedExpr, m as resolveAggregateSearch, n as AggregateExpr, o as BucketExpr, p as isBucketExpr, r as AggregateFn, s as BucketUnit, t as AggregateControls, u as ResolvedBucket, v as assertAggregateFn } from "./agg-42CSpGDR.cjs";
3
3
  export { type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, type BucketExpr, type BucketUnit, type CalendarBucketLabel, type ComputedExpr, type ResolvedBucket, type TDbAggregateFn, type TResolvedBucket, type WeekStart, assertAggregateFn, isAggregateExpr, isBucketExpr, resolveAggregateSearch, resolveAlias };
package/dist/agg.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { r as TResolvedBucket } from "./buckets-CHyspjYP.mjs";
1
+ import { r as TResolvedBucket } from "./buckets-CHUgky8T.mjs";
2
2
  import { _ as TDbAggregateFn, a as AggregateResult, c as CalendarBucketLabel, d as WeekStart, f as isAggregateExpr, h as resolveAlias, i as AggregateQuery, l as ComputedExpr, m as resolveAggregateSearch, n as AggregateExpr, o as BucketExpr, p as isBucketExpr, r as AggregateFn, s as BucketUnit, t as AggregateControls, u as ResolvedBucket, v as assertAggregateFn } from "./agg-Wo-smrYV.mjs";
3
3
  export { type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, type BucketExpr, type BucketUnit, type CalendarBucketLabel, type ComputedExpr, type ResolvedBucket, type TDbAggregateFn, type TResolvedBucket, type WeekStart, assertAggregateFn, isAggregateExpr, isBucketExpr, resolveAggregateSearch, resolveAlias };
package/dist/agg.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { s as assertAggregateFn } from "./aggregate-fns-DsS9UQVB.mjs";
1
+ import { s as assertAggregateFn } from "./aggregate-fns-CmtSNIHm.mjs";
2
2
  import { isAggregateExpr, isBucketExpr, resolveAlias } from "@uniqu/core";
3
3
  //#region src/agg.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- const require_db_error = require("./db-error-DmF1_xrz.cjs");
1
+ const require_db_error = require("./db-error-G3sgvL87.cjs");
2
2
  let _uniqu_core = require("@uniqu/core");
3
3
  //#region src/query/aggregate-fns.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { r as DbError } from "./db-error-hraC12B9.mjs";
1
+ import { r as DbError } from "./db-error-BMy4-OWq.mjs";
2
2
  import { ROW_ORDER_FNS, isAggregateExpr } from "@uniqu/core";
3
3
  //#region src/query/aggregate-fns.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { r as DbError } from "./db-error-B_DRL1E9.cjs";
1
+ import { r as DbError } from "./db-error-DQUw2cED.cjs";
2
2
  import { f as TFieldOps } from "./ops-AqhV7s9o.cjs";
3
3
  import { AggregateControls, AggregateExpr, AggregateExpr as AggregateExpr$1, AggregateFn, AggregateFn as AggregateFn$1, AggregateQuery, AggregateQuery as AggregateQuery$1, AggregateResult, BucketUnit, FieldOpsFor, FilterExpr, FilterExpr as FilterExpr$1, NullsPlacement, NullsPlacement as NullsPlacement$1, RelationOp, ResolvedBucket, ResolvedRowOrderKey, ResolvedSelectExpr, TypedWithRelation, Uniquery, Uniquery as Uniquery$1, UniqueryControls, UniqueryControls as UniqueryControls$1, UniqueryInsights, WithRelation, WithRelation as WithRelation$1 } from "@uniqu/core";
4
4
  import { AtscriptExprNode, AtscriptExprNode as AtscriptExprNode$1, AtscriptOrderItem, AtscriptQueryComparison, AtscriptQueryFieldRef, AtscriptQueryFieldRef as AtscriptQueryFieldRef$1, AtscriptQueryNode, AtscriptQueryNode as AtscriptQueryNode$1, AtscriptRef, FlatOf, FlatOf as FlatOf$1, NavPropsOf, NavPropsOf as NavPropsOf$1, OwnPropsOf, OwnPropsOf as OwnPropsOf$1, PrimaryKeyOf, PrimaryKeyOf as PrimaryKeyOf$1, TAtscriptAnnotatedType, TAtscriptDataType, TAtscriptTypeObject, TMetadataMap, TSerializedAnnotatedType, TValidatorOptions, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
@@ -568,16 +568,17 @@ declare function relationStaticFilter(relation: TDbRelation, name?: string): TRe
568
568
  //#endregion
569
569
  //#region src/table/db-readable.d.ts
570
570
  /**
571
- * Extracts nav prop names from a query's `$with` array.
571
+ * Extracts nav prop names from a query's `$with` array — mutable or readonly
572
+ * (`as const`, since 0.1.165), object entries or the string shorthand.
572
573
  * Returns `never` when `$with` is absent → all nav props stripped from response.
573
574
  */
574
575
  type ExtractWith<Q> = Q extends {
575
576
  controls: {
576
- $with: Array<{
577
- name: infer N extends string;
578
- }>;
577
+ $with: ReadonlyArray<infer E>;
579
578
  };
580
- } ? N : never;
579
+ } ? E extends {
580
+ name: infer N extends string;
581
+ } ? N : E extends string ? E : never : never;
581
582
  /**
582
583
  * Computes the response type for a query:
583
584
  * - Strips all nav props from the base DataType
@@ -770,6 +771,17 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
770
771
  */
771
772
  get onUpdateIncPhysical(): readonly string[];
772
773
  private _onUpdateIncPhysical?;
774
+ /**
775
+ * Physical column names of the insert-only fields (`number.timestamp.created`,
776
+ * since 0.1.165): a full replace keeps their stored values. Empty when
777
+ * there are none.
778
+ *
779
+ * @internal Adapter-facing surface; not part of the consumer API.
780
+ */
781
+ get insertOnlyPhysical(): readonly string[];
782
+ private _insertOnlyPhysical?;
783
+ /** The physical columns of a set of top-level logical fields. */
784
+ private _physicalNames;
773
785
  /**
774
786
  * Logical paths of the `@db.column.version.exempt` fields, including objects
775
787
  * whose direct children are all exempt. A patch that writes only these (and
@@ -1327,6 +1339,14 @@ declare class NativeIntegrity extends IntegrityStrategy {
1327
1339
  }
1328
1340
  //#endregion
1329
1341
  //#region src/table/db-table.d.ts
1342
+ /**
1343
+ * The filter of `updateMany` / `replaceMany` / `deleteMany` (since 0.1.165):
1344
+ * the flat field paths with the nav keys taking relational predicates
1345
+ * (`$some` / `$none`), as in the read filter. Before, a nav key was typed as
1346
+ * the flat type's empty value, so a predicate failed to typecheck. A table
1347
+ * without nav props keeps the plain flat filter.
1348
+ */
1349
+ type MutationFilter<FlatType, NavType extends Record<string, unknown>> = string extends keyof NavType ? FilterExpr<FlatType> : FilterExpr<Omit<FlatType, keyof NavType>, NavType>;
1330
1350
  declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnotatedType, DataType = TAtscriptDataType<T>, FlatType = NullableOptional<FlatOf<T>>, A extends BaseDbAdapter = BaseDbAdapter, IdType = PrimaryKeyOf<T>, OwnProps = NullableOptional<OwnPropsOf<T>>, NavType extends Record<string, unknown> = NavPropsOf<T>> extends AtscriptDbReadable<T, DataType, FlatType, A, IdType, OwnProps, NavType> {
1331
1351
  protected _cascadeResolver?: TCascadeResolver;
1332
1352
  protected _fkLookupResolver?: TFkLookupResolver;
@@ -1352,14 +1372,67 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
1352
1372
  * Adapters may define additional purposes.
1353
1373
  */
1354
1374
  getValidator(purpose: string): Validator<T, DataType>;
1375
+ /**
1376
+ * A standard purpose's validator called WITHOUT a context validates in that
1377
+ * purpose's write mode (since 0.1.165): `getValidator("insert").validate(row, true)`
1378
+ * accepts what an insert accepts — omitted primary key, defaulted, FK and
1379
+ * navigation fields. Before, the db plugin saw no mode and ran inert while
1380
+ * navigation fields were forced required. An explicit context still wins.
1381
+ */
1382
+ private _withDefaultContext;
1383
+ /** A fresh validation context of a write `mode` — the one its write paths build. */
1384
+ private _validationCtx;
1385
+ /** {@link normalizeWriteErrors} for this table: its constraint errors normalized against its metadata. */
1386
+ private _normalizeWrite;
1387
+ /**
1388
+ * Validates rows exactly as a write in `mode` would, without writing
1389
+ * (since 0.1.165): each row is cloned, given the defaults / stamps that
1390
+ * write applies, and validated with that write's validator and context.
1391
+ * Returns one `{ index, path, message }` per problem — `[]` when every row
1392
+ * is valid; the caller's rows are not modified.
1393
+ *
1394
+ * `fk: true` also checks that every foreign key names an existing row
1395
+ * (by lookup, on every adapter — native-FK adapters otherwise leave that to
1396
+ * the engine at write time); a missing target is reported on each of the
1397
+ * key's fields. Rows that fail type validation are not looked up.
1398
+ *
1399
+ * @param mode - `'insert'` (default), `'replace'` or `'patch'`.
1400
+ */
1401
+ validateRows(rows: ReadonlyArray<Record<string, unknown>>, mode?: "insert" | "replace" | "patch", opts?: {
1402
+ fk?: boolean;
1403
+ }): Promise<TValidateRowsError[]>;
1404
+ /**
1405
+ * {@link validateRows}' FK lookup: one entry per FK field of each row naming
1406
+ * a missing target. Distinct key tuples are looked up in chunks of
1407
+ * {@link FK_LOOKUP_CHUNK} — reading the target keys that exist (`$in` for a
1408
+ * single-column key, `$or` for a composite one) and diffing in memory, so a
1409
+ * batch never exceeds a bind-parameter limit and a miss costs no extra
1410
+ * query. A lookup target without `find` (a custom resolver) is counted per
1411
+ * chunk, and per tuple only in a chunk that comes up short.
1412
+ */
1413
+ private _missingForeignKeys;
1414
+ /** How {@link _missingForeignKeys} reads an FK's target table, if it can. */
1415
+ private _fkTargetReader;
1355
1416
  /**
1356
1417
  * Inserts a single record. Delegates to {@link insertMany} for unified
1357
1418
  * nested creation support.
1358
1419
  */
1359
- insertOne(payload: DbPatch<DataType>, opts: TInsertOptions<DataType> & {
1420
+ insertOne(payload: DbPatch<DataType>, opts: TInsertOneOptions<DataType> & {
1421
+ onConflict: "ignore";
1422
+ returning: true | readonly (keyof DataType & string)[];
1423
+ }): Promise<TDbInsertIgnoreResult & {
1424
+ row?: DataType;
1425
+ }>;
1426
+ insertOne(payload: DbPatch<DataType>, opts: TInsertOneOptions<DataType> & {
1360
1427
  onConflict: "ignore";
1361
1428
  }): Promise<TDbInsertIgnoreResult>;
1362
- insertOne(payload: DbPatch<DataType>, opts?: TInsertOptions<DataType>): Promise<TDbInsertResult>;
1429
+ insertOne(payload: DbPatch<DataType>, opts: TInsertOneOptions<DataType> & {
1430
+ returning: true | readonly (keyof DataType & string)[];
1431
+ }): Promise<TDbInsertResult & {
1432
+ row: DataType;
1433
+ }>;
1434
+ insertOne(payload: DbPatch<DataType>, opts?: TInsertOneOptions<DataType>): Promise<TDbInsertResult>;
1435
+ private _insertOneRow;
1363
1436
  /**
1364
1437
  * Inserts multiple records with batch-optimized nested creation.
1365
1438
  *
@@ -1480,14 +1553,14 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
1480
1553
  * always breaks ties). Loop until `matchedCount === 0` to process every
1481
1554
  * match in batches. Not exposed over HTTP.
1482
1555
  */
1483
- updateMany(filter: FilterExpr<FlatType>, data: DbPatch<DataType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbUpdateResult>;
1556
+ updateMany(filter: MutationFilter<FlatType, NavType>, data: DbPatch<DataType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbUpdateResult>;
1484
1557
  /**
1485
1558
  * Replaces the own fields of every row matching `filter` with `data`. The
1486
1559
  * payload is validated in `replace` mode (since 0.1.162) — every required
1487
1560
  * field must be present — except the primary key, which the filter
1488
1561
  * replaces as a row picker.
1489
1562
  */
1490
- replaceMany(filter: FilterExpr<FlatType>, data: DbRow<DataType>): Promise<TDbUpdateResult>;
1563
+ replaceMany(filter: MutationFilter<FlatType, NavType>, data: DbRow<DataType>): Promise<TDbUpdateResult>;
1491
1564
  /**
1492
1565
  * Deletes every row matching `filter` (application-level cascades run first
1493
1566
  * where the adapter has no native foreign keys).
@@ -1499,7 +1572,7 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
1499
1572
  * `limit`: a concurrent writer can make one round delete fewer rows while
1500
1573
  * matches remain. Not exposed over HTTP.
1501
1574
  */
1502
- deleteMany(filter: FilterExpr<FlatType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbDeleteResult>;
1575
+ deleteMany(filter: MutationFilter<FlatType, NavType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbDeleteResult>;
1503
1576
  /**
1504
1577
  * Runs a bounded write. `native` (default: `supportsWriteLimit()`) hands
1505
1578
  * `write` the physical filter and the bound; otherwise the primary keys of
@@ -1749,6 +1822,8 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
1749
1822
  * Used by parent tables to validate FROM children before the main insert,
1750
1823
  * ensuring errors are caught before the parent is committed.
1751
1824
  *
1825
+ * @internal Nested-write plumbing — its FK step is a no-op on native-FK
1826
+ * adapters. To validate rows yourself, use {@link validateRows}.
1752
1827
  * @param opts.excludeFkTargetTable - Skip FK validation to this table (the parent).
1753
1828
  */
1754
1829
  preValidateItems(items: Array<Record<string, unknown>>, opts?: {
@@ -3371,6 +3446,12 @@ declare abstract class BaseDbAdapter {
3371
3446
  }
3372
3447
  //#endregion
3373
3448
  //#region src/shared/union-shape.d.ts
3449
+ /**
3450
+ * The one value member of a union (`T | null` → `T`), or `undefined` when
3451
+ * `type` is no union or has several value members. A column of a nullable
3452
+ * union is the column `T` alone would get (its type tags, size, precision).
3453
+ */
3454
+ declare function soleUnionMember(type: TAtscriptAnnotatedType): TAtscriptAnnotatedType | undefined;
3374
3455
  /**
3375
3456
  * Whether a value at a path is always there (`"required"`), may be NULL /
3376
3457
  * missing (`"nullable"` — the path or an ancestor object is optional or a
@@ -3438,6 +3519,12 @@ declare class TableMetadata {
3438
3519
  * @since 0.1.156
3439
3520
  */
3440
3521
  onUpdateNow: Set<string>;
3522
+ /**
3523
+ * Top-level `number.timestamp.created` fields (since 0.1.165): set by the
3524
+ * insert only — a replace keeps the stored value, a replace or patch
3525
+ * payload's value is dropped.
3526
+ */
3527
+ insertOnly: Set<string>;
3441
3528
  /**
3442
3529
  * Top-level fields annotated with `@db.onUpdate.inc`: `0` on insert, `+1` in
3443
3530
  * the same statement on every update and replace.
@@ -3797,8 +3884,20 @@ interface TTransactionOptions {
3797
3884
  }
3798
3885
  /** Describes an available search index exposed by a database adapter. */
3799
3886
  interface TSearchIndexInfo {
3800
- /** Index name. Empty string or 'DEFAULT' for the default index. */
3887
+ /**
3888
+ * Index name — the name declared in the model (`@db.index.fulltext 'name'`).
3889
+ * An index with no declared name (a MongoDB dynamic Atlas mapping) is
3890
+ * `'DEFAULT'`.
3891
+ */
3801
3892
  name: string;
3893
+ /**
3894
+ * Other names that resolve to the same index (`$index` / `search(…, name)`),
3895
+ * kept for compatibility: the internal key (`atscript__fulltext__<name>`) on
3896
+ * PostgreSQL and MySQL, and `'DEFAULT'` for MongoDB's default text index.
3897
+ * Deprecated — address an index by {@link name}.
3898
+ * @since 0.1.165
3899
+ */
3900
+ aliases?: string[];
3802
3901
  /** Human-readable label for UI display. */
3803
3902
  description?: string;
3804
3903
  /** Index type: text search or vector similarity search. */
@@ -4285,6 +4384,15 @@ interface TDbIndexField {
4285
4384
  */
4286
4385
  integer?: boolean;
4287
4386
  }
4387
+ /**
4388
+ * One problem {@link AtscriptDbTable.validateRows} found: the row's position
4389
+ * in the input, the field path and the message (since 0.1.165).
4390
+ */
4391
+ interface TValidateRowsError {
4392
+ index: number;
4393
+ path: string;
4394
+ message: string;
4395
+ }
4288
4396
  interface TDbIndex {
4289
4397
  /** Unique key used for identity/diffing (e.g., "atscript__plain__email") */
4290
4398
  key: string;
@@ -4356,6 +4464,12 @@ interface TDbFieldMeta {
4356
4464
  ignored: boolean;
4357
4465
  /** Default value from @db.default.* */
4358
4466
  defaultValue?: TDbDefaultValue;
4467
+ /**
4468
+ * Set by the insert only — a top-level `number.timestamp.created` (since
4469
+ * 0.1.165). A replace keeps the stored value: SQL adapters leave the
4470
+ * column out of the replace's assignment, document adapters carry it over.
4471
+ */
4472
+ insertOnly?: boolean;
4359
4473
  /**
4360
4474
  * How this field is stored in the database.
4361
4475
  * - 'column': a standard scalar column (default for primitives)
@@ -4797,6 +4911,12 @@ type TCascadeResolver = (tableName: string) => TCascadeTarget[];
4797
4911
  */
4798
4912
  interface TFkLookupTarget {
4799
4913
  count(filter: Record<string, unknown>): Promise<number>;
4914
+ /**
4915
+ * The rows matching `filter`, projected to `fields` (since 0.1.165) — lets
4916
+ * `validateRows({ fk: true })` diff existing keys in memory. Optional: a
4917
+ * target without it is counted instead.
4918
+ */
4919
+ find?(filter: Record<string, unknown>, fields: readonly string[]): Promise<Array<Record<string, unknown>>>;
4800
4920
  }
4801
4921
  /**
4802
4922
  * Callback that resolves a table name to a queryable target for FK validation.
@@ -4980,6 +5100,16 @@ interface TInsertOptions<Row = Record<string, unknown>> extends TWriteOptions<Ro
4980
5100
  */
4981
5101
  lockConflicts?: boolean;
4982
5102
  }
5103
+ /**
5104
+ * Options of `insertOne` (since 0.1.165): {@link TInsertOptions} plus
5105
+ * `returning` — read the stored row back by its primary key in the insert's
5106
+ * transaction (`true`: every field, server defaults and stamps included; a
5107
+ * field list: those fields) and answer it as `row`. A row skipped by
5108
+ * `onConflict: 'ignore'` answers no `row`.
5109
+ */
5110
+ interface TInsertOneOptions<Row = Record<string, unknown>> extends TInsertOptions<Row> {
5111
+ returning?: true | readonly (keyof Row & string)[];
5112
+ }
4983
5113
  /**
4984
5114
  * Context handed to a write {@link TWriteOptions.check} (since 0.1.143) — and
4985
5115
  * through it to `AsDbController.checkWrite()`. Lets a permission layer verify
@@ -5156,4 +5286,4 @@ declare function isJsonValueField(fd: TDbFieldMeta): boolean;
5156
5286
  */
5157
5287
  declare function jsonValueAncestor(path: string, jsonValueParents: ReadonlySet<string>): string | undefined;
5158
5288
  //#endregion
5159
- export { TDbInsertManyIgnoreResult as $, hasRelationOp as $n, TWriteOptions as $t, TCascadeTarget as A, AtscriptRef as An, TForeignKeyChange as At, TDbCollation as B, AtscriptDbReadable as Bn, TReadLockOptions as Bt, NavPropsOf$1 as C, TViewReadPlan as Cn, TEnsureTableOptions as Ct, PrimaryKeyOf$1 as D, AtscriptQueryComparison as Dn, TFieldMeta as Dt, OwnPropsOf$1 as E, AtscriptOrderItem as En, TExistingTableOption as Et, TDbActionIntent as F, translateQueryTree as Fn, TInsertOptions as Ft, TDbFieldMeta as G, ResolvedRelationFilter as Gn, TSyncColumnResult as Gt, TDbDefaultValue as H, resolveDesignType as Hn, TRelationInfo as Ht, TDbActionLevel as I, AtscriptDbTable as In, TJsonCopyTarget as It, TDbIndexField as J, TRelationFilterTable as Jn, TTableResolver as Jt, TDbForeignKey as K, TRelGuardState as Kn, TSyncIndexesOptions as Kt, TDbActionProcessor as L, IntegrityStrategy as Ln, TMetaResponse as Lt, TCrudOp as M, TViewPlan as Mn, TIdResolveOptions as Mt, TCrudPermissions as N, evaluateExpr as Nn, TIdentification as Nt, TBulkWriteOptions as O, AtscriptQueryFieldRef$1 as On, TFkLookupResolver as Ot, TDbActionInfo as P, isFieldRef as Pn, TIndexChange as Pt, TDbInsertIgnoreSlot as Q, forEachResolvedRelation as Qn, TViewJsonType as Qt, TDbActionTargetSummary as R, NativeIntegrity as Rn, TMetadataOverrides as Rt, FlatOf$1 as S, isViewType as Sn, TDerivedColumn as St, NullsPlacement$1 as T, AtscriptExprNode$1 as Tn, TExistingForeignKey as Tt, TDbDeleteManyOptions as U, REL_FILTER_MAX_DEPTH as Un, TRowResolveOptions as Ut, TDbDefaultFn as V, DbResponse as Vn, TReferencingForeignKey as Vt, TDbDeleteResult as W, REL_FILTER_MAX_NODES as Wn, TSearchIndexInfo as Wt, TDbInsertIgnoreOptions as X, andFilters as Xn, TTransactionOptions as Xt, TDbIndexType as Y, TRelationStaticFilter as Yn, TTouchManyOptions as Yt, TDbInsertIgnoreResult as Z, containsRelationFilter as Zn, TValueFormatterPair as Zt, DbPatch as _, TAdapterFactory as _n, TDbWriteGuard as _t, isJsonValueField as a, TableMetadata as an, FieldMappingStrategy as ar, TDbObjectKind as at, FieldOpsFor as b, TViewColumnMapping as bn, TDeleteOptions as bt, resolveCalendarBuckets as c, TPathPresence as cn, TGenericLogger as cr, TDbRelation as ct, AggregateFn$1 as d, ALL_VIEW_CAPABILITIES as dn, TRowOrderKey as dr, TDbStorageType as dt, TWriteTableResolver as en, isResolvedRelationFilter as er, TDbInsertManyResult as et, AggregateQuery$1 as f, BaseDbAdapter as fn, UniquSelect as fr, TDbUpdateOptions as ft, DbControls as g, DbSpace as gn, TDbWriteCheckContext as gt, AtscriptDbWritable as h, TViewCapability as hn, TDbWriteCheck as ht, isBucketableField as i, WithRelation$1 as in, DocumentFieldMapper as ir, TDbLockWait as it, TColumnDiff as j, TViewJoin as jn, TIdDescriptor as jt, TCascadeResolver as k, AtscriptQueryNode$1 as kn, TFkLookupTarget as kt, AggregateControls as l, ALL_BUCKET_UNITS as ln, TExprAggregate as lr, TDbRemoveGuard as lt, AtscriptDbTableLike as m, TIndexDiffOptions as mn, TDbWriteAction as mt, TComputedSelect as n, Uniquery$1 as nn, DbEncryption as nr, TDbIsolationLevel as nt, jsonValueAncestor as o, isGeoIndexableType as on, TReadControls as or, TDbReadLock as ot, AggregateResult as p, TForeignKeyDiffOptions as pn, TDbUpdateResult as pt, TDbIndex as q, TRelationFilterJunction as qn, TTableOptionDiff as qt, TResolvedBucket as r, UniqueryControls$1 as rn, TDbEncryptionOptions as rr, TDbLockMode as rt, normalizeComputedSelect as s, isGeoPointType as sn, NoopLogger as sr, TDbReferentialAction as st, TBucketFieldSource as t, TypedWithRelation as tn, relationStaticFilter as tr, TDbInsertResult as tt, AggregateExpr$1 as u, ALL_ISOLATION_LEVELS as un, TFirstLast as ur, TDbRemoveGuardContext as ut, DbQuery as v, TDbSpaceOptions as vn, TDbWriteGuardContext as vt, NullableOptional as w, aliasTargetOf as wn, TExistingColumn as wt, FilterExpr$1 as x, isAtscriptDbView as xn, TDerivedChangeReason as xt, DbRow as y, AtscriptDbView as yn, TDbWriteLimit as yt, TDbAvailableActions as z, TCascadePin as zn, TPrimaryKeyChange as zt };
5289
+ export { TDbInsertManyIgnoreResult as $, TRelationStaticFilter as $n, TValueFormatterPair as $t, TCascadeTarget as A, AtscriptQueryComparison as An, TForeignKeyChange as At, TDbCollation as B, MutationFilter as Bn, TPrimaryKeyChange as Bt, NavPropsOf$1 as C, TViewColumnMapping as Cn, TEnsureTableOptions as Ct, PrimaryKeyOf$1 as D, aliasTargetOf as Dn, TFieldMeta as Dt, OwnPropsOf$1 as E, TViewReadPlan as En, TExistingTableOption as Et, TDbActionIntent as F, TViewPlan as Fn, TInsertOneOptions as Ft, TDbFieldMeta as G, DbResponse as Gn, TSearchIndexInfo as Gt, TDbDefaultValue as H, NativeIntegrity as Hn, TReferencingForeignKey as Ht, TDbActionLevel as I, evaluateExpr as In, TInsertOptions as It, TDbIndexField as J, REL_FILTER_MAX_NODES as Jn, TTableOptionDiff as Jt, TDbForeignKey as K, resolveDesignType as Kn, TSyncColumnResult as Kt, TDbActionProcessor as L, isFieldRef as Ln, TJsonCopyTarget as Lt, TCrudOp as M, AtscriptQueryNode$1 as Mn, TIdResolveOptions as Mt, TCrudPermissions as N, AtscriptRef as Nn, TIdentification as Nt, TBulkWriteOptions as O, AtscriptExprNode$1 as On, TFkLookupResolver as Ot, TDbActionInfo as P, TViewJoin as Pn, TIndexChange as Pt, TDbInsertIgnoreSlot as Q, TRelationFilterTable as Qn, TValidateRowsError as Qt, TDbActionTargetSummary as R, translateQueryTree as Rn, TMetaResponse as Rt, FlatOf$1 as S, AtscriptDbView as Sn, TDerivedColumn as St, NullsPlacement$1 as T, isViewType as Tn, TExistingForeignKey as Tt, TDbDeleteManyOptions as U, TCascadePin as Un, TRelationInfo as Ut, TDbDefaultFn as V, IntegrityStrategy as Vn, TReadLockOptions as Vt, TDbDeleteResult as W, AtscriptDbReadable as Wn, TRowResolveOptions as Wt, TDbInsertIgnoreOptions as X, TRelGuardState as Xn, TTouchManyOptions as Xt, TDbIndexType as Y, ResolvedRelationFilter as Yn, TTableResolver as Yt, TDbInsertIgnoreResult as Z, TRelationFilterJunction as Zn, TTransactionOptions as Zt, DbPatch as _, TIndexDiffOptions as _n, TDbWriteGuard as _t, isJsonValueField as a, UniqueryControls$1 as an, relationStaticFilter as ar, TDbObjectKind as at, FieldOpsFor as b, TAdapterFactory as bn, TDeleteOptions as bt, resolveCalendarBuckets as c, isGeoIndexableType as cn, DocumentFieldMapper as cr, TDbRelation as ct, AggregateFn$1 as d, soleUnionMember as dn, NoopLogger as dr, TDbStorageType as dt, TViewJsonType as en, andFilters as er, TDbInsertManyResult as et, AggregateQuery$1 as f, ALL_BUCKET_UNITS as fn, TGenericLogger as fr, TDbUpdateOptions as ft, DbControls as g, TForeignKeyDiffOptions as gn, UniquSelect as gr, TDbWriteCheckContext as gt, AtscriptDbWritable as h, BaseDbAdapter as hn, TRowOrderKey as hr, TDbWriteCheck as ht, isBucketableField as i, Uniquery$1 as in, isResolvedRelationFilter as ir, TDbLockWait as it, TColumnDiff as j, AtscriptQueryFieldRef$1 as jn, TIdDescriptor as jt, TCascadeResolver as k, AtscriptOrderItem as kn, TFkLookupTarget as kt, AggregateControls as l, isGeoPointType as ln, FieldMappingStrategy as lr, TDbRemoveGuard as lt, AtscriptDbTableLike as m, ALL_VIEW_CAPABILITIES as mn, TFirstLast as mr, TDbWriteAction as mt, TComputedSelect as n, TWriteTableResolver as nn, forEachResolvedRelation as nr, TDbIsolationLevel as nt, jsonValueAncestor as o, WithRelation$1 as on, DbEncryption as or, TDbReadLock as ot, AggregateResult as p, ALL_ISOLATION_LEVELS as pn, TExprAggregate as pr, TDbUpdateResult as pt, TDbIndex as q, REL_FILTER_MAX_DEPTH as qn, TSyncIndexesOptions as qt, TResolvedBucket as r, TypedWithRelation as rn, hasRelationOp as rr, TDbLockMode as rt, normalizeComputedSelect as s, TableMetadata as sn, TDbEncryptionOptions as sr, TDbReferentialAction as st, TBucketFieldSource as t, TWriteOptions as tn, containsRelationFilter as tr, TDbInsertResult as tt, AggregateExpr$1 as u, TPathPresence as un, TReadControls as ur, TDbRemoveGuardContext as ut, DbQuery as v, TViewCapability as vn, TDbWriteGuardContext as vt, NullableOptional as w, isAtscriptDbView as wn, TExistingColumn as wt, FilterExpr$1 as x, TDbSpaceOptions as xn, TDerivedChangeReason as xt, DbRow as y, DbSpace as yn, TDbWriteLimit as yt, TDbAvailableActions as z, AtscriptDbTable as zn, TMetadataOverrides as zt };
@@ -1,4 +1,4 @@
1
- import { r as DbError } from "./db-error-B_DRL1E9.mjs";
1
+ import { r as DbError } from "./db-error-DQUw2cED.mjs";
2
2
  import { f as TFieldOps } from "./ops-AqhV7s9o.mjs";
3
3
  import { AtscriptExprNode, AtscriptExprNode as AtscriptExprNode$1, AtscriptOrderItem, AtscriptQueryComparison, AtscriptQueryFieldRef, AtscriptQueryFieldRef as AtscriptQueryFieldRef$1, AtscriptQueryNode, AtscriptQueryNode as AtscriptQueryNode$1, AtscriptRef, FlatOf, FlatOf as FlatOf$1, NavPropsOf, NavPropsOf as NavPropsOf$1, OwnPropsOf, OwnPropsOf as OwnPropsOf$1, PrimaryKeyOf, PrimaryKeyOf as PrimaryKeyOf$1, TAtscriptAnnotatedType, TAtscriptDataType, TAtscriptTypeObject, TMetadataMap, TSerializedAnnotatedType, TValidatorOptions, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
4
4
  import { AggregateControls, AggregateExpr, AggregateExpr as AggregateExpr$1, AggregateFn, AggregateFn as AggregateFn$1, AggregateQuery, AggregateQuery as AggregateQuery$1, AggregateResult, BucketUnit, FieldOpsFor, FilterExpr, FilterExpr as FilterExpr$1, NullsPlacement, NullsPlacement as NullsPlacement$1, RelationOp, ResolvedBucket, ResolvedRowOrderKey, ResolvedSelectExpr, TypedWithRelation, Uniquery, Uniquery as Uniquery$1, UniqueryControls, UniqueryControls as UniqueryControls$1, UniqueryInsights, WithRelation, WithRelation as WithRelation$1 } from "@uniqu/core";
@@ -568,16 +568,17 @@ declare function relationStaticFilter(relation: TDbRelation, name?: string): TRe
568
568
  //#endregion
569
569
  //#region src/table/db-readable.d.ts
570
570
  /**
571
- * Extracts nav prop names from a query's `$with` array.
571
+ * Extracts nav prop names from a query's `$with` array — mutable or readonly
572
+ * (`as const`, since 0.1.165), object entries or the string shorthand.
572
573
  * Returns `never` when `$with` is absent → all nav props stripped from response.
573
574
  */
574
575
  type ExtractWith<Q> = Q extends {
575
576
  controls: {
576
- $with: Array<{
577
- name: infer N extends string;
578
- }>;
577
+ $with: ReadonlyArray<infer E>;
579
578
  };
580
- } ? N : never;
579
+ } ? E extends {
580
+ name: infer N extends string;
581
+ } ? N : E extends string ? E : never : never;
581
582
  /**
582
583
  * Computes the response type for a query:
583
584
  * - Strips all nav props from the base DataType
@@ -770,6 +771,17 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
770
771
  */
771
772
  get onUpdateIncPhysical(): readonly string[];
772
773
  private _onUpdateIncPhysical?;
774
+ /**
775
+ * Physical column names of the insert-only fields (`number.timestamp.created`,
776
+ * since 0.1.165): a full replace keeps their stored values. Empty when
777
+ * there are none.
778
+ *
779
+ * @internal Adapter-facing surface; not part of the consumer API.
780
+ */
781
+ get insertOnlyPhysical(): readonly string[];
782
+ private _insertOnlyPhysical?;
783
+ /** The physical columns of a set of top-level logical fields. */
784
+ private _physicalNames;
773
785
  /**
774
786
  * Logical paths of the `@db.column.version.exempt` fields, including objects
775
787
  * whose direct children are all exempt. A patch that writes only these (and
@@ -1327,6 +1339,14 @@ declare class NativeIntegrity extends IntegrityStrategy {
1327
1339
  }
1328
1340
  //#endregion
1329
1341
  //#region src/table/db-table.d.ts
1342
+ /**
1343
+ * The filter of `updateMany` / `replaceMany` / `deleteMany` (since 0.1.165):
1344
+ * the flat field paths with the nav keys taking relational predicates
1345
+ * (`$some` / `$none`), as in the read filter. Before, a nav key was typed as
1346
+ * the flat type's empty value, so a predicate failed to typecheck. A table
1347
+ * without nav props keeps the plain flat filter.
1348
+ */
1349
+ type MutationFilter<FlatType, NavType extends Record<string, unknown>> = string extends keyof NavType ? FilterExpr<FlatType> : FilterExpr<Omit<FlatType, keyof NavType>, NavType>;
1330
1350
  declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnotatedType, DataType = TAtscriptDataType<T>, FlatType = NullableOptional<FlatOf<T>>, A extends BaseDbAdapter = BaseDbAdapter, IdType = PrimaryKeyOf<T>, OwnProps = NullableOptional<OwnPropsOf<T>>, NavType extends Record<string, unknown> = NavPropsOf<T>> extends AtscriptDbReadable<T, DataType, FlatType, A, IdType, OwnProps, NavType> {
1331
1351
  protected _cascadeResolver?: TCascadeResolver;
1332
1352
  protected _fkLookupResolver?: TFkLookupResolver;
@@ -1352,14 +1372,67 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
1352
1372
  * Adapters may define additional purposes.
1353
1373
  */
1354
1374
  getValidator(purpose: string): Validator<T, DataType>;
1375
+ /**
1376
+ * A standard purpose's validator called WITHOUT a context validates in that
1377
+ * purpose's write mode (since 0.1.165): `getValidator("insert").validate(row, true)`
1378
+ * accepts what an insert accepts — omitted primary key, defaulted, FK and
1379
+ * navigation fields. Before, the db plugin saw no mode and ran inert while
1380
+ * navigation fields were forced required. An explicit context still wins.
1381
+ */
1382
+ private _withDefaultContext;
1383
+ /** A fresh validation context of a write `mode` — the one its write paths build. */
1384
+ private _validationCtx;
1385
+ /** {@link normalizeWriteErrors} for this table: its constraint errors normalized against its metadata. */
1386
+ private _normalizeWrite;
1387
+ /**
1388
+ * Validates rows exactly as a write in `mode` would, without writing
1389
+ * (since 0.1.165): each row is cloned, given the defaults / stamps that
1390
+ * write applies, and validated with that write's validator and context.
1391
+ * Returns one `{ index, path, message }` per problem — `[]` when every row
1392
+ * is valid; the caller's rows are not modified.
1393
+ *
1394
+ * `fk: true` also checks that every foreign key names an existing row
1395
+ * (by lookup, on every adapter — native-FK adapters otherwise leave that to
1396
+ * the engine at write time); a missing target is reported on each of the
1397
+ * key's fields. Rows that fail type validation are not looked up.
1398
+ *
1399
+ * @param mode - `'insert'` (default), `'replace'` or `'patch'`.
1400
+ */
1401
+ validateRows(rows: ReadonlyArray<Record<string, unknown>>, mode?: "insert" | "replace" | "patch", opts?: {
1402
+ fk?: boolean;
1403
+ }): Promise<TValidateRowsError[]>;
1404
+ /**
1405
+ * {@link validateRows}' FK lookup: one entry per FK field of each row naming
1406
+ * a missing target. Distinct key tuples are looked up in chunks of
1407
+ * {@link FK_LOOKUP_CHUNK} — reading the target keys that exist (`$in` for a
1408
+ * single-column key, `$or` for a composite one) and diffing in memory, so a
1409
+ * batch never exceeds a bind-parameter limit and a miss costs no extra
1410
+ * query. A lookup target without `find` (a custom resolver) is counted per
1411
+ * chunk, and per tuple only in a chunk that comes up short.
1412
+ */
1413
+ private _missingForeignKeys;
1414
+ /** How {@link _missingForeignKeys} reads an FK's target table, if it can. */
1415
+ private _fkTargetReader;
1355
1416
  /**
1356
1417
  * Inserts a single record. Delegates to {@link insertMany} for unified
1357
1418
  * nested creation support.
1358
1419
  */
1359
- insertOne(payload: DbPatch<DataType>, opts: TInsertOptions<DataType> & {
1420
+ insertOne(payload: DbPatch<DataType>, opts: TInsertOneOptions<DataType> & {
1421
+ onConflict: "ignore";
1422
+ returning: true | readonly (keyof DataType & string)[];
1423
+ }): Promise<TDbInsertIgnoreResult & {
1424
+ row?: DataType;
1425
+ }>;
1426
+ insertOne(payload: DbPatch<DataType>, opts: TInsertOneOptions<DataType> & {
1360
1427
  onConflict: "ignore";
1361
1428
  }): Promise<TDbInsertIgnoreResult>;
1362
- insertOne(payload: DbPatch<DataType>, opts?: TInsertOptions<DataType>): Promise<TDbInsertResult>;
1429
+ insertOne(payload: DbPatch<DataType>, opts: TInsertOneOptions<DataType> & {
1430
+ returning: true | readonly (keyof DataType & string)[];
1431
+ }): Promise<TDbInsertResult & {
1432
+ row: DataType;
1433
+ }>;
1434
+ insertOne(payload: DbPatch<DataType>, opts?: TInsertOneOptions<DataType>): Promise<TDbInsertResult>;
1435
+ private _insertOneRow;
1363
1436
  /**
1364
1437
  * Inserts multiple records with batch-optimized nested creation.
1365
1438
  *
@@ -1480,14 +1553,14 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
1480
1553
  * always breaks ties). Loop until `matchedCount === 0` to process every
1481
1554
  * match in batches. Not exposed over HTTP.
1482
1555
  */
1483
- updateMany(filter: FilterExpr<FlatType>, data: DbPatch<DataType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbUpdateResult>;
1556
+ updateMany(filter: MutationFilter<FlatType, NavType>, data: DbPatch<DataType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbUpdateResult>;
1484
1557
  /**
1485
1558
  * Replaces the own fields of every row matching `filter` with `data`. The
1486
1559
  * payload is validated in `replace` mode (since 0.1.162) — every required
1487
1560
  * field must be present — except the primary key, which the filter
1488
1561
  * replaces as a row picker.
1489
1562
  */
1490
- replaceMany(filter: FilterExpr<FlatType>, data: DbRow<DataType>): Promise<TDbUpdateResult>;
1563
+ replaceMany(filter: MutationFilter<FlatType, NavType>, data: DbRow<DataType>): Promise<TDbUpdateResult>;
1491
1564
  /**
1492
1565
  * Deletes every row matching `filter` (application-level cascades run first
1493
1566
  * where the adapter has no native foreign keys).
@@ -1499,7 +1572,7 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
1499
1572
  * `limit`: a concurrent writer can make one round delete fewer rows while
1500
1573
  * matches remain. Not exposed over HTTP.
1501
1574
  */
1502
- deleteMany(filter: FilterExpr<FlatType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbDeleteResult>;
1575
+ deleteMany(filter: MutationFilter<FlatType, NavType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbDeleteResult>;
1503
1576
  /**
1504
1577
  * Runs a bounded write. `native` (default: `supportsWriteLimit()`) hands
1505
1578
  * `write` the physical filter and the bound; otherwise the primary keys of
@@ -1749,6 +1822,8 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
1749
1822
  * Used by parent tables to validate FROM children before the main insert,
1750
1823
  * ensuring errors are caught before the parent is committed.
1751
1824
  *
1825
+ * @internal Nested-write plumbing — its FK step is a no-op on native-FK
1826
+ * adapters. To validate rows yourself, use {@link validateRows}.
1752
1827
  * @param opts.excludeFkTargetTable - Skip FK validation to this table (the parent).
1753
1828
  */
1754
1829
  preValidateItems(items: Array<Record<string, unknown>>, opts?: {
@@ -3371,6 +3446,12 @@ declare abstract class BaseDbAdapter {
3371
3446
  }
3372
3447
  //#endregion
3373
3448
  //#region src/shared/union-shape.d.ts
3449
+ /**
3450
+ * The one value member of a union (`T | null` → `T`), or `undefined` when
3451
+ * `type` is no union or has several value members. A column of a nullable
3452
+ * union is the column `T` alone would get (its type tags, size, precision).
3453
+ */
3454
+ declare function soleUnionMember(type: TAtscriptAnnotatedType): TAtscriptAnnotatedType | undefined;
3374
3455
  /**
3375
3456
  * Whether a value at a path is always there (`"required"`), may be NULL /
3376
3457
  * missing (`"nullable"` — the path or an ancestor object is optional or a
@@ -3438,6 +3519,12 @@ declare class TableMetadata {
3438
3519
  * @since 0.1.156
3439
3520
  */
3440
3521
  onUpdateNow: Set<string>;
3522
+ /**
3523
+ * Top-level `number.timestamp.created` fields (since 0.1.165): set by the
3524
+ * insert only — a replace keeps the stored value, a replace or patch
3525
+ * payload's value is dropped.
3526
+ */
3527
+ insertOnly: Set<string>;
3441
3528
  /**
3442
3529
  * Top-level fields annotated with `@db.onUpdate.inc`: `0` on insert, `+1` in
3443
3530
  * the same statement on every update and replace.
@@ -3797,8 +3884,20 @@ interface TTransactionOptions {
3797
3884
  }
3798
3885
  /** Describes an available search index exposed by a database adapter. */
3799
3886
  interface TSearchIndexInfo {
3800
- /** Index name. Empty string or 'DEFAULT' for the default index. */
3887
+ /**
3888
+ * Index name — the name declared in the model (`@db.index.fulltext 'name'`).
3889
+ * An index with no declared name (a MongoDB dynamic Atlas mapping) is
3890
+ * `'DEFAULT'`.
3891
+ */
3801
3892
  name: string;
3893
+ /**
3894
+ * Other names that resolve to the same index (`$index` / `search(…, name)`),
3895
+ * kept for compatibility: the internal key (`atscript__fulltext__<name>`) on
3896
+ * PostgreSQL and MySQL, and `'DEFAULT'` for MongoDB's default text index.
3897
+ * Deprecated — address an index by {@link name}.
3898
+ * @since 0.1.165
3899
+ */
3900
+ aliases?: string[];
3802
3901
  /** Human-readable label for UI display. */
3803
3902
  description?: string;
3804
3903
  /** Index type: text search or vector similarity search. */
@@ -4285,6 +4384,15 @@ interface TDbIndexField {
4285
4384
  */
4286
4385
  integer?: boolean;
4287
4386
  }
4387
+ /**
4388
+ * One problem {@link AtscriptDbTable.validateRows} found: the row's position
4389
+ * in the input, the field path and the message (since 0.1.165).
4390
+ */
4391
+ interface TValidateRowsError {
4392
+ index: number;
4393
+ path: string;
4394
+ message: string;
4395
+ }
4288
4396
  interface TDbIndex {
4289
4397
  /** Unique key used for identity/diffing (e.g., "atscript__plain__email") */
4290
4398
  key: string;
@@ -4356,6 +4464,12 @@ interface TDbFieldMeta {
4356
4464
  ignored: boolean;
4357
4465
  /** Default value from @db.default.* */
4358
4466
  defaultValue?: TDbDefaultValue;
4467
+ /**
4468
+ * Set by the insert only — a top-level `number.timestamp.created` (since
4469
+ * 0.1.165). A replace keeps the stored value: SQL adapters leave the
4470
+ * column out of the replace's assignment, document adapters carry it over.
4471
+ */
4472
+ insertOnly?: boolean;
4359
4473
  /**
4360
4474
  * How this field is stored in the database.
4361
4475
  * - 'column': a standard scalar column (default for primitives)
@@ -4797,6 +4911,12 @@ type TCascadeResolver = (tableName: string) => TCascadeTarget[];
4797
4911
  */
4798
4912
  interface TFkLookupTarget {
4799
4913
  count(filter: Record<string, unknown>): Promise<number>;
4914
+ /**
4915
+ * The rows matching `filter`, projected to `fields` (since 0.1.165) — lets
4916
+ * `validateRows({ fk: true })` diff existing keys in memory. Optional: a
4917
+ * target without it is counted instead.
4918
+ */
4919
+ find?(filter: Record<string, unknown>, fields: readonly string[]): Promise<Array<Record<string, unknown>>>;
4800
4920
  }
4801
4921
  /**
4802
4922
  * Callback that resolves a table name to a queryable target for FK validation.
@@ -4980,6 +5100,16 @@ interface TInsertOptions<Row = Record<string, unknown>> extends TWriteOptions<Ro
4980
5100
  */
4981
5101
  lockConflicts?: boolean;
4982
5102
  }
5103
+ /**
5104
+ * Options of `insertOne` (since 0.1.165): {@link TInsertOptions} plus
5105
+ * `returning` — read the stored row back by its primary key in the insert's
5106
+ * transaction (`true`: every field, server defaults and stamps included; a
5107
+ * field list: those fields) and answer it as `row`. A row skipped by
5108
+ * `onConflict: 'ignore'` answers no `row`.
5109
+ */
5110
+ interface TInsertOneOptions<Row = Record<string, unknown>> extends TInsertOptions<Row> {
5111
+ returning?: true | readonly (keyof Row & string)[];
5112
+ }
4983
5113
  /**
4984
5114
  * Context handed to a write {@link TWriteOptions.check} (since 0.1.143) — and
4985
5115
  * through it to `AsDbController.checkWrite()`. Lets a permission layer verify
@@ -5156,4 +5286,4 @@ declare function isJsonValueField(fd: TDbFieldMeta): boolean;
5156
5286
  */
5157
5287
  declare function jsonValueAncestor(path: string, jsonValueParents: ReadonlySet<string>): string | undefined;
5158
5288
  //#endregion
5159
- export { TDbInsertManyIgnoreResult as $, hasRelationOp as $n, TWriteOptions as $t, TCascadeTarget as A, AtscriptRef as An, TForeignKeyChange as At, TDbCollation as B, AtscriptDbReadable as Bn, TReadLockOptions as Bt, NavPropsOf$1 as C, TViewReadPlan as Cn, TEnsureTableOptions as Ct, PrimaryKeyOf$1 as D, AtscriptQueryComparison as Dn, TFieldMeta as Dt, OwnPropsOf$1 as E, AtscriptOrderItem as En, TExistingTableOption as Et, TDbActionIntent as F, translateQueryTree as Fn, TInsertOptions as Ft, TDbFieldMeta as G, ResolvedRelationFilter as Gn, TSyncColumnResult as Gt, TDbDefaultValue as H, resolveDesignType as Hn, TRelationInfo as Ht, TDbActionLevel as I, AtscriptDbTable as In, TJsonCopyTarget as It, TDbIndexField as J, TRelationFilterTable as Jn, TTableResolver as Jt, TDbForeignKey as K, TRelGuardState as Kn, TSyncIndexesOptions as Kt, TDbActionProcessor as L, IntegrityStrategy as Ln, TMetaResponse as Lt, TCrudOp as M, TViewPlan as Mn, TIdResolveOptions as Mt, TCrudPermissions as N, evaluateExpr as Nn, TIdentification as Nt, TBulkWriteOptions as O, AtscriptQueryFieldRef$1 as On, TFkLookupResolver as Ot, TDbActionInfo as P, isFieldRef as Pn, TIndexChange as Pt, TDbInsertIgnoreSlot as Q, forEachResolvedRelation as Qn, TViewJsonType as Qt, TDbActionTargetSummary as R, NativeIntegrity as Rn, TMetadataOverrides as Rt, FlatOf$1 as S, isViewType as Sn, TDerivedColumn as St, NullsPlacement$1 as T, AtscriptExprNode$1 as Tn, TExistingForeignKey as Tt, TDbDeleteManyOptions as U, REL_FILTER_MAX_DEPTH as Un, TRowResolveOptions as Ut, TDbDefaultFn as V, DbResponse as Vn, TReferencingForeignKey as Vt, TDbDeleteResult as W, REL_FILTER_MAX_NODES as Wn, TSearchIndexInfo as Wt, TDbInsertIgnoreOptions as X, andFilters as Xn, TTransactionOptions as Xt, TDbIndexType as Y, TRelationStaticFilter as Yn, TTouchManyOptions as Yt, TDbInsertIgnoreResult as Z, containsRelationFilter as Zn, TValueFormatterPair as Zt, DbPatch as _, TAdapterFactory as _n, TDbWriteGuard as _t, isJsonValueField as a, TableMetadata as an, FieldMappingStrategy as ar, TDbObjectKind as at, FieldOpsFor as b, TViewColumnMapping as bn, TDeleteOptions as bt, resolveCalendarBuckets as c, TPathPresence as cn, TGenericLogger as cr, TDbRelation as ct, AggregateFn$1 as d, ALL_VIEW_CAPABILITIES as dn, TRowOrderKey as dr, TDbStorageType as dt, TWriteTableResolver as en, isResolvedRelationFilter as er, TDbInsertManyResult as et, AggregateQuery$1 as f, BaseDbAdapter as fn, UniquSelect as fr, TDbUpdateOptions as ft, DbControls as g, DbSpace as gn, TDbWriteCheckContext as gt, AtscriptDbWritable as h, TViewCapability as hn, TDbWriteCheck as ht, isBucketableField as i, WithRelation$1 as in, DocumentFieldMapper as ir, TDbLockWait as it, TColumnDiff as j, TViewJoin as jn, TIdDescriptor as jt, TCascadeResolver as k, AtscriptQueryNode$1 as kn, TFkLookupTarget as kt, AggregateControls as l, ALL_BUCKET_UNITS as ln, TExprAggregate as lr, TDbRemoveGuard as lt, AtscriptDbTableLike as m, TIndexDiffOptions as mn, TDbWriteAction as mt, TComputedSelect as n, Uniquery$1 as nn, DbEncryption as nr, TDbIsolationLevel as nt, jsonValueAncestor as o, isGeoIndexableType as on, TReadControls as or, TDbReadLock as ot, AggregateResult as p, TForeignKeyDiffOptions as pn, TDbUpdateResult as pt, TDbIndex as q, TRelationFilterJunction as qn, TTableOptionDiff as qt, TResolvedBucket as r, UniqueryControls$1 as rn, TDbEncryptionOptions as rr, TDbLockMode as rt, normalizeComputedSelect as s, isGeoPointType as sn, NoopLogger as sr, TDbReferentialAction as st, TBucketFieldSource as t, TypedWithRelation as tn, relationStaticFilter as tr, TDbInsertResult as tt, AggregateExpr$1 as u, ALL_ISOLATION_LEVELS as un, TFirstLast as ur, TDbRemoveGuardContext as ut, DbQuery as v, TDbSpaceOptions as vn, TDbWriteGuardContext as vt, NullableOptional as w, aliasTargetOf as wn, TExistingColumn as wt, FilterExpr$1 as x, isAtscriptDbView as xn, TDerivedChangeReason as xt, DbRow as y, AtscriptDbView as yn, TDbWriteLimit as yt, TDbAvailableActions as z, TCascadePin as zn, TPrimaryKeyChange as zt };
5289
+ export { TDbInsertManyIgnoreResult as $, TRelationStaticFilter as $n, TValueFormatterPair as $t, TCascadeTarget as A, AtscriptQueryComparison as An, TForeignKeyChange as At, TDbCollation as B, MutationFilter as Bn, TPrimaryKeyChange as Bt, NavPropsOf$1 as C, TViewColumnMapping as Cn, TEnsureTableOptions as Ct, PrimaryKeyOf$1 as D, aliasTargetOf as Dn, TFieldMeta as Dt, OwnPropsOf$1 as E, TViewReadPlan as En, TExistingTableOption as Et, TDbActionIntent as F, TViewPlan as Fn, TInsertOneOptions as Ft, TDbFieldMeta as G, DbResponse as Gn, TSearchIndexInfo as Gt, TDbDefaultValue as H, NativeIntegrity as Hn, TReferencingForeignKey as Ht, TDbActionLevel as I, evaluateExpr as In, TInsertOptions as It, TDbIndexField as J, REL_FILTER_MAX_NODES as Jn, TTableOptionDiff as Jt, TDbForeignKey as K, resolveDesignType as Kn, TSyncColumnResult as Kt, TDbActionProcessor as L, isFieldRef as Ln, TJsonCopyTarget as Lt, TCrudOp as M, AtscriptQueryNode$1 as Mn, TIdResolveOptions as Mt, TCrudPermissions as N, AtscriptRef as Nn, TIdentification as Nt, TBulkWriteOptions as O, AtscriptExprNode$1 as On, TFkLookupResolver as Ot, TDbActionInfo as P, TViewJoin as Pn, TIndexChange as Pt, TDbInsertIgnoreSlot as Q, TRelationFilterTable as Qn, TValidateRowsError as Qt, TDbActionTargetSummary as R, translateQueryTree as Rn, TMetaResponse as Rt, FlatOf$1 as S, AtscriptDbView as Sn, TDerivedColumn as St, NullsPlacement$1 as T, isViewType as Tn, TExistingForeignKey as Tt, TDbDeleteManyOptions as U, TCascadePin as Un, TRelationInfo as Ut, TDbDefaultFn as V, IntegrityStrategy as Vn, TReadLockOptions as Vt, TDbDeleteResult as W, AtscriptDbReadable as Wn, TRowResolveOptions as Wt, TDbInsertIgnoreOptions as X, TRelGuardState as Xn, TTouchManyOptions as Xt, TDbIndexType as Y, ResolvedRelationFilter as Yn, TTableResolver as Yt, TDbInsertIgnoreResult as Z, TRelationFilterJunction as Zn, TTransactionOptions as Zt, DbPatch as _, TIndexDiffOptions as _n, TDbWriteGuard as _t, isJsonValueField as a, UniqueryControls$1 as an, relationStaticFilter as ar, TDbObjectKind as at, FieldOpsFor as b, TAdapterFactory as bn, TDeleteOptions as bt, resolveCalendarBuckets as c, isGeoIndexableType as cn, DocumentFieldMapper as cr, TDbRelation as ct, AggregateFn$1 as d, soleUnionMember as dn, NoopLogger as dr, TDbStorageType as dt, TViewJsonType as en, andFilters as er, TDbInsertManyResult as et, AggregateQuery$1 as f, ALL_BUCKET_UNITS as fn, TGenericLogger as fr, TDbUpdateOptions as ft, DbControls as g, TForeignKeyDiffOptions as gn, UniquSelect as gr, TDbWriteCheckContext as gt, AtscriptDbWritable as h, BaseDbAdapter as hn, TRowOrderKey as hr, TDbWriteCheck as ht, isBucketableField as i, Uniquery$1 as in, isResolvedRelationFilter as ir, TDbLockWait as it, TColumnDiff as j, AtscriptQueryFieldRef$1 as jn, TIdDescriptor as jt, TCascadeResolver as k, AtscriptOrderItem as kn, TFkLookupTarget as kt, AggregateControls as l, isGeoPointType as ln, FieldMappingStrategy as lr, TDbRemoveGuard as lt, AtscriptDbTableLike as m, ALL_VIEW_CAPABILITIES as mn, TFirstLast as mr, TDbWriteAction as mt, TComputedSelect as n, TWriteTableResolver as nn, forEachResolvedRelation as nr, TDbIsolationLevel as nt, jsonValueAncestor as o, WithRelation$1 as on, DbEncryption as or, TDbReadLock as ot, AggregateResult as p, ALL_ISOLATION_LEVELS as pn, TExprAggregate as pr, TDbUpdateResult as pt, TDbIndex as q, REL_FILTER_MAX_DEPTH as qn, TSyncIndexesOptions as qt, TResolvedBucket as r, TypedWithRelation as rn, hasRelationOp as rr, TDbLockMode as rt, normalizeComputedSelect as s, TableMetadata as sn, TDbEncryptionOptions as sr, TDbReferentialAction as st, TBucketFieldSource as t, TWriteOptions as tn, containsRelationFilter as tr, TDbInsertResult as tt, AggregateExpr$1 as u, TPathPresence as un, TReadControls as ur, TDbRemoveGuardContext as ut, DbQuery as v, TViewCapability as vn, TDbWriteGuardContext as vt, NullableOptional as w, isAtscriptDbView as wn, TExistingColumn as wt, FilterExpr$1 as x, TDbSpaceOptions as xn, TDerivedChangeReason as xt, DbRow as y, DbSpace as yn, TDbWriteLimit as yt, TDbAvailableActions as z, AtscriptDbTable as zn, TMetadataOverrides as zt };