@atscript/moost-db 0.1.58 → 0.1.59
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/README.md +1 -1
- package/dist/index.cjs +608 -290
- package/dist/index.d.cts +180 -136
- package/dist/index.d.mts +180 -136
- package/dist/index.mjs +604 -287
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _atscript_typescript_utils0 from "@atscript/typescript/utils";
|
|
2
2
|
import { TAtscriptAnnotatedType, TAtscriptDataType, TSerializeOptions, Validator } from "@atscript/typescript/utils";
|
|
3
3
|
import * as _uniqu_url0 from "@uniqu/url";
|
|
4
|
-
import { AtscriptDbReadable, AtscriptDbTable, FilterExpr, TCrudOp, TCrudPermissions, TCrudPermissions as TCrudPermissions$1, TDbActionInfo, TDbActionInfo as TDbActionInfo$1, TDbActionIntent, TDbActionIntent as TDbActionIntent$1, TDbActionLevel, TDbActionLevel as TDbActionLevel$1, TDbActionProcessor, TDbFieldMeta, TMetaResponse, Uniquery, UniqueryControls } from "@atscript/db";
|
|
4
|
+
import { AtscriptDbReadable, AtscriptDbTable, FilterExpr, FlatOf, TCrudOp, TCrudPermissions, TCrudPermissions as TCrudPermissions$1, TDbActionInfo, TDbActionInfo as TDbActionInfo$1, TDbActionIntent, TDbActionIntent as TDbActionIntent$1, TDbActionLevel, TDbActionLevel as TDbActionLevel$1, TDbActionProcessor, TDbFieldMeta, TIdentification, TMetaResponse, Uniquery, UniqueryControls } from "@atscript/db";
|
|
5
5
|
import { HttpError } from "@moostjs/event-http";
|
|
6
6
|
import * as moost from "moost";
|
|
7
7
|
import { Moost, TConsoleBase } from "moost";
|
|
@@ -154,6 +154,9 @@ declare class AsDbReadableController<T extends TAtscriptAnnotatedType = TAtscrip
|
|
|
154
154
|
/** Reference to the underlying readable (table or view). */
|
|
155
155
|
protected readable: AtscriptDbReadable<T>;
|
|
156
156
|
private readonly _gates;
|
|
157
|
+
private readonly _preferredIdSet;
|
|
158
|
+
private readonly _compositeIdShapes;
|
|
159
|
+
private readonly _overlayIsNoOp;
|
|
157
160
|
constructor(readable: AtscriptDbReadable<T>, app: Moost);
|
|
158
161
|
private _buildGates;
|
|
159
162
|
private _collectAnnotated;
|
|
@@ -176,6 +179,27 @@ declare class AsDbReadableController<T extends TAtscriptAnnotatedType = TAtscrip
|
|
|
176
179
|
* May return a Promise for async lookups.
|
|
177
180
|
*/
|
|
178
181
|
protected transformProjection(projection?: UniqueryControls["$select"]): UniqueryControls["$select"] | undefined | Promise<UniqueryControls["$select"] | undefined>;
|
|
182
|
+
private widenPreferredIdProjection;
|
|
183
|
+
private _widenArrayProjection;
|
|
184
|
+
private _widenMapProjection;
|
|
185
|
+
/** WHY: the URL parser only auto-coerces `$count`; every other boolean control reaches us as `"true"`/`"1"` and would fail DTO validation. */
|
|
186
|
+
private _coerceActionsControl;
|
|
187
|
+
/** Normalize a post-`widenPreferredIdProjection` $select into `string[] | null` (`null` = all fields). */
|
|
188
|
+
private _resolveProjectionForAugmenter;
|
|
189
|
+
/** WHY: filter row/rows envelopes by the per-request `applyMetaOverlay` action set; skip `meta()` when overlay is identity. */
|
|
190
|
+
private _resolveAugmentEnvelopes;
|
|
191
|
+
/** Returns a widened `$select` only when at least one `requiredFields` entry is missing; `null` means "no widening needed". */
|
|
192
|
+
private _widenSelectForActions;
|
|
193
|
+
private _prepareAugmentation;
|
|
194
|
+
private _resolveReadStrategy;
|
|
195
|
+
/**
|
|
196
|
+
* Shared `query` / `pages` pipeline: prepare actions augmentation + read
|
|
197
|
+
* strategy in parallel, pre-widen $select for `requiredFields`, run
|
|
198
|
+
* `exec`, and augment `result.data` with `$actions` when the request set
|
|
199
|
+
* `$actions=true`. Caller dispatches the strategy to its read-method
|
|
200
|
+
* family (count vs no-count).
|
|
201
|
+
*/
|
|
202
|
+
private _runReadWithActions;
|
|
179
203
|
/**
|
|
180
204
|
* Extracts a composite identifier object from query params.
|
|
181
205
|
* Tries composite primary key first, then compound unique indexes.
|
|
@@ -204,6 +228,7 @@ declare class AsDbReadableController<T extends TAtscriptAnnotatedType = TAtscrip
|
|
|
204
228
|
* (composite primary key or compound unique index).
|
|
205
229
|
*/
|
|
206
230
|
getOneComposite(query: Record<string, string>, url: string): Promise<DataType | HttpError>;
|
|
231
|
+
private _findByIdAndAugment;
|
|
207
232
|
/**
|
|
208
233
|
* **GET /meta** — returns table/view metadata for UI.
|
|
209
234
|
*
|
|
@@ -464,70 +489,81 @@ declare const UseValidationErrorTransform: () => ClassDecorator & MethodDecorato
|
|
|
464
489
|
/** `'rows'`-level batch policy — controls whether failing rows reject or are filtered out. */
|
|
465
490
|
type TOnDisabledRows = "reject" | "skip";
|
|
466
491
|
/**
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
* `'backend'` for method-decorator actions, and `value` is filled from the
|
|
476
|
-
* `@Post` path.
|
|
477
|
-
*
|
|
478
|
-
* Generic over `TRow` so the `disabled` predicate can be type-checked against
|
|
479
|
-
* the bound table's row shape. Note: TS decorators cannot infer `TRow` from
|
|
480
|
-
* the enclosing controller's class generic, so the dev MUST annotate the row
|
|
481
|
-
* arg explicitly (`(row: Order) => …`) to get type-checking.
|
|
492
|
+
* Dot-notation field paths of `TRow`'s flat type. Drives both the runtime
|
|
493
|
+
* projection widening and the type narrowing of the `disabled` predicate's
|
|
494
|
+
* row argument. Relations are absent from `FlatOf<T>` — listing a relation
|
|
495
|
+
* field is therefore a compile error.
|
|
496
|
+
*
|
|
497
|
+
* Permissive fallback when `TRow = unknown` (no explicit decorator generic):
|
|
498
|
+
* any string is allowed and the `disabled` predicate's row arg is `any[]`,
|
|
499
|
+
* preserving the prior loose typing for un-annotated call sites.
|
|
482
500
|
*/
|
|
483
|
-
type
|
|
501
|
+
type FlatKey<TRow> = unknown extends TRow ? string : keyof FlatOf<TRow> & string;
|
|
502
|
+
/** Row-shape narrowing for the `disabled` predicate. Falls back to `any` when `TRow = unknown`. */
|
|
503
|
+
type DisabledRowsArg<TRow, R extends readonly FlatKey<TRow>[]> = unknown extends TRow ? any[] : Pick<FlatOf<TRow>, R[number] & keyof FlatOf<TRow>>[];
|
|
504
|
+
interface NoGate {
|
|
505
|
+
requiredFields?: never;
|
|
506
|
+
disabled?: never;
|
|
507
|
+
onDisabledRows?: never;
|
|
508
|
+
}
|
|
509
|
+
interface WithGate<TRow, R extends readonly FlatKey<TRow>[]> {
|
|
484
510
|
/**
|
|
485
|
-
*
|
|
486
|
-
*
|
|
487
|
-
*
|
|
488
|
-
*
|
|
489
|
-
* The dev MUST annotate the row arg explicitly (`(row: Order) => …`) —
|
|
490
|
-
* TS decorators cannot infer `TRow` from the enclosing class generic.
|
|
511
|
+
* Dot-notation field paths the predicate references. SERVER-INTERNAL —
|
|
512
|
+
* never emitted on the `/meta` wire. Consumed verbatim to widen the DB
|
|
513
|
+
* projection so `disabled` always sees the fields it declared.
|
|
491
514
|
*/
|
|
492
|
-
|
|
515
|
+
requiredFields: R;
|
|
493
516
|
/**
|
|
494
|
-
*
|
|
495
|
-
*
|
|
496
|
-
*
|
|
497
|
-
*
|
|
498
|
-
* type pattern is finicky for nested objects/arrays/optionals and isn't
|
|
499
|
-
* blocking v1.
|
|
517
|
+
* Sync batch gate predicate — returns a parallel `boolean[]` aligned with
|
|
518
|
+
* the input. `true` = disabled for the corresponding row. The `rows`
|
|
519
|
+
* argument is type-narrowed to `Pick<FlatOf<TRow>, R[number]>[]`; reading
|
|
520
|
+
* a field not listed in `requiredFields` is a compile error.
|
|
500
521
|
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
* server does NOT auto-derive or merge.
|
|
522
|
+
* Promise return is NOT permitted — the predicate is consumed in the
|
|
523
|
+
* same tick by the gate and the augmenter.
|
|
504
524
|
*/
|
|
505
|
-
|
|
525
|
+
disabled?: (rows: DisabledRowsArg<TRow, R>) => boolean[];
|
|
506
526
|
/**
|
|
507
527
|
* `'rows'`-level batch policy. Default `'reject'`.
|
|
508
528
|
*
|
|
509
|
-
* - `'reject'`: evaluate every row
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
* zero survivors → reject. Handler runs against the survivors.
|
|
529
|
+
* - `'reject'`: evaluate every row before throwing; if any row fails, the
|
|
530
|
+
* error body lists ALL failing IDs; handler not invoked.
|
|
531
|
+
* - `'skip'`: filter cached rows + cached IDs to passing-only; zero
|
|
532
|
+
* survivors → reject. Handler runs against the survivors.
|
|
514
533
|
*
|
|
515
534
|
* Ignored for `'row'` and `'table'` level actions.
|
|
516
535
|
*/
|
|
517
536
|
onDisabledRows?: TOnDisabledRows;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Loose gate shape used when `TRow = unknown` (no explicit decorator generic).
|
|
540
|
+
* Preserves the prior un-typed call-site flexibility; the runtime still drops
|
|
541
|
+
* actions where `disabled` is set without `requiredFields`.
|
|
542
|
+
*/
|
|
543
|
+
interface LooseGate {
|
|
544
|
+
requiredFields?: string[];
|
|
545
|
+
disabled?: (rows: any[]) => boolean[];
|
|
546
|
+
onDisabledRows?: TOnDisabledRows;
|
|
547
|
+
}
|
|
548
|
+
type GateOpts<TRow, R extends readonly FlatKey<TRow>[]> = unknown extends TRow ? LooseGate : NoGate | WithGate<TRow, R>;
|
|
549
|
+
interface BaseActionOpts extends Partial<Omit<TDbActionInfo$1, "name" | "level" | "processor" | "value" | "disabled">> {
|
|
518
550
|
/**
|
|
519
551
|
* Bound table reference. REQUIRED on non-`AsDbReadableController` classes
|
|
520
552
|
* when `disabled` is set OR a `@DbActionRow*` parameter is declared.
|
|
521
553
|
*
|
|
522
554
|
* Silently ignored on `AsDbReadableController` subclasses (which include
|
|
523
|
-
* `AsDbController`) — the bound table from the controller wins
|
|
524
|
-
* gate / thin interceptor probes `instanceof AsDbReadableController` and
|
|
525
|
-
* populates the bound-table slot from `controller.readable` before
|
|
526
|
-
* checking `opts.table`.
|
|
555
|
+
* `AsDbController`) — the bound table from the controller wins.
|
|
527
556
|
*/
|
|
528
557
|
table?: AtscriptDbTable<any>;
|
|
529
|
-
}
|
|
530
|
-
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Options accepted by `@DbAction(name, opts?)`. Generic over `TRow` (the
|
|
561
|
+
* controller's bound atscript type) and `R` (the literal `requiredFields`
|
|
562
|
+
* tuple). Both are inferred at the call site via the decorator's `<TRow>`
|
|
563
|
+
* argument plus `const R` generic.
|
|
564
|
+
*/
|
|
565
|
+
type DbActionOpts<TRow = unknown, R extends readonly FlatKey<TRow>[] = []> = BaseActionOpts & GateOpts<TRow, R>;
|
|
566
|
+
interface DbActionsEntryCommonBase {
|
|
531
567
|
label: string;
|
|
532
568
|
level: TDbActionLevel$1;
|
|
533
569
|
icon?: string;
|
|
@@ -539,51 +575,36 @@ interface DbActionsEntryCommon {
|
|
|
539
575
|
promptText?: string | [string, string];
|
|
540
576
|
/** Mirrors {@link TDbActionInfo.shortcut} — single-character UI hint. */
|
|
541
577
|
shortcut?: string;
|
|
542
|
-
/**
|
|
543
|
-
* UI-only gate predicate (class-level dict entries do NOT register a
|
|
544
|
-
* server-side gate interceptor — the dict entry's `value` may point at an
|
|
545
|
-
* endpoint in another controller). The wire emits `fn.toString()` so the
|
|
546
|
-
* UI can grey-out / hide the button. For symmetric server enforcement at
|
|
547
|
-
* the actual `@Post`-bound handler, declare `@DbAction(name, { disabled })`
|
|
548
|
-
* on that handler too.
|
|
549
|
-
*
|
|
550
|
-
* Not generic over `TRow` — devs type the row arg explicitly.
|
|
551
|
-
*/
|
|
552
|
-
disabled?: (row: any) => boolean;
|
|
553
|
-
/** Same as method-decorator `requiredFields`. UI hint, not server-derived. */
|
|
554
|
-
requiredFields?: string[];
|
|
555
|
-
/**
|
|
556
|
-
* Reserved for future API symmetry with method-decorator opts. Currently a
|
|
557
|
-
* no-op for class-level dict entries (no gate interceptor registers).
|
|
558
|
-
*/
|
|
559
|
-
onDisabledRows?: TOnDisabledRows;
|
|
560
578
|
}
|
|
579
|
+
type DbActionsEntryWithGate<TRow, R extends readonly FlatKey<TRow>[]> = DbActionsEntryCommonBase & GateOpts<TRow, R>;
|
|
561
580
|
/**
|
|
562
581
|
* Class-level dict entry. `value` semantics by processor:
|
|
563
582
|
*
|
|
564
|
-
* - `'navigate'` — REQUIRED, non-empty.
|
|
565
|
-
* - `'backend'` — REQUIRED, non-empty.
|
|
566
|
-
* For row/rows entries the dev-supplied path MUST point to a `@Post`-bound
|
|
567
|
-
* handler accepting the PK-shaped JSON body (single PK scalar / composite
|
|
568
|
-
* object / array thereof) — typically a method using `@DbActionPK()` or
|
|
569
|
-
* `@DbActionPKs()`. The meta builder does NOT validate this.
|
|
583
|
+
* - `'navigate'` — REQUIRED, non-empty. URL template (`$1` substituted client-side).
|
|
584
|
+
* - `'backend'` — REQUIRED, non-empty. Full HTTP POST path the UI client invokes.
|
|
570
585
|
* - `'custom'` — `value` is forbidden in the entry; the meta builder fills it
|
|
571
586
|
* with the dict key.
|
|
572
587
|
*/
|
|
573
|
-
type TDbActionsEntry = (
|
|
588
|
+
type TDbActionsEntry<TRow = unknown, R extends readonly FlatKey<TRow>[] = []> = (DbActionsEntryWithGate<TRow, R> & {
|
|
574
589
|
processor: "navigate";
|
|
575
590
|
value: string;
|
|
576
|
-
}) | (
|
|
591
|
+
}) | (DbActionsEntryWithGate<TRow, R> & {
|
|
577
592
|
processor: "custom";
|
|
578
593
|
value?: never;
|
|
579
|
-
}) | (
|
|
594
|
+
}) | (DbActionsEntryWithGate<TRow, R> & {
|
|
580
595
|
processor: "backend";
|
|
581
596
|
value: string;
|
|
582
597
|
});
|
|
583
598
|
/** Distributes `Omit` across the discriminated union members. */
|
|
584
599
|
type DistributiveOmit<T, K extends keyof T> = T extends T ? Omit<T, K> : never;
|
|
585
600
|
/** Same as {@link TDbActionsEntry} but without the `level` field — used by the level-pinned shortcuts. */
|
|
586
|
-
type TDbActionsEntryUnpinned = DistributiveOmit<TDbActionsEntry, "level">;
|
|
601
|
+
type TDbActionsEntryUnpinned<TRow = unknown, R extends readonly FlatKey<TRow>[] = []> = DistributiveOmit<TDbActionsEntry<TRow, R>, "level">;
|
|
602
|
+
type DbActionsDictBase = Record<string, unknown>;
|
|
603
|
+
type EntryRequiredFields<E, TRow> = E extends {
|
|
604
|
+
requiredFields: infer R;
|
|
605
|
+
} ? R extends readonly FlatKey<TRow>[] ? R : [] : [];
|
|
606
|
+
type ValidatedDict<TRow, D extends DbActionsDictBase> = { [K in keyof D]: TDbActionsEntry<TRow, EntryRequiredFields<D[K], TRow>> };
|
|
607
|
+
type ValidatedUnpinnedDict<TRow, D extends DbActionsDictBase> = { [K in keyof D]: TDbActionsEntryUnpinned<TRow, EntryRequiredFields<D[K], TRow>> };
|
|
587
608
|
//#endregion
|
|
588
609
|
//#region src/actions/db-action.decorator.d.ts
|
|
589
610
|
/**
|
|
@@ -592,8 +613,13 @@ type TDbActionsEntryUnpinned = DistributiveOmit<TDbActionsEntry, "level">;
|
|
|
592
613
|
* (gate when `disabled` is set, thin bound-table injector when only
|
|
593
614
|
* `@DbActionRow*` is present). Stacking two `@DbAction` on the same method
|
|
594
615
|
* is undefined and emits a warning.
|
|
616
|
+
*
|
|
617
|
+
* Generic over `TRow` (annotate at the call site: `@DbAction<Order>(...)`)
|
|
618
|
+
* and `R` (the literal `requiredFields` tuple, inferred via `const R`).
|
|
619
|
+
* The `disabled` predicate's `rows` argument is type-narrowed to
|
|
620
|
+
* `Pick<FlatOf<TRow>, R[number]>[]`.
|
|
595
621
|
*/
|
|
596
|
-
declare function DbAction<TRow = unknown>(name: string, opts?: DbActionOpts<TRow>): MethodDecorator;
|
|
622
|
+
declare function DbAction<TRow = unknown, const R extends readonly FlatKey<TRow>[] = []>(name: string, opts?: DbActionOpts<TRow, R>): MethodDecorator;
|
|
597
623
|
//#endregion
|
|
598
624
|
//#region src/actions/db-action-default.decorator.d.ts
|
|
599
625
|
/**
|
|
@@ -602,49 +628,56 @@ declare function DbAction<TRow = unknown>(name: string, opts?: DbActionOpts<TRow
|
|
|
602
628
|
*/
|
|
603
629
|
declare function DbActionDefault(): MethodDecorator;
|
|
604
630
|
//#endregion
|
|
605
|
-
//#region src/actions/db-action-
|
|
631
|
+
//#region src/actions/db-action-id.decorator.d.ts
|
|
606
632
|
/**
|
|
607
|
-
* Parameter resolver that reads
|
|
608
|
-
* and validates it against the bound table's
|
|
633
|
+
* Parameter resolver that reads a row identifier from the JSON request body
|
|
634
|
+
* and validates it against the bound table's legitimate identifiers.
|
|
609
635
|
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
636
|
+
* Body shape is always a JSON object — no scalar form. The object's key set
|
|
637
|
+
* MUST exactly match one of the table's legitimate identifications:
|
|
612
638
|
*
|
|
613
|
-
*
|
|
639
|
+
* - Single-field PK → `{ id: "abc" }` (or whatever the PK prop is named).
|
|
640
|
+
* - Composite PK → `{ tenantId: "...", userId: "..." }`.
|
|
641
|
+
* - Single-field unique index → `{ slug: "alpha" }`.
|
|
642
|
+
* - Compound unique index → `{ tenantId: "...", slug: "..." }`.
|
|
643
|
+
*
|
|
644
|
+
* Strict — unknown fields are rejected, no type coercion. Mismatches throw a
|
|
614
645
|
* `ValidatorError` which the existing validation interceptor surfaces as
|
|
615
646
|
* HTTP 400 with the same envelope as DTO failures.
|
|
616
647
|
*
|
|
617
648
|
* Marks the param so {@link discoverActions} can infer the action's `level`
|
|
618
649
|
* as `'row'`.
|
|
619
650
|
*
|
|
620
|
-
* Implementation note: the resolver is a thin reader of the cached
|
|
651
|
+
* Implementation note: the resolver is a thin reader of the cached ID wook
|
|
621
652
|
* — validation logic lives in the wook factory, which runs once per request
|
|
622
653
|
* regardless of how many readers consume the value.
|
|
623
654
|
*/
|
|
624
|
-
declare function
|
|
655
|
+
declare function DbActionID(): ParameterDecorator;
|
|
625
656
|
//#endregion
|
|
626
|
-
//#region src/actions/db-action-
|
|
657
|
+
//#region src/actions/db-action-ids.decorator.d.ts
|
|
627
658
|
/**
|
|
628
|
-
* Parameter resolver that reads a JSON array of
|
|
629
|
-
* body and validates each entry against the bound table
|
|
659
|
+
* Parameter resolver that reads a JSON array of row identifiers from the
|
|
660
|
+
* request body and validates each entry against the bound table.
|
|
630
661
|
*
|
|
631
|
-
*
|
|
632
|
-
*
|
|
662
|
+
* Body shape is always a JSON array of objects — no scalar form. Each
|
|
663
|
+
* element's key set MUST exactly match one of the table's legitimate
|
|
664
|
+
* identifications (PK or any unique index). Elements MAY mix shapes:
|
|
665
|
+
* `[{ id: "1" }, { slug: "alpha" }]` is valid when both `id` is the PK
|
|
666
|
+
* and `slug` is a unique index.
|
|
633
667
|
*
|
|
634
|
-
*
|
|
635
|
-
* {@link discoverActions} can infer the action's `level` as `'rows'`.
|
|
668
|
+
* Strict — unknown fields are rejected, no type coercion. Marks the param
|
|
669
|
+
* so {@link discoverActions} can infer the action's `level` as `'rows'`.
|
|
636
670
|
*
|
|
637
671
|
* In `'rows'` skip mode the resolved value reflects the gate interceptor's
|
|
638
|
-
* filtered subset (the cached
|
|
639
|
-
* {@link
|
|
672
|
+
* filtered subset (the cached ID slot is overwritten in place); see
|
|
673
|
+
* {@link dbActionIdsSlot} for precedence details.
|
|
640
674
|
*/
|
|
641
|
-
declare function
|
|
675
|
+
declare function DbActionIDs(): ParameterDecorator;
|
|
642
676
|
//#endregion
|
|
643
677
|
//#region src/actions/db-action-row.decorator.d.ts
|
|
644
678
|
/**
|
|
645
|
-
* Parameter decorator that injects the row whose
|
|
646
|
-
* request body.
|
|
647
|
-
* shared with the gate interceptor when `disabled` is set).
|
|
679
|
+
* Parameter decorator that injects the row whose identifier was supplied in
|
|
680
|
+
* the request body.
|
|
648
681
|
*
|
|
649
682
|
* Marks the param so {@link discoverActions} infers the action's `level` as
|
|
650
683
|
* `'row'`. Co-occurrence with `@DbActionRows()` (or any multi-cardinality
|
|
@@ -655,8 +688,8 @@ declare function DbActionPKs(): ParameterDecorator;
|
|
|
655
688
|
*/
|
|
656
689
|
declare function DbActionRow(): ParameterDecorator;
|
|
657
690
|
/**
|
|
658
|
-
* Parameter decorator that injects the rows
|
|
659
|
-
*
|
|
691
|
+
* Parameter decorator that injects the rows fetched by the identifiers
|
|
692
|
+
* supplied in the request body.
|
|
660
693
|
*
|
|
661
694
|
* Marks the param so {@link discoverActions} infers the action's `level` as
|
|
662
695
|
* `'rows'`. In `'rows'` + `'skip'` mode the resolved value contains only the
|
|
@@ -672,50 +705,46 @@ declare function DbActionRows(): ParameterDecorator;
|
|
|
672
705
|
* the level-pinned shortcuts (`@DbTableActions`, `@DbRowActions`,
|
|
673
706
|
* `@DbRowsActions`) to avoid repeating `level`.
|
|
674
707
|
*
|
|
675
|
-
*
|
|
676
|
-
*
|
|
677
|
-
* `
|
|
678
|
-
* `@Post`-bound endpoint accepting the level-determined body shape.
|
|
708
|
+
* Generic over `TRow` (annotate at the call site: `@DbActions<Order>(...)`)
|
|
709
|
+
* and `D` (the literal dict, captured via `const D`). Each entry's
|
|
710
|
+
* `disabled` predicate is type-narrowed by its own `requiredFields` literal.
|
|
679
711
|
*
|
|
680
712
|
* Multiple `@DbActions` (and shortcut) decorators on the same class
|
|
681
713
|
* accumulate.
|
|
682
714
|
*/
|
|
683
|
-
declare function DbActions(dict:
|
|
715
|
+
declare function DbActions<TRow = unknown, const D extends Record<string, unknown> = {}>(dict: D & ValidatedDict<TRow, D>): ClassDecorator;
|
|
684
716
|
/** Sugar for `@DbActions` with `level: 'table'` injected into each entry. */
|
|
685
|
-
declare function DbTableActions(dict:
|
|
717
|
+
declare function DbTableActions<TRow = unknown, const D extends Record<string, unknown> = {}>(dict: D & ValidatedUnpinnedDict<TRow, D>): ClassDecorator;
|
|
686
718
|
/** Sugar for `@DbActions` with `level: 'row'` injected into each entry. */
|
|
687
|
-
declare function DbRowActions(dict:
|
|
719
|
+
declare function DbRowActions<TRow = unknown, const D extends Record<string, unknown> = {}>(dict: D & ValidatedUnpinnedDict<TRow, D>): ClassDecorator;
|
|
688
720
|
/** Sugar for `@DbActions` with `level: 'rows'` injected into each entry. */
|
|
689
|
-
declare function DbRowsActions(dict:
|
|
721
|
+
declare function DbRowsActions<TRow = unknown, const D extends Record<string, unknown> = {}>(dict: D & ValidatedUnpinnedDict<TRow, D>): ClassDecorator;
|
|
690
722
|
//#endregion
|
|
691
723
|
//#region src/actions/discover.d.ts
|
|
692
724
|
/**
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
* Result is memoized per controller constructor — discovery walks every
|
|
698
|
-
* handler entry and reads decorator metadata, which is wasted work to repeat
|
|
699
|
-
* across instances.
|
|
725
|
+
* Pairs the wire-shaped `info` with the original decorator opts / dict entry,
|
|
726
|
+
* so the augmenter can invoke the live `disabled` reference (deliberately
|
|
727
|
+
* absent from the wire `info`).
|
|
700
728
|
*/
|
|
701
|
-
|
|
729
|
+
interface TDbActionEnvelope {
|
|
730
|
+
info: TDbActionInfo$1;
|
|
731
|
+
raw: DbActionOpts | TDbActionsEntry;
|
|
732
|
+
}
|
|
733
|
+
/** Discover actions on a controller, memoized per ctor. `info`-only callers map `e => e.info`. */
|
|
734
|
+
declare function discoverActions(controllerCtor: Function, app: Moost, logger: TConsoleBase): TDbActionEnvelope[];
|
|
702
735
|
//#endregion
|
|
703
|
-
//#region src/actions/
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
* controller's underlying `AtscriptDbReadable`/`AtscriptDbTable`.
|
|
707
|
-
*/
|
|
708
|
-
interface PkValidationSource {
|
|
709
|
-
primaryKeys: readonly string[];
|
|
736
|
+
//#region src/actions/id-validation.d.ts
|
|
737
|
+
interface IdValidationSource {
|
|
738
|
+
getIdentifications(): readonly TIdentification[];
|
|
710
739
|
fieldDescriptors: readonly TDbFieldMeta[];
|
|
711
740
|
}
|
|
712
741
|
//#endregion
|
|
713
|
-
//#region src/actions/
|
|
714
|
-
declare const
|
|
715
|
-
load: () => Promise<unknown
|
|
742
|
+
//#region src/actions/id-cache.d.ts
|
|
743
|
+
declare const useDbActionId: _wooksjs_event_core0.WookComposable<{
|
|
744
|
+
load: () => Promise<Record<string, unknown>>;
|
|
716
745
|
}>;
|
|
717
|
-
declare const
|
|
718
|
-
load: () => Promise<unknown[]>;
|
|
746
|
+
declare const useDbActionIds: _wooksjs_event_core0.WookComposable<{
|
|
747
|
+
load: () => Promise<Record<string, unknown>[]>;
|
|
719
748
|
}>;
|
|
720
749
|
//#endregion
|
|
721
750
|
//#region src/actions/row-cache.d.ts
|
|
@@ -723,7 +752,7 @@ declare const useDbActionRow: _wooksjs_event_core0.WookComposable<{
|
|
|
723
752
|
load: () => Promise<unknown>;
|
|
724
753
|
}>;
|
|
725
754
|
declare const useDbActionRows: _wooksjs_event_core0.WookComposable<{
|
|
726
|
-
load: () => Promise<unknown[]>;
|
|
755
|
+
load: () => Promise<(Record<string, unknown> | undefined)[]>;
|
|
727
756
|
}>;
|
|
728
757
|
//#endregion
|
|
729
758
|
//#region src/actions/action-disabled-error.d.ts
|
|
@@ -736,8 +765,8 @@ declare const useDbActionRows: _wooksjs_event_core0.WookComposable<{
|
|
|
736
765
|
*
|
|
737
766
|
* - `name: 'ActionDisabledError'` — discriminator the client matches.
|
|
738
767
|
* - `action` — the `@DbAction` name that rejected the request.
|
|
739
|
-
* - `
|
|
740
|
-
* - `
|
|
768
|
+
* - `id?` — present only for `'row'`-level rejections.
|
|
769
|
+
* - `ids?` — present only for `'rows'`-level rejections.
|
|
741
770
|
*
|
|
742
771
|
* `message` is populated with a human-readable string so generic
|
|
743
772
|
* `ClientError` consumers (which read `body.message`) still get something
|
|
@@ -748,27 +777,42 @@ interface ActionDisabledErrorBody {
|
|
|
748
777
|
message: string;
|
|
749
778
|
statusCode: 409;
|
|
750
779
|
action: string;
|
|
751
|
-
|
|
752
|
-
|
|
780
|
+
id?: Record<string, unknown>;
|
|
781
|
+
ids?: Record<string, unknown>[];
|
|
753
782
|
}
|
|
754
783
|
/**
|
|
755
784
|
* Thrown by the gate interceptor when `disabled` returns truthy. Composes
|
|
756
785
|
* with Moost's existing error mapper to produce HTTP 409 with the wire body
|
|
757
786
|
* defined by {@link ActionDisabledErrorBody}.
|
|
758
787
|
*
|
|
759
|
-
* - `'row'`-level rejection: pass `(action,
|
|
760
|
-
* - `'rows'`-level rejection: pass `(action, undefined,
|
|
761
|
-
* emits `
|
|
762
|
-
* of request
|
|
788
|
+
* - `'row'`-level rejection: pass `(action, id)` — the body emits `id`.
|
|
789
|
+
* - `'rows'`-level rejection: pass `(action, undefined, ids)` — the body
|
|
790
|
+
* emits `ids` (the FULL list of failing IDs in reject mode; the FULL list
|
|
791
|
+
* of request IDs in skip mode with zero survivors).
|
|
763
792
|
*/
|
|
764
793
|
declare class ActionDisabledError extends HttpError<ActionDisabledErrorBody> {
|
|
765
794
|
name: string;
|
|
766
|
-
constructor(action: string,
|
|
795
|
+
constructor(action: string, id?: Record<string, unknown>, ids?: Record<string, unknown>[]);
|
|
767
796
|
}
|
|
768
797
|
//#endregion
|
|
798
|
+
//#region src/actions/per-row.d.ts
|
|
799
|
+
/**
|
|
800
|
+
* Lift a per-row predicate into the batch shape required by
|
|
801
|
+
* `@DbAction` opts.`disabled` and class-level dict `disabled`. Polarity is
|
|
802
|
+
* preserved — `true` from `fn` means the action is disabled for that row.
|
|
803
|
+
*
|
|
804
|
+
* ```ts
|
|
805
|
+
* @DbAction<Order>('archive', {
|
|
806
|
+
* requiredFields: ['status'],
|
|
807
|
+
* disabled: perRow(r => r.status === 'archived'),
|
|
808
|
+
* })
|
|
809
|
+
* ```
|
|
810
|
+
*/
|
|
811
|
+
declare const perRow: <TRow>(fn: (row: TRow) => boolean) => (rows: TRow[]) => boolean[];
|
|
812
|
+
//#endregion
|
|
769
813
|
//#region src/permissions/crud-controls.d.ts
|
|
770
814
|
declare const QUERY_CONTROLS: readonly string[];
|
|
771
815
|
declare const PAGES_CONTROLS: readonly string[];
|
|
772
816
|
declare const ONE_CONTROLS: readonly string[];
|
|
773
817
|
//#endregion
|
|
774
|
-
export { ActionDisabledError, ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault,
|
|
818
|
+
export { ActionDisabledError, ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionID, DbActionIDs, DbActionOpts, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, IdValidationSource, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, TDbActionsEntry, TDbActionsEntryUnpinned, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, discoverActions, perRow, useDbActionId, useDbActionIds, useDbActionRow, useDbActionRows, validationErrorTransform };
|