@atscript/db 0.1.110 → 0.1.112

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.
@@ -2101,6 +2101,31 @@ var NativeIntegrity = class extends IntegrityStrategy {
2101
2101
  }
2102
2102
  };
2103
2103
  //#endregion
2104
+ //#region src/shared/failure-collector.ts
2105
+ /**
2106
+ * Collects failures from a batch of independent operations so one failing
2107
+ * operation (e.g. CREATE UNIQUE INDEX over duplicate rows) doesn't abort the
2108
+ * rest. Run every operation through `attempt`, then call `throwIfAny()` to
2109
+ * rethrow the collected failures as a single aggregate error — so the caller
2110
+ * (schema sync) still marks the entry errored and skips persisting the schema
2111
+ * hash, and the next boot retries.
2112
+ */
2113
+ function createFailureCollector(what) {
2114
+ const failures = [];
2115
+ return {
2116
+ attempt: async (label, op) => {
2117
+ try {
2118
+ await op();
2119
+ } catch (error) {
2120
+ failures.push(`${label}: ${error.message}`);
2121
+ }
2122
+ },
2123
+ throwIfAny: () => {
2124
+ if (failures.length > 0) throw new Error(`${what} failed for ${failures.length} operation(s): ${failures.join("; ")}`);
2125
+ }
2126
+ };
2127
+ }
2128
+ //#endregion
2104
2129
  //#region src/base-adapter.ts
2105
2130
  const EMPTY_DEFAULT_FNS = /* @__PURE__ */ new Set();
2106
2131
  const txStorage = new AsyncLocalStorage();
@@ -2387,6 +2412,7 @@ var BaseDbAdapter = class {
2387
2412
  const existingNames = new Set(managed.map((i) => i.name));
2388
2413
  const existingColumns = new Map(managed.filter((i) => i.columns).map((i) => [i.name, i.columns]));
2389
2414
  const desiredNames = /* @__PURE__ */ new Set();
2415
+ const { attempt, throwIfAny } = createFailureCollector("index sync");
2390
2416
  for (const index of this._table.indexes.values()) {
2391
2417
  if (opts.warnUnsupportedTypes?.types.includes(index.type)) {
2392
2418
  this.logger.warn(`[${opts.warnUnsupportedTypes.adapter}] ${index.type} index "${index.name}" declared but not supported by this adapter — skipped`);
@@ -2395,19 +2421,20 @@ var BaseDbAdapter = class {
2395
2421
  if (opts.shouldSkipType?.(index.type)) continue;
2396
2422
  desiredNames.add(index.key);
2397
2423
  if (!existingNames.has(index.key)) {
2398
- await opts.createIndex(index);
2424
+ await attempt(`create index "${index.key}"`, () => opts.createIndex(index));
2399
2425
  continue;
2400
2426
  }
2401
2427
  if (index.type === "plain" || index.type === "unique") {
2402
2428
  const liveColumns = existingColumns.get(index.key);
2403
2429
  const desiredColumns = index.fields.map((f) => f.name);
2404
- if (liveColumns && (liveColumns.length !== desiredColumns.length || liveColumns.some((c, i) => c !== desiredColumns[i]))) {
2430
+ if (liveColumns && (liveColumns.length !== desiredColumns.length || liveColumns.some((c, i) => c !== desiredColumns[i]))) await attempt(`rebuild index "${index.key}"`, async () => {
2405
2431
  await opts.dropIndex(index.key);
2406
2432
  await opts.createIndex(index);
2407
- }
2433
+ });
2408
2434
  }
2409
2435
  }
2410
- for (const name of existingNames) if (!desiredNames.has(name)) await opts.dropIndex(name);
2436
+ for (const name of existingNames) if (!desiredNames.has(name)) await attempt(`drop index "${name}"`, () => opts.dropIndex(name));
2437
+ throwIfAny();
2411
2438
  }
2412
2439
  /**
2413
2440
  * Returns available search indexes for this adapter.
@@ -3678,4 +3705,4 @@ var AtscriptDbView = class extends AtscriptDbReadable {
3678
3705
  }
3679
3706
  };
3680
3707
  //#endregion
3681
- export { NoopLogger as S, FieldMappingStrategy as _, ApplicationIntegrity as a, isGeoIndexableType as b, NativeIntegrity as c, assertGeoPoint as d, guardAggregate as f, DocumentFieldMapper as g, RelationalFieldMapper as h, decomposePatch as i, AtscriptDbReadable as l, guardQuery as m, AtscriptDbTable as n, BaseDbAdapter as o, guardFilter as p, assertNoVersionWrites as r, IntegrityStrategy as s, AtscriptDbView as t, resolveDesignType as u, UniquSelect as v, isGeoPointType as x, TableMetadata as y };
3708
+ export { NoopLogger as C, isGeoPointType as S, DocumentFieldMapper as _, ApplicationIntegrity as a, TableMetadata as b, IntegrityStrategy as c, resolveDesignType as d, assertGeoPoint as f, RelationalFieldMapper as g, guardQuery as h, decomposePatch as i, NativeIntegrity as l, guardFilter as m, AtscriptDbTable as n, BaseDbAdapter as o, guardAggregate as p, assertNoVersionWrites as r, createFailureCollector as s, AtscriptDbView as t, AtscriptDbReadable as u, FieldMappingStrategy as v, isGeoIndexableType as x, UniquSelect as y };
@@ -2101,6 +2101,31 @@ var NativeIntegrity = class extends IntegrityStrategy {
2101
2101
  }
2102
2102
  };
2103
2103
  //#endregion
2104
+ //#region src/shared/failure-collector.ts
2105
+ /**
2106
+ * Collects failures from a batch of independent operations so one failing
2107
+ * operation (e.g. CREATE UNIQUE INDEX over duplicate rows) doesn't abort the
2108
+ * rest. Run every operation through `attempt`, then call `throwIfAny()` to
2109
+ * rethrow the collected failures as a single aggregate error — so the caller
2110
+ * (schema sync) still marks the entry errored and skips persisting the schema
2111
+ * hash, and the next boot retries.
2112
+ */
2113
+ function createFailureCollector(what) {
2114
+ const failures = [];
2115
+ return {
2116
+ attempt: async (label, op) => {
2117
+ try {
2118
+ await op();
2119
+ } catch (error) {
2120
+ failures.push(`${label}: ${error.message}`);
2121
+ }
2122
+ },
2123
+ throwIfAny: () => {
2124
+ if (failures.length > 0) throw new Error(`${what} failed for ${failures.length} operation(s): ${failures.join("; ")}`);
2125
+ }
2126
+ };
2127
+ }
2128
+ //#endregion
2104
2129
  //#region src/base-adapter.ts
2105
2130
  const EMPTY_DEFAULT_FNS = /* @__PURE__ */ new Set();
2106
2131
  const txStorage = new node_async_hooks.AsyncLocalStorage();
@@ -2387,6 +2412,7 @@ var BaseDbAdapter = class {
2387
2412
  const existingNames = new Set(managed.map((i) => i.name));
2388
2413
  const existingColumns = new Map(managed.filter((i) => i.columns).map((i) => [i.name, i.columns]));
2389
2414
  const desiredNames = /* @__PURE__ */ new Set();
2415
+ const { attempt, throwIfAny } = createFailureCollector("index sync");
2390
2416
  for (const index of this._table.indexes.values()) {
2391
2417
  if (opts.warnUnsupportedTypes?.types.includes(index.type)) {
2392
2418
  this.logger.warn(`[${opts.warnUnsupportedTypes.adapter}] ${index.type} index "${index.name}" declared but not supported by this adapter — skipped`);
@@ -2395,19 +2421,20 @@ var BaseDbAdapter = class {
2395
2421
  if (opts.shouldSkipType?.(index.type)) continue;
2396
2422
  desiredNames.add(index.key);
2397
2423
  if (!existingNames.has(index.key)) {
2398
- await opts.createIndex(index);
2424
+ await attempt(`create index "${index.key}"`, () => opts.createIndex(index));
2399
2425
  continue;
2400
2426
  }
2401
2427
  if (index.type === "plain" || index.type === "unique") {
2402
2428
  const liveColumns = existingColumns.get(index.key);
2403
2429
  const desiredColumns = index.fields.map((f) => f.name);
2404
- if (liveColumns && (liveColumns.length !== desiredColumns.length || liveColumns.some((c, i) => c !== desiredColumns[i]))) {
2430
+ if (liveColumns && (liveColumns.length !== desiredColumns.length || liveColumns.some((c, i) => c !== desiredColumns[i]))) await attempt(`rebuild index "${index.key}"`, async () => {
2405
2431
  await opts.dropIndex(index.key);
2406
2432
  await opts.createIndex(index);
2407
- }
2433
+ });
2408
2434
  }
2409
2435
  }
2410
- for (const name of existingNames) if (!desiredNames.has(name)) await opts.dropIndex(name);
2436
+ for (const name of existingNames) if (!desiredNames.has(name)) await attempt(`drop index "${name}"`, () => opts.dropIndex(name));
2437
+ throwIfAny();
2411
2438
  }
2412
2439
  /**
2413
2440
  * Returns available search indexes for this adapter.
@@ -3768,6 +3795,12 @@ Object.defineProperty(exports, "assertNoVersionWrites", {
3768
3795
  return assertNoVersionWrites;
3769
3796
  }
3770
3797
  });
3798
+ Object.defineProperty(exports, "createFailureCollector", {
3799
+ enumerable: true,
3800
+ get: function() {
3801
+ return createFailureCollector;
3802
+ }
3803
+ });
3771
3804
  Object.defineProperty(exports, "decomposePatch", {
3772
3805
  enumerable: true,
3773
3806
  get: function() {
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_db_error = require("./db-error-DXwEzmYJ.cjs");
3
- const require_db_view = require("./db-view-BIbH65VE.cjs");
3
+ const require_db_view = require("./db-view-UfGVUAol.cjs");
4
4
  const require_ops = require("./ops.cjs");
5
5
  const require_validator = require("./validator-BSk8lPH1.cjs");
6
6
  let node_crypto = require("node:crypto");
@@ -377,6 +377,7 @@ Object.defineProperty(exports, "computeInsights", {
377
377
  }
378
378
  });
379
379
  exports.createDbValidatorPlugin = require_validator.createDbValidatorPlugin;
380
+ exports.createFailureCollector = require_db_view.createFailureCollector;
380
381
  exports.decomposePatch = require_db_view.decomposePatch;
381
382
  exports.forceNavNonOptional = require_validator.forceNavNonOptional;
382
383
  exports.getDbFieldOp = require_ops.getDbFieldOp;
package/dist/index.d.cts CHANGED
@@ -215,4 +215,18 @@ declare function decomposePatch(payload: Record<string, unknown>, table: Atscrip
215
215
  */
216
216
  declare function assertNoVersionWrites(data: Record<string, unknown>, versionColumn: string): void;
217
217
  //#endregion
218
- export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptQueryComparison, type AtscriptQueryFieldRef, type AtscriptQueryNode, type AtscriptRef, BaseDbAdapter, CasExhaustedError, type DbControls, DbEncryption, DbError, type DbErrorCode, type DbQuery, type DbResponse, DbSpace, type DbValidationContext, DocumentFieldMapper, FieldMappingStrategy, type FieldOpsFor, type FilterExpr, type FilterVisitor, type FlatOf, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type OwnPropsOf, type PrimaryKeyOf, RelationalFieldMapper, type TAdapterFactory, type TArrayPatch, type TCascadeResolver, type TCascadeTarget, type TColumnDiff, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbCas, type TDbCollation, type TDbDefaultFn, type TDbDefaultValue, type TDbDeleteResult, type TDbEncryptionOptions, type TDbFieldMeta, type TDbFieldOp, type TDbForeignKey, type TDbIndex, type TDbIndexField, type TDbIndexType, type TDbInsertManyResult, type TDbInsertResult, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateResult, type TExistingColumn, type TExistingTableOption, type TFieldMeta, type TFieldOps, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TIdDescriptor, type TIdentification, type TMetaResponse, type TMetadataOverrides, type TRelationInfo, type TSearchIndexInfo, type TSyncColumnResult, type TTableOptionDiff, type TTableResolver, type TValueFormatterPair, type TViewColumnMapping, type TViewJoin, type TViewPlan, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WithOptimisticRetryOptions, type WithRelation, assertGeoPoint, assertNoVersionWrites, buildDbValidator, buildValidationContext, computeInsights, createDbValidatorPlugin, decomposePatch, forceNavNonOptional, getDbFieldOp, getKeyProps, guardAggregate, guardFilter, guardQuery, isDbFieldOp, isGeoIndexableType, isGeoPointType, isNavRelation, isPrimitive, resolveDesignType, separateCas, separateFieldOps, translateQueryTree, walkFilter, withOptimisticRetry };
218
+ //#region src/shared/failure-collector.d.ts
219
+ /**
220
+ * Collects failures from a batch of independent operations so one failing
221
+ * operation (e.g. CREATE UNIQUE INDEX over duplicate rows) doesn't abort the
222
+ * rest. Run every operation through `attempt`, then call `throwIfAny()` to
223
+ * rethrow the collected failures as a single aggregate error — so the caller
224
+ * (schema sync) still marks the entry errored and skips persisting the schema
225
+ * hash, and the next boot retries.
226
+ */
227
+ declare function createFailureCollector(what: string): {
228
+ attempt: (label: string, op: () => Promise<unknown>) => Promise<void>;
229
+ throwIfAny: () => void;
230
+ };
231
+ //#endregion
232
+ export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptQueryComparison, type AtscriptQueryFieldRef, type AtscriptQueryNode, type AtscriptRef, BaseDbAdapter, CasExhaustedError, type DbControls, DbEncryption, DbError, type DbErrorCode, type DbQuery, type DbResponse, DbSpace, type DbValidationContext, DocumentFieldMapper, FieldMappingStrategy, type FieldOpsFor, type FilterExpr, type FilterVisitor, type FlatOf, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type OwnPropsOf, type PrimaryKeyOf, RelationalFieldMapper, type TAdapterFactory, type TArrayPatch, type TCascadeResolver, type TCascadeTarget, type TColumnDiff, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbCas, type TDbCollation, type TDbDefaultFn, type TDbDefaultValue, type TDbDeleteResult, type TDbEncryptionOptions, type TDbFieldMeta, type TDbFieldOp, type TDbForeignKey, type TDbIndex, type TDbIndexField, type TDbIndexType, type TDbInsertManyResult, type TDbInsertResult, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateResult, type TExistingColumn, type TExistingTableOption, type TFieldMeta, type TFieldOps, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TIdDescriptor, type TIdentification, type TMetaResponse, type TMetadataOverrides, type TRelationInfo, type TSearchIndexInfo, type TSyncColumnResult, type TTableOptionDiff, type TTableResolver, type TValueFormatterPair, type TViewColumnMapping, type TViewJoin, type TViewPlan, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WithOptimisticRetryOptions, type WithRelation, assertGeoPoint, assertNoVersionWrites, buildDbValidator, buildValidationContext, computeInsights, createDbValidatorPlugin, createFailureCollector, decomposePatch, forceNavNonOptional, getDbFieldOp, getKeyProps, guardAggregate, guardFilter, guardQuery, isDbFieldOp, isGeoIndexableType, isGeoPointType, isNavRelation, isPrimitive, resolveDesignType, separateCas, separateFieldOps, translateQueryTree, walkFilter, withOptimisticRetry };
package/dist/index.d.mts CHANGED
@@ -215,4 +215,18 @@ declare function decomposePatch(payload: Record<string, unknown>, table: Atscrip
215
215
  */
216
216
  declare function assertNoVersionWrites(data: Record<string, unknown>, versionColumn: string): void;
217
217
  //#endregion
218
- export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptQueryComparison, type AtscriptQueryFieldRef, type AtscriptQueryNode, type AtscriptRef, BaseDbAdapter, CasExhaustedError, type DbControls, DbEncryption, DbError, type DbErrorCode, type DbQuery, type DbResponse, DbSpace, type DbValidationContext, DocumentFieldMapper, FieldMappingStrategy, type FieldOpsFor, type FilterExpr, type FilterVisitor, type FlatOf, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type OwnPropsOf, type PrimaryKeyOf, RelationalFieldMapper, type TAdapterFactory, type TArrayPatch, type TCascadeResolver, type TCascadeTarget, type TColumnDiff, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbCas, type TDbCollation, type TDbDefaultFn, type TDbDefaultValue, type TDbDeleteResult, type TDbEncryptionOptions, type TDbFieldMeta, type TDbFieldOp, type TDbForeignKey, type TDbIndex, type TDbIndexField, type TDbIndexType, type TDbInsertManyResult, type TDbInsertResult, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateResult, type TExistingColumn, type TExistingTableOption, type TFieldMeta, type TFieldOps, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TIdDescriptor, type TIdentification, type TMetaResponse, type TMetadataOverrides, type TRelationInfo, type TSearchIndexInfo, type TSyncColumnResult, type TTableOptionDiff, type TTableResolver, type TValueFormatterPair, type TViewColumnMapping, type TViewJoin, type TViewPlan, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WithOptimisticRetryOptions, type WithRelation, assertGeoPoint, assertNoVersionWrites, buildDbValidator, buildValidationContext, computeInsights, createDbValidatorPlugin, decomposePatch, forceNavNonOptional, getDbFieldOp, getKeyProps, guardAggregate, guardFilter, guardQuery, isDbFieldOp, isGeoIndexableType, isGeoPointType, isNavRelation, isPrimitive, resolveDesignType, separateCas, separateFieldOps, translateQueryTree, walkFilter, withOptimisticRetry };
218
+ //#region src/shared/failure-collector.d.ts
219
+ /**
220
+ * Collects failures from a batch of independent operations so one failing
221
+ * operation (e.g. CREATE UNIQUE INDEX over duplicate rows) doesn't abort the
222
+ * rest. Run every operation through `attempt`, then call `throwIfAny()` to
223
+ * rethrow the collected failures as a single aggregate error — so the caller
224
+ * (schema sync) still marks the entry errored and skips persisting the schema
225
+ * hash, and the next boot retries.
226
+ */
227
+ declare function createFailureCollector(what: string): {
228
+ attempt: (label: string, op: () => Promise<unknown>) => Promise<void>;
229
+ throwIfAny: () => void;
230
+ };
231
+ //#endregion
232
+ export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, type AtscriptDbWritable, type AtscriptQueryComparison, type AtscriptQueryFieldRef, type AtscriptQueryNode, type AtscriptRef, BaseDbAdapter, CasExhaustedError, type DbControls, DbEncryption, DbError, type DbErrorCode, type DbQuery, type DbResponse, DbSpace, type DbValidationContext, DocumentFieldMapper, FieldMappingStrategy, type FieldOpsFor, type FilterExpr, type FilterVisitor, type FlatOf, IntegrityStrategy, NativeIntegrity, type NavPropsOf, NoopLogger, type OwnPropsOf, type PrimaryKeyOf, RelationalFieldMapper, type TAdapterFactory, type TArrayPatch, type TCascadeResolver, type TCascadeTarget, type TColumnDiff, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbCas, type TDbCollation, type TDbDefaultFn, type TDbDefaultValue, type TDbDeleteResult, type TDbEncryptionOptions, type TDbFieldMeta, type TDbFieldOp, type TDbForeignKey, type TDbIndex, type TDbIndexField, type TDbIndexType, type TDbInsertManyResult, type TDbInsertResult, type TDbPatch, type TDbReferentialAction, type TDbRelation, type TDbSpaceOptions, type TDbStorageType, type TDbUpdateResult, type TExistingColumn, type TExistingTableOption, type TFieldMeta, type TFieldOps, type TFkLookupResolver, type TFkLookupTarget, type TGenericLogger, type TIdDescriptor, type TIdentification, type TMetaResponse, type TMetadataOverrides, type TRelationInfo, type TSearchIndexInfo, type TSyncColumnResult, type TTableOptionDiff, type TTableResolver, type TValueFormatterPair, type TViewColumnMapping, type TViewJoin, type TViewPlan, type TWriteTableResolver, TableMetadata, type TypedWithRelation, UniquSelect, type Uniquery, type UniqueryControls, type ValidationContext, type ValidatorMode, type WithOptimisticRetryOptions, type WithRelation, assertGeoPoint, assertNoVersionWrites, buildDbValidator, buildValidationContext, computeInsights, createDbValidatorPlugin, createFailureCollector, decomposePatch, forceNavNonOptional, getDbFieldOp, getKeyProps, guardAggregate, guardFilter, guardQuery, isDbFieldOp, isGeoIndexableType, isGeoPointType, isNavRelation, isPrimitive, resolveDesignType, separateCas, separateFieldOps, translateQueryTree, walkFilter, withOptimisticRetry };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as DbError, t as CasExhaustedError } from "./db-error-BHPXOKzc.mjs";
2
- import { S as NoopLogger, _ as FieldMappingStrategy, a as ApplicationIntegrity, b as isGeoIndexableType, c as NativeIntegrity, d as assertGeoPoint, f as guardAggregate, g as DocumentFieldMapper, h as RelationalFieldMapper, i as decomposePatch, l as AtscriptDbReadable, m as guardQuery, n as AtscriptDbTable, o as BaseDbAdapter, p as guardFilter, r as assertNoVersionWrites, s as IntegrityStrategy, t as AtscriptDbView, u as resolveDesignType, v as UniquSelect, x as isGeoPointType, y as TableMetadata } from "./db-view-CHprAlvK.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-BllUecjK.mjs";
3
3
  import { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, getDbFieldOp, isDbFieldOp, separateCas, separateFieldOps } from "./ops.mjs";
4
4
  import { a as isNavRelation, i as forceNavNonOptional, n as buildValidationContext, o as createDbValidatorPlugin, s as getKeyProps, t as buildDbValidator } from "./validator-C7plt6Kf.mjs";
5
5
  import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
@@ -339,4 +339,4 @@ function translateQueryTree(node, resolveField) {
339
339
  return { [leftField]: { [comp.op]: comp.right } };
340
340
  }
341
341
  //#endregion
342
- export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, BaseDbAdapter, CasExhaustedError, DbEncryption, DbError, DbSpace, DocumentFieldMapper, FieldMappingStrategy, IntegrityStrategy, NativeIntegrity, NoopLogger, RelationalFieldMapper, TableMetadata, UniquSelect, assertGeoPoint, assertNoVersionWrites, buildDbValidator, buildValidationContext, computeInsights, createDbValidatorPlugin, decomposePatch, forceNavNonOptional, getDbFieldOp, getKeyProps, guardAggregate, guardFilter, guardQuery, isDbFieldOp, isGeoIndexableType, isGeoPointType, isNavRelation, isPrimitive, resolveDesignType, separateCas, separateFieldOps, translateQueryTree, walkFilter, withOptimisticRetry };
342
+ export { $cas, $dec, $inc, $insert, $mul, $remove, $replace, $update, $upsert, ApplicationIntegrity, AtscriptDbReadable, AtscriptDbTable, AtscriptDbView, BaseDbAdapter, CasExhaustedError, DbEncryption, DbError, DbSpace, DocumentFieldMapper, FieldMappingStrategy, IntegrityStrategy, NativeIntegrity, NoopLogger, RelationalFieldMapper, TableMetadata, UniquSelect, assertGeoPoint, assertNoVersionWrites, buildDbValidator, buildValidationContext, computeInsights, createDbValidatorPlugin, createFailureCollector, decomposePatch, forceNavNonOptional, getDbFieldOp, getKeyProps, guardAggregate, guardFilter, guardQuery, isDbFieldOp, isGeoIndexableType, isGeoPointType, isNavRelation, isPrimitive, resolveDesignType, separateCas, separateFieldOps, translateQueryTree, walkFilter, withOptimisticRetry };
package/dist/plugin.cjs CHANGED
@@ -2,13 +2,14 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_validation_utils = require("./validation-utils-CR4H3_nc.cjs");
5
+ const require_validation_utils = require("./validation-utils-B7SXPkm7.cjs");
6
6
  let _atscript_core = require("@atscript/core");
7
7
  //#region src/plugin/annotations/agg.ts
8
8
  const dbAggAnnotations = { agg: {
9
9
  sum: new _atscript_core.AnnotationSpec({
10
10
  description: "Declares a view field as SUM of a source column.",
11
11
  nodeType: ["prop"],
12
+ passedWhenReferred: false,
12
13
  argument: {
13
14
  name: "field",
14
15
  type: "string",
@@ -21,6 +22,7 @@ const dbAggAnnotations = { agg: {
21
22
  avg: new _atscript_core.AnnotationSpec({
22
23
  description: "Declares a view field as AVG of a source column.",
23
24
  nodeType: ["prop"],
25
+ passedWhenReferred: false,
24
26
  argument: {
25
27
  name: "field",
26
28
  type: "string",
@@ -33,6 +35,7 @@ const dbAggAnnotations = { agg: {
33
35
  count: new _atscript_core.AnnotationSpec({
34
36
  description: "Declares a view field as COUNT. Without argument: COUNT(*). With field name argument: COUNT(field) (non-null count).",
35
37
  nodeType: ["prop"],
38
+ passedWhenReferred: false,
36
39
  argument: {
37
40
  name: "field",
38
41
  type: "string",
@@ -46,6 +49,7 @@ const dbAggAnnotations = { agg: {
46
49
  min: new _atscript_core.AnnotationSpec({
47
50
  description: "Declares a view field as MIN of a source column.",
48
51
  nodeType: ["prop"],
52
+ passedWhenReferred: false,
49
53
  argument: {
50
54
  name: "field",
51
55
  type: "string",
@@ -55,6 +59,7 @@ const dbAggAnnotations = { agg: {
55
59
  max: new _atscript_core.AnnotationSpec({
56
60
  description: "Declares a view field as MAX of a source column.",
57
61
  nodeType: ["prop"],
62
+ passedWhenReferred: false,
58
63
  argument: {
59
64
  name: "field",
60
65
  type: "string",
@@ -94,6 +99,7 @@ const dbAmountAnnotations = { amount: { currency: {
94
99
  ref: new _atscript_core.AnnotationSpec({
95
100
  description: "Binds this amount to a **sibling field** that holds its currency code. Use when each row may have a different currency.\n\nThe referenced field should be of type `db.currencyCode` (or at least a `string`).\n\nOnly valid on `decimal` fields.\n\n**Example:**\n```atscript\ncurrency: db.currencyCode\n@db.amount.currency.ref 'currency'\namount: decimal\n```\n",
96
101
  nodeType: ["prop"],
102
+ passedWhenReferred: false,
97
103
  multiple: false,
98
104
  argument: {
99
105
  name: "fieldName",
@@ -121,6 +127,7 @@ const dbColumnAnnotations = {
121
127
  patch: { strategy: new _atscript_core.AnnotationSpec({
122
128
  description: "Defines the **patching strategy** for updating nested objects.\n\n- **\"replace\"** → The field or object will be **fully replaced**.\n- **\"merge\"** → The field or object will be **merged recursively** (applies only to objects, not arrays).\n\n**Example:**\n```atscript\n@db.patch.strategy \"merge\"\nsettings: {\n notifications: boolean\n preferences: {\n theme: string\n }\n}\n```\n",
123
129
  nodeType: ["prop"],
130
+ passedWhenReferred: false,
124
131
  multiple: false,
125
132
  argument: {
126
133
  name: "strategy",
@@ -150,6 +157,7 @@ const dbColumnAnnotations = {
150
157
  $self: new _atscript_core.AnnotationSpec({
151
158
  description: "Overrides the physical column name in the database. For nested (flattened) fields, the parent prefix is still prepended automatically.\n\n**Example:**\n```atscript\n@db.column \"first_name\"\nfirstName: string\n// → physical column: first_name\n\n// Nested:\naddress: {\n @db.column \"zip_code\"\n zip: string\n}\n// → physical column: address__zip_code\n```\n",
152
159
  nodeType: ["prop"],
160
+ passedWhenReferred: false,
153
161
  argument: {
154
162
  name: "name",
155
163
  type: "string",
@@ -159,6 +167,7 @@ const dbColumnAnnotations = {
159
167
  renamed: new _atscript_core.AnnotationSpec({
160
168
  description: "Specifies the previous local field name for column rename migration. The sync engine generates ALTER TABLE RENAME COLUMN instead of drop+add.\n\n**Example:**\n```atscript\n@db.column.renamed \"zip\"\npostalCode: string\n// Renames address__zip → address__postalCode\n```\n",
161
169
  nodeType: ["prop"],
170
+ passedWhenReferred: false,
162
171
  argument: {
163
172
  name: "oldName",
164
173
  type: "string",
@@ -168,6 +177,7 @@ const dbColumnAnnotations = {
168
177
  collate: new _atscript_core.AnnotationSpec({
169
178
  description: "Portable collation for string comparison and sorting. Adapters map the generic value to their native collation.\n\n- **\"binary\"** — exact byte comparison (case-sensitive)\n- **\"nocase\"** — case-insensitive comparison\n- **\"unicode\"** — full Unicode-aware sorting\n\nFor adapter-specific collations, use `@db.<engine>.collate` instead.\n\n**Example:**\n```atscript\n@db.column.collate \"nocase\"\nusername: string\n```\n",
170
179
  nodeType: ["prop"],
180
+ passedWhenReferred: false,
171
181
  argument: {
172
182
  name: "collation",
173
183
  type: "string",
@@ -185,6 +195,7 @@ const dbColumnAnnotations = {
185
195
  precision: new _atscript_core.AnnotationSpec({
186
196
  description: "Sets decimal precision and scale for database storage. Adapters map this to their native decimal type (e.g., `DECIMAL(10,2)` in SQL, ignored in MongoDB).\n\nFor `decimal` fields the runtime value is a string; for `number` fields this is a DB storage hint only.\n\n**Example:**\n```atscript\n@db.column.precision 10, 2\nprice: decimal\n```\n",
187
197
  nodeType: ["prop"],
198
+ passedWhenReferred: false,
188
199
  argument: [{
189
200
  name: "precision",
190
201
  type: "number",
@@ -200,11 +211,13 @@ const dbColumnAnnotations = {
200
211
  }),
201
212
  dimension: new _atscript_core.AnnotationSpec({
202
213
  description: "Marks a field as a dimension — groupable in aggregate queries ($groupBy). Dimension fields automatically receive a database index during schema sync.",
203
- nodeType: ["prop"]
214
+ nodeType: ["prop"],
215
+ passedWhenReferred: false
204
216
  }),
205
217
  measure: new _atscript_core.AnnotationSpec({
206
218
  description: "Marks a field as a measure — aggregatable in aggregate queries (sum, avg, count, min, max). Only valid on numeric or decimal fields.",
207
219
  nodeType: ["prop"],
220
+ passedWhenReferred: false,
208
221
  validate(token, _args, doc) {
209
222
  return require_validation_utils.validateFieldBaseType(token, doc, "@db.column.measure", ["number", "decimal"]);
210
223
  }
@@ -214,6 +227,7 @@ const dbColumnAnnotations = {
214
227
  version: new _atscript_core.AnnotationSpec({
215
228
  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",
216
229
  nodeType: ["prop"],
230
+ passedWhenReferred: false,
217
231
  validate(token, _args, doc) {
218
232
  const errors = require_validation_utils.validateFieldBaseType(token, doc, "@db.column.version", "number");
219
233
  if (token.parentNode.has("optional")) errors.push({
@@ -239,6 +253,7 @@ const dbColumnAnnotations = {
239
253
  $self: new _atscript_core.AnnotationSpec({
240
254
  description: "Sets a static DB-level default value (used in DDL DEFAULT clause). For string fields the value is used as-is; for other types it is parsed as JSON.\n\n**Example:**\n```atscript\n@db.default \"active\"\nstatus: string\n```\n",
241
255
  nodeType: ["prop"],
256
+ passedWhenReferred: false,
242
257
  argument: {
243
258
  name: "value",
244
259
  type: "string",
@@ -248,6 +263,7 @@ const dbColumnAnnotations = {
248
263
  increment: new _atscript_core.AnnotationSpec({
249
264
  description: "Auto-incrementing integer default. Each adapter maps this to its native mechanism (e.g., `AUTO_INCREMENT` in MySQL, `INTEGER PRIMARY KEY` in SQLite, counter collection in MongoDB).\n\n**Example:**\n```atscript\n@db.default.increment\nid: number.int\n\n// With optional start value:\n@db.default.increment 1000\nid: number.int\n```\n",
250
265
  nodeType: ["prop"],
266
+ passedWhenReferred: false,
251
267
  argument: {
252
268
  optional: true,
253
269
  name: "start",
@@ -261,6 +277,7 @@ const dbColumnAnnotations = {
261
277
  uuid: new _atscript_core.AnnotationSpec({
262
278
  description: "UUID generation default. Each adapter maps this to its native mechanism (e.g., `DEFAULT (UUID())` in MySQL, `gen_random_uuid()` in PostgreSQL, app-level in SQLite).\n\n**Example:**\n```atscript\n@db.default.uuid\nid: string.uuid\n```\n",
263
279
  nodeType: ["prop"],
280
+ passedWhenReferred: false,
264
281
  validate(token, args, doc) {
265
282
  return require_validation_utils.validateFieldBaseType(token, doc, "db.default.uuid", "string");
266
283
  }
@@ -268,6 +285,7 @@ const dbColumnAnnotations = {
268
285
  now: new _atscript_core.AnnotationSpec({
269
286
  description: "Current timestamp default. Each adapter maps this to its native mechanism (e.g., `DEFAULT CURRENT_TIMESTAMP` in MySQL, `DEFAULT now()` in PostgreSQL).\n\n**Example:**\n```atscript\n@db.default.now\ncreatedAt: number.timestamp\n```\n",
270
287
  nodeType: ["prop"],
288
+ passedWhenReferred: false,
271
289
  validate(token, args, doc) {
272
290
  return require_validation_utils.validateFieldBaseType(token, doc, "db.default.now", ["number", "string"]);
273
291
  }
@@ -276,6 +294,7 @@ const dbColumnAnnotations = {
276
294
  json: new _atscript_core.AnnotationSpec({
277
295
  description: "Forces a field to be stored as a single JSON column instead of being flattened into separate columns. Use on nested object fields that should remain as JSON in the database.\n\n**Example:**\n```atscript\n@db.json\nmetadata: { key: string, value: string }\n```\n",
278
296
  nodeType: ["prop"],
297
+ passedWhenReferred: false,
279
298
  validate(token, _args, doc) {
280
299
  const errors = [];
281
300
  const definition = token.parentNode.getDefinition();
@@ -293,6 +312,7 @@ const dbColumnAnnotations = {
293
312
  ignore: new _atscript_core.AnnotationSpec({
294
313
  description: "Excludes a field from the database schema. The field exists in the Atscript type but has no column in the DB.\n\n**Example:**\n```atscript\n@db.ignore\ndisplayName: string\n```\n",
295
314
  nodeType: ["prop"],
315
+ passedWhenReferred: false,
296
316
  validate(token, _args, _doc) {
297
317
  const errors = [];
298
318
  if (token.parentNode.countAnnotations("meta.id") > 0) errors.push({
@@ -306,6 +326,7 @@ const dbColumnAnnotations = {
306
326
  encrypted: new _atscript_core.AnnotationSpec({
307
327
  description: "Encrypts this field at rest. Values are AES-256-GCM encrypted by the core layer before reaching the database and decrypted on read — transparent to application code.\n\nConstraints: the field cannot be filtered, sorted, indexed, used as PK/FK, patched with arithmetic ops, or referenced by search/vector/geo features.\n\n**Example:**\n```atscript\n@db.encrypted\napiToken?: string\n```\n",
308
328
  nodeType: ["prop"],
329
+ passedWhenReferred: false,
309
330
  multiple: false,
310
331
  validate(token, _args, _doc) {
311
332
  const errors = [];
@@ -344,6 +365,7 @@ function columnCapability(capability, verb) {
344
365
  @db.table.${capability} "manual"\nexport interface User {
345
366
  ` + example + "}\n```\n",
346
367
  nodeType: ["prop"],
368
+ passedWhenReferred: false,
347
369
  multiple: false,
348
370
  validate(token, _args, _doc) {
349
371
  const errors = [];
@@ -363,6 +385,7 @@ const dbIndexAnnotations = { index: {
363
385
  plain: new _atscript_core.AnnotationSpec({
364
386
  description: "Standard (non-unique) index for query performance. Fields sharing the same index name form a composite index.\n\n**Example:**\n```atscript\n@db.index.plain \"idx_timeline\", \"desc\"\ncreatedAt: number.timestamp\n```\n",
365
387
  nodeType: ["prop"],
388
+ passedWhenReferred: false,
366
389
  multiple: true,
367
390
  mergeStrategy: "append",
368
391
  argument: [{
@@ -381,6 +404,7 @@ const dbIndexAnnotations = { index: {
381
404
  unique: new _atscript_core.AnnotationSpec({
382
405
  description: "Unique index — ensures no two rows/documents have the same value(s). Fields sharing the same index name form a composite unique constraint.\n\n**Example:**\n```atscript\n@db.index.unique \"tenant_email\"\nemail: string.email\n```\n",
383
406
  nodeType: ["prop"],
407
+ passedWhenReferred: false,
384
408
  multiple: true,
385
409
  mergeStrategy: "append",
386
410
  argument: {
@@ -393,6 +417,7 @@ const dbIndexAnnotations = { index: {
393
417
  fulltext: new _atscript_core.AnnotationSpec({
394
418
  description: "Full-text search index. Fields sharing the same index name form a composite full-text index.\n\n**Example:**\n```atscript\n@db.index.fulltext \"ft_content\"\ntitle: string\n\n@db.index.fulltext \"ft_content\", 5\nbio: string\n```\n",
395
419
  nodeType: ["prop"],
420
+ passedWhenReferred: false,
396
421
  multiple: true,
397
422
  mergeStrategy: "append",
398
423
  argument: [{
@@ -410,6 +435,7 @@ const dbIndexAnnotations = { index: {
410
435
  geo: new _atscript_core.AnnotationSpec({
411
436
  description: "Geospatial index on a `db.geoPoint` field. Enables `geoSearch()` (distance-ranked) and accelerates `$geoWithin` filters.\n\n**Example:**\n```atscript\n@db.index.geo\ngeo: db.geoPoint\n```\n",
412
437
  nodeType: ["prop"],
438
+ passedWhenReferred: false,
413
439
  multiple: false,
414
440
  argument: {
415
441
  optional: true,
@@ -425,6 +451,7 @@ const dbRelAnnotations = { rel: {
425
451
  FK: new _atscript_core.AnnotationSpec({
426
452
  description: "Declares a foreign key reference on this field. The field must use a chain reference type (e.g., `User.id`) whose target is a primary key (`@meta.id`) or unique (`@db.index.unique`) field.\n\n**Dual role:**\n- On a `@db.table` interface, `@db.rel.FK` additionally drives DB-relation semantics — relation loading with `@db.rel.to` / `@db.rel.from`, junction pairing with `@db.rel.via`, etc.\n- On any other interface (value-help sources, WF forms, plain interfaces), `@db.rel.FK` acts purely as the value-help indicator: the client-side picker resolver uses it to decide which fields render a value-help picker. The target's `@db.http.path` (stamped by its readable controller) supplies the picker URL.\n\n**Example:**\n```atscript\n@db.rel.FK\nauthorId: User.id\n\n// With alias (required when multiple FKs point to the same type)\n@db.rel.FK \"author\"\nauthorId: User.id\n```\n",
427
453
  nodeType: ["prop"],
454
+ passedWhenReferred: false,
428
455
  argument: {
429
456
  optional: true,
430
457
  name: "alias",
@@ -509,6 +536,7 @@ const dbRelAnnotations = { rel: {
509
536
  to: new _atscript_core.AnnotationSpec({
510
537
  description: "Forward navigational property — the FK is on **this** interface. The compiler resolves the matching @db.rel.FK by target type or alias.\n\n**Example:**\n```atscript\n@db.rel.to\nauthor?: User\n\n// With alias\n@db.rel.to \"author\"\nauthor?: User\n```\n",
511
538
  nodeType: ["prop"],
539
+ passedWhenReferred: false,
512
540
  argument: {
513
541
  optional: true,
514
542
  name: "alias",
@@ -592,6 +620,7 @@ const dbRelAnnotations = { rel: {
592
620
  from: new _atscript_core.AnnotationSpec({
593
621
  description: "Inverse navigational property — the FK is on the **target** interface, pointing back to this one.\n\n**Example:**\n```atscript\n@db.rel.from\nposts: Post[]\n\n// With alias\n@db.rel.from \"original\"\ncomments: Comment[]\n```\n",
594
622
  nodeType: ["prop"],
623
+ passedWhenReferred: false,
595
624
  argument: {
596
625
  optional: true,
597
626
  name: "alias",
@@ -680,6 +709,7 @@ const dbRelAnnotations = { rel: {
680
709
  via: new _atscript_core.AnnotationSpec({
681
710
  description: "Declares a many-to-many navigational property through an explicit junction table. `@db.rel.via` is self-sufficient — no `@db.rel.from` pairing is needed.\n\n**Example:**\n```atscript\n@db.rel.via PostTag\ntags: Tag[]\n```\n",
682
711
  nodeType: ["prop"],
712
+ passedWhenReferred: false,
683
713
  argument: {
684
714
  name: "junction",
685
715
  type: "ref",
@@ -739,6 +769,7 @@ const dbRelAnnotations = { rel: {
739
769
  filter: new _atscript_core.AnnotationSpec({
740
770
  description: "Applies a filter to a navigational property, restricting which related records are loaded.\n\n**Example:**\n```atscript\n@db.rel.from\n@db.rel.filter `Post.published = true`\npublishedPosts: Post[]\n```\n",
741
771
  nodeType: ["prop"],
772
+ passedWhenReferred: false,
742
773
  argument: {
743
774
  name: "condition",
744
775
  type: "query",
@@ -778,6 +809,7 @@ const dbSearchAnnotations = { search: {
778
809
  $self: new _atscript_core.AnnotationSpec({
779
810
  description: "Marks a field as a **vector embedding** for **similarity search**.\n\n- Each adapter maps this to its native vector type and index:\n - **MongoDB** → Atlas `$vectorSearch` index\n - **MySQL 9+** → `VECTOR(N)` column + `VEC_DISTANCE_*` functions\n - **PostgreSQL** → pgvector `vector(N)` column + distance operators\n - **SQLite** → `BLOB` column + `vec0` virtual index (requires the `sqlite-vec` extension; falls back to JSON `TEXT` when unavailable)\n\n**Example:**\n```atscript\n@db.search.vector 1536, \"cosine\"\nembedding: db.vector\n```\n",
780
811
  nodeType: ["prop"],
812
+ passedWhenReferred: false,
781
813
  multiple: false,
782
814
  argument: [
783
815
  {
@@ -822,6 +854,7 @@ const dbSearchAnnotations = { search: {
822
854
  threshold: new _atscript_core.AnnotationSpec({
823
855
  description: "Sets a **default minimum similarity threshold** for vector search queries on this field.\n\n- Results with a similarity score below this threshold are excluded.\n- Query-time `$threshold` control overrides this default.\n- Value range: `0` to `1` (where `1` means exact match).\n\n**Example:**\n```atscript\n@db.search.vector 1536, \"cosine\"\n@db.search.vector.threshold 0.7\nembedding: db.vector\n```\n",
824
856
  nodeType: ["prop"],
857
+ passedWhenReferred: false,
825
858
  multiple: false,
826
859
  argument: {
827
860
  optional: false,
@@ -834,6 +867,7 @@ const dbSearchAnnotations = { search: {
834
867
  filter: new _atscript_core.AnnotationSpec({
835
868
  description: "Assigns a field as a **pre-filter** for a **vector search index**.\n\n- Filters allow vector search queries to return results only within a specific subset.\n- The referenced index must be defined using `@db.search.vector`.\n\n**Example:**\n```atscript\n@db.search.vector 1536, \"cosine\"\nembedding: db.vector\n\n@db.search.filter \"embedding\"\ncategory: string\n```\n",
836
869
  nodeType: ["prop"],
870
+ passedWhenReferred: false,
837
871
  multiple: true,
838
872
  argument: {
839
873
  optional: false,
@@ -1074,6 +1108,7 @@ const dbUnitAnnotations = { unit: {
1074
1108
  ref: new _atscript_core.AnnotationSpec({
1075
1109
  description: "Binds this quantity to a **sibling field** that holds its unit. Use when different rows may carry different units (e.g. mixed kg/lb measurements).\n\nThe referenced field must be a `string`.\n\nValid on `decimal` and `number` fields. Aggregating this field forces the referenced unit field into `$groupBy` at runtime — summing rows with different units is rejected.\n\n**Example:**\n```atscript\nunit: string\n@db.unit.ref 'unit'\nweight: decimal\n```\n",
1076
1110
  nodeType: ["prop"],
1111
+ passedWhenReferred: false,
1077
1112
  multiple: false,
1078
1113
  argument: {
1079
1114
  name: "fieldName",
package/dist/plugin.mjs CHANGED
@@ -1,10 +1,11 @@
1
- import { a as getAnnotationAlias, c as getParentStruct, d as validateExclusiveWith, f as validateFieldBaseType, i as validateRefArgument, l as getParentTypeName, n as hasAnyViewAnnotation, o as getDbTableOwner, p as validateSiblingStringField, r as validateQueryScope, s as getNavTargetTypeName, t as findFKFieldsPointingTo, u as refActionAnnotation } from "./validation-utils-D4R08oed.mjs";
1
+ import { a as getAnnotationAlias, c as getParentStruct, d as validateExclusiveWith, f as validateFieldBaseType, i as validateRefArgument, l as getParentTypeName, n as hasAnyViewAnnotation, o as getDbTableOwner, p as validateSiblingStringField, r as validateQueryScope, s as getNavTargetTypeName, t as findFKFieldsPointingTo, u as refActionAnnotation } from "./validation-utils-MWOP1Ts4.mjs";
2
2
  import { AnnotationSpec, isArray, isInterface, isPrimitive, isRef, isStructure } from "@atscript/core";
3
3
  //#region src/plugin/annotations/agg.ts
4
4
  const dbAggAnnotations = { agg: {
5
5
  sum: new AnnotationSpec({
6
6
  description: "Declares a view field as SUM of a source column.",
7
7
  nodeType: ["prop"],
8
+ passedWhenReferred: false,
8
9
  argument: {
9
10
  name: "field",
10
11
  type: "string",
@@ -17,6 +18,7 @@ const dbAggAnnotations = { agg: {
17
18
  avg: new AnnotationSpec({
18
19
  description: "Declares a view field as AVG of a source column.",
19
20
  nodeType: ["prop"],
21
+ passedWhenReferred: false,
20
22
  argument: {
21
23
  name: "field",
22
24
  type: "string",
@@ -29,6 +31,7 @@ const dbAggAnnotations = { agg: {
29
31
  count: new AnnotationSpec({
30
32
  description: "Declares a view field as COUNT. Without argument: COUNT(*). With field name argument: COUNT(field) (non-null count).",
31
33
  nodeType: ["prop"],
34
+ passedWhenReferred: false,
32
35
  argument: {
33
36
  name: "field",
34
37
  type: "string",
@@ -42,6 +45,7 @@ const dbAggAnnotations = { agg: {
42
45
  min: new AnnotationSpec({
43
46
  description: "Declares a view field as MIN of a source column.",
44
47
  nodeType: ["prop"],
48
+ passedWhenReferred: false,
45
49
  argument: {
46
50
  name: "field",
47
51
  type: "string",
@@ -51,6 +55,7 @@ const dbAggAnnotations = { agg: {
51
55
  max: new AnnotationSpec({
52
56
  description: "Declares a view field as MAX of a source column.",
53
57
  nodeType: ["prop"],
58
+ passedWhenReferred: false,
54
59
  argument: {
55
60
  name: "field",
56
61
  type: "string",
@@ -90,6 +95,7 @@ const dbAmountAnnotations = { amount: { currency: {
90
95
  ref: new AnnotationSpec({
91
96
  description: "Binds this amount to a **sibling field** that holds its currency code. Use when each row may have a different currency.\n\nThe referenced field should be of type `db.currencyCode` (or at least a `string`).\n\nOnly valid on `decimal` fields.\n\n**Example:**\n```atscript\ncurrency: db.currencyCode\n@db.amount.currency.ref 'currency'\namount: decimal\n```\n",
92
97
  nodeType: ["prop"],
98
+ passedWhenReferred: false,
93
99
  multiple: false,
94
100
  argument: {
95
101
  name: "fieldName",
@@ -117,6 +123,7 @@ const dbColumnAnnotations = {
117
123
  patch: { strategy: new AnnotationSpec({
118
124
  description: "Defines the **patching strategy** for updating nested objects.\n\n- **\"replace\"** → The field or object will be **fully replaced**.\n- **\"merge\"** → The field or object will be **merged recursively** (applies only to objects, not arrays).\n\n**Example:**\n```atscript\n@db.patch.strategy \"merge\"\nsettings: {\n notifications: boolean\n preferences: {\n theme: string\n }\n}\n```\n",
119
125
  nodeType: ["prop"],
126
+ passedWhenReferred: false,
120
127
  multiple: false,
121
128
  argument: {
122
129
  name: "strategy",
@@ -146,6 +153,7 @@ const dbColumnAnnotations = {
146
153
  $self: new AnnotationSpec({
147
154
  description: "Overrides the physical column name in the database. For nested (flattened) fields, the parent prefix is still prepended automatically.\n\n**Example:**\n```atscript\n@db.column \"first_name\"\nfirstName: string\n// → physical column: first_name\n\n// Nested:\naddress: {\n @db.column \"zip_code\"\n zip: string\n}\n// → physical column: address__zip_code\n```\n",
148
155
  nodeType: ["prop"],
156
+ passedWhenReferred: false,
149
157
  argument: {
150
158
  name: "name",
151
159
  type: "string",
@@ -155,6 +163,7 @@ const dbColumnAnnotations = {
155
163
  renamed: new AnnotationSpec({
156
164
  description: "Specifies the previous local field name for column rename migration. The sync engine generates ALTER TABLE RENAME COLUMN instead of drop+add.\n\n**Example:**\n```atscript\n@db.column.renamed \"zip\"\npostalCode: string\n// Renames address__zip → address__postalCode\n```\n",
157
165
  nodeType: ["prop"],
166
+ passedWhenReferred: false,
158
167
  argument: {
159
168
  name: "oldName",
160
169
  type: "string",
@@ -164,6 +173,7 @@ const dbColumnAnnotations = {
164
173
  collate: new AnnotationSpec({
165
174
  description: "Portable collation for string comparison and sorting. Adapters map the generic value to their native collation.\n\n- **\"binary\"** — exact byte comparison (case-sensitive)\n- **\"nocase\"** — case-insensitive comparison\n- **\"unicode\"** — full Unicode-aware sorting\n\nFor adapter-specific collations, use `@db.<engine>.collate` instead.\n\n**Example:**\n```atscript\n@db.column.collate \"nocase\"\nusername: string\n```\n",
166
175
  nodeType: ["prop"],
176
+ passedWhenReferred: false,
167
177
  argument: {
168
178
  name: "collation",
169
179
  type: "string",
@@ -181,6 +191,7 @@ const dbColumnAnnotations = {
181
191
  precision: new AnnotationSpec({
182
192
  description: "Sets decimal precision and scale for database storage. Adapters map this to their native decimal type (e.g., `DECIMAL(10,2)` in SQL, ignored in MongoDB).\n\nFor `decimal` fields the runtime value is a string; for `number` fields this is a DB storage hint only.\n\n**Example:**\n```atscript\n@db.column.precision 10, 2\nprice: decimal\n```\n",
183
193
  nodeType: ["prop"],
194
+ passedWhenReferred: false,
184
195
  argument: [{
185
196
  name: "precision",
186
197
  type: "number",
@@ -196,11 +207,13 @@ const dbColumnAnnotations = {
196
207
  }),
197
208
  dimension: new AnnotationSpec({
198
209
  description: "Marks a field as a dimension — groupable in aggregate queries ($groupBy). Dimension fields automatically receive a database index during schema sync.",
199
- nodeType: ["prop"]
210
+ nodeType: ["prop"],
211
+ passedWhenReferred: false
200
212
  }),
201
213
  measure: new AnnotationSpec({
202
214
  description: "Marks a field as a measure — aggregatable in aggregate queries (sum, avg, count, min, max). Only valid on numeric or decimal fields.",
203
215
  nodeType: ["prop"],
216
+ passedWhenReferred: false,
204
217
  validate(token, _args, doc) {
205
218
  return validateFieldBaseType(token, doc, "@db.column.measure", ["number", "decimal"]);
206
219
  }
@@ -210,6 +223,7 @@ const dbColumnAnnotations = {
210
223
  version: new AnnotationSpec({
211
224
  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",
212
225
  nodeType: ["prop"],
226
+ passedWhenReferred: false,
213
227
  validate(token, _args, doc) {
214
228
  const errors = validateFieldBaseType(token, doc, "@db.column.version", "number");
215
229
  if (token.parentNode.has("optional")) errors.push({
@@ -235,6 +249,7 @@ const dbColumnAnnotations = {
235
249
  $self: new AnnotationSpec({
236
250
  description: "Sets a static DB-level default value (used in DDL DEFAULT clause). For string fields the value is used as-is; for other types it is parsed as JSON.\n\n**Example:**\n```atscript\n@db.default \"active\"\nstatus: string\n```\n",
237
251
  nodeType: ["prop"],
252
+ passedWhenReferred: false,
238
253
  argument: {
239
254
  name: "value",
240
255
  type: "string",
@@ -244,6 +259,7 @@ const dbColumnAnnotations = {
244
259
  increment: new AnnotationSpec({
245
260
  description: "Auto-incrementing integer default. Each adapter maps this to its native mechanism (e.g., `AUTO_INCREMENT` in MySQL, `INTEGER PRIMARY KEY` in SQLite, counter collection in MongoDB).\n\n**Example:**\n```atscript\n@db.default.increment\nid: number.int\n\n// With optional start value:\n@db.default.increment 1000\nid: number.int\n```\n",
246
261
  nodeType: ["prop"],
262
+ passedWhenReferred: false,
247
263
  argument: {
248
264
  optional: true,
249
265
  name: "start",
@@ -257,6 +273,7 @@ const dbColumnAnnotations = {
257
273
  uuid: new AnnotationSpec({
258
274
  description: "UUID generation default. Each adapter maps this to its native mechanism (e.g., `DEFAULT (UUID())` in MySQL, `gen_random_uuid()` in PostgreSQL, app-level in SQLite).\n\n**Example:**\n```atscript\n@db.default.uuid\nid: string.uuid\n```\n",
259
275
  nodeType: ["prop"],
276
+ passedWhenReferred: false,
260
277
  validate(token, args, doc) {
261
278
  return validateFieldBaseType(token, doc, "db.default.uuid", "string");
262
279
  }
@@ -264,6 +281,7 @@ const dbColumnAnnotations = {
264
281
  now: new AnnotationSpec({
265
282
  description: "Current timestamp default. Each adapter maps this to its native mechanism (e.g., `DEFAULT CURRENT_TIMESTAMP` in MySQL, `DEFAULT now()` in PostgreSQL).\n\n**Example:**\n```atscript\n@db.default.now\ncreatedAt: number.timestamp\n```\n",
266
283
  nodeType: ["prop"],
284
+ passedWhenReferred: false,
267
285
  validate(token, args, doc) {
268
286
  return validateFieldBaseType(token, doc, "db.default.now", ["number", "string"]);
269
287
  }
@@ -272,6 +290,7 @@ const dbColumnAnnotations = {
272
290
  json: new AnnotationSpec({
273
291
  description: "Forces a field to be stored as a single JSON column instead of being flattened into separate columns. Use on nested object fields that should remain as JSON in the database.\n\n**Example:**\n```atscript\n@db.json\nmetadata: { key: string, value: string }\n```\n",
274
292
  nodeType: ["prop"],
293
+ passedWhenReferred: false,
275
294
  validate(token, _args, doc) {
276
295
  const errors = [];
277
296
  const definition = token.parentNode.getDefinition();
@@ -289,6 +308,7 @@ const dbColumnAnnotations = {
289
308
  ignore: new AnnotationSpec({
290
309
  description: "Excludes a field from the database schema. The field exists in the Atscript type but has no column in the DB.\n\n**Example:**\n```atscript\n@db.ignore\ndisplayName: string\n```\n",
291
310
  nodeType: ["prop"],
311
+ passedWhenReferred: false,
292
312
  validate(token, _args, _doc) {
293
313
  const errors = [];
294
314
  if (token.parentNode.countAnnotations("meta.id") > 0) errors.push({
@@ -302,6 +322,7 @@ const dbColumnAnnotations = {
302
322
  encrypted: new AnnotationSpec({
303
323
  description: "Encrypts this field at rest. Values are AES-256-GCM encrypted by the core layer before reaching the database and decrypted on read — transparent to application code.\n\nConstraints: the field cannot be filtered, sorted, indexed, used as PK/FK, patched with arithmetic ops, or referenced by search/vector/geo features.\n\n**Example:**\n```atscript\n@db.encrypted\napiToken?: string\n```\n",
304
324
  nodeType: ["prop"],
325
+ passedWhenReferred: false,
305
326
  multiple: false,
306
327
  validate(token, _args, _doc) {
307
328
  const errors = [];
@@ -340,6 +361,7 @@ function columnCapability(capability, verb) {
340
361
  @db.table.${capability} "manual"\nexport interface User {
341
362
  ` + example + "}\n```\n",
342
363
  nodeType: ["prop"],
364
+ passedWhenReferred: false,
343
365
  multiple: false,
344
366
  validate(token, _args, _doc) {
345
367
  const errors = [];
@@ -359,6 +381,7 @@ const dbIndexAnnotations = { index: {
359
381
  plain: new AnnotationSpec({
360
382
  description: "Standard (non-unique) index for query performance. Fields sharing the same index name form a composite index.\n\n**Example:**\n```atscript\n@db.index.plain \"idx_timeline\", \"desc\"\ncreatedAt: number.timestamp\n```\n",
361
383
  nodeType: ["prop"],
384
+ passedWhenReferred: false,
362
385
  multiple: true,
363
386
  mergeStrategy: "append",
364
387
  argument: [{
@@ -377,6 +400,7 @@ const dbIndexAnnotations = { index: {
377
400
  unique: new AnnotationSpec({
378
401
  description: "Unique index — ensures no two rows/documents have the same value(s). Fields sharing the same index name form a composite unique constraint.\n\n**Example:**\n```atscript\n@db.index.unique \"tenant_email\"\nemail: string.email\n```\n",
379
402
  nodeType: ["prop"],
403
+ passedWhenReferred: false,
380
404
  multiple: true,
381
405
  mergeStrategy: "append",
382
406
  argument: {
@@ -389,6 +413,7 @@ const dbIndexAnnotations = { index: {
389
413
  fulltext: new AnnotationSpec({
390
414
  description: "Full-text search index. Fields sharing the same index name form a composite full-text index.\n\n**Example:**\n```atscript\n@db.index.fulltext \"ft_content\"\ntitle: string\n\n@db.index.fulltext \"ft_content\", 5\nbio: string\n```\n",
391
415
  nodeType: ["prop"],
416
+ passedWhenReferred: false,
392
417
  multiple: true,
393
418
  mergeStrategy: "append",
394
419
  argument: [{
@@ -406,6 +431,7 @@ const dbIndexAnnotations = { index: {
406
431
  geo: new AnnotationSpec({
407
432
  description: "Geospatial index on a `db.geoPoint` field. Enables `geoSearch()` (distance-ranked) and accelerates `$geoWithin` filters.\n\n**Example:**\n```atscript\n@db.index.geo\ngeo: db.geoPoint\n```\n",
408
433
  nodeType: ["prop"],
434
+ passedWhenReferred: false,
409
435
  multiple: false,
410
436
  argument: {
411
437
  optional: true,
@@ -421,6 +447,7 @@ const dbRelAnnotations = { rel: {
421
447
  FK: new AnnotationSpec({
422
448
  description: "Declares a foreign key reference on this field. The field must use a chain reference type (e.g., `User.id`) whose target is a primary key (`@meta.id`) or unique (`@db.index.unique`) field.\n\n**Dual role:**\n- On a `@db.table` interface, `@db.rel.FK` additionally drives DB-relation semantics — relation loading with `@db.rel.to` / `@db.rel.from`, junction pairing with `@db.rel.via`, etc.\n- On any other interface (value-help sources, WF forms, plain interfaces), `@db.rel.FK` acts purely as the value-help indicator: the client-side picker resolver uses it to decide which fields render a value-help picker. The target's `@db.http.path` (stamped by its readable controller) supplies the picker URL.\n\n**Example:**\n```atscript\n@db.rel.FK\nauthorId: User.id\n\n// With alias (required when multiple FKs point to the same type)\n@db.rel.FK \"author\"\nauthorId: User.id\n```\n",
423
449
  nodeType: ["prop"],
450
+ passedWhenReferred: false,
424
451
  argument: {
425
452
  optional: true,
426
453
  name: "alias",
@@ -505,6 +532,7 @@ const dbRelAnnotations = { rel: {
505
532
  to: new AnnotationSpec({
506
533
  description: "Forward navigational property — the FK is on **this** interface. The compiler resolves the matching @db.rel.FK by target type or alias.\n\n**Example:**\n```atscript\n@db.rel.to\nauthor?: User\n\n// With alias\n@db.rel.to \"author\"\nauthor?: User\n```\n",
507
534
  nodeType: ["prop"],
535
+ passedWhenReferred: false,
508
536
  argument: {
509
537
  optional: true,
510
538
  name: "alias",
@@ -588,6 +616,7 @@ const dbRelAnnotations = { rel: {
588
616
  from: new AnnotationSpec({
589
617
  description: "Inverse navigational property — the FK is on the **target** interface, pointing back to this one.\n\n**Example:**\n```atscript\n@db.rel.from\nposts: Post[]\n\n// With alias\n@db.rel.from \"original\"\ncomments: Comment[]\n```\n",
590
618
  nodeType: ["prop"],
619
+ passedWhenReferred: false,
591
620
  argument: {
592
621
  optional: true,
593
622
  name: "alias",
@@ -676,6 +705,7 @@ const dbRelAnnotations = { rel: {
676
705
  via: new AnnotationSpec({
677
706
  description: "Declares a many-to-many navigational property through an explicit junction table. `@db.rel.via` is self-sufficient — no `@db.rel.from` pairing is needed.\n\n**Example:**\n```atscript\n@db.rel.via PostTag\ntags: Tag[]\n```\n",
678
707
  nodeType: ["prop"],
708
+ passedWhenReferred: false,
679
709
  argument: {
680
710
  name: "junction",
681
711
  type: "ref",
@@ -735,6 +765,7 @@ const dbRelAnnotations = { rel: {
735
765
  filter: new AnnotationSpec({
736
766
  description: "Applies a filter to a navigational property, restricting which related records are loaded.\n\n**Example:**\n```atscript\n@db.rel.from\n@db.rel.filter `Post.published = true`\npublishedPosts: Post[]\n```\n",
737
767
  nodeType: ["prop"],
768
+ passedWhenReferred: false,
738
769
  argument: {
739
770
  name: "condition",
740
771
  type: "query",
@@ -774,6 +805,7 @@ const dbSearchAnnotations = { search: {
774
805
  $self: new AnnotationSpec({
775
806
  description: "Marks a field as a **vector embedding** for **similarity search**.\n\n- Each adapter maps this to its native vector type and index:\n - **MongoDB** → Atlas `$vectorSearch` index\n - **MySQL 9+** → `VECTOR(N)` column + `VEC_DISTANCE_*` functions\n - **PostgreSQL** → pgvector `vector(N)` column + distance operators\n - **SQLite** → `BLOB` column + `vec0` virtual index (requires the `sqlite-vec` extension; falls back to JSON `TEXT` when unavailable)\n\n**Example:**\n```atscript\n@db.search.vector 1536, \"cosine\"\nembedding: db.vector\n```\n",
776
807
  nodeType: ["prop"],
808
+ passedWhenReferred: false,
777
809
  multiple: false,
778
810
  argument: [
779
811
  {
@@ -818,6 +850,7 @@ const dbSearchAnnotations = { search: {
818
850
  threshold: new AnnotationSpec({
819
851
  description: "Sets a **default minimum similarity threshold** for vector search queries on this field.\n\n- Results with a similarity score below this threshold are excluded.\n- Query-time `$threshold` control overrides this default.\n- Value range: `0` to `1` (where `1` means exact match).\n\n**Example:**\n```atscript\n@db.search.vector 1536, \"cosine\"\n@db.search.vector.threshold 0.7\nembedding: db.vector\n```\n",
820
852
  nodeType: ["prop"],
853
+ passedWhenReferred: false,
821
854
  multiple: false,
822
855
  argument: {
823
856
  optional: false,
@@ -830,6 +863,7 @@ const dbSearchAnnotations = { search: {
830
863
  filter: new AnnotationSpec({
831
864
  description: "Assigns a field as a **pre-filter** for a **vector search index**.\n\n- Filters allow vector search queries to return results only within a specific subset.\n- The referenced index must be defined using `@db.search.vector`.\n\n**Example:**\n```atscript\n@db.search.vector 1536, \"cosine\"\nembedding: db.vector\n\n@db.search.filter \"embedding\"\ncategory: string\n```\n",
832
865
  nodeType: ["prop"],
866
+ passedWhenReferred: false,
833
867
  multiple: true,
834
868
  argument: {
835
869
  optional: false,
@@ -1070,6 +1104,7 @@ const dbUnitAnnotations = { unit: {
1070
1104
  ref: new AnnotationSpec({
1071
1105
  description: "Binds this quantity to a **sibling field** that holds its unit. Use when different rows may carry different units (e.g. mixed kg/lb measurements).\n\nThe referenced field must be a `string`.\n\nValid on `decimal` and `number` fields. Aggregating this field forces the referenced unit field into `$groupBy` at runtime — summing rows with different units is rejected.\n\n**Example:**\n```atscript\nunit: string\n@db.unit.ref 'unit'\nweight: decimal\n```\n",
1072
1106
  nodeType: ["prop"],
1107
+ passedWhenReferred: false,
1073
1108
  multiple: false,
1074
1109
  argument: {
1075
1110
  name: "fieldName",
package/dist/shared.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_validation_utils = require("./validation-utils-CR4H3_nc.cjs");
2
+ const require_validation_utils = require("./validation-utils-B7SXPkm7.cjs");
3
3
  exports.findFKFieldsPointingTo = require_validation_utils.findFKFieldsPointingTo;
4
4
  exports.getAnnotationAlias = require_validation_utils.getAnnotationAlias;
5
5
  exports.getDbTableOwner = require_validation_utils.getDbTableOwner;
package/dist/shared.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as getAnnotationAlias, c as getParentStruct, d as validateExclusiveWith, f as validateFieldBaseType, i as validateRefArgument, l as getParentTypeName, n as hasAnyViewAnnotation, o as getDbTableOwner, p as validateSiblingStringField, r as validateQueryScope, s as getNavTargetTypeName, t as findFKFieldsPointingTo, u as refActionAnnotation } from "./validation-utils-D4R08oed.mjs";
1
+ import { a as getAnnotationAlias, c as getParentStruct, d as validateExclusiveWith, f as validateFieldBaseType, i as validateRefArgument, l as getParentTypeName, n as hasAnyViewAnnotation, o as getDbTableOwner, p as validateSiblingStringField, r as validateQueryScope, s as getNavTargetTypeName, t as findFKFieldsPointingTo, u as refActionAnnotation } from "./validation-utils-MWOP1Ts4.mjs";
2
2
  export { findFKFieldsPointingTo, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField };
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-BIbH65VE.cjs");
2
+ const require_db_view = require("./db-view-UfGVUAol.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) {
@@ -930,6 +930,7 @@ var SchemaSync = class {
930
930
  * Runs schema synchronization with distributed locking.
931
931
  */
932
932
  async run(types, opts) {
933
+ this.logger = opts?.logger ?? this.logger;
933
934
  const podId = opts?.podId ?? crypto.randomUUID();
934
935
  const lockTtlMs = opts?.lockTtlMs ?? 3e4;
935
936
  const waitTimeoutMs = opts?.waitTimeoutMs ?? 6e4;
package/dist/sync.d.cts CHANGED
@@ -235,6 +235,11 @@ interface TSyncOptions {
235
235
  force?: boolean;
236
236
  /** Safe mode — skip destructive operations (column drops, table drops). Default: false. */
237
237
  safe?: boolean;
238
+ /**
239
+ * Logger for sync progress and failures (index/FK DDL errors are logged,
240
+ * not thrown). Default: NoopLogger — pass `console` to surface them.
241
+ */
242
+ logger?: TGenericLogger;
238
243
  }
239
244
  interface TSyncResult {
240
245
  status: "up-to-date" | "synced" | "synced-by-peer";
@@ -244,7 +249,7 @@ interface TSyncResult {
244
249
  declare class SchemaSync {
245
250
  private readonly space;
246
251
  private readonly store;
247
- private readonly logger;
252
+ private logger;
248
253
  constructor(space: DbSpace, logger?: TGenericLogger);
249
254
  /**
250
255
  * Resolves types into categorized readables and computes the schema hash.
package/dist/sync.d.mts CHANGED
@@ -235,6 +235,11 @@ interface TSyncOptions {
235
235
  force?: boolean;
236
236
  /** Safe mode — skip destructive operations (column drops, table drops). Default: false. */
237
237
  safe?: boolean;
238
+ /**
239
+ * Logger for sync progress and failures (index/FK DDL errors are logged,
240
+ * not thrown). Default: NoopLogger — pass `console` to surface them.
241
+ */
242
+ logger?: TGenericLogger;
238
243
  }
239
244
  interface TSyncResult {
240
245
  status: "up-to-date" | "synced" | "synced-by-peer";
@@ -244,7 +249,7 @@ interface TSyncResult {
244
249
  declare class SchemaSync {
245
250
  private readonly space;
246
251
  private readonly store;
247
- private readonly logger;
252
+ private logger;
248
253
  constructor(space: DbSpace, logger?: TGenericLogger);
249
254
  /**
250
255
  * Resolves types into categorized readables and computes the schema hash.
package/dist/sync.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { S as NoopLogger } from "./db-view-CHprAlvK.mjs";
1
+ import { C as NoopLogger } from "./db-view-BllUecjK.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) {
@@ -929,6 +929,7 @@ var SchemaSync = class {
929
929
  * Runs schema synchronization with distributed locking.
930
930
  */
931
931
  async run(types, opts) {
932
+ this.logger = opts?.logger ?? this.logger;
932
933
  const podId = opts?.podId ?? crypto.randomUUID();
933
934
  const lockTtlMs = opts?.lockTtlMs ?? 3e4;
934
935
  const waitTimeoutMs = opts?.waitTimeoutMs ?? 6e4;
@@ -116,6 +116,7 @@ function refActionAnnotation(name) {
116
116
  \`\`\`
117
117
  `,
118
118
  nodeType: ["prop"],
119
+ passedWhenReferred: false,
119
120
  argument: {
120
121
  name: "action",
121
122
  type: "string",
@@ -116,6 +116,7 @@ function refActionAnnotation(name) {
116
116
  \`\`\`
117
117
  `,
118
118
  nodeType: ["prop"],
119
+ passedWhenReferred: false,
119
120
  argument: {
120
121
  name: "action",
121
122
  type: "string",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/db",
3
- "version": "0.1.110",
3
+ "version": "0.1.112",
4
4
  "description": "Database adapter utilities for atscript.",
5
5
  "keywords": [
6
6
  "atscript",
@@ -71,14 +71,14 @@
71
71
  "access": "public"
72
72
  },
73
73
  "devDependencies": {
74
- "@atscript/core": "^0.1.78",
75
- "@atscript/typescript": "^0.1.78",
74
+ "@atscript/core": "^0.1.80",
75
+ "@atscript/typescript": "^0.1.80",
76
76
  "@uniqu/core": "^0.1.6",
77
- "unplugin-atscript": "^0.1.78"
77
+ "unplugin-atscript": "^0.1.80"
78
78
  },
79
79
  "peerDependencies": {
80
- "@atscript/core": "^0.1.78",
81
- "@atscript/typescript": "^0.1.78",
80
+ "@atscript/core": "^0.1.80",
81
+ "@atscript/typescript": "^0.1.80",
82
82
  "@uniqu/core": "^0.1.6"
83
83
  },
84
84
  "scripts": {