@lunora/do 1.0.0-alpha.4 → 1.0.0-alpha.5

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.
package/dist/index.d.mts CHANGED
@@ -195,10 +195,17 @@ interface RelationDefinitionLike {
195
195
  readonly references: string;
196
196
  readonly table: string;
197
197
  }
198
- /** Per-relation refinements: filter / order / cap / recurse into the children. */
198
+ /** Per-relation refinements: filter / order / cap / project / recurse into the children. */
199
199
  interface NestedWith {
200
200
  limit?: number;
201
201
  orderBy?: OrderByInput[];
202
+ /**
203
+ * Project each loaded child down to these fields (like the top-level
204
+ * `findMany` `select`). Applied AFTER grouping, so the join key stays
205
+ * available to map children to parents; `_id`/`_creationTime` and any deeper
206
+ * `with` relations are always retained.
207
+ */
208
+ select?: ReadonlyArray<string>;
202
209
  where?: WhereInput;
203
210
  with?: WithInput;
204
211
  }
@@ -304,6 +311,12 @@ interface QueryArgs {
304
311
  */
305
312
  baseWhere?: WhereInput;
306
313
  cursor?: null | string;
314
+ /**
315
+ * Opt a list read OUT of soft-delete scoping: when `true`, rows whose
316
+ * soft-delete column is set are INCLUDED. Has no effect on a table without
317
+ * `.softDelete()`. Default (absent/false) hides soft-deleted rows.
318
+ */
319
+ includeDeleted?: boolean;
307
320
  limit?: number;
308
321
  orderBy?: OrderByInput[];
309
322
  /**
@@ -324,6 +337,15 @@ interface QueryArgs {
324
337
  * reads (`findMany`/`findFirst`) — this flag specifically guards `count`.
325
338
  */
326
339
  restrictsCounts?: boolean;
340
+ /**
341
+ * Project each returned row down to these fields. The system fields `_id` and
342
+ * `_creationTime` are always retained (cursors + by-id reuse depend on them),
343
+ * and any relations attached via `with` (their relation keys and `_count`)
344
+ * survive the trim. Applied AFTER the rows are read and relations resolved, so
345
+ * read-dependency tracking and cursor encoding see the full row — only the
346
+ * payload returned to the caller is narrowed. Omit for the full document.
347
+ */
348
+ select?: ReadonlyArray<string>;
327
349
  where?: WhereInput;
328
350
  with?: WithInput;
329
351
  }
@@ -376,6 +398,26 @@ declare const buildSeekWhere: (keys: OrderKey[], cursorValues: unknown[]) => Whe
376
398
  * the page it terminates. Reactive pagination uses this for a page's fixed end
377
399
  * cursor; the shared compiler renders it per dialect.
378
400
  */
401
+
402
+ /**
403
+ * Project `page` rows down to `select` — plus the always-kept system fields and
404
+ * the relation/`_count` keys attached by a `with` load (passed as `withInput`,
405
+ * the same object handed to `findMany`). Returns the page unchanged when
406
+ * `select` is undefined. Pure; callers apply it AFTER relation resolution +
407
+ * cursor encoding so only the returned payload is trimmed (dependency tracking +
408
+ * the cursor still see the full row).
409
+ */
410
+ declare const applySelect: (page: Record<string, unknown>[], select: ReadonlyArray<string> | undefined, withInput?: Record<string, unknown>) => Record<string, unknown>[];
411
+ /**
412
+ * The read-scope predicate that hides soft-deleted rows — `{ [field]: { isNull:
413
+ * true } }` matching the live rows whose soft-delete column is null/absent — or
414
+ * `undefined` when the table isn't `.softDelete()` or the read opted in via
415
+ * `includeDeleted`. AND-merge it into a list read's `where` (the by-id path
416
+ * never calls this, so `get`/`patch`/`replace`/`restore` still address the row).
417
+ */
418
+ declare const softDeleteScope: (softDeleteMode: {
419
+ field: string;
420
+ } | undefined, includeDeleted: boolean | undefined) => undefined | WhereInput;
379
421
  type RankDirection = "asc" | "desc";
380
422
  interface RankSortKeyLike {
381
423
  readonly direction: RankDirection;
@@ -1233,6 +1275,16 @@ interface TableDefinitionLike {
1233
1275
  field?: string;
1234
1276
  kind: "global" | "root" | "shardBy";
1235
1277
  };
1278
+ /**
1279
+ * Mirror of `@lunora/server`'s `TableDefinition.softDeleteMode` (set by
1280
+ * `.softDelete()`). When present, `delete()` flips the `field` column to a
1281
+ * timestamp instead of physically removing the row (cascading as a soft
1282
+ * delete), and list reads scope out rows whose `field` is set unless
1283
+ * `includeDeleted` is passed. By-id reads/writes are unaffected.
1284
+ */
1285
+ readonly softDeleteMode?: {
1286
+ field: string;
1287
+ };
1236
1288
  readonly triggerMap?: Record<string, TriggerDefinitionLike>;
1237
1289
  }
1238
1290
  interface IndexDefinitionLike {
@@ -1525,7 +1577,16 @@ interface DatabaseWriterLike {
1525
1577
  * RLS-aware ctx seam from §3.2).
1526
1578
  */
1527
1579
  count: (tableName: string, where?: RestrictableQueryOptions | WhereInput) => Promise<number>;
1528
- delete: (id: string, expectedTable?: string) => Promise<void>;
1580
+ /**
1581
+ * Delete a row by id. On a `.softDelete()` table this flips the marker column
1582
+ * (cascading as a soft delete) instead of removing the row; pass
1583
+ * `options.hard` to force a physical removal (which cascades as a physical
1584
+ * delete, reaching already-soft-deleted children too). Non-soft tables ignore
1585
+ * `options.hard` — they always delete physically.
1586
+ */
1587
+ delete: (id: string, expectedTable?: string, options?: {
1588
+ hard?: boolean;
1589
+ }) => Promise<void>;
1529
1590
  /**
1530
1591
  * Delete many rows by id in one call (a loop over `delete()`). The returned
1531
1592
  * `deleted` is the number of ids **requested**, not rows actually removed (an
@@ -1702,6 +1763,14 @@ interface DatabaseWriterLike {
1702
1763
  rankPageRows?: (tableName: string, indexName: string, options?: RankPageOptions) => Promise<ShardRankPageResult>;
1703
1764
  replace: (id: string, document: Record<string, unknown>, expectedTable?: string) => Promise<void>;
1704
1765
  /**
1766
+ * Un-soft-delete a row: clears the `.softDelete()` marker column (a by-id
1767
+ * UPDATE, so it works on a row that list reads currently hide). Throws when
1768
+ * the row's table isn't `.softDelete()`. Optional on the interface — the DO
1769
+ * writer implements it; the `.global()` twin does too, so a restore on a
1770
+ * global table routes through the DO writer's global fallback.
1771
+ */
1772
+ restore?: (id: string, expectedTable?: string) => Promise<void>;
1773
+ /**
1705
1774
  * Best-effort, read-only reader over Lunora's system tables
1706
1775
  * (`_scheduled_functions`, `_storage`). Eventually consistent and **not**
1707
1776
  * part of the shard's transaction snapshot — see {@link SystemDatabaseReader}.
@@ -5586,4 +5655,4 @@ interface WhereSqlStrategy {
5586
5655
  * `undefined` when the input imposes no constraint (empty `where`).
5587
5656
  */
5588
5657
  declare const compileWhereSql: (where: WhereInput | undefined, strategy: WhereSqlStrategy) => SQL | undefined;
5589
- export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, AGGREGATE_SQL_FUNCTION, AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, type AdvisoriesResult, type AdvisoryFinding, type AggregateIndexDefinitionLike, type AggregateOp, type AggregateOptions, type AggregateResult, type AggregateTally, type ApplyOnDeleteOptions, type AuditEntry, type AuditLogResult, type AuthMetrics, type AuthMetricsBucket, type BroadcastDelta, CDC_LOG_TABLE, type CacheEntry, type CapturedMailRow, type CdcChange, type Clock, type ColumnMeta, type ColumnMetaLike, ConflictError, type CountArgs, CountRlsUnsupportedError, type CtxDbOptions, DATA_MIGRATION_STATE_TABLE, DEFAULT_MAX_RELATION_KEYS, type DataMigrationDocument, type DataMigrationLike, type DataMigrationTransform, type DatabaseWriterLike, type DependencyTracker, type DeployInfo, type ExportRow, type ExportShardAdminArgs, type ExportShardArgs, FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, type FacetColumnOptions, type FacetColumnResult, type FacetValue, type FieldOperators, type FunctionCallStat, type FunctionMetricBucket, type FunctionMetricIndexHit, type FunctionStatsResult, type GroupByEntry, type GroupByOptions, type HibernatableWebSocket, type IdGenerator, type ImportError, type ImportShardAdminArgs, type ImportShardArgs, type ImportShardResult, type IndexDefinitionLike, type IndexRangeBuilderLike, LogBuffer, type LogEntry, type LogEventInput, type LogLevel, type LogSink, MAIL_RETENTION, MAIL_TABLE, MAX_SQL_ROWS, MIN_ADMIN_TOKEN_LENGTH, MIN_AUTH_SECRET_LENGTH, type MaskColumnMetadata, type MaskPoliciesResult, type MigrationDirection, type MigrationRunResult, type MigrationStatus, type MigrationStatusRow, type MutationDelta, type NestedWith, NotFoundError, NotUniqueError, type OnDeleteActionLike, type OrderByInput, type OrderKey, type PaginationOptions, type PitrBookmarkResult, type PitrRestoreArgs, type PitrRestoreResult, type PitrStorage, type QueryArgs, type QueryPage, RANK_TIEBREAK, RELATION_FUNCTION_PREFIX, RLS_UNWRAP_SYMBOL, ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, type RankDirection, type RankIndexDefinitionLike, type RankOptions, type RankPage, type RankPageOptions, type RankPageRow, type RankPageRowKey, type RankResult, type RankSortKeyLike, ReactiveCache, type ReactiveCacheOptions, type ReadHook, type ReadTablePageOptions, type RecordAuthEventInput, type RecordFunctionMetricInput, type RecordMailInput, type RelationDefinitionLike, type RenderedSql, type ResolveRelationPredicatesOptions, type ResolveWithOptions, type RestrictableQueryOptions, type RlsPoliciesResult, type RlsPolicyMetadata, RlsRequiredError, type RlsRoleMetadata, type RpcRequest, type RunDataMigrationOptions, type RunShardApplyCdcArgs, type RunShardApplyCdcResult, type RunShardBulkDeleteArgs, type RunShardBulkDeleteResult, type RunShardExportArgs, type RunShardImportArgs, type RunShardMigrationArgs, type RunShardRankBeforeArgs, type RunShardRankPageArgs, type RunShardWriteArgs, type RunShardWriteResult, type RunTriggersOptions, SCAN_DEP, SESSION_DO_TTL_DEFAULT, SHARD_REGISTRY_DO_NAME, type ScheduledFunctionDoc, type SchedulerLike, type SchemaLike, type SearchFilterBuilderLike, type SecurityAuditResult, type SecurityFinding, type SecurityFindingKind, type SecurityFindingLevel, type SelectMatchingIdsOptions, type ServerDefaultContextLike, SessionDO, type SessionRecord, type SettingEntry, type SettingKind, type SettingsResult, ShardDO, type ShardDOOptions, type ShardDOState, type ShardRankPageResult, ShardRegistryDO, type SocketAttachment, type SortDirection, type SqlConsoleResult, type SqlCursor, type SqlEngine, type SqlExec, type StorageRuleMetadata, type StorageRulesResult, type StudioFeaturesResult, type SubscriptionEnvelope, type SubscriptionOutcome, type SubscriptionQuery, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemReaderOptions, type SystemReaderSchedulerLike, type SystemReaderStorageLike, type SystemTableName, type TableColumnsResult, type TableDefinitionLike, type TableIndexInfo, type TableIndexesResult, type TableInfo, type TablePage, type TableReaderLike, type TablesColumnsResult, type TransactionSqlLike, type TriggerContextLike, type TriggerDefinitionLike, type TriggerEventLike, type TriggerOpLike, type TriggerTimingLike, type ValidatorLike, type WhereInput, type WhereSqlStrategy, type WithInput, type WorkflowMetadata, type WorkflowsResult, type WriteEvent, type WriteHook, aggregateSqlFunction, aggregateTableName, applyCdcChanges, applyOnDelete, armRestore, assertFlatPredicate, assertReadonly, assertValidClientId, backfillAggregateIndexes, backfillRankIndexes, buildFtsMatch, buildSecurityAudit, buildSeekWhere, clearCapturedMail, coerceAggregateNumber, compileWhereSql, containsRelationPredicate, createDependencyTracker, createShardCtxDb, createSystemReader, decodeCursor, depKey, encodeAggregateKey, encodeCursor, encodePartitionKey, ensureAuthMetricsTables, ensureFunctionMetricsTables, ensureMailTable, exportShardRows, exportShardTable, facetColumn, foldAggregateTally, ftsTableName, guardWriter, hasTrigger, importShardRows, isRelationPredicate, listTables, matchesRankStaticWhere, matchesStaticWhere, mergeWhere, normalizeCountArgument, normalizeIdStructurally, normalizeOrderKeys, parseExportShardArgs, parseImportShardArgs, planAggregateLookup, rankTableName, reactiveCacheKey, readAggregateValue, readAuthMetrics, readBookmark, readCapturedMail, readCdcChanges, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, readMigrationStatus, readTablePage, recordAuthEvent, recordCapturedMail, recordFunctionMetric, renderSql, resolveRankPartition, resolveRelationPredicates, resolveWith, runDataMigration, runReadonlySql, runRowValidators, runShardMigrations, runTriggers, scoreDocument, selectExportTables, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy, selectMatchingIds, serveRelationFanout, sortColumnName, stableStringify, stringifySearchText, subscriptionListDeltas, throwingScheduler, tokenizeSearch, trimCdcChanges, validateImportRow };
5658
+ export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, AGGREGATE_SQL_FUNCTION, AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, type AdvisoriesResult, type AdvisoryFinding, type AggregateIndexDefinitionLike, type AggregateOp, type AggregateOptions, type AggregateResult, type AggregateTally, type ApplyOnDeleteOptions, type AuditEntry, type AuditLogResult, type AuthMetrics, type AuthMetricsBucket, type BroadcastDelta, CDC_LOG_TABLE, type CacheEntry, type CapturedMailRow, type CdcChange, type Clock, type ColumnMeta, type ColumnMetaLike, ConflictError, type CountArgs, CountRlsUnsupportedError, type CtxDbOptions, DATA_MIGRATION_STATE_TABLE, DEFAULT_MAX_RELATION_KEYS, type DataMigrationDocument, type DataMigrationLike, type DataMigrationTransform, type DatabaseWriterLike, type DependencyTracker, type DeployInfo, type ExportRow, type ExportShardAdminArgs, type ExportShardArgs, FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, type FacetColumnOptions, type FacetColumnResult, type FacetValue, type FieldOperators, type FunctionCallStat, type FunctionMetricBucket, type FunctionMetricIndexHit, type FunctionStatsResult, type GroupByEntry, type GroupByOptions, type HibernatableWebSocket, type IdGenerator, type ImportError, type ImportShardAdminArgs, type ImportShardArgs, type ImportShardResult, type IndexDefinitionLike, type IndexRangeBuilderLike, LogBuffer, type LogEntry, type LogEventInput, type LogLevel, type LogSink, MAIL_RETENTION, MAIL_TABLE, MAX_SQL_ROWS, MIN_ADMIN_TOKEN_LENGTH, MIN_AUTH_SECRET_LENGTH, type MaskColumnMetadata, type MaskPoliciesResult, type MigrationDirection, type MigrationRunResult, type MigrationStatus, type MigrationStatusRow, type MutationDelta, type NestedWith, NotFoundError, NotUniqueError, type OnDeleteActionLike, type OrderByInput, type OrderKey, type PaginationOptions, type PitrBookmarkResult, type PitrRestoreArgs, type PitrRestoreResult, type PitrStorage, type QueryArgs, type QueryPage, RANK_TIEBREAK, RELATION_FUNCTION_PREFIX, RLS_UNWRAP_SYMBOL, ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, type RankDirection, type RankIndexDefinitionLike, type RankOptions, type RankPage, type RankPageOptions, type RankPageRow, type RankPageRowKey, type RankResult, type RankSortKeyLike, ReactiveCache, type ReactiveCacheOptions, type ReadHook, type ReadTablePageOptions, type RecordAuthEventInput, type RecordFunctionMetricInput, type RecordMailInput, type RelationDefinitionLike, type RenderedSql, type ResolveRelationPredicatesOptions, type ResolveWithOptions, type RestrictableQueryOptions, type RlsPoliciesResult, type RlsPolicyMetadata, RlsRequiredError, type RlsRoleMetadata, type RpcRequest, type RunDataMigrationOptions, type RunShardApplyCdcArgs, type RunShardApplyCdcResult, type RunShardBulkDeleteArgs, type RunShardBulkDeleteResult, type RunShardExportArgs, type RunShardImportArgs, type RunShardMigrationArgs, type RunShardRankBeforeArgs, type RunShardRankPageArgs, type RunShardWriteArgs, type RunShardWriteResult, type RunTriggersOptions, SCAN_DEP, SESSION_DO_TTL_DEFAULT, SHARD_REGISTRY_DO_NAME, type ScheduledFunctionDoc, type SchedulerLike, type SchemaLike, type SearchFilterBuilderLike, type SecurityAuditResult, type SecurityFinding, type SecurityFindingKind, type SecurityFindingLevel, type SelectMatchingIdsOptions, type ServerDefaultContextLike, SessionDO, type SessionRecord, type SettingEntry, type SettingKind, type SettingsResult, ShardDO, type ShardDOOptions, type ShardDOState, type ShardRankPageResult, ShardRegistryDO, type SocketAttachment, type SortDirection, type SqlConsoleResult, type SqlCursor, type SqlEngine, type SqlExec, type StorageRuleMetadata, type StorageRulesResult, type StudioFeaturesResult, type SubscriptionEnvelope, type SubscriptionOutcome, type SubscriptionQuery, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemReaderOptions, type SystemReaderSchedulerLike, type SystemReaderStorageLike, type SystemTableName, type TableColumnsResult, type TableDefinitionLike, type TableIndexInfo, type TableIndexesResult, type TableInfo, type TablePage, type TableReaderLike, type TablesColumnsResult, type TransactionSqlLike, type TriggerContextLike, type TriggerDefinitionLike, type TriggerEventLike, type TriggerOpLike, type TriggerTimingLike, type ValidatorLike, type WhereInput, type WhereSqlStrategy, type WithInput, type WorkflowMetadata, type WorkflowsResult, type WriteEvent, type WriteHook, aggregateSqlFunction, aggregateTableName, applyCdcChanges, applyOnDelete, applySelect, armRestore, assertFlatPredicate, assertReadonly, assertValidClientId, backfillAggregateIndexes, backfillRankIndexes, buildFtsMatch, buildSecurityAudit, buildSeekWhere, clearCapturedMail, coerceAggregateNumber, compileWhereSql, containsRelationPredicate, createDependencyTracker, createShardCtxDb, createSystemReader, decodeCursor, depKey, encodeAggregateKey, encodeCursor, encodePartitionKey, ensureAuthMetricsTables, ensureFunctionMetricsTables, ensureMailTable, exportShardRows, exportShardTable, facetColumn, foldAggregateTally, ftsTableName, guardWriter, hasTrigger, importShardRows, isRelationPredicate, listTables, matchesRankStaticWhere, matchesStaticWhere, mergeWhere, normalizeCountArgument, normalizeIdStructurally, normalizeOrderKeys, parseExportShardArgs, parseImportShardArgs, planAggregateLookup, rankTableName, reactiveCacheKey, readAggregateValue, readAuthMetrics, readBookmark, readCapturedMail, readCdcChanges, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, readMigrationStatus, readTablePage, recordAuthEvent, recordCapturedMail, recordFunctionMetric, renderSql, resolveRankPartition, resolveRelationPredicates, resolveWith, runDataMigration, runReadonlySql, runRowValidators, runShardMigrations, runTriggers, scoreDocument, selectExportTables, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy, selectMatchingIds, serveRelationFanout, softDeleteScope, sortColumnName, stableStringify, stringifySearchText, subscriptionListDeltas, throwingScheduler, tokenizeSearch, trimCdcChanges, validateImportRow };
package/dist/index.d.ts CHANGED
@@ -195,10 +195,17 @@ interface RelationDefinitionLike {
195
195
  readonly references: string;
196
196
  readonly table: string;
197
197
  }
198
- /** Per-relation refinements: filter / order / cap / recurse into the children. */
198
+ /** Per-relation refinements: filter / order / cap / project / recurse into the children. */
199
199
  interface NestedWith {
200
200
  limit?: number;
201
201
  orderBy?: OrderByInput[];
202
+ /**
203
+ * Project each loaded child down to these fields (like the top-level
204
+ * `findMany` `select`). Applied AFTER grouping, so the join key stays
205
+ * available to map children to parents; `_id`/`_creationTime` and any deeper
206
+ * `with` relations are always retained.
207
+ */
208
+ select?: ReadonlyArray<string>;
202
209
  where?: WhereInput;
203
210
  with?: WithInput;
204
211
  }
@@ -304,6 +311,12 @@ interface QueryArgs {
304
311
  */
305
312
  baseWhere?: WhereInput;
306
313
  cursor?: null | string;
314
+ /**
315
+ * Opt a list read OUT of soft-delete scoping: when `true`, rows whose
316
+ * soft-delete column is set are INCLUDED. Has no effect on a table without
317
+ * `.softDelete()`. Default (absent/false) hides soft-deleted rows.
318
+ */
319
+ includeDeleted?: boolean;
307
320
  limit?: number;
308
321
  orderBy?: OrderByInput[];
309
322
  /**
@@ -324,6 +337,15 @@ interface QueryArgs {
324
337
  * reads (`findMany`/`findFirst`) — this flag specifically guards `count`.
325
338
  */
326
339
  restrictsCounts?: boolean;
340
+ /**
341
+ * Project each returned row down to these fields. The system fields `_id` and
342
+ * `_creationTime` are always retained (cursors + by-id reuse depend on them),
343
+ * and any relations attached via `with` (their relation keys and `_count`)
344
+ * survive the trim. Applied AFTER the rows are read and relations resolved, so
345
+ * read-dependency tracking and cursor encoding see the full row — only the
346
+ * payload returned to the caller is narrowed. Omit for the full document.
347
+ */
348
+ select?: ReadonlyArray<string>;
327
349
  where?: WhereInput;
328
350
  with?: WithInput;
329
351
  }
@@ -376,6 +398,26 @@ declare const buildSeekWhere: (keys: OrderKey[], cursorValues: unknown[]) => Whe
376
398
  * the page it terminates. Reactive pagination uses this for a page's fixed end
377
399
  * cursor; the shared compiler renders it per dialect.
378
400
  */
401
+
402
+ /**
403
+ * Project `page` rows down to `select` — plus the always-kept system fields and
404
+ * the relation/`_count` keys attached by a `with` load (passed as `withInput`,
405
+ * the same object handed to `findMany`). Returns the page unchanged when
406
+ * `select` is undefined. Pure; callers apply it AFTER relation resolution +
407
+ * cursor encoding so only the returned payload is trimmed (dependency tracking +
408
+ * the cursor still see the full row).
409
+ */
410
+ declare const applySelect: (page: Record<string, unknown>[], select: ReadonlyArray<string> | undefined, withInput?: Record<string, unknown>) => Record<string, unknown>[];
411
+ /**
412
+ * The read-scope predicate that hides soft-deleted rows — `{ [field]: { isNull:
413
+ * true } }` matching the live rows whose soft-delete column is null/absent — or
414
+ * `undefined` when the table isn't `.softDelete()` or the read opted in via
415
+ * `includeDeleted`. AND-merge it into a list read's `where` (the by-id path
416
+ * never calls this, so `get`/`patch`/`replace`/`restore` still address the row).
417
+ */
418
+ declare const softDeleteScope: (softDeleteMode: {
419
+ field: string;
420
+ } | undefined, includeDeleted: boolean | undefined) => undefined | WhereInput;
379
421
  type RankDirection = "asc" | "desc";
380
422
  interface RankSortKeyLike {
381
423
  readonly direction: RankDirection;
@@ -1233,6 +1275,16 @@ interface TableDefinitionLike {
1233
1275
  field?: string;
1234
1276
  kind: "global" | "root" | "shardBy";
1235
1277
  };
1278
+ /**
1279
+ * Mirror of `@lunora/server`'s `TableDefinition.softDeleteMode` (set by
1280
+ * `.softDelete()`). When present, `delete()` flips the `field` column to a
1281
+ * timestamp instead of physically removing the row (cascading as a soft
1282
+ * delete), and list reads scope out rows whose `field` is set unless
1283
+ * `includeDeleted` is passed. By-id reads/writes are unaffected.
1284
+ */
1285
+ readonly softDeleteMode?: {
1286
+ field: string;
1287
+ };
1236
1288
  readonly triggerMap?: Record<string, TriggerDefinitionLike>;
1237
1289
  }
1238
1290
  interface IndexDefinitionLike {
@@ -1525,7 +1577,16 @@ interface DatabaseWriterLike {
1525
1577
  * RLS-aware ctx seam from §3.2).
1526
1578
  */
1527
1579
  count: (tableName: string, where?: RestrictableQueryOptions | WhereInput) => Promise<number>;
1528
- delete: (id: string, expectedTable?: string) => Promise<void>;
1580
+ /**
1581
+ * Delete a row by id. On a `.softDelete()` table this flips the marker column
1582
+ * (cascading as a soft delete) instead of removing the row; pass
1583
+ * `options.hard` to force a physical removal (which cascades as a physical
1584
+ * delete, reaching already-soft-deleted children too). Non-soft tables ignore
1585
+ * `options.hard` — they always delete physically.
1586
+ */
1587
+ delete: (id: string, expectedTable?: string, options?: {
1588
+ hard?: boolean;
1589
+ }) => Promise<void>;
1529
1590
  /**
1530
1591
  * Delete many rows by id in one call (a loop over `delete()`). The returned
1531
1592
  * `deleted` is the number of ids **requested**, not rows actually removed (an
@@ -1702,6 +1763,14 @@ interface DatabaseWriterLike {
1702
1763
  rankPageRows?: (tableName: string, indexName: string, options?: RankPageOptions) => Promise<ShardRankPageResult>;
1703
1764
  replace: (id: string, document: Record<string, unknown>, expectedTable?: string) => Promise<void>;
1704
1765
  /**
1766
+ * Un-soft-delete a row: clears the `.softDelete()` marker column (a by-id
1767
+ * UPDATE, so it works on a row that list reads currently hide). Throws when
1768
+ * the row's table isn't `.softDelete()`. Optional on the interface — the DO
1769
+ * writer implements it; the `.global()` twin does too, so a restore on a
1770
+ * global table routes through the DO writer's global fallback.
1771
+ */
1772
+ restore?: (id: string, expectedTable?: string) => Promise<void>;
1773
+ /**
1705
1774
  * Best-effort, read-only reader over Lunora's system tables
1706
1775
  * (`_scheduled_functions`, `_storage`). Eventually consistent and **not**
1707
1776
  * part of the shard's transaction snapshot — see {@link SystemDatabaseReader}.
@@ -5586,4 +5655,4 @@ interface WhereSqlStrategy {
5586
5655
  * `undefined` when the input imposes no constraint (empty `where`).
5587
5656
  */
5588
5657
  declare const compileWhereSql: (where: WhereInput | undefined, strategy: WhereSqlStrategy) => SQL | undefined;
5589
- export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, AGGREGATE_SQL_FUNCTION, AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, type AdvisoriesResult, type AdvisoryFinding, type AggregateIndexDefinitionLike, type AggregateOp, type AggregateOptions, type AggregateResult, type AggregateTally, type ApplyOnDeleteOptions, type AuditEntry, type AuditLogResult, type AuthMetrics, type AuthMetricsBucket, type BroadcastDelta, CDC_LOG_TABLE, type CacheEntry, type CapturedMailRow, type CdcChange, type Clock, type ColumnMeta, type ColumnMetaLike, ConflictError, type CountArgs, CountRlsUnsupportedError, type CtxDbOptions, DATA_MIGRATION_STATE_TABLE, DEFAULT_MAX_RELATION_KEYS, type DataMigrationDocument, type DataMigrationLike, type DataMigrationTransform, type DatabaseWriterLike, type DependencyTracker, type DeployInfo, type ExportRow, type ExportShardAdminArgs, type ExportShardArgs, FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, type FacetColumnOptions, type FacetColumnResult, type FacetValue, type FieldOperators, type FunctionCallStat, type FunctionMetricBucket, type FunctionMetricIndexHit, type FunctionStatsResult, type GroupByEntry, type GroupByOptions, type HibernatableWebSocket, type IdGenerator, type ImportError, type ImportShardAdminArgs, type ImportShardArgs, type ImportShardResult, type IndexDefinitionLike, type IndexRangeBuilderLike, LogBuffer, type LogEntry, type LogEventInput, type LogLevel, type LogSink, MAIL_RETENTION, MAIL_TABLE, MAX_SQL_ROWS, MIN_ADMIN_TOKEN_LENGTH, MIN_AUTH_SECRET_LENGTH, type MaskColumnMetadata, type MaskPoliciesResult, type MigrationDirection, type MigrationRunResult, type MigrationStatus, type MigrationStatusRow, type MutationDelta, type NestedWith, NotFoundError, NotUniqueError, type OnDeleteActionLike, type OrderByInput, type OrderKey, type PaginationOptions, type PitrBookmarkResult, type PitrRestoreArgs, type PitrRestoreResult, type PitrStorage, type QueryArgs, type QueryPage, RANK_TIEBREAK, RELATION_FUNCTION_PREFIX, RLS_UNWRAP_SYMBOL, ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, type RankDirection, type RankIndexDefinitionLike, type RankOptions, type RankPage, type RankPageOptions, type RankPageRow, type RankPageRowKey, type RankResult, type RankSortKeyLike, ReactiveCache, type ReactiveCacheOptions, type ReadHook, type ReadTablePageOptions, type RecordAuthEventInput, type RecordFunctionMetricInput, type RecordMailInput, type RelationDefinitionLike, type RenderedSql, type ResolveRelationPredicatesOptions, type ResolveWithOptions, type RestrictableQueryOptions, type RlsPoliciesResult, type RlsPolicyMetadata, RlsRequiredError, type RlsRoleMetadata, type RpcRequest, type RunDataMigrationOptions, type RunShardApplyCdcArgs, type RunShardApplyCdcResult, type RunShardBulkDeleteArgs, type RunShardBulkDeleteResult, type RunShardExportArgs, type RunShardImportArgs, type RunShardMigrationArgs, type RunShardRankBeforeArgs, type RunShardRankPageArgs, type RunShardWriteArgs, type RunShardWriteResult, type RunTriggersOptions, SCAN_DEP, SESSION_DO_TTL_DEFAULT, SHARD_REGISTRY_DO_NAME, type ScheduledFunctionDoc, type SchedulerLike, type SchemaLike, type SearchFilterBuilderLike, type SecurityAuditResult, type SecurityFinding, type SecurityFindingKind, type SecurityFindingLevel, type SelectMatchingIdsOptions, type ServerDefaultContextLike, SessionDO, type SessionRecord, type SettingEntry, type SettingKind, type SettingsResult, ShardDO, type ShardDOOptions, type ShardDOState, type ShardRankPageResult, ShardRegistryDO, type SocketAttachment, type SortDirection, type SqlConsoleResult, type SqlCursor, type SqlEngine, type SqlExec, type StorageRuleMetadata, type StorageRulesResult, type StudioFeaturesResult, type SubscriptionEnvelope, type SubscriptionOutcome, type SubscriptionQuery, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemReaderOptions, type SystemReaderSchedulerLike, type SystemReaderStorageLike, type SystemTableName, type TableColumnsResult, type TableDefinitionLike, type TableIndexInfo, type TableIndexesResult, type TableInfo, type TablePage, type TableReaderLike, type TablesColumnsResult, type TransactionSqlLike, type TriggerContextLike, type TriggerDefinitionLike, type TriggerEventLike, type TriggerOpLike, type TriggerTimingLike, type ValidatorLike, type WhereInput, type WhereSqlStrategy, type WithInput, type WorkflowMetadata, type WorkflowsResult, type WriteEvent, type WriteHook, aggregateSqlFunction, aggregateTableName, applyCdcChanges, applyOnDelete, armRestore, assertFlatPredicate, assertReadonly, assertValidClientId, backfillAggregateIndexes, backfillRankIndexes, buildFtsMatch, buildSecurityAudit, buildSeekWhere, clearCapturedMail, coerceAggregateNumber, compileWhereSql, containsRelationPredicate, createDependencyTracker, createShardCtxDb, createSystemReader, decodeCursor, depKey, encodeAggregateKey, encodeCursor, encodePartitionKey, ensureAuthMetricsTables, ensureFunctionMetricsTables, ensureMailTable, exportShardRows, exportShardTable, facetColumn, foldAggregateTally, ftsTableName, guardWriter, hasTrigger, importShardRows, isRelationPredicate, listTables, matchesRankStaticWhere, matchesStaticWhere, mergeWhere, normalizeCountArgument, normalizeIdStructurally, normalizeOrderKeys, parseExportShardArgs, parseImportShardArgs, planAggregateLookup, rankTableName, reactiveCacheKey, readAggregateValue, readAuthMetrics, readBookmark, readCapturedMail, readCdcChanges, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, readMigrationStatus, readTablePage, recordAuthEvent, recordCapturedMail, recordFunctionMetric, renderSql, resolveRankPartition, resolveRelationPredicates, resolveWith, runDataMigration, runReadonlySql, runRowValidators, runShardMigrations, runTriggers, scoreDocument, selectExportTables, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy, selectMatchingIds, serveRelationFanout, sortColumnName, stableStringify, stringifySearchText, subscriptionListDeltas, throwingScheduler, tokenizeSearch, trimCdcChanges, validateImportRow };
5658
+ export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, AGGREGATE_SQL_FUNCTION, AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, type AdvisoriesResult, type AdvisoryFinding, type AggregateIndexDefinitionLike, type AggregateOp, type AggregateOptions, type AggregateResult, type AggregateTally, type ApplyOnDeleteOptions, type AuditEntry, type AuditLogResult, type AuthMetrics, type AuthMetricsBucket, type BroadcastDelta, CDC_LOG_TABLE, type CacheEntry, type CapturedMailRow, type CdcChange, type Clock, type ColumnMeta, type ColumnMetaLike, ConflictError, type CountArgs, CountRlsUnsupportedError, type CtxDbOptions, DATA_MIGRATION_STATE_TABLE, DEFAULT_MAX_RELATION_KEYS, type DataMigrationDocument, type DataMigrationLike, type DataMigrationTransform, type DatabaseWriterLike, type DependencyTracker, type DeployInfo, type ExportRow, type ExportShardAdminArgs, type ExportShardArgs, FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, type FacetColumnOptions, type FacetColumnResult, type FacetValue, type FieldOperators, type FunctionCallStat, type FunctionMetricBucket, type FunctionMetricIndexHit, type FunctionStatsResult, type GroupByEntry, type GroupByOptions, type HibernatableWebSocket, type IdGenerator, type ImportError, type ImportShardAdminArgs, type ImportShardArgs, type ImportShardResult, type IndexDefinitionLike, type IndexRangeBuilderLike, LogBuffer, type LogEntry, type LogEventInput, type LogLevel, type LogSink, MAIL_RETENTION, MAIL_TABLE, MAX_SQL_ROWS, MIN_ADMIN_TOKEN_LENGTH, MIN_AUTH_SECRET_LENGTH, type MaskColumnMetadata, type MaskPoliciesResult, type MigrationDirection, type MigrationRunResult, type MigrationStatus, type MigrationStatusRow, type MutationDelta, type NestedWith, NotFoundError, NotUniqueError, type OnDeleteActionLike, type OrderByInput, type OrderKey, type PaginationOptions, type PitrBookmarkResult, type PitrRestoreArgs, type PitrRestoreResult, type PitrStorage, type QueryArgs, type QueryPage, RANK_TIEBREAK, RELATION_FUNCTION_PREFIX, RLS_UNWRAP_SYMBOL, ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, type RankDirection, type RankIndexDefinitionLike, type RankOptions, type RankPage, type RankPageOptions, type RankPageRow, type RankPageRowKey, type RankResult, type RankSortKeyLike, ReactiveCache, type ReactiveCacheOptions, type ReadHook, type ReadTablePageOptions, type RecordAuthEventInput, type RecordFunctionMetricInput, type RecordMailInput, type RelationDefinitionLike, type RenderedSql, type ResolveRelationPredicatesOptions, type ResolveWithOptions, type RestrictableQueryOptions, type RlsPoliciesResult, type RlsPolicyMetadata, RlsRequiredError, type RlsRoleMetadata, type RpcRequest, type RunDataMigrationOptions, type RunShardApplyCdcArgs, type RunShardApplyCdcResult, type RunShardBulkDeleteArgs, type RunShardBulkDeleteResult, type RunShardExportArgs, type RunShardImportArgs, type RunShardMigrationArgs, type RunShardRankBeforeArgs, type RunShardRankPageArgs, type RunShardWriteArgs, type RunShardWriteResult, type RunTriggersOptions, SCAN_DEP, SESSION_DO_TTL_DEFAULT, SHARD_REGISTRY_DO_NAME, type ScheduledFunctionDoc, type SchedulerLike, type SchemaLike, type SearchFilterBuilderLike, type SecurityAuditResult, type SecurityFinding, type SecurityFindingKind, type SecurityFindingLevel, type SelectMatchingIdsOptions, type ServerDefaultContextLike, SessionDO, type SessionRecord, type SettingEntry, type SettingKind, type SettingsResult, ShardDO, type ShardDOOptions, type ShardDOState, type ShardRankPageResult, ShardRegistryDO, type SocketAttachment, type SortDirection, type SqlConsoleResult, type SqlCursor, type SqlEngine, type SqlExec, type StorageRuleMetadata, type StorageRulesResult, type StudioFeaturesResult, type SubscriptionEnvelope, type SubscriptionOutcome, type SubscriptionQuery, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemReaderOptions, type SystemReaderSchedulerLike, type SystemReaderStorageLike, type SystemTableName, type TableColumnsResult, type TableDefinitionLike, type TableIndexInfo, type TableIndexesResult, type TableInfo, type TablePage, type TableReaderLike, type TablesColumnsResult, type TransactionSqlLike, type TriggerContextLike, type TriggerDefinitionLike, type TriggerEventLike, type TriggerOpLike, type TriggerTimingLike, type ValidatorLike, type WhereInput, type WhereSqlStrategy, type WithInput, type WorkflowMetadata, type WorkflowsResult, type WriteEvent, type WriteHook, aggregateSqlFunction, aggregateTableName, applyCdcChanges, applyOnDelete, applySelect, armRestore, assertFlatPredicate, assertReadonly, assertValidClientId, backfillAggregateIndexes, backfillRankIndexes, buildFtsMatch, buildSecurityAudit, buildSeekWhere, clearCapturedMail, coerceAggregateNumber, compileWhereSql, containsRelationPredicate, createDependencyTracker, createShardCtxDb, createSystemReader, decodeCursor, depKey, encodeAggregateKey, encodeCursor, encodePartitionKey, ensureAuthMetricsTables, ensureFunctionMetricsTables, ensureMailTable, exportShardRows, exportShardTable, facetColumn, foldAggregateTally, ftsTableName, guardWriter, hasTrigger, importShardRows, isRelationPredicate, listTables, matchesRankStaticWhere, matchesStaticWhere, mergeWhere, normalizeCountArgument, normalizeIdStructurally, normalizeOrderKeys, parseExportShardArgs, parseImportShardArgs, planAggregateLookup, rankTableName, reactiveCacheKey, readAggregateValue, readAuthMetrics, readBookmark, readCapturedMail, readCdcChanges, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, readMigrationStatus, readTablePage, recordAuthEvent, recordCapturedMail, recordFunctionMetric, renderSql, resolveRankPartition, resolveRelationPredicates, resolveWith, runDataMigration, runReadonlySql, runRowValidators, runShardMigrations, runTriggers, scoreDocument, selectExportTables, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy, selectMatchingIds, serveRelationFanout, softDeleteScope, sortColumnName, stableStringify, stringifySearchText, subscriptionListDeltas, throwingScheduler, tokenizeSearch, trimCdcChanges, validateImportRow };
package/dist/index.mjs CHANGED
@@ -3,7 +3,7 @@ export { AGGREGATE_SQL_FUNCTION, aggregateSqlFunction, matchesStaticWhere, norma
3
3
  export { aggregateTableName, coerceAggregateNumber, encodeAggregateKey, foldAggregateTally, readAggregateValue } from './packem_shared/aggregateTableName-CxNqY1Sl.mjs';
4
4
  export { CountRlsUnsupportedError, mergeWhere, planAggregateLookup, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy } from './packem_shared/CountRlsUnsupportedError-28ZvvwKS.mjs';
5
5
  export { AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, ensureAuthMetricsTables, readAuthMetrics, recordAuthEvent } from './packem_shared/AUTH_METRICS_BUCKETS_TABLE-CiHHYeJi.mjs';
6
- export { NotUniqueError, assertValidClientId, createShardCtxDb, normalizeIdStructurally } from './packem_shared/NotUniqueError-B6tzuDmM.mjs';
6
+ export { NotUniqueError, assertValidClientId, createShardCtxDb, normalizeIdStructurally } from './packem_shared/NotUniqueError-h_thNFSZ.mjs';
7
7
  export { DATA_MIGRATION_STATE_TABLE, readMigrationStatus, runDataMigration } from './packem_shared/DATA_MIGRATION_STATE_TABLE-PTtTiQ7U.mjs';
8
8
  export { SCAN_DEP, createDependencyTracker, depKey } from './packem_shared/SCAN_DEP-DLJF8dsj.mjs';
9
9
  export { renderSql } from './packem_shared/renderSql-D6eUcn2N.mjs';
@@ -13,13 +13,13 @@ export { LogBuffer } from './packem_shared/LogBuffer-B_Ezju_N.mjs';
13
13
  export { MAIL_RETENTION, MAIL_TABLE, clearCapturedMail, ensureMailTable, readCapturedMail, recordCapturedMail } from './packem_shared/MAIL_RETENTION-CPpgl-dX.mjs';
14
14
  export { default as NotFoundError } from './packem_shared/NotFoundError-CMuMZt81.mjs';
15
15
  export { armRestore, readBookmark } from './packem_shared/armRestore-BJk53Ro8.mjs';
16
- export { buildSeekWhere, decodeCursor, encodeCursor, normalizeOrderKeys } from './packem_shared/buildSeekWhere-lVsNXSLy.mjs';
16
+ export { applySelect, buildSeekWhere, decodeCursor, encodeCursor, normalizeOrderKeys, softDeleteScope } from './packem_shared/applySelect-BvZdFUBT.mjs';
17
17
  export { R as RANK_TIEBREAK, e as encodePartitionKey, m as matchesRankStaticWhere, r as rankTableName, a as resolveRankPartition, s as sortColumnName } from './packem_shared/rank-CrkEIpF4.mjs';
18
18
  export { ReactiveCache, reactiveCacheKey, stableStringify } from './packem_shared/ReactiveCache-ByVzgH3d.mjs';
19
19
  export { serveRelationFanout } from './packem_shared/serveRelationFanout-CFBKWJ8Q.mjs';
20
- export { DEFAULT_MAX_RELATION_KEYS, assertFlatPredicate, containsRelationPredicate, isRelationPredicate, resolveRelationPredicates } from './packem_shared/DEFAULT_MAX_RELATION_KEYS-DyVYReuT.mjs';
21
- export { applyOnDelete, resolveWith, runRowValidators } from './packem_shared/applyOnDelete-CMif2RKw.mjs';
22
- export { RLS_UNWRAP_SYMBOL, RlsRequiredError, guardWriter } from './packem_shared/RLS_UNWRAP_SYMBOL-u3UlnCH5.mjs';
20
+ export { DEFAULT_MAX_RELATION_KEYS, assertFlatPredicate, containsRelationPredicate, isRelationPredicate, resolveRelationPredicates } from './packem_shared/DEFAULT_MAX_RELATION_KEYS-Dou2PWdO.mjs';
21
+ export { applyOnDelete, resolveWith, runRowValidators } from './packem_shared/applyOnDelete-sA7o1CqD.mjs';
22
+ export { RLS_UNWRAP_SYMBOL, RlsRequiredError, guardWriter } from './packem_shared/RLS_UNWRAP_SYMBOL-EtGQdC9d.mjs';
23
23
  export { buildFtsMatch, ftsTableName, scoreDocument, stringifySearchText, tokenizeSearch } from './packem_shared/buildFtsMatch-BLEMawrp.mjs';
24
24
  export { M as MIN_ADMIN_TOKEN_LENGTH, a as MIN_AUTH_SECRET_LENGTH, b as buildSecurityAudit } from './packem_shared/security-audit-CucgBice.mjs';
25
25
  export { SESSION_DO_TTL_DEFAULT, SessionDO } from './packem_shared/SESSION_DO_TTL_DEFAULT-ilPZsVwu.mjs';
@@ -1,4 +1,4 @@
1
- import { distinctValues } from './applyOnDelete-CMif2RKw.mjs';
1
+ import { distinctValues } from './applyOnDelete-sA7o1CqD.mjs';
2
2
 
3
3
  const RELATION_EXISTS_KEY = "__relationExists";
4
4
 
@@ -10,11 +10,11 @@ import { param } from './renderSql-D6eUcn2N.mjs';
10
10
  import { s as sortColumnName, m as matchesRankStaticWhere, e as encodePartitionKey, b as serializeSqlValue, r as rankTableName, a as resolveRankPartition, R as RANK_TIEBREAK } from './rank-CrkEIpF4.mjs';
11
11
  import { stringifySearchText, ftsTableName, tokenizeSearch, buildFtsMatch, scoreDocument } from './buildFtsMatch-BLEMawrp.mjs';
12
12
  import { SCAN_DEP } from './SCAN_DEP-DLJF8dsj.mjs';
13
- import { decodeCursor, normalizeOrderKeys, buildSeekWhere, encodeCursor, buildSeekBeforeWhere } from './buildSeekWhere-lVsNXSLy.mjs';
13
+ import { decodeCursor, normalizeOrderKeys, buildSeekWhere, applySelect, encodeCursor, softDeleteScope, buildSeekBeforeWhere } from './applySelect-BvZdFUBT.mjs';
14
14
  import NotFoundError from './NotFoundError-CMuMZt81.mjs';
15
- import { assertFlatPredicate, resolveRelationPredicates } from './DEFAULT_MAX_RELATION_KEYS-DyVYReuT.mjs';
16
- import { runRowValidators, resolveWith, applyOnDelete } from './applyOnDelete-CMif2RKw.mjs';
17
- import { guardWriter } from './RLS_UNWRAP_SYMBOL-u3UlnCH5.mjs';
15
+ import { assertFlatPredicate, resolveRelationPredicates } from './DEFAULT_MAX_RELATION_KEYS-Dou2PWdO.mjs';
16
+ import { runRowValidators, resolveWith, applyOnDelete } from './applyOnDelete-sA7o1CqD.mjs';
17
+ import { guardWriter } from './RLS_UNWRAP_SYMBOL-EtGQdC9d.mjs';
18
18
  import { createSystemReader } from './createSystemReader-8CzSZP9V.mjs';
19
19
  import { ConflictError } from './ConflictError-C0STs6bU.mjs';
20
20
  import { runTriggers } from './hasTrigger-5N6_Fx0A.mjs';
@@ -534,7 +534,7 @@ const createSearchBuilder = (search, tableName) => {
534
534
  };
535
535
  return builder;
536
536
  };
537
- const searchViaFts = (sql$1, tableName, search, limit) => {
537
+ const searchViaFts = (sql$1, tableName, search, limit, scopeCondition) => {
538
538
  const tokens = tokenizeSearch(search.query);
539
539
  if (tokens.length === 0) {
540
540
  return [];
@@ -544,6 +544,9 @@ const searchViaFts = (sql$1, tableName, search, limit) => {
544
544
  for (const filter of search.filters) {
545
545
  whereClauses.push(sql`${jsonPathSql(filter.field)} = ${serializeSqlValue(filter.value)}`);
546
546
  }
547
+ if (scopeCondition) {
548
+ whereClauses.push(scopeCondition);
549
+ }
547
550
  let query = sql`SELECT m.id, m._creationTime, m.${sql.identifier(DOC_COLUMN$1)} FROM ${sql.identifier(ftName)} f JOIN ${sql.identifier(tableName)} m ON m.id = f.${sql.identifier("__id__")} WHERE ${sql.join(whereClauses, sql` AND `)} ORDER BY f.rank, m._creationTime DESC`;
548
551
  if (typeof limit === "number") {
549
552
  query = sql`${query} LIMIT ${sql.raw(String(Math.max(0, Math.floor(limit))))}`;
@@ -558,7 +561,7 @@ const searchViaFts = (sql$1, tableName, search, limit) => {
558
561
  }
559
562
  return docs;
560
563
  };
561
- const searchViaScan = (sql$1, tableName, search, limit) => {
564
+ const searchViaScan = (sql$1, tableName, search, limit, scopeCondition) => {
562
565
  const tokens = tokenizeSearch(search.query);
563
566
  if (tokens.length === 0) {
564
567
  return [];
@@ -567,6 +570,9 @@ const searchViaScan = (sql$1, tableName, search, limit) => {
567
570
  for (const filter of search.filters) {
568
571
  whereClauses.push(sql`${jsonPathSql(filter.field)} = ${serializeSqlValue(filter.value)}`);
569
572
  }
573
+ if (scopeCondition) {
574
+ whereClauses.push(scopeCondition);
575
+ }
570
576
  let query = sql`SELECT id, _creationTime, ${sql.identifier(DOC_COLUMN$1)} FROM ${sql.identifier(tableName)}`;
571
577
  if (whereClauses.length > 0) {
572
578
  query = sql`${query} WHERE ${sql.join(whereClauses, sql` AND `)}`;
@@ -660,11 +666,12 @@ const scanDocs = (rows, filters, cap) => {
660
666
  }
661
667
  return docs;
662
668
  };
663
- const paginateStage = (sql$1, tableName, stage, options) => {
669
+ const paginateStage = (sql$1, tableName, stage, options, scopeCondition) => {
664
670
  const numberItems = Math.max(0, Math.floor(options.numItems));
665
671
  const orderKeys = paginateOrderKeys(stage);
666
672
  const bounded = typeof options.endCursor === "string";
667
- const whereCondition = compileWhereSql(paginateWhere(stage, orderKeys, options.cursor, options.endCursor), doWhereSqlStrategy);
673
+ const pageWhere = compileWhereSql(paginateWhere(stage, orderKeys, options.cursor, options.endCursor), doWhereSqlStrategy);
674
+ const whereCondition = scopeCondition && pageWhere ? sql`${pageWhere} AND ${scopeCondition}` : scopeCondition ?? pageWhere;
668
675
  let query = sql`SELECT id, _creationTime, ${sql.identifier(DOC_COLUMN$1)} FROM ${sql.identifier(tableName)}`;
669
676
  if (whereCondition) {
670
677
  query = sql`${query} WHERE ${whereCondition}`;
@@ -721,6 +728,8 @@ const buildReader = (sql$1, schema, tableName, onIndexUse = () => void 0) => {
721
728
  if (!tableDefinition) {
722
729
  throw new Error(`unknown table: ${tableName}`);
723
730
  }
731
+ const scopeWhere = softDeleteScope(tableDefinition.softDeleteMode, void 0);
732
+ const scopeCondition = scopeWhere ? compileWhereSql(scopeWhere, doWhereSqlStrategy) : void 0;
724
733
  const stage = {
725
734
  indexFields: [],
726
735
  indexName: void 0,
@@ -735,7 +744,7 @@ const buildReader = (sql$1, schema, tableName, onIndexUse = () => void 0) => {
735
744
  }
736
745
  const filtered = stage.inMemoryFilters.length > 0;
737
746
  const engineLimit = filtered ? void 0 : limit;
738
- const docs = isFtsAvailable(sql$1) ? searchViaFts(sql$1, tableName, search, engineLimit) : searchViaScan(sql$1, tableName, search, engineLimit);
747
+ const docs = isFtsAvailable(sql$1) ? searchViaFts(sql$1, tableName, search, engineLimit, scopeCondition) : searchViaScan(sql$1, tableName, search, engineLimit, scopeCondition);
739
748
  if (!filtered) {
740
749
  return docs;
741
750
  }
@@ -766,6 +775,9 @@ const buildReader = (sql$1, schema, tableName, onIndexUse = () => void 0) => {
766
775
  for (const condition of stage.sqlConditions) {
767
776
  whereClauses.push(sql`${jsonPathSql(condition.field)} ${sql.raw(condition.comparator)} ${serializeSqlValue(condition.value)}`);
768
777
  }
778
+ if (scopeCondition) {
779
+ whereClauses.push(scopeCondition);
780
+ }
769
781
  let query = sql`SELECT id, _creationTime, ${sql.identifier(DOC_COLUMN$1)} FROM ${sql.identifier(tableName)}`;
770
782
  if (whereClauses.length > 0) {
771
783
  query = sql`${query} WHERE ${sql.join(whereClauses, sql` AND `)}`;
@@ -813,7 +825,7 @@ const buildReader = (sql$1, schema, tableName, onIndexUse = () => void 0) => {
813
825
  if (stage.search) {
814
826
  throw new Error("pagination is not supported on search queries; use .take(n) or .collect()");
815
827
  }
816
- return paginateStage(sql$1, tableName, stage, options);
828
+ return paginateStage(sql$1, tableName, stage, options, scopeCondition);
817
829
  },
818
830
  // eslint-disable-next-line @typescript-eslint/require-await -- TableReaderLike returns Promises (the D1 twin awaits real I/O); the DO impl is synchronous over local SQLite
819
831
  async take(limit) {
@@ -1130,10 +1142,11 @@ const createShardCtxDb = (options) => {
1130
1142
  throw new Error(`aggregate(${tableName}, { op: "${aggOptions.op}" }): "field" is required for non-count reducers`);
1131
1143
  }
1132
1144
  onRead(tableName, SCAN_DEP);
1133
- const effective = mergeWhere(aggOptions.baseWhere, aggOptions.where);
1145
+ const aggScope = softDeleteScope(definition.softDeleteMode, void 0);
1146
+ const effective = mergeWhere(mergeWhere(aggOptions.baseWhere, aggOptions.where), aggScope);
1134
1147
  const resolved = await resolveAggregateRelations(effective, tableName, aggOptions.relationBaseWhere);
1135
1148
  const hasRelation = resolved !== effective;
1136
- if (definition.aggregateIndexes && !aggOptions.baseWhere && !hasRelation) {
1149
+ if (definition.aggregateIndexes && !aggOptions.baseWhere && !hasRelation && !aggScope) {
1137
1150
  const planned = selectIndexForAggregate(definition.aggregateIndexes, aggOptions.op, aggOptions.field, aggOptions.where);
1138
1151
  if (planned) {
1139
1152
  ensureBackfilled(tableName, planned.index);
@@ -1175,10 +1188,11 @@ const createShardCtxDb = (options) => {
1175
1188
  throw new CountRlsUnsupportedError(tableName);
1176
1189
  }
1177
1190
  onRead(tableName, SCAN_DEP);
1178
- const effective = mergeWhere(countOptions.baseWhere, countOptions.where);
1191
+ const countScope = softDeleteScope(definition.softDeleteMode, void 0);
1192
+ const effective = mergeWhere(mergeWhere(countOptions.baseWhere, countOptions.where), countScope);
1179
1193
  const resolved = await resolveAggregateRelations(effective, tableName, countOptions.relationBaseWhere);
1180
1194
  const hasRelation = resolved !== effective;
1181
- if (definition.aggregateIndexes && !countOptions.baseWhere && !hasRelation) {
1195
+ if (definition.aggregateIndexes && !countOptions.baseWhere && !hasRelation && !countScope) {
1182
1196
  const planned = selectIndexForCount(definition.aggregateIndexes, countOptions.where);
1183
1197
  if (planned) {
1184
1198
  ensureBackfilled(tableName, planned.index);
@@ -1199,16 +1213,22 @@ const createShardCtxDb = (options) => {
1199
1213
  const row = runDrizzle(sql$1, query).one();
1200
1214
  return row.count;
1201
1215
  },
1202
- async delete(id, expectedTable) {
1216
+ async delete(id, expectedTable, deleteOptions) {
1203
1217
  const located = locateRowById(id, expectedTable);
1204
1218
  if (!located) {
1205
1219
  const global = expectedTable === void 0 ? globalFallback() : void 0;
1206
1220
  if (global) {
1207
- await global.delete(id);
1221
+ await global.delete(id, void 0, deleteOptions);
1208
1222
  }
1209
1223
  return;
1210
1224
  }
1211
1225
  const { docJson: existingJson, row: existing, tableName } = located;
1226
+ const definition = schema.tables[tableName];
1227
+ const hard = deleteOptions?.hard === true;
1228
+ const softField = !hard && definition?.softDeleteMode ? definition.softDeleteMode.field : void 0;
1229
+ if (softField && existing[softField] !== null && existing[softField] !== void 0) {
1230
+ return;
1231
+ }
1212
1232
  if (hasMatchingTrigger(tableName, "before", "delete")) {
1213
1233
  await fireTriggers("before", "delete", { id, op: "delete", previous: existing, table: tableName });
1214
1234
  }
@@ -1216,10 +1236,10 @@ const createShardCtxDb = (options) => {
1216
1236
  deletedId: id,
1217
1237
  deletedReference: (references) => existing[references],
1218
1238
  findHolders: async (holderTable, field, value) => {
1219
- const holders = await routeForHolder(holderTable).findMany(holderTable, { where: { [field]: value } });
1239
+ const holders = await routeForHolder(holderTable).findMany(holderTable, { includeDeleted: hard, where: { [field]: value } });
1220
1240
  return holders.page;
1221
1241
  },
1222
- onCascade: (holderTable, holderId) => routeForHolder(holderTable).delete(holderId),
1242
+ onCascade: (holderTable, holderId) => routeForHolder(holderTable).delete(holderId, void 0, deleteOptions),
1223
1243
  onRestrict: (message) => {
1224
1244
  throw new ConflictError(message, "restrict");
1225
1245
  },
@@ -1230,6 +1250,25 @@ const createShardCtxDb = (options) => {
1230
1250
  });
1231
1251
  ensureBackfilledForTable(tableName);
1232
1252
  ensureRankBackfilledForTable(tableName);
1253
+ if (softField) {
1254
+ const merged = { ...existing, [softField]: clock(), _id: id };
1255
+ runGuardedWrite(
1256
+ sql$1,
1257
+ tableName,
1258
+ sql`UPDATE ${sql.identifier(tableName)} SET ${sql.identifier(DOC_COLUMN$1)} = ${JSON.stringify(merged)} WHERE id = ${id} AND ${sql.identifier(DOC_COLUMN$1)} = ${existingJson}`
1259
+ );
1260
+ syncSearch(tableName, id, merged);
1261
+ syncAggregates(tableName, existing, merged);
1262
+ syncRanks(tableName, id, existing, void 0);
1263
+ cache?.invalidate(tableName, id);
1264
+ recordCdc(tableName, id, "update", merged);
1265
+ broadcast({ key: id, op: "update", row: merged, table: tableName });
1266
+ if (hasMatchingTrigger(tableName, "after", "delete")) {
1267
+ await fireTriggers("after", "delete", { id, op: "delete", previous: existing, table: tableName });
1268
+ }
1269
+ await onWrite({ id, op: "delete", table: tableName });
1270
+ return;
1271
+ }
1233
1272
  runGuardedWrite(
1234
1273
  sql$1,
1235
1274
  tableName,
@@ -1271,7 +1310,8 @@ const createShardCtxDb = (options) => {
1271
1310
  onRead(tableName, SCAN_DEP);
1272
1311
  return global.findMany(tableName, args);
1273
1312
  }
1274
- if (!schema.tables[tableName]) {
1313
+ const findManyDefinition = schema.tables[tableName];
1314
+ if (!findManyDefinition) {
1275
1315
  throw new Error(`unknown table: ${tableName}`);
1276
1316
  }
1277
1317
  const isFullScan = !args.where && !args.baseWhere;
@@ -1283,6 +1323,7 @@ const createShardCtxDb = (options) => {
1283
1323
  const orderKeys = normalizeOrderKeys(args.orderBy);
1284
1324
  const seek = args.cursor ? buildSeekWhere(orderKeys, decodeCursor(args.cursor)) : void 0;
1285
1325
  let predicate = mergeWhere(args.baseWhere, args.where);
1326
+ predicate = mergeWhere(predicate, softDeleteScope(findManyDefinition.softDeleteMode, args.includeDeleted));
1286
1327
  predicate = await resolveRelationPredicates(predicate, {
1287
1328
  canPushExists: relationExistsPushDownEnabled ? canPushRelationExists : void 0,
1288
1329
  existsPushMode: relationExistsPushDown === "always" ? "always" : "auto",
@@ -1329,7 +1370,7 @@ const createShardCtxDb = (options) => {
1329
1370
  with: args.with
1330
1371
  });
1331
1372
  }
1332
- return { continueCursor: null, isDone: true, page: docs };
1373
+ return { continueCursor: null, isDone: true, page: applySelect(docs, args.select, args.with) };
1333
1374
  }
1334
1375
  const hasMore = docs.length > limit;
1335
1376
  const page = hasMore ? docs.slice(0, limit) : docs;
@@ -1346,10 +1387,12 @@ const createShardCtxDb = (options) => {
1346
1387
  });
1347
1388
  }
1348
1389
  return {
1390
+ // The cursor is encoded from `last` (the full, unprojected row) above,
1391
+ // so `applySelect` only trims the returned payload — paging is intact.
1349
1392
  // eslint-disable-next-line unicorn/no-null -- QueryPage.continueCursor is `null | string`: null is the documented "no further page" cursor on the wire
1350
1393
  continueCursor: hasMore && last ? encodeCursor(last, orderKeys) : null,
1351
1394
  isDone: !hasMore,
1352
- page
1395
+ page: applySelect(page, args.select, args.with)
1353
1396
  };
1354
1397
  },
1355
1398
  async get(id, expectedTable) {
@@ -1390,10 +1433,11 @@ const createShardCtxDb = (options) => {
1390
1433
  if (agg.op !== "count" && !agg.field) {
1391
1434
  throw new Error(`groupBy(${tableName}, { agg: { op: "${agg.op}" } }): "field" is required for non-count reducers`);
1392
1435
  }
1393
- const effective = mergeWhere(groupOptions.baseWhere, groupOptions.where);
1436
+ const groupScope = softDeleteScope(definition.softDeleteMode, void 0);
1437
+ const effective = mergeWhere(mergeWhere(groupOptions.baseWhere, groupOptions.where), groupScope);
1394
1438
  const resolved = await resolveAggregateRelations(effective, tableName, groupOptions.relationBaseWhere);
1395
1439
  const hasRelation = resolved !== effective;
1396
- if (definition.aggregateIndexes && !groupOptions.baseWhere && !hasRelation) {
1440
+ if (definition.aggregateIndexes && !groupOptions.baseWhere && !hasRelation && !groupScope) {
1397
1441
  const planned = selectIndexForGroupBy(definition.aggregateIndexes, agg.op, agg.field, groupOptions.by, groupOptions.where);
1398
1442
  if (planned) {
1399
1443
  ensureBackfilled(tableName, planned.index);
@@ -1696,6 +1740,26 @@ const createShardCtxDb = (options) => {
1696
1740
  const { directions, hasMore, rows } = computeRankPage(rankPageDeps, tableName, indexName, rankPageOptions);
1697
1741
  return { directions, hasMore, rows };
1698
1742
  },
1743
+ async restore(id, expectedTable) {
1744
+ const located = locateRowById(id, expectedTable);
1745
+ if (!located) {
1746
+ const global = expectedTable === void 0 ? globalFallback() : void 0;
1747
+ if (global?.restore) {
1748
+ await global.restore(id);
1749
+ return;
1750
+ }
1751
+ throw new Error(`document not found: ${id}`);
1752
+ }
1753
+ const field = schema.tables[located.tableName]?.softDeleteMode?.field;
1754
+ if (!field) {
1755
+ throw new Error(`ctx.db.restore: table "${located.tableName}" is not a .softDelete() table`);
1756
+ }
1757
+ const wasDeleted = located.row[field] !== null && located.row[field] !== void 0;
1758
+ await writer.patch(id, { [field]: null }, expectedTable);
1759
+ if (wasDeleted) {
1760
+ syncRanks(located.tableName, id, void 0, located.row);
1761
+ }
1762
+ },
1699
1763
  async replace(id, document, expectedTable) {
1700
1764
  const located = locateRowById(id, expectedTable);
1701
1765
  if (!located) {
@@ -47,9 +47,9 @@ const guardWriter = (raw, schema, tableOfId) => {
47
47
  guardTable(tableName);
48
48
  return base.count(tableName, whereOrArgs);
49
49
  },
50
- delete: async (id, expectedTable) => {
50
+ delete: async (id, expectedTable, options) => {
51
51
  await guardById(id, expectedTable);
52
- return base.delete(id, expectedTable);
52
+ return base.delete(id, expectedTable, options);
53
53
  },
54
54
  deleteMany: async (ids, options, expectedTable) => {
55
55
  for (const id of ids) {
@@ -114,6 +114,10 @@ const guardWriter = (raw, schema, tableOfId) => {
114
114
  replace: async (id, document, expectedTable) => {
115
115
  await guardById(id, expectedTable);
116
116
  return base.replace(id, document, expectedTable);
117
+ },
118
+ restore: async (id, expectedTable) => {
119
+ await guardById(id, expectedTable);
120
+ return base.restore?.(id, expectedTable);
117
121
  }
118
122
  };
119
123
  if (baseRankBefore) {