@atscript/moost-db 0.1.57 → 0.1.58

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.cts CHANGED
@@ -5,6 +5,7 @@ import { AtscriptDbReadable, AtscriptDbTable, FilterExpr, TCrudOp, TCrudPermissi
5
5
  import { HttpError } from "@moostjs/event-http";
6
6
  import * as moost from "moost";
7
7
  import { Moost, TConsoleBase } from "moost";
8
+ import * as _wooksjs_event_core0 from "@wooksjs/event-core";
8
9
 
9
10
  //#region src/as-readable.controller.d.ts
10
11
  /**
@@ -460,15 +461,72 @@ declare const validationErrorTransform: () => moost.TInterceptorDef;
460
461
  declare const UseValidationErrorTransform: () => ClassDecorator & MethodDecorator;
461
462
  //#endregion
462
463
  //#region src/actions/types.d.ts
464
+ /** `'rows'`-level batch policy — controls whether failing rows reject or are filtered out. */
465
+ type TOnDisabledRows = "reject" | "skip";
463
466
  /**
464
467
  * Options accepted by `@DbAction(name, opts?)`. Structurally derived from
465
- * {@link TDbActionInfo} so every addition to the wire shape automatically
466
- * propagates here. Fields owned by the framework (`name`, `level`, `processor`,
467
- * `value`) are excluded `name` comes from the decorator argument, `level` is
468
- * inferred from `@DbActionPK*` usage, `processor` is fixed to `'backend'` for
469
- * method-decorator actions, and `value` is filled from the `@Post` path.
468
+ * {@link TDbActionInfo} so every wire-shape addition propagates here, EXCEPT
469
+ * `disabled` and `requiredFields` which differ in shape between decorator
470
+ * opts (function / dev-supplied) and the wire (string / forwarded verbatim).
471
+ *
472
+ * Fields owned by the framework (`name`, `level`, `processor`, `value`) are
473
+ * excluded — `name` comes from the decorator argument, `level` is inferred
474
+ * from `@DbActionPK*` / `@DbActionRow*` usage, `processor` is fixed to
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.
470
482
  */
471
- type DbActionOpts = Partial<Omit<TDbActionInfo$1, "name" | "level" | "processor" | "value">>;
483
+ type DbActionOpts<TRow = unknown> = Partial<Omit<TDbActionInfo$1, "name" | "level" | "processor" | "value" | "disabled" | "requiredFields">> & {
484
+ /**
485
+ * Per-row gate predicate. Truthy → action is disabled for that row.
486
+ * Server enforces (via the gate interceptor); UI evaluates the same
487
+ * expression to grey-out / hide the button.
488
+ *
489
+ * The dev MUST annotate the row arg explicitly (`(row: Order) => …`) —
490
+ * TS decorators cannot infer `TRow` from the enclosing class generic.
491
+ */
492
+ disabled?: (row: TRow) => boolean;
493
+ /**
494
+ * Optional dot-notation field paths the UI should union into `$select`.
495
+ * Plain `string[]` in v1.
496
+ *
497
+ * TODO: upgrade to typed `PathOf<TRow>[]` in a follow-up — the recursive
498
+ * type pattern is finicky for nested objects/arrays/optionals and isn't
499
+ * blocking v1.
500
+ *
501
+ * When omitted, the UI parses the stringified `disabled` itself to extract
502
+ * row-property accesses. When present, the UI uses this list verbatim — the
503
+ * server does NOT auto-derive or merge.
504
+ */
505
+ requiredFields?: string[];
506
+ /**
507
+ * `'rows'`-level batch policy. Default `'reject'`.
508
+ *
509
+ * - `'reject'`: evaluate every row (FULL scan, NOT short-circuit) before
510
+ * throwing; if any row fails, the error body lists ALL failing PKs;
511
+ * handler not invoked.
512
+ * - `'skip'`: filter cached rows + cached PKs to passing-only;
513
+ * zero survivors → reject. Handler runs against the survivors.
514
+ *
515
+ * Ignored for `'row'` and `'table'` level actions.
516
+ */
517
+ onDisabledRows?: TOnDisabledRows;
518
+ /**
519
+ * Bound table reference. REQUIRED on non-`AsDbReadableController` classes
520
+ * when `disabled` is set OR a `@DbActionRow*` parameter is declared.
521
+ *
522
+ * Silently ignored on `AsDbReadableController` subclasses (which include
523
+ * `AsDbController`) — the bound table from the controller wins; the
524
+ * gate / thin interceptor probes `instanceof AsDbReadableController` and
525
+ * populates the bound-table slot from `controller.readable` before
526
+ * checking `opts.table`.
527
+ */
528
+ table?: AtscriptDbTable<any>;
529
+ };
472
530
  interface DbActionsEntryCommon {
473
531
  label: string;
474
532
  level: TDbActionLevel$1;
@@ -477,7 +535,28 @@ interface DbActionsEntryCommon {
477
535
  description?: string;
478
536
  order?: number;
479
537
  default?: boolean;
480
- promptText?: string;
538
+ /** Mirrors {@link TDbActionInfo.promptText} — singular/plural via tuple. */
539
+ promptText?: string | [string, string];
540
+ /** Mirrors {@link TDbActionInfo.shortcut} — single-character UI hint. */
541
+ 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;
481
560
  }
482
561
  /**
483
562
  * Class-level dict entry. `value` semantics by processor:
@@ -508,21 +587,13 @@ type TDbActionsEntryUnpinned = DistributiveOmit<TDbActionsEntry, "level">;
508
587
  //#endregion
509
588
  //#region src/actions/db-action.decorator.d.ts
510
589
  /**
511
- * Mark a controller method as a database action surfaced via `/meta`.
512
- *
513
- * Metadata-only pair with `@Post(...)` for Moost to bind the route. The
514
- * meta builder reads this metadata plus the bound POST path lazily and
515
- * emits the action with `processor: 'backend'`. Order vs.
516
- * `@DbActionDefault()` does not matter — both merge into the same slot.
517
- *
518
- * @example
519
- * ```ts
520
- * @Post('actions/block')
521
- * @DbAction('block', { label: 'Block', icon: 'i-as-block', intent: 'negative' })
522
- * async blockUser(@DbActionPK() id: string) { ... }
523
- * ```
590
+ * Mark a controller method as a database action surfaced via `/meta`. Writes
591
+ * `MOOST_DB_ACTION` metadata and registers a Moost interceptor when needed
592
+ * (gate when `disabled` is set, thin bound-table injector when only
593
+ * `@DbActionRow*` is present). Stacking two `@DbAction` on the same method
594
+ * is undefined and emits a warning.
524
595
  */
525
- declare function DbAction(name: string, opts?: DbActionOpts): MethodDecorator;
596
+ declare function DbAction<TRow = unknown>(name: string, opts?: DbActionOpts<TRow>): MethodDecorator;
526
597
  //#endregion
527
598
  //#region src/actions/db-action-default.decorator.d.ts
528
599
  /**
@@ -545,6 +616,10 @@ declare function DbActionDefault(): MethodDecorator;
545
616
  *
546
617
  * Marks the param so {@link discoverActions} can infer the action's `level`
547
618
  * as `'row'`.
619
+ *
620
+ * Implementation note: the resolver is a thin reader of the cached PK wook
621
+ * — validation logic lives in the wook factory, which runs once per request
622
+ * regardless of how many readers consume the value.
548
623
  */
549
624
  declare function DbActionPK(): ParameterDecorator;
550
625
  //#endregion
@@ -558,9 +633,37 @@ declare function DbActionPK(): ParameterDecorator;
558
633
  *
559
634
  * Validation is strict — no type coercion. Marks the param so
560
635
  * {@link discoverActions} can infer the action's `level` as `'rows'`.
636
+ *
637
+ * In `'rows'` skip mode the resolved value reflects the gate interceptor's
638
+ * filtered subset (the cached PK slot is overwritten in place); see
639
+ * {@link dbActionPksSlot} for precedence details.
561
640
  */
562
641
  declare function DbActionPKs(): ParameterDecorator;
563
642
  //#endregion
643
+ //#region src/actions/db-action-row.decorator.d.ts
644
+ /**
645
+ * Parameter decorator that injects the row whose PK was supplied in the
646
+ * request body. Reads from the cached row wook (fetched once per request,
647
+ * shared with the gate interceptor when `disabled` is set).
648
+ *
649
+ * Marks the param so {@link discoverActions} infers the action's `level` as
650
+ * `'row'`. Co-occurrence with `@DbActionRows()` (or any multi-cardinality
651
+ * decorator) drops the action with a warning.
652
+ *
653
+ * In `'skip'` mode this returns the gate's filtered row; the original
654
+ * request-body row is not retrievable.
655
+ */
656
+ declare function DbActionRow(): ParameterDecorator;
657
+ /**
658
+ * Parameter decorator that injects the rows-array fetched by primary keys
659
+ * from the request body. Reads from the cached row-array wook.
660
+ *
661
+ * Marks the param so {@link discoverActions} infers the action's `level` as
662
+ * `'rows'`. In `'rows'` + `'skip'` mode the resolved value contains only the
663
+ * gate's surviving rows.
664
+ */
665
+ declare function DbActionRows(): ParameterDecorator;
666
+ //#endregion
564
667
  //#region src/actions/db-actions.decorator.d.ts
565
668
  /**
566
669
  * Declare class-level actions on a controller. Entries are flat dicts with
@@ -607,9 +710,65 @@ interface PkValidationSource {
607
710
  fieldDescriptors: readonly TDbFieldMeta[];
608
711
  }
609
712
  //#endregion
713
+ //#region src/actions/pk-cache.d.ts
714
+ declare const useDbActionPk: _wooksjs_event_core0.WookComposable<{
715
+ load: () => Promise<unknown>;
716
+ }>;
717
+ declare const useDbActionPks: _wooksjs_event_core0.WookComposable<{
718
+ load: () => Promise<unknown[]>;
719
+ }>;
720
+ //#endregion
721
+ //#region src/actions/row-cache.d.ts
722
+ declare const useDbActionRow: _wooksjs_event_core0.WookComposable<{
723
+ load: () => Promise<unknown>;
724
+ }>;
725
+ declare const useDbActionRows: _wooksjs_event_core0.WookComposable<{
726
+ load: () => Promise<unknown[]>;
727
+ }>;
728
+ //#endregion
729
+ //#region src/actions/action-disabled-error.d.ts
730
+ /**
731
+ * Wire-body shape for server-side gate rejections. The `name` discriminator
732
+ * lets `@atscript/db-client` recognise the response and construct the typed
733
+ * `ActionDisabledError` subclass. The shape extends Moost's standard
734
+ * `ServerError` envelope (`{ message, statusCode, errors? }`) with three
735
+ * additional fields:
736
+ *
737
+ * - `name: 'ActionDisabledError'` — discriminator the client matches.
738
+ * - `action` — the `@DbAction` name that rejected the request.
739
+ * - `pk?` — present only for `'row'`-level rejections.
740
+ * - `pks?` — present only for `'rows'`-level rejections.
741
+ *
742
+ * `message` is populated with a human-readable string so generic
743
+ * `ClientError` consumers (which read `body.message`) still get something
744
+ * useful without typed-catch dispatch.
745
+ */
746
+ interface ActionDisabledErrorBody {
747
+ name: "ActionDisabledError";
748
+ message: string;
749
+ statusCode: 409;
750
+ action: string;
751
+ pk?: unknown;
752
+ pks?: unknown[];
753
+ }
754
+ /**
755
+ * Thrown by the gate interceptor when `disabled` returns truthy. Composes
756
+ * with Moost's existing error mapper to produce HTTP 409 with the wire body
757
+ * defined by {@link ActionDisabledErrorBody}.
758
+ *
759
+ * - `'row'`-level rejection: pass `(action, pk)` — the body emits `pk`.
760
+ * - `'rows'`-level rejection: pass `(action, undefined, pks)` — the body
761
+ * emits `pks` (the FULL list of failing PKs in reject mode; the FULL list
762
+ * of request PKs in skip mode with zero survivors).
763
+ */
764
+ declare class ActionDisabledError extends HttpError<ActionDisabledErrorBody> {
765
+ name: string;
766
+ constructor(action: string, pk?: unknown, pks?: unknown[]);
767
+ }
768
+ //#endregion
610
769
  //#region src/permissions/crud-controls.d.ts
611
770
  declare const QUERY_CONTROLS: readonly string[];
612
771
  declare const PAGES_CONTROLS: readonly string[];
613
772
  declare const ONE_CONTROLS: readonly string[];
614
773
  //#endregion
615
- export { AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionOpts, DbActionPK, DbActionPKs, DbActions, DbRowActions, DbRowsActions, DbTableActions, ONE_CONTROLS, PAGES_CONTROLS, PkValidationSource, 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, validationErrorTransform };
774
+ export { ActionDisabledError, ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionOpts, DbActionPK, DbActionPKs, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, ONE_CONTROLS, PAGES_CONTROLS, PkValidationSource, 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, useDbActionPk, useDbActionPks, useDbActionRow, useDbActionRows, validationErrorTransform };
package/dist/index.d.mts CHANGED
@@ -5,6 +5,7 @@ import * as moost from "moost";
5
5
  import { Moost, TConsoleBase } from "moost";
6
6
  import * as _uniqu_url0 from "@uniqu/url";
7
7
  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";
8
+ import * as _wooksjs_event_core0 from "@wooksjs/event-core";
8
9
 
9
10
  //#region src/as-readable.controller.d.ts
10
11
  /**
@@ -460,15 +461,72 @@ declare const validationErrorTransform: () => moost.TInterceptorDef;
460
461
  declare const UseValidationErrorTransform: () => ClassDecorator & MethodDecorator;
461
462
  //#endregion
462
463
  //#region src/actions/types.d.ts
464
+ /** `'rows'`-level batch policy — controls whether failing rows reject or are filtered out. */
465
+ type TOnDisabledRows = "reject" | "skip";
463
466
  /**
464
467
  * Options accepted by `@DbAction(name, opts?)`. Structurally derived from
465
- * {@link TDbActionInfo} so every addition to the wire shape automatically
466
- * propagates here. Fields owned by the framework (`name`, `level`, `processor`,
467
- * `value`) are excluded `name` comes from the decorator argument, `level` is
468
- * inferred from `@DbActionPK*` usage, `processor` is fixed to `'backend'` for
469
- * method-decorator actions, and `value` is filled from the `@Post` path.
468
+ * {@link TDbActionInfo} so every wire-shape addition propagates here, EXCEPT
469
+ * `disabled` and `requiredFields` which differ in shape between decorator
470
+ * opts (function / dev-supplied) and the wire (string / forwarded verbatim).
471
+ *
472
+ * Fields owned by the framework (`name`, `level`, `processor`, `value`) are
473
+ * excluded — `name` comes from the decorator argument, `level` is inferred
474
+ * from `@DbActionPK*` / `@DbActionRow*` usage, `processor` is fixed to
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.
470
482
  */
471
- type DbActionOpts = Partial<Omit<TDbActionInfo$1, "name" | "level" | "processor" | "value">>;
483
+ type DbActionOpts<TRow = unknown> = Partial<Omit<TDbActionInfo$1, "name" | "level" | "processor" | "value" | "disabled" | "requiredFields">> & {
484
+ /**
485
+ * Per-row gate predicate. Truthy → action is disabled for that row.
486
+ * Server enforces (via the gate interceptor); UI evaluates the same
487
+ * expression to grey-out / hide the button.
488
+ *
489
+ * The dev MUST annotate the row arg explicitly (`(row: Order) => …`) —
490
+ * TS decorators cannot infer `TRow` from the enclosing class generic.
491
+ */
492
+ disabled?: (row: TRow) => boolean;
493
+ /**
494
+ * Optional dot-notation field paths the UI should union into `$select`.
495
+ * Plain `string[]` in v1.
496
+ *
497
+ * TODO: upgrade to typed `PathOf<TRow>[]` in a follow-up — the recursive
498
+ * type pattern is finicky for nested objects/arrays/optionals and isn't
499
+ * blocking v1.
500
+ *
501
+ * When omitted, the UI parses the stringified `disabled` itself to extract
502
+ * row-property accesses. When present, the UI uses this list verbatim — the
503
+ * server does NOT auto-derive or merge.
504
+ */
505
+ requiredFields?: string[];
506
+ /**
507
+ * `'rows'`-level batch policy. Default `'reject'`.
508
+ *
509
+ * - `'reject'`: evaluate every row (FULL scan, NOT short-circuit) before
510
+ * throwing; if any row fails, the error body lists ALL failing PKs;
511
+ * handler not invoked.
512
+ * - `'skip'`: filter cached rows + cached PKs to passing-only;
513
+ * zero survivors → reject. Handler runs against the survivors.
514
+ *
515
+ * Ignored for `'row'` and `'table'` level actions.
516
+ */
517
+ onDisabledRows?: TOnDisabledRows;
518
+ /**
519
+ * Bound table reference. REQUIRED on non-`AsDbReadableController` classes
520
+ * when `disabled` is set OR a `@DbActionRow*` parameter is declared.
521
+ *
522
+ * Silently ignored on `AsDbReadableController` subclasses (which include
523
+ * `AsDbController`) — the bound table from the controller wins; the
524
+ * gate / thin interceptor probes `instanceof AsDbReadableController` and
525
+ * populates the bound-table slot from `controller.readable` before
526
+ * checking `opts.table`.
527
+ */
528
+ table?: AtscriptDbTable<any>;
529
+ };
472
530
  interface DbActionsEntryCommon {
473
531
  label: string;
474
532
  level: TDbActionLevel$1;
@@ -477,7 +535,28 @@ interface DbActionsEntryCommon {
477
535
  description?: string;
478
536
  order?: number;
479
537
  default?: boolean;
480
- promptText?: string;
538
+ /** Mirrors {@link TDbActionInfo.promptText} — singular/plural via tuple. */
539
+ promptText?: string | [string, string];
540
+ /** Mirrors {@link TDbActionInfo.shortcut} — single-character UI hint. */
541
+ 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;
481
560
  }
482
561
  /**
483
562
  * Class-level dict entry. `value` semantics by processor:
@@ -508,21 +587,13 @@ type TDbActionsEntryUnpinned = DistributiveOmit<TDbActionsEntry, "level">;
508
587
  //#endregion
509
588
  //#region src/actions/db-action.decorator.d.ts
510
589
  /**
511
- * Mark a controller method as a database action surfaced via `/meta`.
512
- *
513
- * Metadata-only pair with `@Post(...)` for Moost to bind the route. The
514
- * meta builder reads this metadata plus the bound POST path lazily and
515
- * emits the action with `processor: 'backend'`. Order vs.
516
- * `@DbActionDefault()` does not matter — both merge into the same slot.
517
- *
518
- * @example
519
- * ```ts
520
- * @Post('actions/block')
521
- * @DbAction('block', { label: 'Block', icon: 'i-as-block', intent: 'negative' })
522
- * async blockUser(@DbActionPK() id: string) { ... }
523
- * ```
590
+ * Mark a controller method as a database action surfaced via `/meta`. Writes
591
+ * `MOOST_DB_ACTION` metadata and registers a Moost interceptor when needed
592
+ * (gate when `disabled` is set, thin bound-table injector when only
593
+ * `@DbActionRow*` is present). Stacking two `@DbAction` on the same method
594
+ * is undefined and emits a warning.
524
595
  */
525
- declare function DbAction(name: string, opts?: DbActionOpts): MethodDecorator;
596
+ declare function DbAction<TRow = unknown>(name: string, opts?: DbActionOpts<TRow>): MethodDecorator;
526
597
  //#endregion
527
598
  //#region src/actions/db-action-default.decorator.d.ts
528
599
  /**
@@ -545,6 +616,10 @@ declare function DbActionDefault(): MethodDecorator;
545
616
  *
546
617
  * Marks the param so {@link discoverActions} can infer the action's `level`
547
618
  * as `'row'`.
619
+ *
620
+ * Implementation note: the resolver is a thin reader of the cached PK wook
621
+ * — validation logic lives in the wook factory, which runs once per request
622
+ * regardless of how many readers consume the value.
548
623
  */
549
624
  declare function DbActionPK(): ParameterDecorator;
550
625
  //#endregion
@@ -558,9 +633,37 @@ declare function DbActionPK(): ParameterDecorator;
558
633
  *
559
634
  * Validation is strict — no type coercion. Marks the param so
560
635
  * {@link discoverActions} can infer the action's `level` as `'rows'`.
636
+ *
637
+ * In `'rows'` skip mode the resolved value reflects the gate interceptor's
638
+ * filtered subset (the cached PK slot is overwritten in place); see
639
+ * {@link dbActionPksSlot} for precedence details.
561
640
  */
562
641
  declare function DbActionPKs(): ParameterDecorator;
563
642
  //#endregion
643
+ //#region src/actions/db-action-row.decorator.d.ts
644
+ /**
645
+ * Parameter decorator that injects the row whose PK was supplied in the
646
+ * request body. Reads from the cached row wook (fetched once per request,
647
+ * shared with the gate interceptor when `disabled` is set).
648
+ *
649
+ * Marks the param so {@link discoverActions} infers the action's `level` as
650
+ * `'row'`. Co-occurrence with `@DbActionRows()` (or any multi-cardinality
651
+ * decorator) drops the action with a warning.
652
+ *
653
+ * In `'skip'` mode this returns the gate's filtered row; the original
654
+ * request-body row is not retrievable.
655
+ */
656
+ declare function DbActionRow(): ParameterDecorator;
657
+ /**
658
+ * Parameter decorator that injects the rows-array fetched by primary keys
659
+ * from the request body. Reads from the cached row-array wook.
660
+ *
661
+ * Marks the param so {@link discoverActions} infers the action's `level` as
662
+ * `'rows'`. In `'rows'` + `'skip'` mode the resolved value contains only the
663
+ * gate's surviving rows.
664
+ */
665
+ declare function DbActionRows(): ParameterDecorator;
666
+ //#endregion
564
667
  //#region src/actions/db-actions.decorator.d.ts
565
668
  /**
566
669
  * Declare class-level actions on a controller. Entries are flat dicts with
@@ -607,9 +710,65 @@ interface PkValidationSource {
607
710
  fieldDescriptors: readonly TDbFieldMeta[];
608
711
  }
609
712
  //#endregion
713
+ //#region src/actions/pk-cache.d.ts
714
+ declare const useDbActionPk: _wooksjs_event_core0.WookComposable<{
715
+ load: () => Promise<unknown>;
716
+ }>;
717
+ declare const useDbActionPks: _wooksjs_event_core0.WookComposable<{
718
+ load: () => Promise<unknown[]>;
719
+ }>;
720
+ //#endregion
721
+ //#region src/actions/row-cache.d.ts
722
+ declare const useDbActionRow: _wooksjs_event_core0.WookComposable<{
723
+ load: () => Promise<unknown>;
724
+ }>;
725
+ declare const useDbActionRows: _wooksjs_event_core0.WookComposable<{
726
+ load: () => Promise<unknown[]>;
727
+ }>;
728
+ //#endregion
729
+ //#region src/actions/action-disabled-error.d.ts
730
+ /**
731
+ * Wire-body shape for server-side gate rejections. The `name` discriminator
732
+ * lets `@atscript/db-client` recognise the response and construct the typed
733
+ * `ActionDisabledError` subclass. The shape extends Moost's standard
734
+ * `ServerError` envelope (`{ message, statusCode, errors? }`) with three
735
+ * additional fields:
736
+ *
737
+ * - `name: 'ActionDisabledError'` — discriminator the client matches.
738
+ * - `action` — the `@DbAction` name that rejected the request.
739
+ * - `pk?` — present only for `'row'`-level rejections.
740
+ * - `pks?` — present only for `'rows'`-level rejections.
741
+ *
742
+ * `message` is populated with a human-readable string so generic
743
+ * `ClientError` consumers (which read `body.message`) still get something
744
+ * useful without typed-catch dispatch.
745
+ */
746
+ interface ActionDisabledErrorBody {
747
+ name: "ActionDisabledError";
748
+ message: string;
749
+ statusCode: 409;
750
+ action: string;
751
+ pk?: unknown;
752
+ pks?: unknown[];
753
+ }
754
+ /**
755
+ * Thrown by the gate interceptor when `disabled` returns truthy. Composes
756
+ * with Moost's existing error mapper to produce HTTP 409 with the wire body
757
+ * defined by {@link ActionDisabledErrorBody}.
758
+ *
759
+ * - `'row'`-level rejection: pass `(action, pk)` — the body emits `pk`.
760
+ * - `'rows'`-level rejection: pass `(action, undefined, pks)` — the body
761
+ * emits `pks` (the FULL list of failing PKs in reject mode; the FULL list
762
+ * of request PKs in skip mode with zero survivors).
763
+ */
764
+ declare class ActionDisabledError extends HttpError<ActionDisabledErrorBody> {
765
+ name: string;
766
+ constructor(action: string, pk?: unknown, pks?: unknown[]);
767
+ }
768
+ //#endregion
610
769
  //#region src/permissions/crud-controls.d.ts
611
770
  declare const QUERY_CONTROLS: readonly string[];
612
771
  declare const PAGES_CONTROLS: readonly string[];
613
772
  declare const ONE_CONTROLS: readonly string[];
614
773
  //#endregion
615
- export { AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, type DbActionOpts, DbActionPK, DbActionPKs, DbActions, DbRowActions, DbRowsActions, DbTableActions, ONE_CONTROLS, PAGES_CONTROLS, type PkValidationSource, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbActionsEntry, type TDbActionsEntryUnpinned, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, discoverActions, validationErrorTransform };
774
+ export { ActionDisabledError, type ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, type DbActionOpts, DbActionPK, DbActionPKs, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, ONE_CONTROLS, PAGES_CONTROLS, type PkValidationSource, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbActionsEntry, type TDbActionsEntryUnpinned, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, discoverActions, useDbActionPk, useDbActionPks, useDbActionRow, useDbActionRows, validationErrorTransform };