@atscript/utils-db 0.1.30 → 0.1.32

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.ts CHANGED
@@ -1,7 +1,53 @@
1
- import { TAtscriptAnnotatedType, TValidatorPlugin, TMetadataMap, TAtscriptDataType, Validator, TAtscriptTypeObject, TValidatorOptions, TAtscriptTypeArray } from '@atscript/typescript/utils';
2
- import { FilterExpr, Uniquery, UniqueryControls } from '@uniqu/core';
1
+ import { TAtscriptAnnotatedType, TValidatorPlugin, TMetadataMap, TAtscriptDataType, FlatOf, PrimaryKeyOf, Validator, TAtscriptTypeObject, TValidatorOptions, TAtscriptTypeArray } from '@atscript/typescript/utils';
2
+ import { UniqueryControls, FilterExpr, Uniquery } from '@uniqu/core';
3
3
  export { FieldOpsFor, FilterExpr, FilterVisitor, Uniquery, UniqueryControls, isPrimitive, walkFilter } from '@uniqu/core';
4
4
 
5
+ /**
6
+ * Wraps a raw `$select` value and provides lazy-cached conversions
7
+ * to the forms different adapters need.
8
+ *
9
+ * Only instantiated when `$select` is actually provided —
10
+ * `controls.$select` is `UniquSelect | undefined`.
11
+ *
12
+ * For exclusion → inclusion inversion, pass `allFields` (physical field names).
13
+ */
14
+ declare class UniquSelect {
15
+ private _raw;
16
+ private _allFields?;
17
+ private _arrayResolved;
18
+ private _array?;
19
+ private _projectionResolved;
20
+ private _projection?;
21
+ constructor(raw: UniqueryControls['$select'], allFields?: string[]);
22
+ /**
23
+ * Resolved inclusion array of field names.
24
+ * For exclusion form, inverts using `allFields` from constructor.
25
+ */
26
+ get asArray(): string[] | undefined;
27
+ /**
28
+ * Record projection preserving original semantics.
29
+ * Returns original object as-is if raw was object.
30
+ * Converts `string[]` to `{field: 1}` inclusion object.
31
+ */
32
+ get asProjection(): Record<string, 0 | 1> | undefined;
33
+ }
34
+
35
+ /** Controls with resolved projection. Used in the adapter interface. */
36
+ interface DbControls extends Omit<UniqueryControls, '$select'> {
37
+ $select?: UniquSelect;
38
+ }
39
+ /** Query object with resolved projection. Passed to adapter methods. */
40
+ interface DbQuery {
41
+ filter: FilterExpr;
42
+ controls: DbControls;
43
+ }
44
+ /** Describes an available search index exposed by a database adapter. */
45
+ interface TSearchIndexInfo {
46
+ /** Index name. Empty string or 'DEFAULT' for the default index. */
47
+ name: string;
48
+ /** Human-readable label for UI display. */
49
+ description?: string;
50
+ }
5
51
  interface TDbInsertResult {
6
52
  insertedId: unknown;
7
53
  }
@@ -16,9 +62,11 @@ interface TDbUpdateResult {
16
62
  interface TDbDeleteResult {
17
63
  deletedCount: number;
18
64
  }
65
+ type TDbIndexType = 'plain' | 'unique' | 'fulltext';
19
66
  interface TDbIndexField {
20
67
  name: string;
21
68
  sort: 'asc' | 'desc';
69
+ weight?: number;
22
70
  }
23
71
  interface TDbIndex {
24
72
  /** Unique key used for identity/diffing (e.g., "atscript__plain__email") */
@@ -26,16 +74,17 @@ interface TDbIndex {
26
74
  /** Human-readable index name. */
27
75
  name: string;
28
76
  /** Index type. */
29
- type: 'plain' | 'unique' | 'fulltext';
77
+ type: TDbIndexType;
30
78
  /** Ordered list of fields in the index. */
31
79
  fields: TDbIndexField[];
32
80
  }
81
+ type TDbDefaultFn = 'increment' | 'uuid' | 'now';
33
82
  type TDbDefaultValue = {
34
83
  kind: 'value';
35
84
  value: string;
36
85
  } | {
37
86
  kind: 'fn';
38
- fn: 'increment' | 'uuid' | 'now';
87
+ fn: TDbDefaultFn;
39
88
  };
40
89
  interface TIdDescriptor {
41
90
  /** Field names that form the primary key. */
@@ -43,14 +92,15 @@ interface TIdDescriptor {
43
92
  /** Whether this is a composite key (multiple fields). */
44
93
  isComposite: boolean;
45
94
  }
95
+ type TDbStorageType = 'column' | 'flattened' | 'json';
46
96
  interface TDbFieldMeta {
47
97
  /** The dot-notation path to this field (logical name). */
48
98
  path: string;
49
99
  /** The annotated type for this field. */
50
100
  type: TAtscriptAnnotatedType;
51
- /** Physical column/field name (from @db.column, or same as path). */
101
+ /** Physical column/field name (from @db.column, __-separated for flattened, or same as path). */
52
102
  physicalName: string;
53
- /** Resolved design type: 'string', 'number', 'boolean', 'object', etc. */
103
+ /** Resolved design type: 'string', 'number', 'boolean', 'object', 'json', etc. */
54
104
  designType: string;
55
105
  /** Whether the field is optional. */
56
106
  optional: boolean;
@@ -60,6 +110,19 @@ interface TDbFieldMeta {
60
110
  ignored: boolean;
61
111
  /** Default value from @db.default.* */
62
112
  defaultValue?: TDbDefaultValue;
113
+ /**
114
+ * How this field is stored in the database.
115
+ * - 'column': a standard scalar column (default for primitives)
116
+ * - 'flattened': a leaf scalar from a flattened nested object
117
+ * - 'json': stored as a single JSON column (arrays, @db.json fields)
118
+ */
119
+ storage: TDbStorageType;
120
+ /**
121
+ * For flattened fields: the dot-notation path (same as `path`).
122
+ * E.g., for physicalName 'contact__email', this is 'contact.email'.
123
+ * Undefined for non-flattened fields.
124
+ */
125
+ flattenedFrom?: string;
63
126
  }
64
127
 
65
128
  /**
@@ -114,6 +177,13 @@ declare abstract class BaseDbAdapter {
114
177
  * {@link nativePatch} instead of using the generic decomposition.
115
178
  */
116
179
  supportsNativePatch(): boolean;
180
+ /**
181
+ * Whether this adapter handles nested objects natively.
182
+ * When `true`, the generic layer skips flattening and
183
+ * passes nested objects as-is to the adapter.
184
+ * MongoDB returns `true`; relational adapters return `false` (default).
185
+ */
186
+ supportsNestedObjects(): boolean;
117
187
  /**
118
188
  * Applies a patch payload using native database operations.
119
189
  * Only called when {@link supportsNativePatch} returns `true`.
@@ -123,6 +193,24 @@ declare abstract class BaseDbAdapter {
123
193
  * @returns Update result.
124
194
  */
125
195
  nativePatch(filter: FilterExpr, patch: unknown): Promise<TDbUpdateResult>;
196
+ /**
197
+ * Builds a custom insert validator for this adapter.
198
+ * When defined, {@link AtscriptDbTable} uses this instead of the default
199
+ * insert validator (which makes all primary keys optional).
200
+ *
201
+ * Example: MongoDB only makes ObjectId primary keys optional (auto-generated),
202
+ * but string/number IDs remain required.
203
+ */
204
+ buildInsertValidator?(table: AtscriptDbTable): any;
205
+ /**
206
+ * Builds a custom patch validator for this adapter.
207
+ * When defined, {@link AtscriptDbTable} uses this instead of the default
208
+ * partial validator for the `'patch'` purpose.
209
+ *
210
+ * Example: MongoDB wraps top-level array fields with `$replace`/`$insert`/…
211
+ * patch operators that the default validator doesn't understand.
212
+ */
213
+ buildPatchValidator?(table: AtscriptDbTable): any;
126
214
  /**
127
215
  * Called before field flattening begins.
128
216
  * Use to extract table-level adapter-specific annotations.
@@ -134,7 +222,7 @@ declare abstract class BaseDbAdapter {
134
222
  * Called for each field during flattening.
135
223
  * Use to extract field-level adapter-specific annotations.
136
224
  *
137
- * Example: MongoDB adapter extracts `@db.mongo.index.text`, `@db.mongo.search.vector`.
225
+ * Example: MongoDB adapter extracts `@db.mongo.search.vector`, `@db.mongo.search.text`.
138
226
  */
139
227
  onFieldScanned?(field: string, type: TAtscriptAnnotatedType, metadata: TMetadataMap<AtscriptMetadata>): void;
140
228
  /**
@@ -189,14 +277,51 @@ declare abstract class BaseDbAdapter {
189
277
  prefix?: string;
190
278
  shouldSkipType?(type: TDbIndex['type']): boolean;
191
279
  }): Promise<void>;
280
+ /**
281
+ * Returns available search indexes for this adapter.
282
+ * UI uses this to show index picker. Override in adapters that support search.
283
+ */
284
+ getSearchIndexes(): TSearchIndexInfo[];
285
+ /**
286
+ * Whether this adapter supports text search.
287
+ * Default: `true` when {@link getSearchIndexes} returns any entries.
288
+ */
289
+ isSearchable(): boolean;
290
+ /**
291
+ * Full-text search. Override in adapters that support search.
292
+ *
293
+ * @param text - Search text.
294
+ * @param query - Filter, sort, limit, etc.
295
+ * @param indexName - Optional search index to target.
296
+ */
297
+ search(text: string, query: DbQuery, indexName?: string): Promise<Array<Record<string, unknown>>>;
298
+ /**
299
+ * Full-text search with count (for paginated search results).
300
+ *
301
+ * @param text - Search text.
302
+ * @param query - Filter, sort, limit, etc.
303
+ * @param indexName - Optional search index to target.
304
+ */
305
+ searchWithCount(text: string, query: DbQuery, indexName?: string): Promise<{
306
+ data: Array<Record<string, unknown>>;
307
+ count: number;
308
+ }>;
309
+ /**
310
+ * Fetches records and total count in one call.
311
+ * Default: two parallel calls. Adapters may override for single-query optimization.
312
+ */
313
+ findManyWithCount(query: DbQuery): Promise<{
314
+ data: Array<Record<string, unknown>>;
315
+ count: number;
316
+ }>;
192
317
  abstract insertOne(data: Record<string, unknown>): Promise<TDbInsertResult>;
193
318
  abstract insertMany(data: Array<Record<string, unknown>>): Promise<TDbInsertManyResult>;
194
319
  abstract replaceOne(filter: FilterExpr, data: Record<string, unknown>): Promise<TDbUpdateResult>;
195
320
  abstract updateOne(filter: FilterExpr, data: Record<string, unknown>): Promise<TDbUpdateResult>;
196
321
  abstract deleteOne(filter: FilterExpr): Promise<TDbDeleteResult>;
197
- abstract findOne(query: Uniquery): Promise<Record<string, unknown> | null>;
198
- abstract findMany(query: Uniquery): Promise<Array<Record<string, unknown>>>;
199
- abstract count(query: Uniquery): Promise<number>;
322
+ abstract findOne(query: DbQuery): Promise<Record<string, unknown> | null>;
323
+ abstract findMany(query: DbQuery): Promise<Array<Record<string, unknown>>>;
324
+ abstract count(query: DbQuery): Promise<number>;
200
325
  abstract updateMany(filter: FilterExpr, data: Record<string, unknown>): Promise<TDbUpdateResult>;
201
326
  abstract replaceMany(filter: FilterExpr, data: Record<string, unknown>): Promise<TDbUpdateResult>;
202
327
  abstract deleteMany(filter: FilterExpr): Promise<TDbDeleteResult>;
@@ -247,9 +372,9 @@ declare function resolveDesignType(fieldType: TAtscriptAnnotatedType): string;
247
372
  * @typeParam T - The Atscript annotated type for this table.
248
373
  * @typeParam DataType - The inferred data shape from the annotated type.
249
374
  */
250
- declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnotatedType, DataType = TAtscriptDataType<T>> {
375
+ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnotatedType, DataType = TAtscriptDataType<T>, FlatType = FlatOf<T>, A extends BaseDbAdapter = BaseDbAdapter, IdType = PrimaryKeyOf<T>> {
251
376
  protected readonly _type: T;
252
- protected readonly adapter: BaseDbAdapter;
377
+ protected readonly adapter: A;
253
378
  protected readonly logger: TGenericLogger;
254
379
  /** Resolved table/collection name. */
255
380
  readonly tableName: string;
@@ -263,8 +388,28 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
263
388
  protected _defaults: Map<string, TDbDefaultValue>;
264
389
  protected _ignoredFields: Set<string>;
265
390
  protected _uniqueProps: Set<string>;
391
+ /** Logical dot-path → physical column name. */
392
+ protected _pathToPhysical: Map<string, string>;
393
+ /** Physical column name → logical dot-path (inverse). */
394
+ protected _physicalToPath: Map<string, string>;
395
+ /** Object paths being flattened into __-separated columns (no column themselves). */
396
+ protected _flattenedParents: Set<string>;
397
+ /** Fields stored as JSON (@db.json + array fields). */
398
+ protected _jsonFields: Set<string>;
399
+ /** Intermediate paths → their leaf physical column names (for $select expansion in relational DBs). */
400
+ protected _selectExpansion: Map<string, string[]>;
401
+ /** Physical column names of boolean fields (for storage coercion on read). */
402
+ protected _booleanFields: Set<string>;
403
+ /** Fast-path flag: skip all mapping when no nested/json fields exist. */
404
+ protected _requiresMappings: boolean;
405
+ /** All non-ignored physical field names (for UniquSelect exclusion inversion). */
406
+ protected _allPhysicalFields: string[];
407
+ /** Cached result of adapter.supportsNestedObjects(). */
408
+ protected readonly _nestedObjects: boolean;
266
409
  protected readonly validators: Map<string, Validator<T, DataType>>;
267
- constructor(_type: T, adapter: BaseDbAdapter, logger?: TGenericLogger);
410
+ constructor(_type: T, adapter: A, logger?: TGenericLogger);
411
+ /** Returns the underlying adapter with its concrete type preserved. */
412
+ getAdapter(): A;
268
413
  /** The raw annotated type. */
269
414
  get type(): TAtscriptAnnotatedType<TAtscriptTypeObject>;
270
415
  /** Lazily-built flat map of all fields (dot-notation paths → annotated types). */
@@ -273,6 +418,25 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
273
418
  get indexes(): Map<string, TDbIndex>;
274
419
  /** Primary key field names from `@meta.id`. */
275
420
  get primaryKeys(): readonly string[];
421
+ /**
422
+ * Registers an additional primary key field.
423
+ * Useful for adapters (e.g., MongoDB) where `_id` is always the primary key
424
+ * even without an explicit `@meta.id` annotation.
425
+ *
426
+ * Typically called from {@link BaseDbAdapter.onFieldScanned}.
427
+ */
428
+ addPrimaryKey(field: string): void;
429
+ /**
430
+ * Removes a field from the primary key list.
431
+ * Useful for adapters (e.g., MongoDB) where `@meta.id` fields should be
432
+ * unique indexes rather than part of the primary key.
433
+ */
434
+ removePrimaryKey(field: string): void;
435
+ /**
436
+ * Registers a field as having a unique constraint.
437
+ * Used by adapters to ensure `findById` falls back to this field.
438
+ */
439
+ addUniqueField(field: string): void;
276
440
  /** Logical → physical column name mapping from `@db.column`. */
277
441
  get columnMap(): ReadonlyMap<string, string>;
278
442
  /** Default values from `@db.default.*`. */
@@ -281,6 +445,10 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
281
445
  get ignoredFields(): ReadonlySet<string>;
282
446
  /** Single-field unique index properties. */
283
447
  get uniqueProps(): ReadonlySet<string>;
448
+ /** Precomputed logical dot-path → physical column name map. */
449
+ get pathToPhysical(): ReadonlyMap<string, string>;
450
+ /** Precomputed physical column name → logical dot-path map (inverse). */
451
+ get physicalToPath(): ReadonlyMap<string, string>;
284
452
  /** Descriptor for the primary ID field(s). */
285
453
  getIdDescriptor(): TIdDescriptor;
286
454
  /**
@@ -289,14 +457,6 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
289
457
  * encapsulating all the type introspection gotchas.
290
458
  */
291
459
  get fieldDescriptors(): readonly TDbFieldMeta[];
292
- /**
293
- * Resolves `$select` from {@link UniqueryControls} to a list of field names.
294
- * - `undefined` → `undefined` (all fields)
295
- * - `string[]` → pass through
296
- * - `Record<K, 1>` → extract included keys
297
- * - `Record<K, 0>` → invert using known field names
298
- */
299
- resolveProjection(select?: UniqueryControls['$select']): string[] | undefined;
300
460
  /**
301
461
  * Creates a new validator with custom options.
302
462
  * Adapter plugins are NOT automatically included — use {@link getValidator}
@@ -334,22 +494,63 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
334
494
  /**
335
495
  * Deletes a single record by primary key value.
336
496
  */
337
- deleteOne(id: unknown): Promise<TDbDeleteResult>;
497
+ deleteOne(id: IdType): Promise<TDbDeleteResult>;
338
498
  /**
339
499
  * Finds a single record matching the query.
340
500
  */
341
- findOne(query: Uniquery<DataType>): Promise<DataType | null>;
501
+ findOne(query: Uniquery<FlatType>): Promise<DataType | null>;
342
502
  /**
343
503
  * Finds all records matching the query.
344
504
  */
345
- findMany(query: Uniquery<DataType>): Promise<DataType[]>;
505
+ findMany(query: Uniquery<FlatType>): Promise<DataType[]>;
346
506
  /**
347
507
  * Counts records matching the query.
348
508
  */
349
- count(query?: Uniquery<DataType>): Promise<number>;
350
- updateMany(filter: FilterExpr<DataType>, data: Partial<DataType> & Record<string, unknown>): Promise<TDbUpdateResult>;
351
- replaceMany(filter: FilterExpr<DataType>, data: Record<string, unknown>): Promise<TDbUpdateResult>;
352
- deleteMany(filter: FilterExpr<DataType>): Promise<TDbDeleteResult>;
509
+ count(query?: Uniquery<FlatType>): Promise<number>;
510
+ /**
511
+ * Finds records and total count in a single logical call.
512
+ * Adapters may optimize into a single query (e.g., MongoDB `$facet`).
513
+ */
514
+ findManyWithCount(query: Uniquery<FlatType>): Promise<{
515
+ data: DataType[];
516
+ count: number;
517
+ }>;
518
+ /** Whether the underlying adapter supports text search. */
519
+ isSearchable(): boolean;
520
+ /** Returns available search indexes from the adapter. */
521
+ getSearchIndexes(): TSearchIndexInfo[];
522
+ /**
523
+ * Full-text search with query translation and result reconstruction.
524
+ *
525
+ * @param text - Search text.
526
+ * @param query - Filter, sort, limit, etc.
527
+ * @param indexName - Optional search index to target.
528
+ */
529
+ search(text: string, query: Uniquery<FlatType>, indexName?: string): Promise<DataType[]>;
530
+ /**
531
+ * Full-text search with count for paginated search results.
532
+ *
533
+ * @param text - Search text.
534
+ * @param query - Filter, sort, limit, etc.
535
+ * @param indexName - Optional search index to target.
536
+ */
537
+ searchWithCount(text: string, query: Uniquery<FlatType>, indexName?: string): Promise<{
538
+ data: DataType[];
539
+ count: number;
540
+ }>;
541
+ /**
542
+ * Finds a single record by primary key or unique property.
543
+ *
544
+ * 1. Tries primary key lookup (single or composite).
545
+ * 2. Falls back to unique properties if PK validation fails.
546
+ *
547
+ * @param id - Primary key value (scalar for single PK, object for composite).
548
+ * @param controls - Optional query controls ($select, etc.).
549
+ */
550
+ findById(id: unknown, controls?: UniqueryControls<FlatType>): Promise<DataType | null>;
551
+ updateMany(filter: FilterExpr<FlatType>, data: Partial<DataType> & Record<string, unknown>): Promise<TDbUpdateResult>;
552
+ replaceMany(filter: FilterExpr<FlatType>, data: Record<string, unknown>): Promise<TDbUpdateResult>;
553
+ deleteMany(filter: FilterExpr<FlatType>): Promise<TDbDeleteResult>;
353
554
  /**
354
555
  * Synchronizes indexes between Atscript definitions and the database.
355
556
  * Delegates to the adapter, which uses `this._table.indexes`.
@@ -364,7 +565,21 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
364
565
  * Scans `@db.*` and `@meta.id` annotations on a field during flattening.
365
566
  */
366
567
  private _scanGenericAnnotations;
367
- protected _addIndexField(type: TDbIndex['type'], name: string, field: string, sort?: 'asc' | 'desc'): void;
568
+ protected _addIndexField(type: TDbIndex['type'], name: string, field: string, opts?: {
569
+ sort?: 'asc' | 'desc';
570
+ weight?: number;
571
+ }): void;
572
+ /**
573
+ * Classifies each field as column, flattened, json, or parent-object.
574
+ * Builds the bidirectional _pathToPhysical / _physicalToPath maps.
575
+ * Only called when the adapter does NOT support nested objects natively.
576
+ */
577
+ private _classifyFields;
578
+ /**
579
+ * Finds the nearest ancestor of `path` that belongs to `set`.
580
+ * Used to locate flattened parents and @db.json ancestors.
581
+ */
582
+ private _findAncestorInSet;
368
583
  private _finalizeIndexes;
369
584
  /**
370
585
  * Applies default values for fields that are missing from the payload.
@@ -373,10 +588,62 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
373
588
  protected _applyDefaults(data: Record<string, unknown>): Record<string, unknown>;
374
589
  /**
375
590
  * Prepares a payload for writing to the database:
376
- * prepares IDs, strips ignored fields, maps column names.
591
+ * prepares IDs, strips ignored fields, flattens nested objects, maps column names.
377
592
  * Defaults should be applied before this via `_applyDefaults`.
378
593
  */
379
594
  protected _prepareForWrite(payload: Record<string, unknown>): Record<string, unknown>;
595
+ /**
596
+ * Flattens nested object fields into __-separated keys and
597
+ * JSON-stringifies @db.json / array fields.
598
+ * Uses _pathToPhysical for final key names.
599
+ */
600
+ private _flattenPayload;
601
+ /**
602
+ * Classifies and writes a single field to the result object.
603
+ * Recurses into nested objects that should be flattened.
604
+ */
605
+ private _writeFlattenedField;
606
+ /**
607
+ * When a parent object is null/undefined, set all its flattened children to null.
608
+ */
609
+ private _setFlattenedChildrenNull;
610
+ /**
611
+ * Reconstructs nested objects from flat __-separated column values.
612
+ * JSON fields are parsed from strings back to objects/arrays.
613
+ */
614
+ protected _reconstructFromRead(row: Record<string, unknown>): Record<string, unknown>;
615
+ /**
616
+ * Coerces boolean fields from storage representation (0/1) to JS booleans.
617
+ * Used on the fast-path when no column mapping is needed.
618
+ */
619
+ private _coerceBooleans;
620
+ /**
621
+ * Sets a value at a dot-notation path, creating intermediate objects as needed.
622
+ */
623
+ private _setNestedValue;
624
+ /**
625
+ * If all children of a flattened parent are null, collapse the parent to null.
626
+ */
627
+ private _reconstructNullParent;
628
+ /**
629
+ * Translates a Uniquery's filter, sort, and projection from logical
630
+ * dot-notation paths to physical column names.
631
+ * Always wraps `$select` in {@link UniquSelect}.
632
+ */
633
+ private _translateQuery;
634
+ /**
635
+ * Recursively translates field names in a filter expression.
636
+ */
637
+ private _translateFilter;
638
+ /**
639
+ * Translates field names in sort and projection controls.
640
+ * Wraps `$select` in {@link UniquSelect} after path translation.
641
+ */
642
+ private _translateControls;
643
+ /**
644
+ * Translates dot-notation keys in a decomposed patch to physical column names.
645
+ */
646
+ private _translatePatchKeys;
380
647
  /**
381
648
  * Extracts primary key field(s) from a payload to build a filter.
382
649
  */
@@ -431,5 +698,5 @@ type TDbPatch<T> = {
431
698
  */
432
699
  declare function getKeyProps(def: TAtscriptAnnotatedType<TAtscriptTypeArray>): Set<string>;
433
700
 
434
- export { AtscriptDbTable, BaseDbAdapter, NoopLogger, decomposePatch, getKeyProps, resolveDesignType };
435
- export type { TArrayPatch, TDbDefaultValue, TDbDeleteResult, TDbFieldMeta, TDbIndex, TDbIndexField, TDbInsertManyResult, TDbInsertResult, TDbPatch, TDbUpdateResult, TGenericLogger, TIdDescriptor };
701
+ export { AtscriptDbTable, BaseDbAdapter, NoopLogger, UniquSelect, decomposePatch, getKeyProps, resolveDesignType };
702
+ export type { DbControls, DbQuery, TArrayPatch, TDbDefaultFn, TDbDefaultValue, TDbDeleteResult, TDbFieldMeta, TDbIndex, TDbIndexField, TDbIndexType, TDbInsertManyResult, TDbInsertResult, TDbPatch, TDbStorageType, TDbUpdateResult, TGenericLogger, TIdDescriptor, TSearchIndexInfo };