@atscript/moost-db 0.1.55 → 0.1.57

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
@@ -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, TMetaResponse, Uniquery, UniqueryControls } from "@atscript/db";
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";
5
5
  import { HttpError } from "@moostjs/event-http";
6
6
  import * as moost from "moost";
7
7
  import { Moost, TConsoleBase } from "moost";
@@ -88,11 +88,6 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
88
88
  * to customise.
89
89
  */
90
90
  protected getSerializeOptions(): TSerializeOptions;
91
- /**
92
- * Whether this controller is read-only (no write endpoints).
93
- * Returns `true` by default; {@link AsDbController} overrides to `false`.
94
- */
95
- protected _isReadOnly(): boolean;
96
91
  private _queryControlsValidator?;
97
92
  private _pagesControlsValidator?;
98
93
  private _getOneControlsValidator?;
@@ -111,20 +106,39 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
111
106
  protected parseQueryString(url: string): _uniqu_url0.UrlQuery;
112
107
  protected returnOne(result: Promise<DataType | null>): Promise<DataType | HttpError>;
113
108
  /**
114
- * **GET /meta** — returns the bound interface's metadata envelope.
115
- *
116
- * Base implementation delegates to {@link buildMetaResponse}, which subclasses
117
- * override to add source-specific fields (relations, searchable flags, etc.).
118
- * The response is cached on the instance; async overrides must cache any
119
- * extra enrichment themselves.
109
+ * **GET /meta** — returns the bound interface's metadata envelope. The
110
+ * static envelope is cached; {@link applyMetaOverlay} runs per request so
111
+ * subclasses can prune the response by principal.
120
112
  */
121
113
  meta(): Promise<TMetaResponse>;
122
114
  /**
123
115
  * Builds the `/meta` payload. Override in subclasses to populate source-specific
124
- * fields. Defaults return a minimal envelope with the serialized type and the
125
- * read-only flag; value-help dicts populate their capability hints here.
116
+ * fields. Subclasses that fully replace the envelope must call
117
+ * {@link buildActions} and {@link buildCrud} directly so `@DbAction*`
118
+ * decorators and CRUD permissions still surface.
119
+ */
120
+ protected buildMetaResponse(): TMetaResponse;
121
+ /**
122
+ * Discovers `@DbAction*` and `@DbActions`-style class metadata on this
123
+ * controller and produces the `actions` array. Returns `[]` for value-help
124
+ * controllers — see {@link AsValueHelpController#buildMetaResponse}.
125
+ */
126
+ protected buildActions(): TDbActionInfo$1[];
127
+ /**
128
+ * Declares the built-in CRUD operations this controller exposes. Subclasses
129
+ * override to add their keys; the bare base only exposes `/meta`. See
130
+ * `docs/http/permissions.md` for the wire shape and overlay rules.
126
131
  */
127
- protected buildMetaResponse(): Promise<TMetaResponse>;
132
+ protected buildCrud(): TCrudPermissions$1;
133
+ /**
134
+ * Per-request overlay applied to the cached `/meta` envelope. Default no-op.
135
+ * Subclasses may shallow-clone and prune `crud` keys, `crud[op]` arrays, or
136
+ * `actions[]` based on the current request principal (read via Moost
137
+ * composables). The cached envelope MUST NOT be mutated — see
138
+ * `docs/http/permissions.md` for the full contract, including the
139
+ * "discoverability only" caveat.
140
+ */
141
+ protected applyMetaOverlay(meta: TMetaResponse): TMetaResponse | Promise<TMetaResponse>;
128
142
  }
129
143
  //#endregion
130
144
  //#region src/as-db-readable.controller.d.ts
@@ -196,7 +210,8 @@ declare class AsDbReadableController<T extends TAtscriptAnnotatedType = TAtscrip
196
210
  * vector-searchable flags, field-descriptor-derived filter/sort hints, and
197
211
  * the configured primary keys.
198
212
  */
199
- protected buildMetaResponse(): Promise<TMetaResponse>;
213
+ protected buildMetaResponse(): TMetaResponse;
214
+ protected buildCrud(): TCrudPermissions$1;
200
215
  }
201
216
  //#endregion
202
217
  //#region src/as-db.controller.d.ts
@@ -214,7 +229,7 @@ declare class AsDbController<T extends TAtscriptAnnotatedType = TAtscriptAnnotat
214
229
  /** Reference to the underlying table (typed for write access). */
215
230
  protected get table(): AtscriptDbTable<T>;
216
231
  constructor(table: AtscriptDbTable<T>, app: Moost);
217
- protected _isReadOnly(): boolean;
232
+ protected buildCrud(): TCrudPermissions$1;
218
233
  /**
219
234
  * Intercepts write operations. Return `undefined` to abort.
220
235
  * May be async (e.g. to enrich payloads from session / permissions).
@@ -280,6 +295,12 @@ interface ValueHelpQuery<T> {
280
295
  * requests against them. Subclasses that need a backend gate should compose
281
296
  * one of their own (see {@link AsDbReadableController} for the
282
297
  * `@db.column.filterable` / `@db.column.sortable` pattern).
298
+ *
299
+ * **Actions are intentionally NOT supported on value-help controllers.** The
300
+ * `/meta` payload still includes `actions: []` for shape uniformity, and any
301
+ * `@DbAction*` / `@DbActions*` decorators applied here are silently ignored.
302
+ * Value-help is for FK pickers and dictionary surfaces — adding row/table
303
+ * actions there would muddy the contract.
283
304
  */
284
305
  declare abstract class AsValueHelpController<T extends TAtscriptAnnotatedType = TAtscriptAnnotatedType, DataType = TAtscriptDataType<T>> extends AsReadableController<T, DataType> {
285
306
  /** Per-prop metadata map of the bound interface; eagerly built once. */
@@ -330,7 +351,9 @@ declare abstract class AsValueHelpController<T extends TAtscriptAnnotatedType =
330
351
  * client picker UI (which controls to render); the server does not enforce
331
352
  * these flags at request time.
332
353
  */
333
- protected buildMetaResponse(): Promise<TMetaResponse>;
354
+ protected buildMetaResponse(): TMetaResponse;
355
+ protected buildActions(): never[];
356
+ protected buildCrud(): TCrudPermissions$1;
334
357
  }
335
358
  //#endregion
336
359
  //#region src/as-json-value-help.controller.d.ts
@@ -436,4 +459,157 @@ declare const ViewController: (readable: AtscriptDbReadable, prefix?: string) =>
436
459
  declare const validationErrorTransform: () => moost.TInterceptorDef;
437
460
  declare const UseValidationErrorTransform: () => ClassDecorator & MethodDecorator;
438
461
  //#endregion
439
- export { AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, validationErrorTransform };
462
+ //#region src/actions/types.d.ts
463
+ /**
464
+ * 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.
470
+ */
471
+ type DbActionOpts = Partial<Omit<TDbActionInfo$1, "name" | "level" | "processor" | "value">>;
472
+ interface DbActionsEntryCommon {
473
+ label: string;
474
+ level: TDbActionLevel$1;
475
+ icon?: string;
476
+ intent?: TDbActionIntent$1;
477
+ description?: string;
478
+ order?: number;
479
+ default?: boolean;
480
+ promptText?: string;
481
+ }
482
+ /**
483
+ * Class-level dict entry. `value` semantics by processor:
484
+ *
485
+ * - `'navigate'` — REQUIRED, non-empty. The URL template (with `$1` substituted client-side).
486
+ * - `'backend'` — REQUIRED, non-empty. The full HTTP POST path the UI client should invoke.
487
+ * For row/rows entries the dev-supplied path MUST point to a `@Post`-bound
488
+ * handler accepting the PK-shaped JSON body (single PK scalar / composite
489
+ * object / array thereof) — typically a method using `@DbActionPK()` or
490
+ * `@DbActionPKs()`. The meta builder does NOT validate this.
491
+ * - `'custom'` — `value` is forbidden in the entry; the meta builder fills it
492
+ * with the dict key.
493
+ */
494
+ type TDbActionsEntry = (DbActionsEntryCommon & {
495
+ processor: "navigate";
496
+ value: string;
497
+ }) | (DbActionsEntryCommon & {
498
+ processor: "custom";
499
+ value?: never;
500
+ }) | (DbActionsEntryCommon & {
501
+ processor: "backend";
502
+ value: string;
503
+ });
504
+ /** Distributes `Omit` across the discriminated union members. */
505
+ type DistributiveOmit<T, K extends keyof T> = T extends T ? Omit<T, K> : never;
506
+ /** Same as {@link TDbActionsEntry} but without the `level` field — used by the level-pinned shortcuts. */
507
+ type TDbActionsEntryUnpinned = DistributiveOmit<TDbActionsEntry, "level">;
508
+ //#endregion
509
+ //#region src/actions/db-action.decorator.d.ts
510
+ /**
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
+ * ```
524
+ */
525
+ declare function DbAction(name: string, opts?: DbActionOpts): MethodDecorator;
526
+ //#endregion
527
+ //#region src/actions/db-action-default.decorator.d.ts
528
+ /**
529
+ * Sugar that flips `default: true` on the same method's `@DbAction` metadata.
530
+ * Equivalent to passing `opts.default = true`. Decorator order does not matter.
531
+ */
532
+ declare function DbActionDefault(): MethodDecorator;
533
+ //#endregion
534
+ //#region src/actions/db-action-pk.decorator.d.ts
535
+ /**
536
+ * Parameter resolver that reads the primary key from the JSON request body
537
+ * and validates it against the bound table's PK schema.
538
+ *
539
+ * - Single-field PK → JSON-encoded scalar (`"abc"`, `42`, `true`).
540
+ * - Composite PK → JSON object with all PK fields.
541
+ *
542
+ * Validation is strict — no type coercion. Mismatches throw a
543
+ * `ValidatorError` which the existing validation interceptor surfaces as
544
+ * HTTP 400 with the same envelope as DTO failures.
545
+ *
546
+ * Marks the param so {@link discoverActions} can infer the action's `level`
547
+ * as `'row'`.
548
+ */
549
+ declare function DbActionPK(): ParameterDecorator;
550
+ //#endregion
551
+ //#region src/actions/db-action-pks.decorator.d.ts
552
+ /**
553
+ * Parameter resolver that reads a JSON array of primary keys from the request
554
+ * body and validates each entry against the bound table's PK schema.
555
+ *
556
+ * - Scalar PK → JSON array of scalars (`["a","b","c"]`).
557
+ * - Composite PK → JSON array of objects.
558
+ *
559
+ * Validation is strict — no type coercion. Marks the param so
560
+ * {@link discoverActions} can infer the action's `level` as `'rows'`.
561
+ */
562
+ declare function DbActionPKs(): ParameterDecorator;
563
+ //#endregion
564
+ //#region src/actions/db-actions.decorator.d.ts
565
+ /**
566
+ * Declare class-level actions on a controller. Entries are flat dicts with
567
+ * `processor: 'navigate' | 'custom' | 'backend'` matching the `/meta` wire
568
+ * shape (see {@link TDbActionsEntry}). Each entry MUST specify `level`. Use
569
+ * the level-pinned shortcuts (`@DbTableActions`, `@DbRowActions`,
570
+ * `@DbRowsActions`) to avoid repeating `level`.
571
+ *
572
+ * The dictionary key serves as the action `name`. Entries do NOT bind any
573
+ * HTTP route — the meta builder surfaces them in `/meta` only. For
574
+ * `processor: 'backend'`, the dev-supplied `value` MUST point to a real
575
+ * `@Post`-bound endpoint accepting the level-determined body shape.
576
+ *
577
+ * Multiple `@DbActions` (and shortcut) decorators on the same class
578
+ * accumulate.
579
+ */
580
+ declare function DbActions(dict: Record<string, TDbActionsEntry>): ClassDecorator;
581
+ /** Sugar for `@DbActions` with `level: 'table'` injected into each entry. */
582
+ declare function DbTableActions(dict: Record<string, TDbActionsEntryUnpinned>): ClassDecorator;
583
+ /** Sugar for `@DbActions` with `level: 'row'` injected into each entry. */
584
+ declare function DbRowActions(dict: Record<string, TDbActionsEntryUnpinned>): ClassDecorator;
585
+ /** Sugar for `@DbActions` with `level: 'rows'` injected into each entry. */
586
+ declare function DbRowsActions(dict: Record<string, TDbActionsEntryUnpinned>): ClassDecorator;
587
+ //#endregion
588
+ //#region src/actions/discover.d.ts
589
+ /**
590
+ * Discover all actions declared on a controller and produce the `/meta` array.
591
+ * Reads class + method metadata via `getMoostMate()` and resolves bound POST
592
+ * paths through the Moost controller overview.
593
+ *
594
+ * Result is memoized per controller constructor — discovery walks every
595
+ * handler entry and reads decorator metadata, which is wasted work to repeat
596
+ * across instances.
597
+ */
598
+ declare function discoverActions(controllerCtor: Function, app: Moost, logger: TConsoleBase): TDbActionInfo$1[];
599
+ //#endregion
600
+ //#region src/actions/pk-validation.d.ts
601
+ /**
602
+ * Minimal shape required to validate PKs against a table — supplied by the
603
+ * controller's underlying `AtscriptDbReadable`/`AtscriptDbTable`.
604
+ */
605
+ interface PkValidationSource {
606
+ primaryKeys: readonly string[];
607
+ fieldDescriptors: readonly TDbFieldMeta[];
608
+ }
609
+ //#endregion
610
+ //#region src/permissions/crud-controls.d.ts
611
+ declare const QUERY_CONTROLS: readonly string[];
612
+ declare const PAGES_CONTROLS: readonly string[];
613
+ declare const ONE_CONTROLS: readonly string[];
614
+ //#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 };
package/dist/index.d.mts CHANGED
@@ -4,7 +4,7 @@ import { HttpError } from "@moostjs/event-http";
4
4
  import * as moost from "moost";
5
5
  import { Moost, TConsoleBase } from "moost";
6
6
  import * as _uniqu_url0 from "@uniqu/url";
7
- import { AtscriptDbReadable, AtscriptDbTable, FilterExpr, TMetaResponse, Uniquery, UniqueryControls } from "@atscript/db";
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
8
 
9
9
  //#region src/as-readable.controller.d.ts
10
10
  /**
@@ -88,11 +88,6 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
88
88
  * to customise.
89
89
  */
90
90
  protected getSerializeOptions(): TSerializeOptions;
91
- /**
92
- * Whether this controller is read-only (no write endpoints).
93
- * Returns `true` by default; {@link AsDbController} overrides to `false`.
94
- */
95
- protected _isReadOnly(): boolean;
96
91
  private _queryControlsValidator?;
97
92
  private _pagesControlsValidator?;
98
93
  private _getOneControlsValidator?;
@@ -111,20 +106,39 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
111
106
  protected parseQueryString(url: string): _uniqu_url0.UrlQuery;
112
107
  protected returnOne(result: Promise<DataType | null>): Promise<DataType | HttpError>;
113
108
  /**
114
- * **GET /meta** — returns the bound interface's metadata envelope.
115
- *
116
- * Base implementation delegates to {@link buildMetaResponse}, which subclasses
117
- * override to add source-specific fields (relations, searchable flags, etc.).
118
- * The response is cached on the instance; async overrides must cache any
119
- * extra enrichment themselves.
109
+ * **GET /meta** — returns the bound interface's metadata envelope. The
110
+ * static envelope is cached; {@link applyMetaOverlay} runs per request so
111
+ * subclasses can prune the response by principal.
120
112
  */
121
113
  meta(): Promise<TMetaResponse>;
122
114
  /**
123
115
  * Builds the `/meta` payload. Override in subclasses to populate source-specific
124
- * fields. Defaults return a minimal envelope with the serialized type and the
125
- * read-only flag; value-help dicts populate their capability hints here.
116
+ * fields. Subclasses that fully replace the envelope must call
117
+ * {@link buildActions} and {@link buildCrud} directly so `@DbAction*`
118
+ * decorators and CRUD permissions still surface.
119
+ */
120
+ protected buildMetaResponse(): TMetaResponse;
121
+ /**
122
+ * Discovers `@DbAction*` and `@DbActions`-style class metadata on this
123
+ * controller and produces the `actions` array. Returns `[]` for value-help
124
+ * controllers — see {@link AsValueHelpController#buildMetaResponse}.
125
+ */
126
+ protected buildActions(): TDbActionInfo$1[];
127
+ /**
128
+ * Declares the built-in CRUD operations this controller exposes. Subclasses
129
+ * override to add their keys; the bare base only exposes `/meta`. See
130
+ * `docs/http/permissions.md` for the wire shape and overlay rules.
126
131
  */
127
- protected buildMetaResponse(): Promise<TMetaResponse>;
132
+ protected buildCrud(): TCrudPermissions$1;
133
+ /**
134
+ * Per-request overlay applied to the cached `/meta` envelope. Default no-op.
135
+ * Subclasses may shallow-clone and prune `crud` keys, `crud[op]` arrays, or
136
+ * `actions[]` based on the current request principal (read via Moost
137
+ * composables). The cached envelope MUST NOT be mutated — see
138
+ * `docs/http/permissions.md` for the full contract, including the
139
+ * "discoverability only" caveat.
140
+ */
141
+ protected applyMetaOverlay(meta: TMetaResponse): TMetaResponse | Promise<TMetaResponse>;
128
142
  }
129
143
  //#endregion
130
144
  //#region src/as-db-readable.controller.d.ts
@@ -196,7 +210,8 @@ declare class AsDbReadableController<T extends TAtscriptAnnotatedType = TAtscrip
196
210
  * vector-searchable flags, field-descriptor-derived filter/sort hints, and
197
211
  * the configured primary keys.
198
212
  */
199
- protected buildMetaResponse(): Promise<TMetaResponse>;
213
+ protected buildMetaResponse(): TMetaResponse;
214
+ protected buildCrud(): TCrudPermissions$1;
200
215
  }
201
216
  //#endregion
202
217
  //#region src/as-db.controller.d.ts
@@ -214,7 +229,7 @@ declare class AsDbController<T extends TAtscriptAnnotatedType = TAtscriptAnnotat
214
229
  /** Reference to the underlying table (typed for write access). */
215
230
  protected get table(): AtscriptDbTable<T>;
216
231
  constructor(table: AtscriptDbTable<T>, app: Moost);
217
- protected _isReadOnly(): boolean;
232
+ protected buildCrud(): TCrudPermissions$1;
218
233
  /**
219
234
  * Intercepts write operations. Return `undefined` to abort.
220
235
  * May be async (e.g. to enrich payloads from session / permissions).
@@ -280,6 +295,12 @@ interface ValueHelpQuery<T> {
280
295
  * requests against them. Subclasses that need a backend gate should compose
281
296
  * one of their own (see {@link AsDbReadableController} for the
282
297
  * `@db.column.filterable` / `@db.column.sortable` pattern).
298
+ *
299
+ * **Actions are intentionally NOT supported on value-help controllers.** The
300
+ * `/meta` payload still includes `actions: []` for shape uniformity, and any
301
+ * `@DbAction*` / `@DbActions*` decorators applied here are silently ignored.
302
+ * Value-help is for FK pickers and dictionary surfaces — adding row/table
303
+ * actions there would muddy the contract.
283
304
  */
284
305
  declare abstract class AsValueHelpController<T extends TAtscriptAnnotatedType = TAtscriptAnnotatedType, DataType = TAtscriptDataType<T>> extends AsReadableController<T, DataType> {
285
306
  /** Per-prop metadata map of the bound interface; eagerly built once. */
@@ -330,7 +351,9 @@ declare abstract class AsValueHelpController<T extends TAtscriptAnnotatedType =
330
351
  * client picker UI (which controls to render); the server does not enforce
331
352
  * these flags at request time.
332
353
  */
333
- protected buildMetaResponse(): Promise<TMetaResponse>;
354
+ protected buildMetaResponse(): TMetaResponse;
355
+ protected buildActions(): never[];
356
+ protected buildCrud(): TCrudPermissions$1;
334
357
  }
335
358
  //#endregion
336
359
  //#region src/as-json-value-help.controller.d.ts
@@ -436,4 +459,157 @@ declare const ViewController: (readable: AtscriptDbReadable, prefix?: string) =>
436
459
  declare const validationErrorTransform: () => moost.TInterceptorDef;
437
460
  declare const UseValidationErrorTransform: () => ClassDecorator & MethodDecorator;
438
461
  //#endregion
439
- export { AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, validationErrorTransform };
462
+ //#region src/actions/types.d.ts
463
+ /**
464
+ * 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.
470
+ */
471
+ type DbActionOpts = Partial<Omit<TDbActionInfo$1, "name" | "level" | "processor" | "value">>;
472
+ interface DbActionsEntryCommon {
473
+ label: string;
474
+ level: TDbActionLevel$1;
475
+ icon?: string;
476
+ intent?: TDbActionIntent$1;
477
+ description?: string;
478
+ order?: number;
479
+ default?: boolean;
480
+ promptText?: string;
481
+ }
482
+ /**
483
+ * Class-level dict entry. `value` semantics by processor:
484
+ *
485
+ * - `'navigate'` — REQUIRED, non-empty. The URL template (with `$1` substituted client-side).
486
+ * - `'backend'` — REQUIRED, non-empty. The full HTTP POST path the UI client should invoke.
487
+ * For row/rows entries the dev-supplied path MUST point to a `@Post`-bound
488
+ * handler accepting the PK-shaped JSON body (single PK scalar / composite
489
+ * object / array thereof) — typically a method using `@DbActionPK()` or
490
+ * `@DbActionPKs()`. The meta builder does NOT validate this.
491
+ * - `'custom'` — `value` is forbidden in the entry; the meta builder fills it
492
+ * with the dict key.
493
+ */
494
+ type TDbActionsEntry = (DbActionsEntryCommon & {
495
+ processor: "navigate";
496
+ value: string;
497
+ }) | (DbActionsEntryCommon & {
498
+ processor: "custom";
499
+ value?: never;
500
+ }) | (DbActionsEntryCommon & {
501
+ processor: "backend";
502
+ value: string;
503
+ });
504
+ /** Distributes `Omit` across the discriminated union members. */
505
+ type DistributiveOmit<T, K extends keyof T> = T extends T ? Omit<T, K> : never;
506
+ /** Same as {@link TDbActionsEntry} but without the `level` field — used by the level-pinned shortcuts. */
507
+ type TDbActionsEntryUnpinned = DistributiveOmit<TDbActionsEntry, "level">;
508
+ //#endregion
509
+ //#region src/actions/db-action.decorator.d.ts
510
+ /**
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
+ * ```
524
+ */
525
+ declare function DbAction(name: string, opts?: DbActionOpts): MethodDecorator;
526
+ //#endregion
527
+ //#region src/actions/db-action-default.decorator.d.ts
528
+ /**
529
+ * Sugar that flips `default: true` on the same method's `@DbAction` metadata.
530
+ * Equivalent to passing `opts.default = true`. Decorator order does not matter.
531
+ */
532
+ declare function DbActionDefault(): MethodDecorator;
533
+ //#endregion
534
+ //#region src/actions/db-action-pk.decorator.d.ts
535
+ /**
536
+ * Parameter resolver that reads the primary key from the JSON request body
537
+ * and validates it against the bound table's PK schema.
538
+ *
539
+ * - Single-field PK → JSON-encoded scalar (`"abc"`, `42`, `true`).
540
+ * - Composite PK → JSON object with all PK fields.
541
+ *
542
+ * Validation is strict — no type coercion. Mismatches throw a
543
+ * `ValidatorError` which the existing validation interceptor surfaces as
544
+ * HTTP 400 with the same envelope as DTO failures.
545
+ *
546
+ * Marks the param so {@link discoverActions} can infer the action's `level`
547
+ * as `'row'`.
548
+ */
549
+ declare function DbActionPK(): ParameterDecorator;
550
+ //#endregion
551
+ //#region src/actions/db-action-pks.decorator.d.ts
552
+ /**
553
+ * Parameter resolver that reads a JSON array of primary keys from the request
554
+ * body and validates each entry against the bound table's PK schema.
555
+ *
556
+ * - Scalar PK → JSON array of scalars (`["a","b","c"]`).
557
+ * - Composite PK → JSON array of objects.
558
+ *
559
+ * Validation is strict — no type coercion. Marks the param so
560
+ * {@link discoverActions} can infer the action's `level` as `'rows'`.
561
+ */
562
+ declare function DbActionPKs(): ParameterDecorator;
563
+ //#endregion
564
+ //#region src/actions/db-actions.decorator.d.ts
565
+ /**
566
+ * Declare class-level actions on a controller. Entries are flat dicts with
567
+ * `processor: 'navigate' | 'custom' | 'backend'` matching the `/meta` wire
568
+ * shape (see {@link TDbActionsEntry}). Each entry MUST specify `level`. Use
569
+ * the level-pinned shortcuts (`@DbTableActions`, `@DbRowActions`,
570
+ * `@DbRowsActions`) to avoid repeating `level`.
571
+ *
572
+ * The dictionary key serves as the action `name`. Entries do NOT bind any
573
+ * HTTP route — the meta builder surfaces them in `/meta` only. For
574
+ * `processor: 'backend'`, the dev-supplied `value` MUST point to a real
575
+ * `@Post`-bound endpoint accepting the level-determined body shape.
576
+ *
577
+ * Multiple `@DbActions` (and shortcut) decorators on the same class
578
+ * accumulate.
579
+ */
580
+ declare function DbActions(dict: Record<string, TDbActionsEntry>): ClassDecorator;
581
+ /** Sugar for `@DbActions` with `level: 'table'` injected into each entry. */
582
+ declare function DbTableActions(dict: Record<string, TDbActionsEntryUnpinned>): ClassDecorator;
583
+ /** Sugar for `@DbActions` with `level: 'row'` injected into each entry. */
584
+ declare function DbRowActions(dict: Record<string, TDbActionsEntryUnpinned>): ClassDecorator;
585
+ /** Sugar for `@DbActions` with `level: 'rows'` injected into each entry. */
586
+ declare function DbRowsActions(dict: Record<string, TDbActionsEntryUnpinned>): ClassDecorator;
587
+ //#endregion
588
+ //#region src/actions/discover.d.ts
589
+ /**
590
+ * Discover all actions declared on a controller and produce the `/meta` array.
591
+ * Reads class + method metadata via `getMoostMate()` and resolves bound POST
592
+ * paths through the Moost controller overview.
593
+ *
594
+ * Result is memoized per controller constructor — discovery walks every
595
+ * handler entry and reads decorator metadata, which is wasted work to repeat
596
+ * across instances.
597
+ */
598
+ declare function discoverActions(controllerCtor: Function, app: Moost, logger: TConsoleBase): TDbActionInfo$1[];
599
+ //#endregion
600
+ //#region src/actions/pk-validation.d.ts
601
+ /**
602
+ * Minimal shape required to validate PKs against a table — supplied by the
603
+ * controller's underlying `AtscriptDbReadable`/`AtscriptDbTable`.
604
+ */
605
+ interface PkValidationSource {
606
+ primaryKeys: readonly string[];
607
+ fieldDescriptors: readonly TDbFieldMeta[];
608
+ }
609
+ //#endregion
610
+ //#region src/permissions/crud-controls.d.ts
611
+ declare const QUERY_CONTROLS: readonly string[];
612
+ declare const PAGES_CONTROLS: readonly string[];
613
+ declare const ONE_CONTROLS: readonly string[];
614
+ //#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 };