@atscript/db 0.1.145 → 0.1.147
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/agg.cjs +1 -1
- package/dist/agg.d.cts +1 -1
- package/dist/agg.d.mts +1 -1
- package/dist/agg.mjs +1 -1
- package/dist/{aggregate-fns-CfsveE1w.mjs → aggregate-fns-C0BymEqa.mjs} +3 -1
- package/dist/{aggregate-fns-CGBv3E8S.cjs → aggregate-fns-CtsRbZn9.cjs} +8 -0
- package/dist/{buckets-DYFu0eZ8.d.cts → buckets-CjdPipCC.d.cts} +522 -17
- package/dist/{buckets-DRycmhOW.d.mts → buckets-DYopfd2Y.d.mts} +522 -17
- package/dist/{column-diff-e2oHc71_.mjs → column-diff-CO06iQvI.mjs} +862 -115
- package/dist/{column-diff-D_Kyuh0S.cjs → column-diff-Dt7EDJsA.cjs} +872 -113
- package/dist/{column-diff-Q9UmWn5x.d.mts → fk-diff-BtOmL4OW.d.mts} +48 -2
- package/dist/{column-diff-w-Mym_3w.d.cts → fk-diff-DLqwVkKG.d.cts} +48 -2
- package/dist/index.cjs +28 -33
- package/dist/index.d.cts +40 -15
- package/dist/index.d.mts +40 -15
- package/dist/index.mjs +5 -33
- package/dist/{nested-writer-CnOOAehr.mjs → nested-writer-D35UsDBT.mjs} +542 -2
- package/dist/{nested-writer-xfQwxplL.cjs → nested-writer-SqtYJHF0.cjs} +666 -0
- package/dist/plugin.cjs +266 -5
- package/dist/plugin.mjs +267 -6
- package/dist/rel.cjs +2 -2
- package/dist/rel.d.cts +2 -2
- package/dist/rel.d.mts +2 -2
- package/dist/rel.mjs +2 -2
- package/dist/{relation-helpers-B-0NRKat.d.mts → relation-helpers-C2bLtE-t.d.mts} +1 -1
- package/dist/{relation-helpers-BOMm_HUI.d.cts → relation-helpers-DH3LvwLV.d.cts} +1 -1
- package/dist/relation-loader-BFhVuJ-B.cjs +369 -0
- package/dist/relation-loader-C0qE8xgR.mjs +370 -0
- package/dist/shared.cjs +1 -1
- package/dist/shared.d.cts +4 -3
- package/dist/shared.d.mts +4 -3
- package/dist/shared.mjs +1 -1
- package/dist/sync.cjs +10 -6
- package/dist/sync.d.cts +2 -25
- package/dist/sync.d.mts +2 -25
- package/dist/sync.mjs +10 -6
- package/dist/{validation-utils-DOsB4e6G.cjs → validation-utils-Da2GjobR.cjs} +35 -24
- package/dist/{validation-utils-CMR4fe2M.mjs → validation-utils-Dq0uZ7ef.mjs} +35 -24
- package/dist/{validator-Bw6ks9Hy.d.mts → validator-CMnTI6r7.d.cts} +9 -6
- package/dist/{validator-Bw6ks9Hy.d.cts → validator-CMnTI6r7.d.mts} +9 -6
- package/dist/validator.d.cts +1 -1
- package/dist/validator.d.mts +1 -1
- package/package.json +8 -8
- package/dist/relation-loader-CBPY6kM7.cjs +0 -461
- package/dist/relation-loader-D9XuXaMv.mjs +0 -462
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { f as TFieldOps } from "./ops-AqhV7s9o.cjs";
|
|
2
|
-
import { AggregateControls, AggregateExpr, AggregateExpr as AggregateExpr$1, AggregateFn, AggregateFn as AggregateFn$1, AggregateQuery, AggregateQuery as AggregateQuery$1, AggregateResult, BucketUnit, FieldOpsFor, FilterExpr, FilterExpr as FilterExpr$1, ResolvedBucket, TypedWithRelation, Uniquery, Uniquery as Uniquery$1, UniqueryControls, UniqueryControls as UniqueryControls$1, UniqueryInsights, WithRelation, WithRelation as WithRelation$1 } from "@uniqu/core";
|
|
3
|
-
import { AtscriptQueryComparison, AtscriptQueryFieldRef, AtscriptQueryFieldRef as AtscriptQueryFieldRef$1, AtscriptQueryNode, AtscriptQueryNode as AtscriptQueryNode$1, AtscriptRef, FlatOf, FlatOf as FlatOf$1, NavPropsOf, NavPropsOf as NavPropsOf$1, OwnPropsOf, OwnPropsOf as OwnPropsOf$1, PrimaryKeyOf, PrimaryKeyOf as PrimaryKeyOf$1, TAtscriptAnnotatedType, TAtscriptDataType, TAtscriptTypeObject, TMetadataMap, TSerializedAnnotatedType, TValidatorOptions, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
|
|
2
|
+
import { AggregateControls, AggregateExpr, AggregateExpr as AggregateExpr$1, AggregateFn, AggregateFn as AggregateFn$1, AggregateQuery, AggregateQuery as AggregateQuery$1, AggregateResult, BucketUnit, FieldOpsFor, FilterExpr, FilterExpr as FilterExpr$1, RelationOp, ResolvedBucket, TypedWithRelation, Uniquery, Uniquery as Uniquery$1, UniqueryControls, UniqueryControls as UniqueryControls$1, UniqueryInsights, WithRelation, WithRelation as WithRelation$1 } from "@uniqu/core";
|
|
3
|
+
import { AtscriptExprNode, AtscriptExprNode as AtscriptExprNode$1, AtscriptOrderItem, AtscriptQueryComparison, AtscriptQueryFieldRef, AtscriptQueryFieldRef as AtscriptQueryFieldRef$1, AtscriptQueryNode, AtscriptQueryNode as AtscriptQueryNode$1, AtscriptRef, FlatOf, FlatOf as FlatOf$1, NavPropsOf, NavPropsOf as NavPropsOf$1, OwnPropsOf, OwnPropsOf as OwnPropsOf$1, PrimaryKeyOf, PrimaryKeyOf as PrimaryKeyOf$1, TAtscriptAnnotatedType, TAtscriptDataType, TAtscriptTypeObject, TMetadataMap, TSerializedAnnotatedType, TValidatorOptions, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
|
|
4
4
|
|
|
5
5
|
//#region src/query/uniqu-select.d.ts
|
|
6
6
|
/**
|
|
@@ -146,14 +146,30 @@ declare abstract class FieldMappingStrategy {
|
|
|
146
146
|
/** `$sort` with physical keys; computed `aliases` (grouped queries) pass through. */
|
|
147
147
|
protected physicalSort(sort: NonNullable<DbControls["$sort"]>, meta: TableMetadata, aliases?: ReadonlySet<string>): DbControls["$sort"];
|
|
148
148
|
/**
|
|
149
|
-
*
|
|
150
|
-
* (
|
|
151
|
-
*
|
|
149
|
+
* Translates a logical filter for the adapter: relational predicates are
|
|
150
|
+
* resolved first (`resolveRelationFilterTree`), then every key and value
|
|
151
|
+
* goes through {@link translateResolvedFilter}. `depth` is the predicate
|
|
152
|
+
* level of `filter` itself (0 for a query's own filter; the related tables
|
|
153
|
+
* translate predicate operands at deeper levels).
|
|
154
|
+
*/
|
|
155
|
+
translateFilter(filter: FilterExpr, meta: TableMetadata, depth?: number): FilterExpr;
|
|
156
|
+
/**
|
|
157
|
+
* `out` — the translation of the caller's `filter` — with its pre-scan
|
|
158
|
+
* result (`has`) cached for the adapter's repeated `containsRelationFilter`
|
|
159
|
+
* checks; only when the core built it (never the caller's own object).
|
|
160
|
+
*/
|
|
161
|
+
protected noteTranslated(filter: unknown, out: FilterExpr, has: boolean): FilterExpr;
|
|
162
|
+
/**
|
|
163
|
+
* Recursively walks a filter expression (predicates already resolved),
|
|
164
|
+
* applying `@db.column` key renames (document paths —
|
|
165
|
+
* {@link TableMetadata.documentPath}) and adapter-specific value formatting
|
|
166
|
+
* via `formatFilterValue`. A resolved predicate passes through under its
|
|
167
|
+
* navigation-field key.
|
|
152
168
|
*
|
|
153
169
|
* The relational mapper overrides this to use `leafByLogical` for deeper
|
|
154
170
|
* key resolution (flattened nested paths).
|
|
155
171
|
*/
|
|
156
|
-
|
|
172
|
+
protected translateResolvedFilter(filter: FilterExpr, meta: TableMetadata): FilterExpr;
|
|
157
173
|
abstract prepareForWrite(payload: Record<string, unknown>, meta: TableMetadata, adapter: BaseDbAdapter): Record<string, unknown>;
|
|
158
174
|
abstract translatePatchKeys(update: Record<string, unknown>, meta: TableMetadata): Record<string, unknown>;
|
|
159
175
|
/** `$inc` / `$mul` field-op keys to physical names ({@link physicalPath}). */
|
|
@@ -289,6 +305,167 @@ declare class DbEncryption {
|
|
|
289
305
|
private _getKey;
|
|
290
306
|
}
|
|
291
307
|
//#endregion
|
|
308
|
+
//#region src/query/relation-filter.d.ts
|
|
309
|
+
/**
|
|
310
|
+
* Relational filter predicates (`{ nav: { $some | $none: <filter on the
|
|
311
|
+
* related table> } }`) — resolution against the related tables.
|
|
312
|
+
*
|
|
313
|
+
* Semantics: `rel(r, nav)` is exactly the set of related rows `$with=nav`
|
|
314
|
+
* loads for row `r` (same foreign-key pairing, the relation's
|
|
315
|
+
* `@db.rel.filter` included). `$some: F` holds when one of them matches `F`,
|
|
316
|
+
* `$none: F` when none does; a NULL foreign-key component means "no related
|
|
317
|
+
* row". The core resolves each predicate into a {@link ResolvedRelationFilter}
|
|
318
|
+
* (physical names on every side, the inner filter translated by the related
|
|
319
|
+
* table's own field mapper) before the adapter sees the filter — adapters
|
|
320
|
+
* only render it.
|
|
321
|
+
*
|
|
322
|
+
* @since 0.1.147
|
|
323
|
+
*/
|
|
324
|
+
/**
|
|
325
|
+
* Maximum nesting of relational predicates in one filter, server-added ones
|
|
326
|
+
* included (a predicate inside a predicate's operand counts one level). The
|
|
327
|
+
* core backstop for every caller; higher than moost-db's per-client limit
|
|
328
|
+
* (`REL_FILTER_CLIENT_MAX_DEPTH`) so server overlays (row scopes,
|
|
329
|
+
* `transformRelationFilter`) have headroom above what a client may send.
|
|
330
|
+
*/
|
|
331
|
+
declare const REL_FILTER_MAX_DEPTH = 4;
|
|
332
|
+
/** Maximum number of relational predicates in one filter (nested and server-added ones included). See {@link REL_FILTER_MAX_DEPTH}. */
|
|
333
|
+
declare const REL_FILTER_MAX_NODES = 16;
|
|
334
|
+
/** A table taking part in a resolved predicate. */
|
|
335
|
+
interface TRelationFilterTable {
|
|
336
|
+
/** The adapter's `resolveTableName()` — schema-qualified when the table has a `@db.schema`. */
|
|
337
|
+
table: string;
|
|
338
|
+
/** The adapter's `resolveTableName(false)` — the bare table / collection name. */
|
|
339
|
+
name: string;
|
|
340
|
+
/** The adapter instance bound to this table. */
|
|
341
|
+
adapter: BaseDbAdapter;
|
|
342
|
+
}
|
|
343
|
+
/** The junction side of a resolved `via` predicate. */
|
|
344
|
+
interface TRelationFilterJunction extends TRelationFilterTable {
|
|
345
|
+
/** Junction column → the SOURCE column it references (physical names). */
|
|
346
|
+
toSource: Array<{
|
|
347
|
+
junction: string;
|
|
348
|
+
source: string;
|
|
349
|
+
}>;
|
|
350
|
+
/** Junction column → the TARGET column it references (physical names). */
|
|
351
|
+
toTarget: Array<{
|
|
352
|
+
junction: string;
|
|
353
|
+
target: string;
|
|
354
|
+
}>;
|
|
355
|
+
/** The junction part of the relation's `@db.rel.filter` (junction physical names), if any. */
|
|
356
|
+
filter?: FilterExpr;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Cross-realm brand of {@link ResolvedRelationFilter}: `instanceof` fails when
|
|
360
|
+
* two copies of `@atscript/db` are loaded (ESM + CJS, or nested installs) and
|
|
361
|
+
* an adapter from one sees nodes built by the other.
|
|
362
|
+
*/
|
|
363
|
+
declare const RESOLVED_BRAND: unique symbol;
|
|
364
|
+
/**
|
|
365
|
+
* A relational predicate as adapters receive it — the operand of
|
|
366
|
+
* `FilterVisitor.relation(field, op, operand)` once the core translated the
|
|
367
|
+
* filter. Every name is physical:
|
|
368
|
+
*
|
|
369
|
+
* - `to` / `from`: `pairs` correlate a SOURCE column with a TARGET column
|
|
370
|
+
* (`target.<pair.target> = source.<pair.source>`, one pair per composite
|
|
371
|
+
* key part);
|
|
372
|
+
* - `via`: `pairs` is empty — `junction.toSource` correlates the junction
|
|
373
|
+
* with the source row, `junction.toTarget` with the target row.
|
|
374
|
+
*
|
|
375
|
+
* `filter` is the inner filter on the TARGET (already translated by the
|
|
376
|
+
* target's field mapper: renames, flattening, value formatters; nested
|
|
377
|
+
* predicates resolved the same way), conjoined with the target part of the
|
|
378
|
+
* relation's `@db.rel.filter`. `{}` matches every related row.
|
|
379
|
+
*
|
|
380
|
+
* @since 0.1.147
|
|
381
|
+
*/
|
|
382
|
+
declare class ResolvedRelationFilter {
|
|
383
|
+
/** @internal cross-realm brand (see {@link isResolvedRelationFilter}). */
|
|
384
|
+
readonly [RESOLVED_BRAND]: true;
|
|
385
|
+
readonly kind: "to" | "from" | "via";
|
|
386
|
+
/** Logical navigation field name on the source table. */
|
|
387
|
+
readonly nav: string;
|
|
388
|
+
readonly source: TRelationFilterTable;
|
|
389
|
+
readonly target: TRelationFilterTable;
|
|
390
|
+
readonly pairs: ReadonlyArray<{
|
|
391
|
+
source: string;
|
|
392
|
+
target: string;
|
|
393
|
+
}>;
|
|
394
|
+
readonly junction?: TRelationFilterJunction;
|
|
395
|
+
readonly filter: FilterExpr;
|
|
396
|
+
constructor(init: {
|
|
397
|
+
kind: "to" | "from" | "via";
|
|
398
|
+
nav: string;
|
|
399
|
+
source: TRelationFilterTable;
|
|
400
|
+
target: TRelationFilterTable;
|
|
401
|
+
pairs: Array<{
|
|
402
|
+
source: string;
|
|
403
|
+
target: string;
|
|
404
|
+
}>;
|
|
405
|
+
junction?: TRelationFilterJunction;
|
|
406
|
+
filter: FilterExpr;
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
/** `true` for a {@link ResolvedRelationFilter} (the resolved operand of a predicate). */
|
|
410
|
+
declare function isResolvedRelationFilter(value: unknown): value is ResolvedRelationFilter;
|
|
411
|
+
/** `true` when `value` (a filter entry's value) is an operator map with a `$some` / `$none` key. */
|
|
412
|
+
declare function hasRelationOp(value: unknown): value is Record<string, unknown>;
|
|
413
|
+
/**
|
|
414
|
+
* `true` when `filter` holds a relational predicate anywhere outside
|
|
415
|
+
* predicate operands (through `$and` / `$or` / `$not`) — the cheap pre-scan
|
|
416
|
+
* the field mappers and renderers use to keep predicate-free filters on
|
|
417
|
+
* their fast paths. Results for filters the core translated are cached.
|
|
418
|
+
*/
|
|
419
|
+
declare function containsRelationFilter(filter: unknown): boolean;
|
|
420
|
+
/**
|
|
421
|
+
* Calls `visit` for every resolved predicate of a TRANSLATED filter,
|
|
422
|
+
* depth-first: the top-level ones, then (with `nested`) those inside each
|
|
423
|
+
* operand — target filters and junction filters alike. Adapters use it to
|
|
424
|
+
* prepare per-predicate data (memory snapshots, self-referencing checks).
|
|
425
|
+
*/
|
|
426
|
+
declare function forEachResolvedRelation(filter: unknown, visit: (node: ResolvedRelationFilter, op: RelationOp) => void, nested?: boolean): void;
|
|
427
|
+
/** Shared state of one guarded filter: predicate depth / count and the read/write mode. */
|
|
428
|
+
interface TRelGuardState {
|
|
429
|
+
/** Nesting level of the filter being guarded (0 = the query's own filter). */
|
|
430
|
+
depth: number;
|
|
431
|
+
/** Predicates seen so far in this query (shared by every level). */
|
|
432
|
+
counter: {
|
|
433
|
+
nodes: number;
|
|
434
|
+
};
|
|
435
|
+
/** Mutation filter (`supportsRelationFilters('write')`) vs read filter. */
|
|
436
|
+
write: boolean;
|
|
437
|
+
/** Dotted navigation chain of the filter being guarded (`""` at the root). */
|
|
438
|
+
path: string;
|
|
439
|
+
}
|
|
440
|
+
/** Installed on `TableMetadata.relationFilters` by the owning readable. */
|
|
441
|
+
interface TRelationFilterHost {
|
|
442
|
+
/** Validates one predicate's operand against the related table (recursively). */
|
|
443
|
+
guard(nav: string, op: RelationOp, inner: FilterExpr, state: TRelGuardState): void;
|
|
444
|
+
/** Resolves one predicate into its adapter-facing form; `depth` is this predicate's level (≥ 1). */
|
|
445
|
+
resolve(nav: string, op: RelationOp, inner: FilterExpr, depth: number): ResolvedRelationFilter;
|
|
446
|
+
}
|
|
447
|
+
/** The present, non-empty `parts` ANDed (`{}` when none, a single one as is). */
|
|
448
|
+
declare function andFilters(...parts: Array<FilterExpr | null | undefined>): FilterExpr;
|
|
449
|
+
/** A relation's `@db.rel.filter`, split by the table each condition reads (LOGICAL names). */
|
|
450
|
+
interface TRelationStaticFilter {
|
|
451
|
+
/** Conditions on the related (target) table. */
|
|
452
|
+
target?: FilterExpr;
|
|
453
|
+
/** Conditions on the junction table (`@db.rel.via` only). */
|
|
454
|
+
junction?: FilterExpr;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* A relation's `@db.rel.filter` as logical filters per side — what `$with`
|
|
458
|
+
* loading and relational predicates both AND into the related rows (the
|
|
459
|
+
* filter is part of the relation's meaning). Top-level `and` conditions are
|
|
460
|
+
* split by side: an unqualified field and the related type's fields go to
|
|
461
|
+
* `target`, the `@db.rel.via` junction's to `junction`. A single condition
|
|
462
|
+
* that reads both sides (e.g. an `or` across them) or compares two fields is
|
|
463
|
+
* rejected with `INVALID_QUERY` — `name` is the navigation field (error path).
|
|
464
|
+
*
|
|
465
|
+
* @since 0.1.147
|
|
466
|
+
*/
|
|
467
|
+
declare function relationStaticFilter(relation: TDbRelation, name?: string): TRelationStaticFilter;
|
|
468
|
+
//#endregion
|
|
292
469
|
//#region src/table/db-readable.d.ts
|
|
293
470
|
/**
|
|
294
471
|
* Extracts nav prop names from a query's `$with` array.
|
|
@@ -369,6 +546,40 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
369
546
|
protected _ensureSearchable(): void;
|
|
370
547
|
/** Engine-agnostic query-time guards (encrypted-field refs, $geoWithin shape). */
|
|
371
548
|
protected _guardQuery(query: Uniquery | undefined): void;
|
|
549
|
+
/**
|
|
550
|
+
* Guards a relational predicate operand against THIS table — the filter
|
|
551
|
+
* guard and the path guard with the predicate's shared `state` (depth,
|
|
552
|
+
* count, read/write mode). Called by the source table's relation host.
|
|
553
|
+
*
|
|
554
|
+
* @internal Core wiring for relational predicates; not consumer API.
|
|
555
|
+
*/
|
|
556
|
+
_guardRelationOperand(filter: FilterExpr, state: TRelGuardState): void;
|
|
557
|
+
/**
|
|
558
|
+
* Translates a relational predicate operand for THIS table's adapter (its
|
|
559
|
+
* own field mapper; nested predicates resolved at `depth + 1`).
|
|
560
|
+
*
|
|
561
|
+
* @internal Core wiring for relational predicates; not consumer API.
|
|
562
|
+
*/
|
|
563
|
+
_resolveRelationOperand(filter: FilterExpr, depth: number): FilterExpr;
|
|
564
|
+
/**
|
|
565
|
+
* Translates a logical query (filter + controls) for THIS table's adapter
|
|
566
|
+
* after the read guards — exactly what `findMany` hands the adapter.
|
|
567
|
+
* For adapters that load `$with` relations natively and must address the
|
|
568
|
+
* related table's physical names.
|
|
569
|
+
*
|
|
570
|
+
* @internal Adapter-facing surface; not part of the consumer API.
|
|
571
|
+
* @since 0.1.147
|
|
572
|
+
*/
|
|
573
|
+
_translateForAdapter(query: Uniquery): ReturnType<FieldMappingStrategy["translateQuery"]>;
|
|
574
|
+
/**
|
|
575
|
+
* Physical rows of THIS table → logical rows (field mapping, value
|
|
576
|
+
* formatters, decryption) — what every read does before `$with` loading.
|
|
577
|
+
* `controls` are the logical read controls the rows were read with.
|
|
578
|
+
*
|
|
579
|
+
* @internal Adapter-facing surface; not part of the consumer API.
|
|
580
|
+
* @since 0.1.147
|
|
581
|
+
*/
|
|
582
|
+
_rowsFromAdapter(rows: Record<string, unknown>[], controls?: TReadControls): Promise<Record<string, unknown>[]>;
|
|
372
583
|
private _encryptedPathsCache?;
|
|
373
584
|
/** Pre-split `encryptedFields` paths — computed once, reused on every read/write. */
|
|
374
585
|
protected get _encryptedPaths(): Array<{
|
|
@@ -495,6 +706,12 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
495
706
|
setVerbose(enabled: boolean): void;
|
|
496
707
|
/** Precomputed logical dot-path → physical column name map. */
|
|
497
708
|
get pathToPhysical(): ReadonlyMap<string, string>;
|
|
709
|
+
/**
|
|
710
|
+
* Physical column (or document path) of a logical field path —
|
|
711
|
+
* `@db.column` renames and flattening applied.
|
|
712
|
+
* @since 0.1.147
|
|
713
|
+
*/
|
|
714
|
+
physicalPath(logical: string): string;
|
|
498
715
|
/** Precomputed physical column name → logical dot-path map (inverse). */
|
|
499
716
|
get physicalToPath(): ReadonlyMap<string, string>;
|
|
500
717
|
/** Descriptor for the primary ID field(s). */
|
|
@@ -514,7 +731,10 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
514
731
|
* its key was not selected.
|
|
515
732
|
*/
|
|
516
733
|
private _translateRead;
|
|
517
|
-
/**
|
|
734
|
+
/**
|
|
735
|
+
* Reconstructs + decrypts a read's rows, keeps the ones `pick` selects (all
|
|
736
|
+
* by default), loads their `$with` relations and strips widened keys.
|
|
737
|
+
*/
|
|
518
738
|
private _finishRead;
|
|
519
739
|
/** `$select` plus the join keys of `withRelations` it leaves out — `undefined` when none is missing. */
|
|
520
740
|
private _widenSelectForWith;
|
|
@@ -564,11 +784,12 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
564
784
|
* table. Defense-in-depth for query-path validation: `flattenAnnotatedType`
|
|
565
785
|
* still truncates real self-referential cycles, so paths like
|
|
566
786
|
* `parent.parent.name` on a self-ref schema would miss `flatMap.has` but
|
|
567
|
-
* remain valid field references on the target
|
|
787
|
+
* remain valid field references on the target — a path may cross the same
|
|
788
|
+
* relation any number of times (callers cap the depth).
|
|
568
789
|
*
|
|
569
|
-
*
|
|
790
|
+
* Terminates on cyclic schemas: every hop consumes one path segment.
|
|
570
791
|
*/
|
|
571
|
-
isValidFieldPath(path: string
|
|
792
|
+
isValidFieldPath(path: string): boolean;
|
|
572
793
|
/**
|
|
573
794
|
* Creates a new validator with custom options.
|
|
574
795
|
*/
|
|
@@ -585,6 +806,19 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
585
806
|
* explicitly requested via `$with`.
|
|
586
807
|
*/
|
|
587
808
|
findMany<Q extends Uniquery<OwnProps, NavType>>(query: Q): Promise<Array<DbResponse<DataType, NavType, Q>>>;
|
|
809
|
+
/**
|
|
810
|
+
* `findMany` for the generic `$with` loader. With `partitionBy` (logical
|
|
811
|
+
* fields), `$skip` / `$limit` apply per group of rows sharing those fields'
|
|
812
|
+
* values (`BaseDbAdapter.findManyPerPartition`); `pick` chooses which of the
|
|
813
|
+
* read rows to keep before their own `$with` relations load.
|
|
814
|
+
*
|
|
815
|
+
* @internal Relation-loader surface; not part of the consumer API.
|
|
816
|
+
* @since 0.1.147
|
|
817
|
+
*/
|
|
818
|
+
_findManyForRelation(query: Uniquery, opts: {
|
|
819
|
+
partitionBy?: readonly string[];
|
|
820
|
+
pick?: (rows: Record<string, unknown>[]) => Record<string, unknown>[];
|
|
821
|
+
}): Promise<Record<string, unknown>[]>;
|
|
588
822
|
/**
|
|
589
823
|
* Counts records matching the query.
|
|
590
824
|
*/
|
|
@@ -836,6 +1070,18 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
836
1070
|
}
|
|
837
1071
|
//#endregion
|
|
838
1072
|
//#region src/strategies/integrity.d.ts
|
|
1073
|
+
/**
|
|
1074
|
+
* Result of {@link IntegrityStrategy.cascadeBeforeDelete}:
|
|
1075
|
+
* - `undefined` — no cascade ran, or the filter holds no relational
|
|
1076
|
+
* predicate; delete with the caller's own filter;
|
|
1077
|
+
* - an array — the rows the cascade ran for, pinned by primary key as
|
|
1078
|
+
* ADAPTER-READY (physical, already translated) filters, in batches. The
|
|
1079
|
+
* caller must delete exactly these rows instead of evaluating its filter
|
|
1080
|
+
* again: the cascade changed the data the filter may read (a relational
|
|
1081
|
+
* predicate on a child relation no longer matches once the children are
|
|
1082
|
+
* gone). An empty array means no row matched.
|
|
1083
|
+
*/
|
|
1084
|
+
type TCascadePin = FilterExpr[] | undefined;
|
|
839
1085
|
/**
|
|
840
1086
|
* Strategy for referential integrity enforcement.
|
|
841
1087
|
* Two implementations: {@link NativeIntegrity} (DB handles FK constraints)
|
|
@@ -843,7 +1089,7 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
843
1089
|
*/
|
|
844
1090
|
declare abstract class IntegrityStrategy {
|
|
845
1091
|
abstract validateForeignKeys(items: Array<Record<string, unknown>>, meta: TableMetadata, fkLookupResolver: TFkLookupResolver | undefined, writeTableResolver: TWriteTableResolver | undefined, partial?: boolean, excludeTargetTable?: string): Promise<void>;
|
|
846
|
-
abstract cascadeBeforeDelete(filter: FilterExpr, tableName: string, meta: TableMetadata, cascadeResolver: TCascadeResolver, translateFilter: (f: FilterExpr) => FilterExpr, adapter: BaseDbAdapter): Promise<
|
|
1092
|
+
abstract cascadeBeforeDelete(filter: FilterExpr, tableName: string, meta: TableMetadata, cascadeResolver: TCascadeResolver, translateFilter: (f: FilterExpr) => FilterExpr, adapter: BaseDbAdapter): Promise<TCascadePin>;
|
|
847
1093
|
abstract needsCascade(cascadeResolver: TCascadeResolver | undefined): boolean;
|
|
848
1094
|
}
|
|
849
1095
|
/**
|
|
@@ -852,7 +1098,7 @@ declare abstract class IntegrityStrategy {
|
|
|
852
1098
|
*/
|
|
853
1099
|
declare class NativeIntegrity extends IntegrityStrategy {
|
|
854
1100
|
validateForeignKeys(): Promise<void>;
|
|
855
|
-
cascadeBeforeDelete(): Promise<
|
|
1101
|
+
cascadeBeforeDelete(): Promise<TCascadePin>;
|
|
856
1102
|
needsCascade(): boolean;
|
|
857
1103
|
}
|
|
858
1104
|
//#endregion
|
|
@@ -1173,6 +1419,22 @@ interface TViewJoin {
|
|
|
1173
1419
|
* @since 0.1.136
|
|
1174
1420
|
*/
|
|
1175
1421
|
kind: "inner" | "left";
|
|
1422
|
+
/**
|
|
1423
|
+
* Set for a first-row join (the `@db.view.joins` 4th argument): of the
|
|
1424
|
+
* target rows matching {@link condition} only the first by `order` joins.
|
|
1425
|
+
* `order` refs are qualified with the target (`ref.type`), the target's
|
|
1426
|
+
* primary key appended as the final ascending key unless already a key;
|
|
1427
|
+
* `key` is that primary key's logical path — the anchor of the join's
|
|
1428
|
+
* correlated subquery. NULL is the smallest value (first in `asc`).
|
|
1429
|
+
* @since 0.1.147
|
|
1430
|
+
*/
|
|
1431
|
+
first?: {
|
|
1432
|
+
order: Array<{
|
|
1433
|
+
ref: AtscriptQueryFieldRef;
|
|
1434
|
+
desc: boolean;
|
|
1435
|
+
}>;
|
|
1436
|
+
key: string;
|
|
1437
|
+
};
|
|
1176
1438
|
}
|
|
1177
1439
|
/** Resolved view query plan produced by AtscriptDbView. */
|
|
1178
1440
|
interface TViewPlan {
|
|
@@ -1272,6 +1534,15 @@ interface TViewColumnMapping {
|
|
|
1272
1534
|
* `@db.view.filter` (entry table + joins). @since 0.1.136
|
|
1273
1535
|
*/
|
|
1274
1536
|
aggFilter?: AtscriptQueryNode;
|
|
1537
|
+
/**
|
|
1538
|
+
* A computed column (`@db.compute`): the arithmetic expression, its leaves
|
|
1539
|
+
* naming the view's own fields by {@link viewPath}. Such a mapping reads no
|
|
1540
|
+
* source column — `sourceTable` is the entry table and `sourceColumn` is
|
|
1541
|
+
* `""` (unused). Renderers evaluate it in IEEE double with division by zero
|
|
1542
|
+
* → NULL; `nullable` is set when the expression may be NULL.
|
|
1543
|
+
* @since 0.1.147
|
|
1544
|
+
*/
|
|
1545
|
+
expr?: AtscriptExprNode;
|
|
1275
1546
|
}
|
|
1276
1547
|
/**
|
|
1277
1548
|
* Whether `type` declares a view (managed `@db.view.for` or external
|
|
@@ -1367,7 +1638,22 @@ declare class AtscriptDbView<T extends TAtscriptAnnotatedType = TAtscriptAnnotat
|
|
|
1367
1638
|
* aggregate other than `count` over `'*'`.
|
|
1368
1639
|
*/
|
|
1369
1640
|
getViewColumnMappings(): TViewColumnMapping[];
|
|
1641
|
+
/**
|
|
1642
|
+
* Why the bound adapter cannot render this managed view: one message per
|
|
1643
|
+
* computed column / first-row join whose feature its `viewCapabilities()`
|
|
1644
|
+
* does not list. Empty for an external view or when every feature is
|
|
1645
|
+
* rendered. Schema sync refuses such a view; the adapter's `ensureTable()`
|
|
1646
|
+
* throws for it (fail-closed for adapters that predate the features).
|
|
1647
|
+
* @since 0.1.147
|
|
1648
|
+
*/
|
|
1649
|
+
viewCapabilityProblems(): string[];
|
|
1370
1650
|
private _buildColumnMappings;
|
|
1651
|
+
/**
|
|
1652
|
+
* The runtime twin of the compile-time `@db.compute` rules the renderers
|
|
1653
|
+
* rely on: every leaf names a (non-ignored) view column, computed columns
|
|
1654
|
+
* form no cycle; sets each computed mapping's `nullable`.
|
|
1655
|
+
*/
|
|
1656
|
+
private _checkComputed;
|
|
1371
1657
|
/** One view column over one physical source (a column or a JSON leaf). */
|
|
1372
1658
|
private _leafMapping;
|
|
1373
1659
|
}
|
|
@@ -1497,8 +1783,19 @@ declare class DbSpace {
|
|
|
1497
1783
|
}
|
|
1498
1784
|
//#endregion
|
|
1499
1785
|
//#region src/base-adapter.d.ts
|
|
1500
|
-
/**
|
|
1786
|
+
/**
|
|
1787
|
+
* Every calendar-bucket unit — what an adapter that renders them all returns
|
|
1788
|
+
* from `calendarBucketUnits()`. Includes `'hour'` since 0.1.147.
|
|
1789
|
+
*/
|
|
1501
1790
|
declare const ALL_BUCKET_UNITS: ReadonlySet<BucketUnit>;
|
|
1791
|
+
/**
|
|
1792
|
+
* A managed-view feature an adapter may render (`viewCapabilities()`):
|
|
1793
|
+
* `compute` — computed columns (`@db.compute`); `firstJoin` — first-row joins.
|
|
1794
|
+
* @since 0.1.147
|
|
1795
|
+
*/
|
|
1796
|
+
type TViewCapability = "compute" | "firstJoin";
|
|
1797
|
+
/** Every view capability — what the bundled adapters return from `viewCapabilities()`. @since 0.1.147 */
|
|
1798
|
+
declare const ALL_VIEW_CAPABILITIES: ReadonlySet<TViewCapability>;
|
|
1502
1799
|
/**
|
|
1503
1800
|
* Abstract base class for database adapters.
|
|
1504
1801
|
*
|
|
@@ -1548,6 +1845,15 @@ declare abstract class BaseDbAdapter {
|
|
|
1548
1845
|
* index sync, etc.
|
|
1549
1846
|
*/
|
|
1550
1847
|
registerReadable(readable: AtscriptDbReadable<any, any, any, any, any, any, any>, logger?: TGenericLogger): void;
|
|
1848
|
+
/**
|
|
1849
|
+
* Makes `ensureTable()` of a managed view fail closed (since 0.1.147): it
|
|
1850
|
+
* throws before the adapter renders a computed column / first-row join its
|
|
1851
|
+
* {@link viewCapabilities} does not list — schema sync refuses such a view
|
|
1852
|
+
* up front, a direct `ensureTable()` call must not render it as a plain
|
|
1853
|
+
* (row-multiplying) join either. Wraps the subclass's own implementation, so
|
|
1854
|
+
* third-party adapters get the guard without code changes.
|
|
1855
|
+
*/
|
|
1856
|
+
private _guardViewCapabilities;
|
|
1551
1857
|
/**
|
|
1552
1858
|
* Called by {@link DbSpace} right after its factory builds this adapter —
|
|
1553
1859
|
* the administrative one included — before {@link registerReadable}. No-op
|
|
@@ -1679,8 +1985,10 @@ declare abstract class BaseDbAdapter {
|
|
|
1679
1985
|
* be adopted adapter by adapter. An adapter that returns a unit must group
|
|
1680
1986
|
* by the bucket alias in `$groupBy` — see `controls.$select.buckets`
|
|
1681
1987
|
* (`TResolvedBucket`: physical `field`, source `fd`) — and return the
|
|
1682
|
-
* `YYYY-MM-DD` label of the bucket's first local day
|
|
1683
|
-
*
|
|
1988
|
+
* `YYYY-MM-DD` label of the bucket's first local day, or for `'hour'` the
|
|
1989
|
+
* local wall-clock hour `YYYY-MM-DDTHH:00` (null for a null or out-of-range
|
|
1990
|
+
* source, uniqu's `bucketLabel` semantics). Since 0.1.132; `'hour'` since
|
|
1991
|
+
* 0.1.147 — an adapter returning {@link ALL_BUCKET_UNITS} must render it.
|
|
1684
1992
|
*/
|
|
1685
1993
|
calendarBucketUnits(): ReadonlySet<BucketUnit>;
|
|
1686
1994
|
/**
|
|
@@ -1706,6 +2014,16 @@ declare abstract class BaseDbAdapter {
|
|
|
1706
2014
|
* @since 0.1.137
|
|
1707
2015
|
*/
|
|
1708
2016
|
viewRenderRevision(): string | undefined;
|
|
2017
|
+
/**
|
|
2018
|
+
* The managed-view features this adapter renders: `compute` — computed
|
|
2019
|
+
* columns (`@db.compute`); `firstJoin` — first-row joins (the ordered 4th
|
|
2020
|
+
* argument of `@db.view.joins`). Schema sync refuses a view using a feature
|
|
2021
|
+
* not listed. The default is EMPTY (fail-closed): a third-party adapter
|
|
2022
|
+
* opts in once it renders them.
|
|
2023
|
+
*
|
|
2024
|
+
* @since 0.1.147
|
|
2025
|
+
*/
|
|
2026
|
+
viewCapabilities(): ReadonlySet<TViewCapability>;
|
|
1709
2027
|
/**
|
|
1710
2028
|
* Whether this adapter enforces foreign key constraints natively.
|
|
1711
2029
|
* When `true`, the generic layer skips application-level cascade/setNull
|
|
@@ -1752,6 +2070,35 @@ declare abstract class BaseDbAdapter {
|
|
|
1752
2070
|
* Default: `false` — the table layer uses application-level batch loading.
|
|
1753
2071
|
*/
|
|
1754
2072
|
supportsNativeRelations(): boolean;
|
|
2073
|
+
/**
|
|
2074
|
+
* Whether this adapter renders relational filter predicates
|
|
2075
|
+
* (`{ nav: { $some | $none: … } }`) in `mode` — `read` for find / count /
|
|
2076
|
+
* search / aggregate filters, `write` for mutation filters
|
|
2077
|
+
* (`updateMany`, `deleteMany`, …). Default `false`: the core rejects such
|
|
2078
|
+
* filters with `REL_FILTER_NOT_SUPPORTED` before they reach the adapter.
|
|
2079
|
+
*
|
|
2080
|
+
* An adapter returning `true` receives each predicate already resolved by
|
|
2081
|
+
* the core: the filter visitor's `relation(field, op, operand)` callback
|
|
2082
|
+
* gets a `ResolvedRelationFilter` operand (`kind`, physical
|
|
2083
|
+
* correlation `pairs`, `target` / `junction` tables with their adapters,
|
|
2084
|
+
* and the inner `filter` already translated to the target's physical
|
|
2085
|
+
* names, nested predicates resolved too). Keep `relation` on every
|
|
2086
|
+
* `walkFilter` visitor that may meet such a filter.
|
|
2087
|
+
*
|
|
2088
|
+
* @since 0.1.147
|
|
2089
|
+
*/
|
|
2090
|
+
supportsRelationFilters(_mode: "read" | "write"): boolean;
|
|
2091
|
+
/**
|
|
2092
|
+
* Whether `other` serves a table of the SAME store as this adapter, so one
|
|
2093
|
+
* statement / pipeline can correlate both (a relational predicate renders
|
|
2094
|
+
* the related table inside this table's query). Default: same adapter class
|
|
2095
|
+
* and same {@link _transactionOwner} (the driver / pool / client the
|
|
2096
|
+
* adapter was built with). Override when the owner is shared across
|
|
2097
|
+
* separate databases (e.g. one Mongo client over several databases).
|
|
2098
|
+
*
|
|
2099
|
+
* @since 0.1.147
|
|
2100
|
+
*/
|
|
2101
|
+
sharesStoreWith(other: BaseDbAdapter): boolean;
|
|
1755
2102
|
/**
|
|
1756
2103
|
* Loads relations onto result rows using adapter-native operations.
|
|
1757
2104
|
* Only called when {@link supportsNativeRelations} returns `true`.
|
|
@@ -1987,6 +2334,22 @@ declare abstract class BaseDbAdapter {
|
|
|
1987
2334
|
data: Array<Record<string, unknown>>;
|
|
1988
2335
|
count: number;
|
|
1989
2336
|
}>;
|
|
2337
|
+
/**
|
|
2338
|
+
* Reads like {@link findMany}, except that `$skip` / `$limit` apply to each
|
|
2339
|
+
* partition — the rows sharing the values of the `partitionBy` columns
|
|
2340
|
+
* (physical names) — instead of to the whole result. The generic `$with`
|
|
2341
|
+
* loader reads the related rows of many parent rows at once this way, so a
|
|
2342
|
+
* relation's `$skip` / `$limit` page each parent row's related rows.
|
|
2343
|
+
* `$sort` orders the rows within a partition; how partitions interleave is
|
|
2344
|
+
* unspecified.
|
|
2345
|
+
*
|
|
2346
|
+
* Default: one {@link findMany} without `$skip` / `$limit`, paged per
|
|
2347
|
+
* partition in memory. The SQL adapters override it with a `ROW_NUMBER()`
|
|
2348
|
+
* window, so only the kept rows are read.
|
|
2349
|
+
*
|
|
2350
|
+
* @since 0.1.147
|
|
2351
|
+
*/
|
|
2352
|
+
findManyPerPartition(query: DbQuery, partitionBy: readonly string[]): Promise<Array<Record<string, unknown>>>;
|
|
1990
2353
|
/**
|
|
1991
2354
|
* Executes an aggregate query (GROUP BY + aggregate functions).
|
|
1992
2355
|
* Default throws — override in adapters that support aggregation.
|
|
@@ -2350,6 +2713,14 @@ declare class TableMetadata {
|
|
|
2350
2713
|
jsonValueParents: ReadonlySet<string>;
|
|
2351
2714
|
/** Every field descriptor's `physicalName` — reserved names a bucket alias may not take. */
|
|
2352
2715
|
physicalNames: ReadonlySet<string>;
|
|
2716
|
+
/**
|
|
2717
|
+
* Resolves / guards relational filter predicates (`{ nav: { $some: … } }`)
|
|
2718
|
+
* against the related tables — installed by the owning readable when the
|
|
2719
|
+
* table has navigation fields and a table resolver (a `DbSpace`). The field
|
|
2720
|
+
* mappers and the path guard reach the related tables through it.
|
|
2721
|
+
* @since 0.1.147
|
|
2722
|
+
*/
|
|
2723
|
+
relationFilters?: TRelationFilterHost;
|
|
2353
2724
|
private _built;
|
|
2354
2725
|
private _identifications?;
|
|
2355
2726
|
private _alwaysAddressable?;
|
|
@@ -2442,6 +2813,14 @@ declare class TableMetadata {
|
|
|
2442
2813
|
* (flatMap, indexes, columnMap, etc.) is already populated.
|
|
2443
2814
|
*/
|
|
2444
2815
|
private _buildFieldDescriptors;
|
|
2816
|
+
/**
|
|
2817
|
+
* Fills `physicalFields` / `physicalTargetFields` on every FK: the local
|
|
2818
|
+
* side from this table's path maps, the target side from the referenced
|
|
2819
|
+
* type's own `@db.column` renames (same storage rules as this table — a
|
|
2820
|
+
* dotted target path is a flattened column on relational storage, a
|
|
2821
|
+
* renamed top-level key on document storage).
|
|
2822
|
+
*/
|
|
2823
|
+
private _resolveFkPhysicalFields;
|
|
2445
2824
|
/**
|
|
2446
2825
|
* Resolves `fkTargetField` for FK fields in field descriptors.
|
|
2447
2826
|
*/
|
|
@@ -2513,6 +2892,11 @@ interface TRelationInfo {
|
|
|
2513
2892
|
name: string;
|
|
2514
2893
|
direction: "to" | "from" | "via";
|
|
2515
2894
|
isArray: boolean;
|
|
2895
|
+
/**
|
|
2896
|
+
* Present (true) when the relation is `@db.rel.filterable`: clients may
|
|
2897
|
+
* filter by related rows (`nav=$some(…)` / `nav=$none(…)`). @since 0.1.147
|
|
2898
|
+
*/
|
|
2899
|
+
filterable?: true;
|
|
2516
2900
|
}
|
|
2517
2901
|
/** Per-field capability flags in a meta response. */
|
|
2518
2902
|
interface TFieldMeta {
|
|
@@ -2556,6 +2940,13 @@ interface TFieldMeta {
|
|
|
2556
2940
|
* render it read-only. Since 0.1.141.
|
|
2557
2941
|
*/
|
|
2558
2942
|
derived?: true;
|
|
2943
|
+
/**
|
|
2944
|
+
* Present (true) when the field is a computed view column (`@db.compute`):
|
|
2945
|
+
* its value is arithmetic over other fields of the view, evaluated by the
|
|
2946
|
+
* database. Advisory — sorting / filtering follow `sortable` / `filterable`.
|
|
2947
|
+
* Since 0.1.147.
|
|
2948
|
+
*/
|
|
2949
|
+
computed?: true;
|
|
2559
2950
|
}
|
|
2560
2951
|
/** Built-in CRUD operation names; map 1:1 to public method names. */
|
|
2561
2952
|
type TCrudOp = "query" | "pages" | "one" | "geo" | "insert" | "update" | "replace" | "remove";
|
|
@@ -2687,6 +3078,76 @@ interface TDbActionInfo {
|
|
|
2687
3078
|
* @since 0.1.136
|
|
2688
3079
|
*/
|
|
2689
3080
|
formUrl?: string;
|
|
3081
|
+
/**
|
|
3082
|
+
* Present on an action another controller owns and runs (a view
|
|
3083
|
+
* delegating its source table's row actions): that controller's
|
|
3084
|
+
* server-absolute base path. `value`, `formUrl` and the per-row
|
|
3085
|
+
* `GET {owner}/meta/actions/:id` live there; `disabled` is not sent (the
|
|
3086
|
+
* row's `$actions` verdict is authoritative).
|
|
3087
|
+
*
|
|
3088
|
+
* @since 0.1.147
|
|
3089
|
+
*/
|
|
3090
|
+
owner?: string;
|
|
3091
|
+
/**
|
|
3092
|
+
* Delegated action only: the {@link owner}'s identification field → the
|
|
3093
|
+
* path in THIS controller's rows that carries its value. Clients build the
|
|
3094
|
+
* action's `ids` from a row through it. Absent when every pair is
|
|
3095
|
+
* identical and is exactly this controller's `preferredId`.
|
|
3096
|
+
*
|
|
3097
|
+
* @since 0.1.147
|
|
3098
|
+
*/
|
|
3099
|
+
idMap?: Record<string, string>;
|
|
3100
|
+
/**
|
|
3101
|
+
* `'rows'` level only: the action also accepts a query target — "every row
|
|
3102
|
+
* matching this filter / search" instead of a list of identifiers — of at
|
|
3103
|
+
* most `maxRows` rows. `url` (server-absolute) is where such a request is
|
|
3104
|
+
* POSTed when it is not `value` (a delegated action: this controller
|
|
3105
|
+
* resolves the query and runs the owner's action in batches).
|
|
3106
|
+
*
|
|
3107
|
+
* @since 0.1.147
|
|
3108
|
+
*/
|
|
3109
|
+
queryTarget?: {
|
|
3110
|
+
maxRows: number;
|
|
3111
|
+
url?: string;
|
|
3112
|
+
};
|
|
3113
|
+
}
|
|
3114
|
+
/**
|
|
3115
|
+
* Outcome of an action run over a target (a query target, or the
|
|
3116
|
+
* `@DbActionTarget` handler surface): how many rows the target matched, how
|
|
3117
|
+
* many the handler processed, and the rows left out — `skipped` by the gate
|
|
3118
|
+
* (disabled, out of scope, or `"stale"`: the row no longer matches the query
|
|
3119
|
+
* it was selected by) and `failed` as reported by the handler.
|
|
3120
|
+
*
|
|
3121
|
+
* @since 0.1.147
|
|
3122
|
+
*/
|
|
3123
|
+
interface TDbActionTargetSummary {
|
|
3124
|
+
matched: number;
|
|
3125
|
+
processed: number;
|
|
3126
|
+
skipped: {
|
|
3127
|
+
id: Record<string, unknown>;
|
|
3128
|
+
reason?: string;
|
|
3129
|
+
}[];
|
|
3130
|
+
failed: {
|
|
3131
|
+
id: Record<string, unknown>;
|
|
3132
|
+
reason: string;
|
|
3133
|
+
}[];
|
|
3134
|
+
/**
|
|
3135
|
+
* The run stopped early: a batch failed after an earlier batch had run
|
|
3136
|
+
* (those stay applied). Its ids, and every id not reached, are in
|
|
3137
|
+
* `failed`. Absent when the run completed.
|
|
3138
|
+
*/
|
|
3139
|
+
aborted?: {
|
|
3140
|
+
status: number;
|
|
3141
|
+
message: string;
|
|
3142
|
+
};
|
|
3143
|
+
/**
|
|
3144
|
+
* A delegated run (a view's query target onto its source's action): the
|
|
3145
|
+
* `message` each batch's source handler returned, in batch order. Absent
|
|
3146
|
+
* when none returned one.
|
|
3147
|
+
*/
|
|
3148
|
+
messages?: string[];
|
|
3149
|
+
/** {@link messages}, the distinct ones joined by newlines — for a toast. */
|
|
3150
|
+
message?: string;
|
|
2690
3151
|
}
|
|
2691
3152
|
/**
|
|
2692
3153
|
* `GET /meta/actions/:id` (and `/meta/actions?…`) response: the row-level
|
|
@@ -2870,6 +3331,20 @@ interface TDbFieldMeta {
|
|
|
2870
3331
|
* rejected.
|
|
2871
3332
|
*/
|
|
2872
3333
|
derived?: TDerivedColumn;
|
|
3334
|
+
/**
|
|
3335
|
+
* A computed view column (`@db.compute`, since 0.1.147): `operands` are the
|
|
3336
|
+
* logical paths of the view fields its value is computed from — transitive
|
|
3337
|
+
* (a computed operand is replaced by its own operands), never computed
|
|
3338
|
+
* themselves. `via` lists the intermediate computed fields the value is
|
|
3339
|
+
* computed through (transitively; empty when every leaf is a plain field).
|
|
3340
|
+
* Read-only; a computed field must not be visible when one of its operands
|
|
3341
|
+
* or `via` fields is hidden (the same rule as the `@db.writeOnly` seal —
|
|
3342
|
+
* `priority = x * 100 + rank` would otherwise give back a hidden `rank`).
|
|
3343
|
+
*/
|
|
3344
|
+
computed?: {
|
|
3345
|
+
operands: readonly string[];
|
|
3346
|
+
via: readonly string[];
|
|
3347
|
+
};
|
|
2873
3348
|
}
|
|
2874
3349
|
interface TValueFormatterPair {
|
|
2875
3350
|
/** Converts a JS value to storage representation (write + filter paths). */
|
|
@@ -2885,6 +3360,24 @@ interface TDbForeignKey {
|
|
|
2885
3360
|
targetTable: string;
|
|
2886
3361
|
/** Target field names on the referenced table. */
|
|
2887
3362
|
targetFields: string[];
|
|
3363
|
+
/**
|
|
3364
|
+
* Physical column names of {@link fields} (after `@db.column` renames and
|
|
3365
|
+
* flattening), in the same order. Use these for DDL, constraint sync, the
|
|
3366
|
+
* FK diff and the schema snapshot; `fields` stays logical (query / relation
|
|
3367
|
+
* pairing). Absent → same as `fields`.
|
|
3368
|
+
*/
|
|
3369
|
+
physicalFields?: string[];
|
|
3370
|
+
/**
|
|
3371
|
+
* Physical column names of {@link targetFields} on the referenced table
|
|
3372
|
+
* (its `@db.column` renames), in the same order. Absent → same as `targetFields`.
|
|
3373
|
+
*/
|
|
3374
|
+
physicalTargetFields?: string[];
|
|
3375
|
+
/**
|
|
3376
|
+
* `@db.schema` of the referenced table, when it declares one — SQL DDL
|
|
3377
|
+
* qualifies `REFERENCES` with it (a table in another schema). Not part of
|
|
3378
|
+
* the schema snapshot.
|
|
3379
|
+
*/
|
|
3380
|
+
targetSchema?: string;
|
|
2888
3381
|
/** Lazy reference to the target annotated type (for on-demand table resolution). */
|
|
2889
3382
|
targetTypeRef?: () => TAtscriptAnnotatedType;
|
|
2890
3383
|
/** Alias grouping FK fields (if any). */
|
|
@@ -3074,7 +3567,7 @@ interface AtscriptDbTableLike {
|
|
|
3074
3567
|
relations: ReadonlyMap<string, TDbRelation>;
|
|
3075
3568
|
foreignKeys: ReadonlyMap<string, TDbForeignKey>;
|
|
3076
3569
|
getMetadata(): TableMetadata;
|
|
3077
|
-
isValidFieldPath(path: string
|
|
3570
|
+
isValidFieldPath(path: string): boolean;
|
|
3078
3571
|
}
|
|
3079
3572
|
/**
|
|
3080
3573
|
* Nested FROM re-entry option (internal): pins every child's foreign key
|
|
@@ -3170,6 +3663,18 @@ interface TDbRelation {
|
|
|
3170
3663
|
isArray: boolean;
|
|
3171
3664
|
/** Junction type reference for 'via' (M:N) relations. */
|
|
3172
3665
|
viaType?: () => TAtscriptAnnotatedType;
|
|
3666
|
+
/**
|
|
3667
|
+
* `@db.rel.filterable` — HTTP clients may filter the parent rows by this
|
|
3668
|
+
* relation (`{ nav: { $some | $none: … } }`). Server-side code may always.
|
|
3669
|
+
* @since 0.1.147
|
|
3670
|
+
*/
|
|
3671
|
+
filterable?: boolean;
|
|
3672
|
+
/**
|
|
3673
|
+
* `@db.rel.filter` condition: part of the relation's meaning — applied when
|
|
3674
|
+
* the relation is loaded (`$with`) and inside relational predicates.
|
|
3675
|
+
* @since 0.1.147
|
|
3676
|
+
*/
|
|
3677
|
+
filter?: AtscriptQueryNode;
|
|
3173
3678
|
}
|
|
3174
3679
|
/**
|
|
3175
3680
|
* Write payload for insert / patch paths: every key optional, and optional
|
|
@@ -3464,4 +3969,4 @@ declare function isJsonValueField(fd: TDbFieldMeta): boolean;
|
|
|
3464
3969
|
*/
|
|
3465
3970
|
declare function jsonValueAncestor(path: string, jsonValueParents: ReadonlySet<string>): string | undefined;
|
|
3466
3971
|
//#endregion
|
|
3467
|
-
export {
|
|
3972
|
+
export { TDbStorageType as $, AtscriptExprNode$1 as $t, TCrudPermissions as A, TDbEncryptionOptions as An, TValueFormatterPair as At, TDbDeleteResult as B, isGeoPointType as Bt, NullableOptional as C, andFilters as Cn, TRelationInfo as Ct, TCascadeTarget as D, isResolvedRelationFilter as Dn, TTableOptionDiff as Dt, TCascadeResolver as E, hasRelationOp as En, TSyncColumnResult as Et, TDbActionTargetSummary as F, TGenericLogger as Fn, Uniquery$1 as Ft, TDbIndexType as G, DbSpace as Gt, TDbForeignKey as H, ALL_VIEW_CAPABILITIES as Ht, TDbAvailableActions as I, UniquSelect as In, UniqueryControls$1 as It, TDbObjectKind as J, AtscriptDbView as Jt, TDbInsertManyResult as K, TAdapterFactory as Kt, TDbCollation as L, WithRelation$1 as Lt, TDbActionIntent as M, FieldMappingStrategy as Mn, TWriteOptions as Mt, TDbActionLevel as N, TReadControls as Nn, TWriteTableResolver as Nt, TColumnDiff as O, relationStaticFilter as On, TTableResolver as Ot, TDbActionProcessor as P, NoopLogger as Pn, TypedWithRelation as Pt, TDbRemoveGuardContext as Q, aliasTargetOf as Qt, TDbDefaultFn as R, TableMetadata as Rt, NavPropsOf$1 as S, TRelationStaticFilter as Sn, TReferencingForeignKey as St, PrimaryKeyOf$1 as T, forEachResolvedRelation as Tn, TSearchIndexInfo as Tt, TDbIndex as U, BaseDbAdapter as Ut, TDbFieldMeta as V, ALL_BUCKET_UNITS as Vt, TDbIndexField as W, TViewCapability as Wt, TDbRelation as X, isAtscriptDbView as Xt, TDbReferentialAction as Y, TViewColumnMapping as Yt, TDbRemoveGuard as Z, isViewType as Zt, DbQuery as _, REL_FILTER_MAX_NODES as _n, TIdResolveOptions as _t, jsonValueAncestor as a, TViewJoin as an, TDbWriteGuardContext as at, FilterExpr$1 as b, TRelationFilterJunction as bn, TMetadataOverrides as bt, AggregateControls as c, translateQueryTree as cn, TDerivedColumn as ct, AggregateQuery$1 as d, NativeIntegrity as dn, TExistingForeignKey as dt, AtscriptOrderItem as en, TDbUpdateResult as et, AggregateResult as f, TCascadePin as fn, TExistingTableOption as ft, DbPatch as g, REL_FILTER_MAX_DEPTH as gn, TIdDescriptor as gt, DbControls as h, resolveDesignType as hn, TFkLookupTarget as ht, isJsonValueField as i, AtscriptRef as in, TDbWriteGuard as it, TDbActionInfo as j, DocumentFieldMapper as jn, TViewJsonType as jt, TCrudOp as k, DbEncryption as kn, TTouchManyOptions as kt, AggregateExpr$1 as l, AtscriptDbTable as ln, TEnsureTableOptions as lt, AtscriptDbWritable as m, DbResponse as mn, TFkLookupResolver as mt, TResolvedBucket as n, AtscriptQueryFieldRef$1 as nn, TDbWriteCheck as nt, normalizeComputedSelect as o, TViewPlan as on, TDeleteOptions as ot, AtscriptDbTableLike as p, AtscriptDbReadable as pn, TFieldMeta as pt, TDbInsertResult as q, TDbSpaceOptions as qt, isBucketableField as r, AtscriptQueryNode$1 as rn, TDbWriteCheckContext as rt, resolveCalendarBuckets as s, isFieldRef as sn, TDerivedChangeReason as st, TBucketFieldSource as t, AtscriptQueryComparison as tn, TDbWriteAction as tt, AggregateFn$1 as u, IntegrityStrategy as un, TExistingColumn as ut, DbRow as v, ResolvedRelationFilter as vn, TIdentification as vt, OwnPropsOf$1 as w, containsRelationFilter as wn, TRowResolveOptions as wt, FlatOf$1 as x, TRelationFilterTable as xn, TPrimaryKeyChange as xt, FieldOpsFor as y, TRelGuardState as yn, TMetaResponse as yt, TDbDefaultValue as z, isGeoIndexableType as zt };
|