@atscript/db 0.1.122 → 0.1.123

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.
@@ -238,6 +238,12 @@ interface TFieldMeta {
238
238
  encrypted?: boolean;
239
239
  /** Present (true) when the field carries a `@db.index.geo` geospatial index. */
240
240
  geo?: boolean;
241
+ /**
242
+ * Present (true) when the field is write-only over HTTP (`@db.writeOnly` or
243
+ * stamped by a permission overlay): settable in write payloads, never
244
+ * present in read responses. UIs render it as a set-only input.
245
+ */
246
+ writeOnly?: boolean;
241
247
  }
242
248
  /** Built-in CRUD operation names; map 1:1 to public method names. */
243
249
  type TCrudOp = "query" | "pages" | "one" | "geo" | "insert" | "update" | "replace" | "remove";
@@ -238,6 +238,12 @@ interface TFieldMeta {
238
238
  encrypted?: boolean;
239
239
  /** Present (true) when the field carries a `@db.index.geo` geospatial index. */
240
240
  geo?: boolean;
241
+ /**
242
+ * Present (true) when the field is write-only over HTTP (`@db.writeOnly` or
243
+ * stamped by a permission overlay): settable in write payloads, never
244
+ * present in read responses. UIs render it as a set-only input.
245
+ */
246
+ writeOnly?: boolean;
241
247
  }
242
248
  /** Built-in CRUD operation names; map 1:1 to public method names. */
243
249
  type TCrudOp = "query" | "pages" | "one" | "geo" | "insert" | "update" | "replace" | "remove";
@@ -1,4 +1,4 @@
1
- import { C as TCascadeResolver, F as TDbDeleteResult, H as TDbInsertResult, K as TDbUpdateResult, V as TDbInsertManyResult, X as TFkLookupResolver, _t as TGenericLogger, a as TDbEncryptionOptions, c as BaseDbAdapter, ct as TWriteTableResolver, i as DbEncryption, ot as TTableResolver, pt as TableMetadata, t as AtscriptDbReadable } from "./db-readable-wyKeE8ut.mjs";
1
+ import { C as TCascadeResolver, F as TDbDeleteResult, H as TDbInsertResult, K as TDbUpdateResult, V as TDbInsertManyResult, X as TFkLookupResolver, _t as TGenericLogger, a as TDbEncryptionOptions, c as BaseDbAdapter, ct as TWriteTableResolver, i as DbEncryption, ot as TTableResolver, pt as TableMetadata, t as AtscriptDbReadable } from "./db-readable-BkAGccv9.mjs";
2
2
  import { AtscriptQueryComparison, AtscriptQueryFieldRef, AtscriptQueryFieldRef as AtscriptQueryFieldRef$1, AtscriptQueryNode, AtscriptQueryNode as AtscriptQueryNode$1, AtscriptRef, FlatOf, NavPropsOf, OwnPropsOf, PrimaryKeyOf, TAtscriptAnnotatedType, TAtscriptDataType, Validator } from "@atscript/typescript/utils";
3
3
  import { FilterExpr } from "@uniqu/core";
4
4
 
@@ -1,4 +1,4 @@
1
- import { C as TCascadeResolver, F as TDbDeleteResult, H as TDbInsertResult, K as TDbUpdateResult, V as TDbInsertManyResult, X as TFkLookupResolver, _t as TGenericLogger, a as TDbEncryptionOptions, c as BaseDbAdapter, ct as TWriteTableResolver, i as DbEncryption, ot as TTableResolver, pt as TableMetadata, t as AtscriptDbReadable } from "./db-readable-DoJqR5pb.cjs";
1
+ import { C as TCascadeResolver, F as TDbDeleteResult, H as TDbInsertResult, K as TDbUpdateResult, V as TDbInsertManyResult, X as TFkLookupResolver, _t as TGenericLogger, a as TDbEncryptionOptions, c as BaseDbAdapter, ct as TWriteTableResolver, i as DbEncryption, ot as TTableResolver, pt as TableMetadata, t as AtscriptDbReadable } from "./db-readable-C0nDKX8A.cjs";
2
2
  import { FilterExpr } from "@uniqu/core";
3
3
  import { AtscriptQueryComparison, AtscriptQueryFieldRef, AtscriptQueryFieldRef as AtscriptQueryFieldRef$1, AtscriptQueryNode, AtscriptQueryNode as AtscriptQueryNode$1, AtscriptRef, FlatOf, NavPropsOf, OwnPropsOf, PrimaryKeyOf, TAtscriptAnnotatedType, TAtscriptDataType, Validator } from "@atscript/typescript/utils";
4
4
 
@@ -2,7 +2,7 @@ import { n as DbError } from "./db-error-BHPXOKzc.mjs";
2
2
  import { resolveAlias } from "./agg.mjs";
3
3
  import { a as batchPatchNestedTo, c as batchReplaceNestedTo, d as preValidateNestedFrom, f as validateBatch, g as findRemoteFK, h as findFKForRelation, i as batchPatchNestedFrom, l as batchReplaceNestedVia, m as remapDeleteFkViolation, n as batchInsertNestedTo, o as batchPatchNestedVia, p as enrichFkViolation, r as batchInsertNestedVia, s as batchReplaceNestedFrom, t as batchInsertNestedFrom, u as checkDepthOverflow } from "./nested-writer-DI-HeTky.mjs";
4
4
  import { separateCas, separateFieldOps } from "./ops.mjs";
5
- import { i as forceNavNonOptional, r as dbPlugin, s as getKeyProps, t as buildDbValidator } from "./validator-C7plt6Kf.mjs";
5
+ import { i as forceNavNonOptional, r as dbPlugin, s as getKeyProps, t as buildDbValidator } from "./validator-76GCYs80.mjs";
6
6
  import { flattenAnnotatedType, isAnnotatedType } from "@atscript/typescript/utils";
7
7
  import { AsyncLocalStorage } from "node:async_hooks";
8
8
  //#region src/logger.ts
@@ -2,7 +2,7 @@ const require_db_error = require("./db-error-DXwEzmYJ.cjs");
2
2
  const require_agg = require("./agg.cjs");
3
3
  const require_nested_writer = require("./nested-writer-DoDhl3X3.cjs");
4
4
  const require_ops = require("./ops.cjs");
5
- const require_validator = require("./validator-BSk8lPH1.cjs");
5
+ const require_validator = require("./validator-Cf9V8vP9.cjs");
6
6
  let _atscript_typescript_utils = require("@atscript/typescript/utils");
7
7
  let node_async_hooks = require("node:async_hooks");
8
8
  //#region src/logger.ts
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_db_error = require("./db-error-DXwEzmYJ.cjs");
3
- const require_db_view = require("./db-view-BEZuIbsz.cjs");
3
+ const require_db_view = require("./db-view-CHAu4N3N.cjs");
4
4
  const require_consts = require("./consts-BzRfCcH2.cjs");
5
5
  const require_ops = require("./ops.cjs");
6
- const require_validator = require("./validator-BSk8lPH1.cjs");
6
+ const require_validator = require("./validator-Cf9V8vP9.cjs");
7
7
  let node_crypto = require("node:crypto");
8
8
  let _uniqu_core = require("@uniqu/core");
9
9
  //#region src/encryption.ts
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { $ as TIdentification, A as TDbActionLevel, B as TDbIndexType, C as TCascadeResolver, D as TCrudPermissions, E as TCrudOp, F as TDbDeleteResult, G as TDbStorageType, H as TDbInsertResult, I as TDbFieldMeta, J as TExistingTableOption, K as TDbUpdateResult, L as TDbForeignKey, M as TDbCollation, N as TDbDefaultFn, O as TDbActionInfo, P as TDbDefaultValue, Q as TIdDescriptor, R as TDbIndex, S as PrimaryKeyOf, T as TColumnDiff, U as TDbReferentialAction, V as TDbInsertManyResult, W as TDbRelation, X as TFkLookupResolver, Y as TFieldMeta, Z as TFkLookupTarget, _ as FieldOpsFor, _t as TGenericLogger, a as TDbEncryptionOptions, at as TTableOptionDiff, b as NavPropsOf, c as BaseDbAdapter, ct as TWriteTableResolver, d as AggregateFn, dt as UniqueryControls, et as TMetaResponse, f as AggregateQuery, ft as WithRelation, g as DbQuery, gt as NoopLogger, h as DbControls, ht as isGeoPointType, i as DbEncryption, it as TSyncColumnResult, j as TDbActionProcessor, k as TDbActionIntent, l as AggregateControls, lt as TypedWithRelation, m as AtscriptDbWritable, mt as isGeoIndexableType, n as DbResponse, nt as TRelationInfo, o as DocumentFieldMapper, ot as TTableResolver, p as AggregateResult, pt as TableMetadata, q as TExistingColumn, r as resolveDesignType, rt as TSearchIndexInfo, s as FieldMappingStrategy, st as TValueFormatterPair, t as AtscriptDbReadable, tt as TMetadataOverrides, u as AggregateExpr, ut as Uniquery, v as FilterExpr, vt as UniquSelect, w as TCascadeTarget, x as OwnPropsOf, y as FlatOf, z as TDbIndexField } from "./db-readable-DoJqR5pb.cjs";
1
+ import { $ as TIdentification, A as TDbActionLevel, B as TDbIndexType, C as TCascadeResolver, D as TCrudPermissions, E as TCrudOp, F as TDbDeleteResult, G as TDbStorageType, H as TDbInsertResult, I as TDbFieldMeta, J as TExistingTableOption, K as TDbUpdateResult, L as TDbForeignKey, M as TDbCollation, N as TDbDefaultFn, O as TDbActionInfo, P as TDbDefaultValue, Q as TIdDescriptor, R as TDbIndex, S as PrimaryKeyOf, T as TColumnDiff, U as TDbReferentialAction, V as TDbInsertManyResult, W as TDbRelation, X as TFkLookupResolver, Y as TFieldMeta, Z as TFkLookupTarget, _ as FieldOpsFor, _t as TGenericLogger, a as TDbEncryptionOptions, at as TTableOptionDiff, b as NavPropsOf, c as BaseDbAdapter, ct as TWriteTableResolver, d as AggregateFn, dt as UniqueryControls, et as TMetaResponse, f as AggregateQuery, ft as WithRelation, g as DbQuery, gt as NoopLogger, h as DbControls, ht as isGeoPointType, i as DbEncryption, it as TSyncColumnResult, j as TDbActionProcessor, k as TDbActionIntent, l as AggregateControls, lt as TypedWithRelation, m as AtscriptDbWritable, mt as isGeoIndexableType, n as DbResponse, nt as TRelationInfo, o as DocumentFieldMapper, ot as TTableResolver, p as AggregateResult, pt as TableMetadata, q as TExistingColumn, r as resolveDesignType, rt as TSearchIndexInfo, s as FieldMappingStrategy, st as TValueFormatterPair, t as AtscriptDbReadable, tt as TMetadataOverrides, u as AggregateExpr, ut as Uniquery, v as FilterExpr, vt as UniquSelect, w as TCascadeTarget, x as OwnPropsOf, y as FlatOf, z as TDbIndexField } from "./db-readable-C0nDKX8A.cjs";
2
2
  import { a as $mul, c as $update, d as TDbFieldOp, f as TFieldOps, g as separateFieldOps, h as separateCas, 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-DJRnNTVo.cjs";
3
- import { a as TViewColumnMapping, c as AtscriptQueryNode, d as TViewPlan, f as translateQueryTree, h as NativeIntegrity, i as AtscriptDbView, l as AtscriptRef, m as IntegrityStrategy, n as TAdapterFactory, o as AtscriptQueryComparison, p as AtscriptDbTable, r as TDbSpaceOptions, s as AtscriptQueryFieldRef, t as DbSpace, u as TViewJoin } from "./db-space-Bglferws.cjs";
3
+ import { a as TViewColumnMapping, c as AtscriptQueryNode, d as TViewPlan, f as translateQueryTree, h as NativeIntegrity, i as AtscriptDbView, l as AtscriptRef, m as IntegrityStrategy, n as TAdapterFactory, o as AtscriptQueryComparison, p as AtscriptDbTable, r as TDbSpaceOptions, s as AtscriptQueryFieldRef, t as DbSpace, u as TViewJoin } from "./db-space-CSntT6yS.cjs";
4
4
  import { n as createDbValidatorPlugin, t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.cjs";
5
- import { c as TArrayPatch, i as buildValidationContext, l as TDbPatch, n as ValidatorMode, o as forceNavNonOptional, r as buildDbValidator, s as isNavRelation, t as ValidationContext, u as getKeyProps } from "./validator-Crqe6vRW.cjs";
5
+ import { c as TArrayPatch, i as buildValidationContext, l as TDbPatch, n as ValidatorMode, o as forceNavNonOptional, r as buildDbValidator, s as isNavRelation, t as ValidationContext, u as getKeyProps } from "./validator-DbV4wTIJ.cjs";
6
6
  import { AggregateQuery as AggregateQuery$1, FilterExpr as FilterExpr$1, FilterVisitor, Uniquery as Uniquery$1, computeInsights, isPrimitive, walkFilter } from "@uniqu/core";
7
7
 
8
8
  //#region src/shared/consts.d.ts
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { $ as TIdentification, A as TDbActionLevel, B as TDbIndexType, C as TCascadeResolver, D as TCrudPermissions, E as TCrudOp, F as TDbDeleteResult, G as TDbStorageType, H as TDbInsertResult, I as TDbFieldMeta, J as TExistingTableOption, K as TDbUpdateResult, L as TDbForeignKey, M as TDbCollation, N as TDbDefaultFn, O as TDbActionInfo, P as TDbDefaultValue, Q as TIdDescriptor, R as TDbIndex, S as PrimaryKeyOf, T as TColumnDiff, U as TDbReferentialAction, V as TDbInsertManyResult, W as TDbRelation, X as TFkLookupResolver, Y as TFieldMeta, Z as TFkLookupTarget, _ as FieldOpsFor, _t as TGenericLogger, a as TDbEncryptionOptions, at as TTableOptionDiff, b as NavPropsOf, c as BaseDbAdapter, ct as TWriteTableResolver, d as AggregateFn, dt as UniqueryControls, et as TMetaResponse, f as AggregateQuery, ft as WithRelation, g as DbQuery, gt as NoopLogger, h as DbControls, ht as isGeoPointType, i as DbEncryption, it as TSyncColumnResult, j as TDbActionProcessor, k as TDbActionIntent, l as AggregateControls, lt as TypedWithRelation, m as AtscriptDbWritable, mt as isGeoIndexableType, n as DbResponse, nt as TRelationInfo, o as DocumentFieldMapper, ot as TTableResolver, p as AggregateResult, pt as TableMetadata, q as TExistingColumn, r as resolveDesignType, rt as TSearchIndexInfo, s as FieldMappingStrategy, st as TValueFormatterPair, t as AtscriptDbReadable, tt as TMetadataOverrides, u as AggregateExpr, ut as Uniquery, v as FilterExpr, vt as UniquSelect, w as TCascadeTarget, x as OwnPropsOf, y as FlatOf, z as TDbIndexField } from "./db-readable-wyKeE8ut.mjs";
1
+ import { $ as TIdentification, A as TDbActionLevel, B as TDbIndexType, C as TCascadeResolver, D as TCrudPermissions, E as TCrudOp, F as TDbDeleteResult, G as TDbStorageType, H as TDbInsertResult, I as TDbFieldMeta, J as TExistingTableOption, K as TDbUpdateResult, L as TDbForeignKey, M as TDbCollation, N as TDbDefaultFn, O as TDbActionInfo, P as TDbDefaultValue, Q as TIdDescriptor, R as TDbIndex, S as PrimaryKeyOf, T as TColumnDiff, U as TDbReferentialAction, V as TDbInsertManyResult, W as TDbRelation, X as TFkLookupResolver, Y as TFieldMeta, Z as TFkLookupTarget, _ as FieldOpsFor, _t as TGenericLogger, a as TDbEncryptionOptions, at as TTableOptionDiff, b as NavPropsOf, c as BaseDbAdapter, ct as TWriteTableResolver, d as AggregateFn, dt as UniqueryControls, et as TMetaResponse, f as AggregateQuery, ft as WithRelation, g as DbQuery, gt as NoopLogger, h as DbControls, ht as isGeoPointType, i as DbEncryption, it as TSyncColumnResult, j as TDbActionProcessor, k as TDbActionIntent, l as AggregateControls, lt as TypedWithRelation, m as AtscriptDbWritable, mt as isGeoIndexableType, n as DbResponse, nt as TRelationInfo, o as DocumentFieldMapper, ot as TTableResolver, p as AggregateResult, pt as TableMetadata, q as TExistingColumn, r as resolveDesignType, rt as TSearchIndexInfo, s as FieldMappingStrategy, st as TValueFormatterPair, t as AtscriptDbReadable, tt as TMetadataOverrides, u as AggregateExpr, ut as Uniquery, v as FilterExpr, vt as UniquSelect, w as TCascadeTarget, x as OwnPropsOf, y as FlatOf, z as TDbIndexField } from "./db-readable-BkAGccv9.mjs";
2
2
  import { a as $mul, c as $update, d as TDbFieldOp, f as TFieldOps, g as separateFieldOps, h as separateCas, 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-DJRnNTVo.mjs";
3
- import { a as TViewColumnMapping, c as AtscriptQueryNode, d as TViewPlan, f as translateQueryTree, h as NativeIntegrity, i as AtscriptDbView, l as AtscriptRef, m as IntegrityStrategy, n as TAdapterFactory, o as AtscriptQueryComparison, p as AtscriptDbTable, r as TDbSpaceOptions, s as AtscriptQueryFieldRef, t as DbSpace, u as TViewJoin } from "./db-space-B3kgrWvc.mjs";
3
+ import { a as TViewColumnMapping, c as AtscriptQueryNode, d as TViewPlan, f as translateQueryTree, h as NativeIntegrity, i as AtscriptDbView, l as AtscriptRef, m as IntegrityStrategy, n as TAdapterFactory, o as AtscriptQueryComparison, p as AtscriptDbTable, r as TDbSpaceOptions, s as AtscriptQueryFieldRef, t as DbSpace, u as TViewJoin } from "./db-space-B_ASuDaR.mjs";
4
4
  import { n as createDbValidatorPlugin, t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.mjs";
5
- import { c as TArrayPatch, i as buildValidationContext, l as TDbPatch, n as ValidatorMode, o as forceNavNonOptional, r as buildDbValidator, s as isNavRelation, t as ValidationContext, u as getKeyProps } from "./validator-Crqe6vRW.mjs";
5
+ import { c as TArrayPatch, i as buildValidationContext, l as TDbPatch, n as ValidatorMode, o as forceNavNonOptional, r as buildDbValidator, s as isNavRelation, t as ValidationContext, u as getKeyProps } from "./validator-DbV4wTIJ.mjs";
6
6
  import { AggregateQuery as AggregateQuery$1, FilterExpr as FilterExpr$1, FilterVisitor, Uniquery as Uniquery$1, computeInsights, isPrimitive, walkFilter } from "@uniqu/core";
7
7
 
8
8
  //#region src/shared/consts.d.ts
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { n as DbError, t as CasExhaustedError } from "./db-error-BHPXOKzc.mjs";
2
- import { C as NoopLogger, S as isGeoPointType, _ as DocumentFieldMapper, a as ApplicationIntegrity, b as TableMetadata, c as IntegrityStrategy, d as resolveDesignType, f as assertGeoPoint, g as RelationalFieldMapper, h as guardQuery, i as decomposePatch, l as NativeIntegrity, m as guardFilter, n as AtscriptDbTable, o as BaseDbAdapter, p as guardAggregate, r as assertNoVersionWrites, s as createFailureCollector, t as AtscriptDbView, u as AtscriptDbReadable, v as FieldMappingStrategy, x as isGeoIndexableType, y as UniquSelect } from "./db-view-DuJYYz77.mjs";
2
+ import { C as NoopLogger, S as isGeoPointType, _ as DocumentFieldMapper, a as ApplicationIntegrity, b as TableMetadata, c as IntegrityStrategy, d as resolveDesignType, f as assertGeoPoint, g as RelationalFieldMapper, h as guardQuery, i as decomposePatch, l as NativeIntegrity, m as guardFilter, n as AtscriptDbTable, o as BaseDbAdapter, p as guardAggregate, r as assertNoVersionWrites, s as createFailureCollector, t as AtscriptDbView, u as AtscriptDbReadable, v as FieldMappingStrategy, x as isGeoIndexableType, y as UniquSelect } from "./db-view-3yWBRiCf.mjs";
3
3
  import { t as DEFAULT_DB_SPACE } from "./consts-C_-5_pFq.mjs";
4
4
  import { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, getDbFieldOp, isDbFieldOp, separateCas, separateFieldOps } from "./ops.mjs";
5
- import { a as isNavRelation, i as forceNavNonOptional, n as buildValidationContext, o as createDbValidatorPlugin, s as getKeyProps, t as buildDbValidator } from "./validator-C7plt6Kf.mjs";
5
+ import { a as isNavRelation, i as forceNavNonOptional, n as buildValidationContext, o as createDbValidatorPlugin, s as getKeyProps, t as buildDbValidator } from "./validator-76GCYs80.mjs";
6
6
  import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
7
7
  import { computeInsights, isPrimitive, walkFilter } from "@uniqu/core";
8
8
  //#region src/encryption.ts
package/dist/plugin.cjs CHANGED
@@ -349,6 +349,15 @@ const dbColumnAnnotations = {
349
349
  }),
350
350
  filterable: columnCapability("filterable", "filtering"),
351
351
  sortable: columnCapability("sortable", "sorting"),
352
+ searchable: new _atscript_core.AnnotationSpec({
353
+ description: "Includes this column in the generic `$search` fallback: when the adapter reports no native search capability (no FTS / Atlas index configured), the readable controller matches the `$search` term as a case-insensitive substring across all `@db.column.searchable` fields (`$or`). Where adapter-native search IS available it wins and this annotation is not consulted. The term is escaped literally — no user-supplied regex. String-typed columns only.\n\n**Example:**\n```atscript\n@db.table \"jobs\"\nexport interface Job {\n @db.column.searchable\n jobName: string\n @db.column.searchable\n description: string\n}\n```\n",
354
+ nodeType: ["prop"],
355
+ passedWhenReferred: false,
356
+ multiple: false,
357
+ validate(token, _args, doc) {
358
+ return require_validation_utils.validateFieldBaseType(token, doc, "@db.column.searchable", ["string"]);
359
+ }
360
+ }),
352
361
  version: new _atscript_core.AnnotationSpec({
353
362
  description: "Marks a numeric column as the row's version for optimistic concurrency control (OCC). The adapter auto-increments this column on every UPDATE, and callers may pass `$cas: { <col>: N }` in a write payload to make the update conditional on the current version. Direct writes to the version column (as plain SET, `$inc`, or `$mul`) are rejected.\n\n**Constraints:**\n- At most one version column per table.\n- Must resolve to an integer type (`int`, `int32`, `int64`, etc.).\n- Default value on insert is `0`.\n\n**Example:**\n```atscript\n@db.column.version\nversion: int\n```\n",
354
363
  nodeType: ["prop"],
@@ -477,6 +486,21 @@ const dbColumnAnnotations = {
477
486
  });
478
487
  return errors;
479
488
  }
489
+ }),
490
+ writeOnly: new _atscript_core.AnnotationSpec({
491
+ description: "Marks a field as write-only over HTTP: it may be set through insert/update/replace payloads but NEVER appears in read responses — the readable controller excludes it from every projection, rejects filtering/sorting/grouping on it, and `/meta` serves its TYPE (flagged `writeOnly`) so client preflight validation and generated forms still know its shape. The classic case is a sealed secret (pair with `@db.encrypted`): writable via generic forms, unreadable by anyone.\n\nServer-side code reading through `AtscriptDbTable` still sees the value — the seal is an HTTP-layer contract, not a storage one.\n\n**Example:**\n```atscript\n@db.writeOnly\n@db.encrypted\ncredentials?: string\n```\n",
492
+ nodeType: ["prop"],
493
+ passedWhenReferred: false,
494
+ multiple: false,
495
+ validate(token, _args, _doc) {
496
+ const errors = [];
497
+ if (token.parentNode.countAnnotations("meta.id") > 0) errors.push({
498
+ message: `@db.writeOnly cannot coexist with @meta.id — the primary key must be readable`,
499
+ severity: 1,
500
+ range: token.range
501
+ });
502
+ return errors;
503
+ }
480
504
  })
481
505
  };
482
506
  function columnCapability(capability, verb) {
@@ -1459,6 +1483,7 @@ const dbPlugin = (options) => ({
1459
1483
  json: dbColumnAnnotations.json,
1460
1484
  ignore: dbColumnAnnotations.ignore,
1461
1485
  encrypted: dbColumnAnnotations.encrypted,
1486
+ writeOnly: dbColumnAnnotations.writeOnly,
1462
1487
  http: dbTableAnnotations.http,
1463
1488
  sync: dbTableAnnotations.sync,
1464
1489
  depth: dbTableAnnotations.depth,
package/dist/plugin.mjs CHANGED
@@ -314,6 +314,15 @@ const dbColumnAnnotations = {
314
314
  }),
315
315
  filterable: columnCapability("filterable", "filtering"),
316
316
  sortable: columnCapability("sortable", "sorting"),
317
+ searchable: new AnnotationSpec({
318
+ description: "Includes this column in the generic `$search` fallback: when the adapter reports no native search capability (no FTS / Atlas index configured), the readable controller matches the `$search` term as a case-insensitive substring across all `@db.column.searchable` fields (`$or`). Where adapter-native search IS available it wins and this annotation is not consulted. The term is escaped literally — no user-supplied regex. String-typed columns only.\n\n**Example:**\n```atscript\n@db.table \"jobs\"\nexport interface Job {\n @db.column.searchable\n jobName: string\n @db.column.searchable\n description: string\n}\n```\n",
319
+ nodeType: ["prop"],
320
+ passedWhenReferred: false,
321
+ multiple: false,
322
+ validate(token, _args, doc) {
323
+ return validateFieldBaseType(token, doc, "@db.column.searchable", ["string"]);
324
+ }
325
+ }),
317
326
  version: new AnnotationSpec({
318
327
  description: "Marks a numeric column as the row's version for optimistic concurrency control (OCC). The adapter auto-increments this column on every UPDATE, and callers may pass `$cas: { <col>: N }` in a write payload to make the update conditional on the current version. Direct writes to the version column (as plain SET, `$inc`, or `$mul`) are rejected.\n\n**Constraints:**\n- At most one version column per table.\n- Must resolve to an integer type (`int`, `int32`, `int64`, etc.).\n- Default value on insert is `0`.\n\n**Example:**\n```atscript\n@db.column.version\nversion: int\n```\n",
319
328
  nodeType: ["prop"],
@@ -442,6 +451,21 @@ const dbColumnAnnotations = {
442
451
  });
443
452
  return errors;
444
453
  }
454
+ }),
455
+ writeOnly: new AnnotationSpec({
456
+ description: "Marks a field as write-only over HTTP: it may be set through insert/update/replace payloads but NEVER appears in read responses — the readable controller excludes it from every projection, rejects filtering/sorting/grouping on it, and `/meta` serves its TYPE (flagged `writeOnly`) so client preflight validation and generated forms still know its shape. The classic case is a sealed secret (pair with `@db.encrypted`): writable via generic forms, unreadable by anyone.\n\nServer-side code reading through `AtscriptDbTable` still sees the value — the seal is an HTTP-layer contract, not a storage one.\n\n**Example:**\n```atscript\n@db.writeOnly\n@db.encrypted\ncredentials?: string\n```\n",
457
+ nodeType: ["prop"],
458
+ passedWhenReferred: false,
459
+ multiple: false,
460
+ validate(token, _args, _doc) {
461
+ const errors = [];
462
+ if (token.parentNode.countAnnotations("meta.id") > 0) errors.push({
463
+ message: `@db.writeOnly cannot coexist with @meta.id — the primary key must be readable`,
464
+ severity: 1,
465
+ range: token.range
466
+ });
467
+ return errors;
468
+ }
445
469
  })
446
470
  };
447
471
  function columnCapability(capability, verb) {
@@ -1424,6 +1448,7 @@ const dbPlugin = (options) => ({
1424
1448
  json: dbColumnAnnotations.json,
1425
1449
  ignore: dbColumnAnnotations.ignore,
1426
1450
  encrypted: dbColumnAnnotations.encrypted,
1451
+ writeOnly: dbColumnAnnotations.writeOnly,
1427
1452
  http: dbTableAnnotations.http,
1428
1453
  sync: dbTableAnnotations.sync,
1429
1454
  depth: dbTableAnnotations.depth,
package/dist/rel.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { L as TDbForeignKey, W as TDbRelation, _t as TGenericLogger, c as BaseDbAdapter, ct as TWriteTableResolver, ot as TTableResolver, pt as TableMetadata } from "./db-readable-DoJqR5pb.cjs";
1
+ import { L as TDbForeignKey, W as TDbRelation, _t as TGenericLogger, c as BaseDbAdapter, ct as TWriteTableResolver, ot as TTableResolver, pt as TableMetadata } from "./db-readable-C0nDKX8A.cjs";
2
2
  import { t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.cjs";
3
3
  import { FilterExpr, WithRelation } from "@uniqu/core";
4
4
  import { Validator } from "@atscript/typescript/utils";
package/dist/rel.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { L as TDbForeignKey, W as TDbRelation, _t as TGenericLogger, c as BaseDbAdapter, ct as TWriteTableResolver, ot as TTableResolver, pt as TableMetadata } from "./db-readable-wyKeE8ut.mjs";
1
+ import { L as TDbForeignKey, W as TDbRelation, _t as TGenericLogger, c as BaseDbAdapter, ct as TWriteTableResolver, ot as TTableResolver, pt as TableMetadata } from "./db-readable-BkAGccv9.mjs";
2
2
  import { t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.mjs";
3
3
  import { Validator } from "@atscript/typescript/utils";
4
4
  import { FilterExpr, WithRelation } from "@uniqu/core";
package/dist/sync.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_db_view = require("./db-view-BEZuIbsz.cjs");
2
+ const require_db_view = require("./db-view-CHAu4N3N.cjs");
3
3
  //#region src/schema/schema-hash.ts
4
4
  /** Extracts sorted field snapshots from a readable's field descriptors. */
5
5
  function extractFieldSnapshots(fields, typeMapper) {
package/dist/sync.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { G as TDbStorageType, I as TDbFieldMeta, J as TExistingTableOption, L as TDbForeignKey, P as TDbDefaultValue, T as TColumnDiff, _t as TGenericLogger, at as TTableOptionDiff, q as TExistingColumn, t as AtscriptDbReadable } from "./db-readable-DoJqR5pb.cjs";
2
- import { i as AtscriptDbView, t as DbSpace } from "./db-space-Bglferws.cjs";
1
+ import { G as TDbStorageType, I as TDbFieldMeta, J as TExistingTableOption, L as TDbForeignKey, P as TDbDefaultValue, T as TColumnDiff, _t as TGenericLogger, at as TTableOptionDiff, q as TExistingColumn, t as AtscriptDbReadable } from "./db-readable-C0nDKX8A.cjs";
2
+ import { i as AtscriptDbView, t as DbSpace } from "./db-space-CSntT6yS.cjs";
3
3
  import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
4
4
 
5
5
  //#region src/schema/sync-entry.d.ts
package/dist/sync.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { G as TDbStorageType, I as TDbFieldMeta, J as TExistingTableOption, L as TDbForeignKey, P as TDbDefaultValue, T as TColumnDiff, _t as TGenericLogger, at as TTableOptionDiff, q as TExistingColumn, t as AtscriptDbReadable } from "./db-readable-wyKeE8ut.mjs";
2
- import { i as AtscriptDbView, t as DbSpace } from "./db-space-B3kgrWvc.mjs";
1
+ import { G as TDbStorageType, I as TDbFieldMeta, J as TExistingTableOption, L as TDbForeignKey, P as TDbDefaultValue, T as TColumnDiff, _t as TGenericLogger, at as TTableOptionDiff, q as TExistingColumn, t as AtscriptDbReadable } from "./db-readable-BkAGccv9.mjs";
2
+ import { i as AtscriptDbView, t as DbSpace } from "./db-space-B_ASuDaR.mjs";
3
3
  import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
4
4
 
5
5
  //#region src/schema/sync-entry.d.ts
package/dist/sync.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as NoopLogger } from "./db-view-DuJYYz77.mjs";
1
+ import { C as NoopLogger } from "./db-view-3yWBRiCf.mjs";
2
2
  //#region src/schema/schema-hash.ts
3
3
  /** Extracts sorted field snapshots from a readable's field descriptors. */
4
4
  function extractFieldSnapshots(fields, typeMapper) {
@@ -303,13 +303,17 @@ const dbPlugin = createDbValidatorPlugin();
303
303
  * @param type - The annotated type to validate against.
304
304
  * @param mode - The write operation mode.
305
305
  * @param extraPlugins - Additional adapter-specific plugins (prepended before the db plugin).
306
+ * @param opts - `unknownProps` overrides the validator's unknown-property policy
307
+ * (used by db-client's `lenientWrites`, where the served type may be a
308
+ * projection of the full server-side type).
306
309
  */
307
- function buildDbValidator(type, mode, extraPlugins) {
310
+ function buildDbValidator(type, mode, extraPlugins, opts) {
308
311
  const plugins = extraPlugins ? [...extraPlugins, dbPlugin] : [dbPlugin];
309
312
  return type.validator({
310
313
  plugins,
311
314
  partial: mode === "patch",
312
- replace: forceNavNonOptional
315
+ replace: forceNavNonOptional,
316
+ ...opts?.unknownProps ? { unknownProps: opts.unknownProps } : {}
313
317
  });
314
318
  }
315
319
  /** Returns true if the annotated type is a navigation relation (TO/FROM/VIA). */
@@ -303,13 +303,17 @@ const dbPlugin = createDbValidatorPlugin();
303
303
  * @param type - The annotated type to validate against.
304
304
  * @param mode - The write operation mode.
305
305
  * @param extraPlugins - Additional adapter-specific plugins (prepended before the db plugin).
306
+ * @param opts - `unknownProps` overrides the validator's unknown-property policy
307
+ * (used by db-client's `lenientWrites`, where the served type may be a
308
+ * projection of the full server-side type).
306
309
  */
307
- function buildDbValidator(type, mode, extraPlugins) {
310
+ function buildDbValidator(type, mode, extraPlugins, opts) {
308
311
  const plugins = extraPlugins ? [...extraPlugins, dbPlugin] : [dbPlugin];
309
312
  return type.validator({
310
313
  plugins,
311
314
  partial: mode === "patch",
312
- replace: forceNavNonOptional
315
+ replace: forceNavNonOptional,
316
+ ...opts?.unknownProps ? { unknownProps: opts.unknownProps } : {}
313
317
  });
314
318
  }
315
319
  /** Returns true if the annotated type is a navigation relation (TO/FROM/VIA). */
@@ -39,8 +39,13 @@ declare const dbPlugin: TValidatorPlugin;
39
39
  * @param type - The annotated type to validate against.
40
40
  * @param mode - The write operation mode.
41
41
  * @param extraPlugins - Additional adapter-specific plugins (prepended before the db plugin).
42
+ * @param opts - `unknownProps` overrides the validator's unknown-property policy
43
+ * (used by db-client's `lenientWrites`, where the served type may be a
44
+ * projection of the full server-side type).
42
45
  */
43
- declare function buildDbValidator(type: TAtscriptAnnotatedType, mode: ValidatorMode, extraPlugins?: TValidatorPlugin[]): Validator<any>;
46
+ declare function buildDbValidator(type: TAtscriptAnnotatedType, mode: ValidatorMode, extraPlugins?: TValidatorPlugin[], opts?: {
47
+ unknownProps?: "strip" | "ignore" | "error";
48
+ }): Validator<any>;
44
49
  /** Returns true if the annotated type is a navigation relation (TO/FROM/VIA). */
45
50
  declare function isNavRelation(type: TAtscriptAnnotatedType): boolean;
46
51
  /**
@@ -39,8 +39,13 @@ declare const dbPlugin: TValidatorPlugin;
39
39
  * @param type - The annotated type to validate against.
40
40
  * @param mode - The write operation mode.
41
41
  * @param extraPlugins - Additional adapter-specific plugins (prepended before the db plugin).
42
+ * @param opts - `unknownProps` overrides the validator's unknown-property policy
43
+ * (used by db-client's `lenientWrites`, where the served type may be a
44
+ * projection of the full server-side type).
42
45
  */
43
- declare function buildDbValidator(type: TAtscriptAnnotatedType, mode: ValidatorMode, extraPlugins?: TValidatorPlugin[]): Validator<any>;
46
+ declare function buildDbValidator(type: TAtscriptAnnotatedType, mode: ValidatorMode, extraPlugins?: TValidatorPlugin[], opts?: {
47
+ unknownProps?: "strip" | "ignore" | "error";
48
+ }): Validator<any>;
44
49
  /** Returns true if the annotated type is a navigation relation (TO/FROM/VIA). */
45
50
  declare function isNavRelation(type: TAtscriptAnnotatedType): boolean;
46
51
  /**
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_ops = require("./ops.cjs");
3
- const require_validator = require("./validator-BSk8lPH1.cjs");
3
+ const require_validator = require("./validator-Cf9V8vP9.cjs");
4
4
  exports.$cas = require_ops.$cas;
5
5
  exports.$dec = require_ops.$dec;
6
6
  exports.$inc = require_ops.$inc;
@@ -1,4 +1,4 @@
1
1
  import { a as $mul, c as $update, d as TDbFieldOp, i as $insert, l as $upsert, m as isDbFieldOp, n as $dec, o as $remove, r as $inc, s as $replace, t as $cas, u as TDbCas } from "./ops-DJRnNTVo.cjs";
2
2
  import { n as createDbValidatorPlugin, t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.cjs";
3
- import { a as dbPlugin, c as TArrayPatch, i as buildValidationContext, l as TDbPatch, n as ValidatorMode, o as forceNavNonOptional, r as buildDbValidator, s as isNavRelation, t as ValidationContext, u as getKeyProps } from "./validator-Crqe6vRW.cjs";
3
+ import { a as dbPlugin, c as TArrayPatch, i as buildValidationContext, l as TDbPatch, n as ValidatorMode, o as forceNavNonOptional, r as buildDbValidator, s as isNavRelation, t as ValidationContext, u as getKeyProps } from "./validator-DbV4wTIJ.cjs";
4
4
  export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, type DbValidationContext, type TArrayPatch, type TDbCas, type TDbFieldOp, type TDbPatch, ValidationContext, ValidatorMode, buildDbValidator, buildValidationContext, createDbValidatorPlugin, dbPlugin, forceNavNonOptional, getKeyProps, isDbFieldOp, isNavRelation };
@@ -1,4 +1,4 @@
1
1
  import { a as $mul, c as $update, d as TDbFieldOp, i as $insert, l as $upsert, m as isDbFieldOp, n as $dec, o as $remove, r as $inc, s as $replace, t as $cas, u as TDbCas } from "./ops-DJRnNTVo.mjs";
2
2
  import { n as createDbValidatorPlugin, t as DbValidationContext } from "./db-validator-plugin-BWy60OvG.mjs";
3
- import { a as dbPlugin, c as TArrayPatch, i as buildValidationContext, l as TDbPatch, n as ValidatorMode, o as forceNavNonOptional, r as buildDbValidator, s as isNavRelation, t as ValidationContext, u as getKeyProps } from "./validator-Crqe6vRW.mjs";
3
+ import { a as dbPlugin, c as TArrayPatch, i as buildValidationContext, l as TDbPatch, n as ValidatorMode, o as forceNavNonOptional, r as buildDbValidator, s as isNavRelation, t as ValidationContext, u as getKeyProps } from "./validator-DbV4wTIJ.mjs";
4
4
  export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, type DbValidationContext, type TArrayPatch, type TDbCas, type TDbFieldOp, type TDbPatch, ValidationContext, ValidatorMode, buildDbValidator, buildValidationContext, createDbValidatorPlugin, dbPlugin, forceNavNonOptional, getKeyProps, isDbFieldOp, isNavRelation };
@@ -1,3 +1,3 @@
1
1
  import { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, isDbFieldOp } from "./ops.mjs";
2
- import { a as isNavRelation, i as forceNavNonOptional, n as buildValidationContext, o as createDbValidatorPlugin, r as dbPlugin, s as getKeyProps, t as buildDbValidator } from "./validator-C7plt6Kf.mjs";
2
+ import { a as isNavRelation, i as forceNavNonOptional, n as buildValidationContext, o as createDbValidatorPlugin, r as dbPlugin, s as getKeyProps, t as buildDbValidator } from "./validator-76GCYs80.mjs";
3
3
  export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, buildDbValidator, buildValidationContext, createDbValidatorPlugin, dbPlugin, forceNavNonOptional, getKeyProps, isDbFieldOp, isNavRelation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/db",
3
- "version": "0.1.122",
3
+ "version": "0.1.123",
4
4
  "description": "Database adapter utilities for atscript.",
5
5
  "keywords": [
6
6
  "atscript",