@atscript/moost-db 0.1.65 → 0.1.67

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.cjs CHANGED
@@ -182,6 +182,30 @@ function findSortOffender(sort, isAllowed) {
182
182
  }
183
183
  }
184
184
  //#endregion
185
+ //#region src/mate.ts
186
+ /**
187
+ * Returns the shared moost-mate instance, typed against every key that
188
+ * `@atscript/moost-db` writes (see {@link AtscriptDbMeta} +
189
+ * {@link AtscriptDbParamsMeta}).
190
+ *
191
+ * Prefer this over `getMoostMate()` from `moost` whenever you need to
192
+ * read moost-db metadata — callers no longer have to retype the
193
+ * `atscript_db_*` magic strings or hand-cast the result.
194
+ *
195
+ * @example
196
+ * ```ts
197
+ * import { getAtscriptDbMate } from "@atscript/moost-db";
198
+ *
199
+ * const mate = getAtscriptDbMate();
200
+ * const meta = mate.read(controllerCtor.prototype, methodName);
201
+ * const dbAction = meta?.atscript_db_action; // TDbActionMeta | undefined
202
+ * const inputForm = meta?.params?.[0]?.atscript_db_action_input_form;
203
+ * ```
204
+ */
205
+ function getAtscriptDbMate() {
206
+ return (0, moost.getMoostMate)();
207
+ }
208
+ //#endregion
185
209
  //#region src/actions/controller-registry.ts
186
210
  let asDbReadableCtor = null;
187
211
  let asValueHelpCtor = null;
@@ -203,38 +227,14 @@ function isAsValueHelpControllerSubclass(ctor) {
203
227
  //#region src/actions/keys.ts
204
228
  /** Log-message prefix for warnings emitted from the actions subsystem. */
205
229
  const WARN_PREFIX = "[moost-db actions]";
206
- /** Method-level metadata key — written by `@DbAction(name, opts)`. */
207
- const MOOST_DB_ACTION = "atscript_db_action";
208
- /** Class-level metadata key — written by `@DbActions` and the level-pinned shortcuts. Stored as an array; decorators accumulate. */
209
- const MOOST_DB_ACTIONS = "atscript_db_actions";
210
- /** Param-level metadata key — written by `@DbActionID()` / `@DbActionIDs()`. Drives level inference. */
211
- const MOOST_DB_ACTION_PARAM = "atscript_db_action_param";
212
- /** Param-level marker keys — written by `@DbActionRow()` / `@DbActionRows()`. */
213
- const MOOST_DB_ACTION_ROW = "atscript_db_action_row";
214
- const MOOST_DB_ACTION_ROWS = "atscript_db_action_rows";
215
- /**
216
- * Param-level metadata key — written by `@InputForm(FormType)`. Carries the
217
- * compiled `.as` class plus its `.name` so {@link discoverActions} can both
218
- * emit `inputForm` on `/meta` and register the type in the controller's form
219
- * registry for `GET /meta/form/:name`.
220
- */
221
- const MOOST_DB_ACTION_INPUT_FORM = "atscript_db_action_input_form";
222
- /**
223
- * Generic param-level metadata key — written by `@InputForm(FormType)`
224
- * alongside {@link MOOST_DB_ACTION_INPUT_FORM}. Holds just the type ref so a
225
- * generic atscript-aware Moost pipe (installed globally via
226
- * `app.applyGlobalPipes(...)` or scoped via `@Pipe(...)`) can validate the
227
- * resolved value without knowing about the moost-db-specific key.
228
- */
229
- const MOOST_ATSCRIPT_TYPE = "atscript_type";
230
230
  /**
231
231
  * Shared method-decorator update used by `@DbAction` and `@DbActionDefault`:
232
- * read the existing `MOOST_DB_ACTION` slot, merge the patch (later-applied
232
+ * read the existing `atscript_db_action` slot, merge the patch (later-applied
233
233
  * fields win), and write it back. `name` is empty until `@DbAction` provides
234
234
  * one — `discoverActions` warns and drops actions with no name.
235
235
  */
236
236
  function mergeActionMeta(current, patch) {
237
- const existing = current[MOOST_DB_ACTION];
237
+ const existing = current.atscript_db_action;
238
238
  return {
239
239
  name: patch.name ?? existing?.name ?? "",
240
240
  opts: {
@@ -253,21 +253,19 @@ function scanParamLevel(params) {
253
253
  let inputForm;
254
254
  let hasDuplicateInputForm = false;
255
255
  for (const p of params) {
256
- const kind = p[MOOST_DB_ACTION_PARAM];
257
- if (kind === "id") single = true;
258
- else if (kind === "ids") multi = true;
259
- if (p["atscript_db_action_row"]) {
256
+ if (p.atscript_db_action_param === "id") single = true;
257
+ else if (p.atscript_db_action_param === "ids") multi = true;
258
+ if (p.atscript_db_action_row) {
260
259
  single = true;
261
260
  hasRowParam = true;
262
261
  }
263
- if (p["atscript_db_action_rows"]) {
262
+ if (p.atscript_db_action_rows) {
264
263
  multi = true;
265
264
  hasRowParam = true;
266
265
  }
267
266
  if (p.paramSource === "BODY") hasBody = true;
268
- const form = p[MOOST_DB_ACTION_INPUT_FORM];
269
- if (form) if (inputForm) hasDuplicateInputForm = true;
270
- else inputForm = form;
267
+ if (p.atscript_db_action_input_form) if (inputForm) hasDuplicateInputForm = true;
268
+ else inputForm = p.atscript_db_action_input_form;
271
269
  }
272
270
  return {
273
271
  level: single && multi ? "table" : single ? "row" : multi ? "rows" : "table",
@@ -296,7 +294,7 @@ const rowLevelActionsCache = /* @__PURE__ */ new WeakMap();
296
294
  /**
297
295
  * Per-controller registry of form names → compiled `.as` classes, populated
298
296
  * during {@link discoverActions} when a method param carries
299
- * {@link MOOST_DB_ACTION_INPUT_FORM}. Backs `GET /meta/form/:name`.
297
+ * `atscript_db_action_input_form`. Backs `GET /meta/form/:name`.
300
298
  *
301
299
  * Same name + same type ref across multiple actions is fine (forms can be
302
300
  * reused). Same name + *different* type refs is an ambiguity — discovery
@@ -352,7 +350,7 @@ function collectMethodActions(ctor, overview, logger, out, seen) {
352
350
  }
353
351
  for (const [methodName, handlers] of byMethod) {
354
352
  const methodMeta = handlers[0].meta;
355
- const action = methodMeta[MOOST_DB_ACTION];
353
+ const action = methodMeta.atscript_db_action;
356
354
  if (!action) continue;
357
355
  if (!action.name) {
358
356
  logger.warn(`${WARN_PREFIX} method "${methodName}" has @DbActionDefault() but no @DbAction(name) — dropping`);
@@ -433,7 +431,7 @@ function inferMethodLevel(params, actionName, logger) {
433
431
  };
434
432
  }
435
433
  function collectClassActions(ctor, logger, out, seen) {
436
- const list = (0, moost.getMoostMate)().read(ctor)?.[MOOST_DB_ACTIONS];
434
+ const list = getAtscriptDbMate().read(ctor)?.atscript_db_actions;
437
435
  if (!list) return;
438
436
  for (const { name, entry } of list) {
439
437
  if (seen.has(name)) {
@@ -2021,7 +2019,7 @@ function readCurrentActionMeta(ctx) {
2021
2019
  return;
2022
2020
  }
2023
2021
  if (!ctrl || !methodName) return void 0;
2024
- return (0, moost.getMoostMate)().read(ctrl.constructor, methodName)?.[MOOST_DB_ACTION];
2022
+ return getAtscriptDbMate().read(ctrl.constructor, methodName)?.atscript_db_action;
2025
2023
  }
2026
2024
  //#endregion
2027
2025
  //#region src/actions/input-form-cache.ts
@@ -2323,7 +2321,7 @@ function buildThinInterceptor(opts) {
2323
2321
  //#region src/actions/db-action.decorator.ts
2324
2322
  /**
2325
2323
  * Mark a controller method as a database action surfaced via `/meta`. Writes
2326
- * `MOOST_DB_ACTION` metadata and registers a Moost interceptor when needed
2324
+ * `atscript_db_action` metadata and registers a Moost interceptor when needed
2327
2325
  * (gate when `disabled` is set, thin bound-table injector when only
2328
2326
  * `@DbActionRow*` is present). Stacking two `@DbAction` on the same method
2329
2327
  * is undefined and emits a warning.
@@ -2334,20 +2332,17 @@ function buildThinInterceptor(opts) {
2334
2332
  * `Pick<FlatOf<TRow>, R[number]>[]`.
2335
2333
  */
2336
2334
  function DbAction(name, opts = {}) {
2337
- const mate = (0, moost.getMoostMate)();
2335
+ const mate = getAtscriptDbMate();
2338
2336
  return ((target, propertyKey, descriptor) => {
2339
- const priorName = mate.read(target, propertyKey)?.[MOOST_DB_ACTION]?.name;
2337
+ const priorName = mate.read(target, propertyKey)?.atscript_db_action?.name;
2340
2338
  if (priorName) console.warn(`${WARN_PREFIX} stacking @DbAction on the same method is undefined; declare one per method. Detected: "${priorName}" and "${name}".`);
2341
- mate.decorate((current) => {
2342
- const meta = current;
2343
- return {
2344
- ...current,
2345
- [MOOST_DB_ACTION]: mergeActionMeta(meta, {
2346
- name,
2347
- opts
2348
- })
2349
- };
2350
- })(target, propertyKey, descriptor);
2339
+ mate.decorate((current) => ({
2340
+ ...current,
2341
+ atscript_db_action: mergeActionMeta(current, {
2342
+ name,
2343
+ opts
2344
+ })
2345
+ }))(target, propertyKey, descriptor);
2351
2346
  if (isAsValueHelpControllerSubclass(typeof target === "function" ? target : target.constructor)) return descriptor;
2352
2347
  const scan = scanParamLevel(mate.read(target, propertyKey)?.params ?? []);
2353
2348
  const rawOpts = opts;
@@ -2369,13 +2364,10 @@ function DbAction(name, opts = {}) {
2369
2364
  * Equivalent to passing `opts.default = true`. Decorator order does not matter.
2370
2365
  */
2371
2366
  function DbActionDefault() {
2372
- return (0, moost.getMoostMate)().decorate((current) => {
2373
- const meta = current;
2374
- return {
2375
- ...current,
2376
- [MOOST_DB_ACTION]: mergeActionMeta(meta, { opts: { default: true } })
2377
- };
2378
- });
2367
+ return getAtscriptDbMate().decorate((current) => ({
2368
+ ...current,
2369
+ atscript_db_action: mergeActionMeta(current, { opts: { default: true } })
2370
+ }));
2379
2371
  }
2380
2372
  //#endregion
2381
2373
  //#region src/actions/id-source.ts
@@ -2388,10 +2380,9 @@ function DbActionDefault() {
2388
2380
  * Marks the param so {@link discoverActions} can infer the action's `level`.
2389
2381
  */
2390
2382
  function createIdParamDecorator(kind) {
2391
- const mate = (0, moost.getMoostMate)();
2392
2383
  const resolverName = kind === "id" ? "dbActionId" : "dbActionIds";
2393
2384
  const resolver = kind === "id" ? async () => (0, _wooksjs_event_core.current)().get(dbActionIdSlot) : async () => (0, _wooksjs_event_core.current)().get(dbActionIdsSlot);
2394
- return (0, moost.ApplyDecorators)(mate.decorate(MOOST_DB_ACTION_PARAM, kind), (0, moost.Resolve)(resolver, resolverName));
2385
+ return (0, moost.ApplyDecorators)(getAtscriptDbMate().decorate("atscript_db_action_param", kind), (0, moost.Resolve)(resolver, resolverName));
2395
2386
  }
2396
2387
  //#endregion
2397
2388
  //#region src/actions/db-action-id.decorator.ts
@@ -2446,7 +2437,7 @@ function DbActionIDs() {
2446
2437
  //#endregion
2447
2438
  //#region src/actions/db-action-row.decorator.ts
2448
2439
  function createRowParamDecorator(metaKey, slot, resolverName) {
2449
- return (0, moost.ApplyDecorators)((0, moost.getMoostMate)().decorate(metaKey, true), (0, moost.Resolve)(async () => (0, _wooksjs_event_core.current)().get(slot), resolverName));
2440
+ return (0, moost.ApplyDecorators)(getAtscriptDbMate().decorate(metaKey, true), (0, moost.Resolve)(async () => (0, _wooksjs_event_core.current)().get(slot), resolverName));
2450
2441
  }
2451
2442
  /**
2452
2443
  * Parameter decorator that injects the row whose identifier was supplied in
@@ -2460,7 +2451,7 @@ function createRowParamDecorator(metaKey, slot, resolverName) {
2460
2451
  * request-body row is not retrievable.
2461
2452
  */
2462
2453
  function DbActionRow() {
2463
- return createRowParamDecorator(MOOST_DB_ACTION_ROW, dbActionRowSlot, "dbActionRow");
2454
+ return createRowParamDecorator("atscript_db_action_row", dbActionRowSlot, "dbActionRow");
2464
2455
  }
2465
2456
  /**
2466
2457
  * Parameter decorator that injects the rows fetched by the identifiers
@@ -2471,7 +2462,7 @@ function DbActionRow() {
2471
2462
  * gate's surviving rows.
2472
2463
  */
2473
2464
  function DbActionRows() {
2474
- return createRowParamDecorator(MOOST_DB_ACTION_ROWS, dbActionRowsSlot, "dbActionRows");
2465
+ return createRowParamDecorator("atscript_db_action_rows", dbActionRowsSlot, "dbActionRows");
2475
2466
  }
2476
2467
  //#endregion
2477
2468
  //#region src/actions/db-actions.decorator.ts
@@ -2516,13 +2507,10 @@ function classLevelActions(dict, forcedLevel) {
2516
2507
  entry: merged
2517
2508
  });
2518
2509
  }
2519
- return (0, moost.getMoostMate)().decorate((current) => {
2520
- const existing = current["atscript_db_actions"] ?? [];
2521
- return {
2522
- ...current,
2523
- [MOOST_DB_ACTIONS]: [...existing, ...entries]
2524
- };
2525
- });
2510
+ return getAtscriptDbMate().decorate((current) => ({
2511
+ ...current,
2512
+ atscript_db_actions: [...current.atscript_db_actions ?? [], ...entries]
2513
+ }));
2526
2514
  }
2527
2515
  //#endregion
2528
2516
  //#region src/actions/db-action-input-form.decorator.ts
@@ -2532,19 +2520,19 @@ function classLevelActions(dict, forcedLevel) {
2532
2520
  *
2533
2521
  * Pairs the resolved value with two pieces of param-level metadata:
2534
2522
  *
2535
- * 1. {@link MOOST_DB_ACTION_INPUT_FORM} — the compiled `.as` class plus its
2536
- * name, consumed by {@link discoverActions} to:
2523
+ * 1. `atscript_db_action_input_form` — the compiled `.as` class plus its
2524
+ * name, consumed by `discoverActions` to:
2537
2525
  * - emit `inputForm: FormType.name` on the action's `/meta` entry, and
2538
2526
  * - register the type in the controller's form registry so
2539
2527
  * `GET /meta/form/:name` can serve the serialized schema.
2540
- * 2. {@link MOOST_ATSCRIPT_TYPE} — just the type ref, providing a generic
2541
- * hook any atscript-aware Moost pipe can read without knowing about the
2528
+ * 2. `atscript_type` — just the type ref, providing a generic hook any
2529
+ * atscript-aware Moost pipe can read without knowing about the
2542
2530
  * moost-db-specific key.
2543
2531
  *
2544
2532
  * Validation is intentionally *not* performed here. To validate `input`
2545
2533
  * against `FormType`, install an atscript validator pipe globally
2546
2534
  * (`app.applyGlobalPipes(...)`) or scope it via `@Pipe(...)`. The pipe reads
2547
- * `MOOST_ATSCRIPT_TYPE` off the param and runs `FormType.validator()`.
2535
+ * `atscript_type` off the param and runs `FormType.validator()`.
2548
2536
  *
2549
2537
  * Only one `@InputForm()` per action is supported. To collect multiple
2550
2538
  * structured inputs, compose them into a single `.as` interface and pass an
@@ -2559,7 +2547,7 @@ function InputForm(formType) {
2559
2547
  type: formType,
2560
2548
  name: formType.name
2561
2549
  };
2562
- return (0, moost.ApplyDecorators)(mate.decorate(MOOST_DB_ACTION_INPUT_FORM, meta), mate.decorate(MOOST_ATSCRIPT_TYPE, formType), (0, moost.Resolve)(async () => (0, _wooksjs_event_core.current)().get(dbActionInputSlot), "dbActionInputForm"));
2550
+ return (0, moost.ApplyDecorators)(mate.decorate("atscript_db_action_input_form", meta), mate.decorate("atscript_type", formType), (0, moost.Resolve)(async () => (0, _wooksjs_event_core.current)().get(dbActionInputSlot), "dbActionInputForm"));
2563
2551
  }
2564
2552
  //#endregion
2565
2553
  //#region src/actions/per-row.ts
@@ -2619,8 +2607,6 @@ exports.DbRowActions = DbRowActions;
2619
2607
  exports.DbRowsActions = DbRowsActions;
2620
2608
  exports.DbTableActions = DbTableActions;
2621
2609
  exports.InputForm = InputForm;
2622
- exports.MOOST_ATSCRIPT_TYPE = MOOST_ATSCRIPT_TYPE;
2623
- exports.MOOST_DB_ACTION_INPUT_FORM = MOOST_DB_ACTION_INPUT_FORM;
2624
2610
  exports.ONE_CONTROLS = ONE_CONTROLS;
2625
2611
  exports.PAGES_CONTROLS = PAGES_CONTROLS;
2626
2612
  exports.QUERY_CONTROLS = QUERY_CONTROLS;
@@ -2633,6 +2619,7 @@ exports.ViewController = ViewController;
2633
2619
  exports.dbActionBodySlot = dbActionBodySlot;
2634
2620
  exports.dbActionInputSlot = dbActionInputSlot;
2635
2621
  exports.discoverActions = discoverActions;
2622
+ exports.getAtscriptDbMate = getAtscriptDbMate;
2636
2623
  exports.getControllerFormType = getControllerFormType;
2637
2624
  exports.perRow = perRow;
2638
2625
  exports.useDbActionId = useDbActionId;
package/dist/index.d.cts CHANGED
@@ -4,7 +4,7 @@ import { TAtscriptAnnotatedType, TAtscriptDataType, TSerializeOptions, TSerializ
4
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
- import { Moost, TConsoleBase } from "moost";
7
+ import { Mate, Moost, TConsoleBase, TMateParamMeta, TMoostMetadata } from "moost";
8
8
  import * as _wooksjs_event_core0 from "@wooksjs/event-core";
9
9
 
10
10
  //#region src/as-readable.controller.d.ts
@@ -640,7 +640,7 @@ type ValidatedUnpinnedDict<TRow, D extends DbActionsDictBase> = { [K in keyof D]
640
640
  //#region src/actions/db-action.decorator.d.ts
641
641
  /**
642
642
  * Mark a controller method as a database action surfaced via `/meta`. Writes
643
- * `MOOST_DB_ACTION` metadata and registers a Moost interceptor when needed
643
+ * `atscript_db_action` metadata and registers a Moost interceptor when needed
644
644
  * (gate when `disabled` is set, thin bound-table injector when only
645
645
  * `@DbActionRow*` is present). Stacking two `@DbAction` on the same method
646
646
  * is undefined and emits a warning.
@@ -758,19 +758,19 @@ declare function DbRowsActions<TRow = unknown, const D extends Record<string, un
758
758
  *
759
759
  * Pairs the resolved value with two pieces of param-level metadata:
760
760
  *
761
- * 1. {@link MOOST_DB_ACTION_INPUT_FORM} — the compiled `.as` class plus its
762
- * name, consumed by {@link discoverActions} to:
761
+ * 1. `atscript_db_action_input_form` — the compiled `.as` class plus its
762
+ * name, consumed by `discoverActions` to:
763
763
  * - emit `inputForm: FormType.name` on the action's `/meta` entry, and
764
764
  * - register the type in the controller's form registry so
765
765
  * `GET /meta/form/:name` can serve the serialized schema.
766
- * 2. {@link MOOST_ATSCRIPT_TYPE} — just the type ref, providing a generic
767
- * hook any atscript-aware Moost pipe can read without knowing about the
766
+ * 2. `atscript_type` — just the type ref, providing a generic hook any
767
+ * atscript-aware Moost pipe can read without knowing about the
768
768
  * moost-db-specific key.
769
769
  *
770
770
  * Validation is intentionally *not* performed here. To validate `input`
771
771
  * against `FormType`, install an atscript validator pipe globally
772
772
  * (`app.applyGlobalPipes(...)`) or scope it via `@Pipe(...)`. The pipe reads
773
- * `MOOST_ATSCRIPT_TYPE` off the param and runs `FormType.validator()`.
773
+ * `atscript_type` off the param and runs `FormType.validator()`.
774
774
  *
775
775
  * Only one `@InputForm()` per action is supported. To collect multiple
776
776
  * structured inputs, compose them into a single `.as` interface and pass an
@@ -850,30 +850,6 @@ declare const useDbActionInput: _wooksjs_event_core0.WookComposable<{
850
850
  }>;
851
851
  //#endregion
852
852
  //#region src/actions/keys.d.ts
853
- /** Method-level metadata key — written by `@DbAction(name, opts)`. */
854
- declare const MOOST_DB_ACTION = "atscript_db_action";
855
- /** Class-level metadata key — written by `@DbActions` and the level-pinned shortcuts. Stored as an array; decorators accumulate. */
856
- declare const MOOST_DB_ACTIONS = "atscript_db_actions";
857
- /** Param-level metadata key — written by `@DbActionID()` / `@DbActionIDs()`. Drives level inference. */
858
- declare const MOOST_DB_ACTION_PARAM = "atscript_db_action_param";
859
- /** Param-level marker keys — written by `@DbActionRow()` / `@DbActionRows()`. */
860
- declare const MOOST_DB_ACTION_ROW = "atscript_db_action_row";
861
- declare const MOOST_DB_ACTION_ROWS = "atscript_db_action_rows";
862
- /**
863
- * Param-level metadata key — written by `@InputForm(FormType)`. Carries the
864
- * compiled `.as` class plus its `.name` so {@link discoverActions} can both
865
- * emit `inputForm` on `/meta` and register the type in the controller's form
866
- * registry for `GET /meta/form/:name`.
867
- */
868
- declare const MOOST_DB_ACTION_INPUT_FORM = "atscript_db_action_input_form";
869
- /**
870
- * Generic param-level metadata key — written by `@InputForm(FormType)`
871
- * alongside {@link MOOST_DB_ACTION_INPUT_FORM}. Holds just the type ref so a
872
- * generic atscript-aware Moost pipe (installed globally via
873
- * `app.applyGlobalPipes(...)` or scoped via `@Pipe(...)`) can validate the
874
- * resolved value without knowing about the moost-db-specific key.
875
- */
876
- declare const MOOST_ATSCRIPT_TYPE = "atscript_type";
877
853
  type TDbActionRowMarker = true;
878
854
  /** Stamped by `@InputForm(FormType)` — the compiled `.as` class + the wire name (`FormType.name`). */
879
855
  interface TDbActionInputFormMeta {
@@ -894,18 +870,18 @@ interface TDbClassActionMeta {
894
870
  type TDbActionParamKind = "id" | "ids";
895
871
  declare module "moost" {
896
872
  interface TMoostMetadata {
897
- [MOOST_DB_ACTION]?: TDbActionMeta;
898
- [MOOST_DB_ACTIONS]?: TDbClassActionMeta[];
899
- [MOOST_DB_ACTION_PARAM]?: TDbActionParamKind;
900
- [MOOST_DB_ACTION_ROW]?: TDbActionRowMarker;
901
- [MOOST_DB_ACTION_ROWS]?: TDbActionRowMarker;
873
+ atscript_db_action?: TDbActionMeta;
874
+ atscript_db_actions?: TDbClassActionMeta[];
875
+ atscript_db_action_param?: TDbActionParamKind;
876
+ atscript_db_action_row?: TDbActionRowMarker;
877
+ atscript_db_action_rows?: TDbActionRowMarker;
902
878
  }
903
879
  interface TMoostParamsMetadata {
904
- [MOOST_DB_ACTION_PARAM]?: TDbActionParamKind;
905
- [MOOST_DB_ACTION_ROW]?: TDbActionRowMarker;
906
- [MOOST_DB_ACTION_ROWS]?: TDbActionRowMarker;
907
- [MOOST_DB_ACTION_INPUT_FORM]?: TDbActionInputFormMeta;
908
- [MOOST_ATSCRIPT_TYPE]?: TAtscriptAnnotatedType;
880
+ atscript_db_action_param?: TDbActionParamKind;
881
+ atscript_db_action_row?: TDbActionRowMarker;
882
+ atscript_db_action_rows?: TDbActionRowMarker;
883
+ atscript_db_action_input_form?: TDbActionInputFormMeta;
884
+ atscript_type?: TAtscriptAnnotatedType;
909
885
  }
910
886
  }
911
887
  //#endregion
@@ -964,9 +940,95 @@ declare class ActionDisabledError extends HttpError<ActionDisabledErrorBody> {
964
940
  */
965
941
  declare const perRow: <TRow>(fn: (row: TRow) => boolean) => (rows: TRow[]) => boolean[];
966
942
  //#endregion
943
+ //#region src/mate.d.ts
944
+ /**
945
+ * Class- and method-level metadata written by `@atscript/moost-db`'s
946
+ * decorators (`@DbAction`, `@DbActionDefault`, `@DbActions`,
947
+ * `@DbTableActions`, `@DbRowActions`, `@DbRowsActions`).
948
+ *
949
+ * The keys are intentionally kept identical to the underlying
950
+ * mate-storage keys (`atscript_db_*`) so the same shape applies whether
951
+ * the consumer reads via {@link getAtscriptDbMate} or pokes the raw
952
+ * `getMoostMate()` instance directly. End-users never need to type the
953
+ * magic strings — `mate.read(...)?.atscript_db_action` is fully typed.
954
+ */
955
+ interface AtscriptDbMeta {
956
+ /** Method-level — written by `@DbAction(name, opts)` / `@DbActionDefault()`. */
957
+ atscript_db_action?: TDbActionMeta;
958
+ /** Class-level — written by `@DbActions` and the level-pinned shortcuts. Decorators accumulate into the array. */
959
+ atscript_db_actions?: TDbClassActionMeta[];
960
+ /** Param-level marker — written by `@DbActionID()` / `@DbActionIDs()`. Drives action-level inference. */
961
+ atscript_db_action_param?: TDbActionParamKind;
962
+ /** Param-level marker — written by `@DbActionRow()`. */
963
+ atscript_db_action_row?: true;
964
+ /** Param-level marker — written by `@DbActionRows()`. */
965
+ atscript_db_action_rows?: true;
966
+ }
967
+ /**
968
+ * Param-level metadata written by `@atscript/moost-db`'s param
969
+ * decorators. A superset of {@link AtscriptDbMeta}'s param-level keys
970
+ * plus the `@InputForm()`-specific entries.
971
+ */
972
+ interface AtscriptDbParamsMeta {
973
+ /** Param-level — written by `@DbActionID()` / `@DbActionIDs()`. */
974
+ atscript_db_action_param?: TDbActionParamKind;
975
+ /** Param-level marker — written by `@DbActionRow()`. */
976
+ atscript_db_action_row?: true;
977
+ /** Param-level marker — written by `@DbActionRows()`. */
978
+ atscript_db_action_rows?: true;
979
+ /**
980
+ * Param-level — written by `@InputForm(FormType)`. Carries the
981
+ * compiled `.as` class plus its `.name` so `discoverActions` can both
982
+ * emit `inputForm` on `/meta` and register the type in the controller's
983
+ * form registry for `GET /meta/form/:name`.
984
+ */
985
+ atscript_db_action_input_form?: TDbActionInputFormMeta;
986
+ /**
987
+ * Param-level — written by `@InputForm(FormType)` alongside
988
+ * `atscript_db_action_input_form`. Holds just the type ref so a generic
989
+ * atscript-aware Moost pipe (installed globally via
990
+ * `app.applyGlobalPipes(...)` or scoped via `@Pipe(...)`) can validate
991
+ * the resolved value without knowing about the moost-db-specific key.
992
+ */
993
+ atscript_type?: TAtscriptAnnotatedType;
994
+ }
995
+ /**
996
+ * The fully-typed {@link Mate} instance shared across the moost
997
+ * metadata workspace, narrowed to the keys that
998
+ * `@atscript/moost-db` writes.
999
+ *
1000
+ * Class- and prop-meta storage mirror the same shape; param-meta
1001
+ * storage uses {@link AtscriptDbParamsMeta}.
1002
+ */
1003
+ type AtscriptDbMate = Mate<TMoostMetadata & AtscriptDbMeta & {
1004
+ params: (TMateParamMeta & AtscriptDbParamsMeta)[];
1005
+ }, TMoostMetadata & AtscriptDbMeta & {
1006
+ params: (TMateParamMeta & AtscriptDbParamsMeta)[];
1007
+ }>;
1008
+ /**
1009
+ * Returns the shared moost-mate instance, typed against every key that
1010
+ * `@atscript/moost-db` writes (see {@link AtscriptDbMeta} +
1011
+ * {@link AtscriptDbParamsMeta}).
1012
+ *
1013
+ * Prefer this over `getMoostMate()` from `moost` whenever you need to
1014
+ * read moost-db metadata — callers no longer have to retype the
1015
+ * `atscript_db_*` magic strings or hand-cast the result.
1016
+ *
1017
+ * @example
1018
+ * ```ts
1019
+ * import { getAtscriptDbMate } from "@atscript/moost-db";
1020
+ *
1021
+ * const mate = getAtscriptDbMate();
1022
+ * const meta = mate.read(controllerCtor.prototype, methodName);
1023
+ * const dbAction = meta?.atscript_db_action; // TDbActionMeta | undefined
1024
+ * const inputForm = meta?.params?.[0]?.atscript_db_action_input_form;
1025
+ * ```
1026
+ */
1027
+ declare function getAtscriptDbMate(): AtscriptDbMate;
1028
+ //#endregion
967
1029
  //#region src/permissions/crud-controls.d.ts
968
1030
  declare const QUERY_CONTROLS: readonly string[];
969
1031
  declare const PAGES_CONTROLS: readonly string[];
970
1032
  declare const ONE_CONTROLS: readonly string[];
971
1033
  //#endregion
972
- export { ActionDisabledError, type ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, type DbActionEnvelope, DbActionID, DbActionIDs, type DbActionOpts, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, type IdValidationSource, InputForm, MOOST_ATSCRIPT_TYPE, MOOST_DB_ACTION_INPUT_FORM, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionInputFormMeta, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbActionsEntry, type TDbActionsEntryUnpinned, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, dbActionBodySlot, dbActionInputSlot, discoverActions, getControllerFormType, perRow, useDbActionId, useDbActionIds, useDbActionInput, useDbActionRow, useDbActionRows, validationErrorTransform };
1034
+ export { ActionDisabledError, type ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, type AtscriptDbMate, type AtscriptDbMeta, type AtscriptDbParamsMeta, DbAction, DbActionDefault, type DbActionEnvelope, DbActionID, DbActionIDs, type DbActionOpts, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, type IdValidationSource, InputForm, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionInputFormMeta, type TDbActionIntent, type TDbActionLevel, type TDbActionMeta, type TDbActionParamKind, type TDbActionProcessor, type TDbActionsEntry, type TDbActionsEntryUnpinned, type TDbClassActionMeta, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, dbActionBodySlot, dbActionInputSlot, discoverActions, getAtscriptDbMate, getControllerFormType, perRow, useDbActionId, useDbActionIds, useDbActionInput, useDbActionRow, useDbActionRows, validationErrorTransform };
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { TAtscriptAnnotatedType, TAtscriptDataType, TSerializeOptions, TSerializedAnnotatedType, Validator } from "@atscript/typescript/utils";
2
2
  import { HttpError } from "@moostjs/event-http";
3
3
  import * as moost from "moost";
4
- import { Moost, TConsoleBase } from "moost";
4
+ import { Mate, Moost, TConsoleBase, TMateParamMeta, TMoostMetadata } from "moost";
5
5
  import * as _uniqu_url0 from "@uniqu/url";
6
6
  import { parseUrl } from "@uniqu/url";
7
7
  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";
@@ -640,7 +640,7 @@ type ValidatedUnpinnedDict<TRow, D extends DbActionsDictBase> = { [K in keyof D]
640
640
  //#region src/actions/db-action.decorator.d.ts
641
641
  /**
642
642
  * Mark a controller method as a database action surfaced via `/meta`. Writes
643
- * `MOOST_DB_ACTION` metadata and registers a Moost interceptor when needed
643
+ * `atscript_db_action` metadata and registers a Moost interceptor when needed
644
644
  * (gate when `disabled` is set, thin bound-table injector when only
645
645
  * `@DbActionRow*` is present). Stacking two `@DbAction` on the same method
646
646
  * is undefined and emits a warning.
@@ -758,19 +758,19 @@ declare function DbRowsActions<TRow = unknown, const D extends Record<string, un
758
758
  *
759
759
  * Pairs the resolved value with two pieces of param-level metadata:
760
760
  *
761
- * 1. {@link MOOST_DB_ACTION_INPUT_FORM} — the compiled `.as` class plus its
762
- * name, consumed by {@link discoverActions} to:
761
+ * 1. `atscript_db_action_input_form` — the compiled `.as` class plus its
762
+ * name, consumed by `discoverActions` to:
763
763
  * - emit `inputForm: FormType.name` on the action's `/meta` entry, and
764
764
  * - register the type in the controller's form registry so
765
765
  * `GET /meta/form/:name` can serve the serialized schema.
766
- * 2. {@link MOOST_ATSCRIPT_TYPE} — just the type ref, providing a generic
767
- * hook any atscript-aware Moost pipe can read without knowing about the
766
+ * 2. `atscript_type` — just the type ref, providing a generic hook any
767
+ * atscript-aware Moost pipe can read without knowing about the
768
768
  * moost-db-specific key.
769
769
  *
770
770
  * Validation is intentionally *not* performed here. To validate `input`
771
771
  * against `FormType`, install an atscript validator pipe globally
772
772
  * (`app.applyGlobalPipes(...)`) or scope it via `@Pipe(...)`. The pipe reads
773
- * `MOOST_ATSCRIPT_TYPE` off the param and runs `FormType.validator()`.
773
+ * `atscript_type` off the param and runs `FormType.validator()`.
774
774
  *
775
775
  * Only one `@InputForm()` per action is supported. To collect multiple
776
776
  * structured inputs, compose them into a single `.as` interface and pass an
@@ -850,30 +850,6 @@ declare const useDbActionInput: _wooksjs_event_core0.WookComposable<{
850
850
  }>;
851
851
  //#endregion
852
852
  //#region src/actions/keys.d.ts
853
- /** Method-level metadata key — written by `@DbAction(name, opts)`. */
854
- declare const MOOST_DB_ACTION = "atscript_db_action";
855
- /** Class-level metadata key — written by `@DbActions` and the level-pinned shortcuts. Stored as an array; decorators accumulate. */
856
- declare const MOOST_DB_ACTIONS = "atscript_db_actions";
857
- /** Param-level metadata key — written by `@DbActionID()` / `@DbActionIDs()`. Drives level inference. */
858
- declare const MOOST_DB_ACTION_PARAM = "atscript_db_action_param";
859
- /** Param-level marker keys — written by `@DbActionRow()` / `@DbActionRows()`. */
860
- declare const MOOST_DB_ACTION_ROW = "atscript_db_action_row";
861
- declare const MOOST_DB_ACTION_ROWS = "atscript_db_action_rows";
862
- /**
863
- * Param-level metadata key — written by `@InputForm(FormType)`. Carries the
864
- * compiled `.as` class plus its `.name` so {@link discoverActions} can both
865
- * emit `inputForm` on `/meta` and register the type in the controller's form
866
- * registry for `GET /meta/form/:name`.
867
- */
868
- declare const MOOST_DB_ACTION_INPUT_FORM = "atscript_db_action_input_form";
869
- /**
870
- * Generic param-level metadata key — written by `@InputForm(FormType)`
871
- * alongside {@link MOOST_DB_ACTION_INPUT_FORM}. Holds just the type ref so a
872
- * generic atscript-aware Moost pipe (installed globally via
873
- * `app.applyGlobalPipes(...)` or scoped via `@Pipe(...)`) can validate the
874
- * resolved value without knowing about the moost-db-specific key.
875
- */
876
- declare const MOOST_ATSCRIPT_TYPE = "atscript_type";
877
853
  type TDbActionRowMarker = true;
878
854
  /** Stamped by `@InputForm(FormType)` — the compiled `.as` class + the wire name (`FormType.name`). */
879
855
  interface TDbActionInputFormMeta {
@@ -894,18 +870,18 @@ interface TDbClassActionMeta {
894
870
  type TDbActionParamKind = "id" | "ids";
895
871
  declare module "moost" {
896
872
  interface TMoostMetadata {
897
- [MOOST_DB_ACTION]?: TDbActionMeta;
898
- [MOOST_DB_ACTIONS]?: TDbClassActionMeta[];
899
- [MOOST_DB_ACTION_PARAM]?: TDbActionParamKind;
900
- [MOOST_DB_ACTION_ROW]?: TDbActionRowMarker;
901
- [MOOST_DB_ACTION_ROWS]?: TDbActionRowMarker;
873
+ atscript_db_action?: TDbActionMeta;
874
+ atscript_db_actions?: TDbClassActionMeta[];
875
+ atscript_db_action_param?: TDbActionParamKind;
876
+ atscript_db_action_row?: TDbActionRowMarker;
877
+ atscript_db_action_rows?: TDbActionRowMarker;
902
878
  }
903
879
  interface TMoostParamsMetadata {
904
- [MOOST_DB_ACTION_PARAM]?: TDbActionParamKind;
905
- [MOOST_DB_ACTION_ROW]?: TDbActionRowMarker;
906
- [MOOST_DB_ACTION_ROWS]?: TDbActionRowMarker;
907
- [MOOST_DB_ACTION_INPUT_FORM]?: TDbActionInputFormMeta;
908
- [MOOST_ATSCRIPT_TYPE]?: TAtscriptAnnotatedType;
880
+ atscript_db_action_param?: TDbActionParamKind;
881
+ atscript_db_action_row?: TDbActionRowMarker;
882
+ atscript_db_action_rows?: TDbActionRowMarker;
883
+ atscript_db_action_input_form?: TDbActionInputFormMeta;
884
+ atscript_type?: TAtscriptAnnotatedType;
909
885
  }
910
886
  }
911
887
  //#endregion
@@ -964,9 +940,95 @@ declare class ActionDisabledError extends HttpError<ActionDisabledErrorBody> {
964
940
  */
965
941
  declare const perRow: <TRow>(fn: (row: TRow) => boolean) => (rows: TRow[]) => boolean[];
966
942
  //#endregion
943
+ //#region src/mate.d.ts
944
+ /**
945
+ * Class- and method-level metadata written by `@atscript/moost-db`'s
946
+ * decorators (`@DbAction`, `@DbActionDefault`, `@DbActions`,
947
+ * `@DbTableActions`, `@DbRowActions`, `@DbRowsActions`).
948
+ *
949
+ * The keys are intentionally kept identical to the underlying
950
+ * mate-storage keys (`atscript_db_*`) so the same shape applies whether
951
+ * the consumer reads via {@link getAtscriptDbMate} or pokes the raw
952
+ * `getMoostMate()` instance directly. End-users never need to type the
953
+ * magic strings — `mate.read(...)?.atscript_db_action` is fully typed.
954
+ */
955
+ interface AtscriptDbMeta {
956
+ /** Method-level — written by `@DbAction(name, opts)` / `@DbActionDefault()`. */
957
+ atscript_db_action?: TDbActionMeta;
958
+ /** Class-level — written by `@DbActions` and the level-pinned shortcuts. Decorators accumulate into the array. */
959
+ atscript_db_actions?: TDbClassActionMeta[];
960
+ /** Param-level marker — written by `@DbActionID()` / `@DbActionIDs()`. Drives action-level inference. */
961
+ atscript_db_action_param?: TDbActionParamKind;
962
+ /** Param-level marker — written by `@DbActionRow()`. */
963
+ atscript_db_action_row?: true;
964
+ /** Param-level marker — written by `@DbActionRows()`. */
965
+ atscript_db_action_rows?: true;
966
+ }
967
+ /**
968
+ * Param-level metadata written by `@atscript/moost-db`'s param
969
+ * decorators. A superset of {@link AtscriptDbMeta}'s param-level keys
970
+ * plus the `@InputForm()`-specific entries.
971
+ */
972
+ interface AtscriptDbParamsMeta {
973
+ /** Param-level — written by `@DbActionID()` / `@DbActionIDs()`. */
974
+ atscript_db_action_param?: TDbActionParamKind;
975
+ /** Param-level marker — written by `@DbActionRow()`. */
976
+ atscript_db_action_row?: true;
977
+ /** Param-level marker — written by `@DbActionRows()`. */
978
+ atscript_db_action_rows?: true;
979
+ /**
980
+ * Param-level — written by `@InputForm(FormType)`. Carries the
981
+ * compiled `.as` class plus its `.name` so `discoverActions` can both
982
+ * emit `inputForm` on `/meta` and register the type in the controller's
983
+ * form registry for `GET /meta/form/:name`.
984
+ */
985
+ atscript_db_action_input_form?: TDbActionInputFormMeta;
986
+ /**
987
+ * Param-level — written by `@InputForm(FormType)` alongside
988
+ * `atscript_db_action_input_form`. Holds just the type ref so a generic
989
+ * atscript-aware Moost pipe (installed globally via
990
+ * `app.applyGlobalPipes(...)` or scoped via `@Pipe(...)`) can validate
991
+ * the resolved value without knowing about the moost-db-specific key.
992
+ */
993
+ atscript_type?: TAtscriptAnnotatedType;
994
+ }
995
+ /**
996
+ * The fully-typed {@link Mate} instance shared across the moost
997
+ * metadata workspace, narrowed to the keys that
998
+ * `@atscript/moost-db` writes.
999
+ *
1000
+ * Class- and prop-meta storage mirror the same shape; param-meta
1001
+ * storage uses {@link AtscriptDbParamsMeta}.
1002
+ */
1003
+ type AtscriptDbMate = Mate<TMoostMetadata & AtscriptDbMeta & {
1004
+ params: (TMateParamMeta & AtscriptDbParamsMeta)[];
1005
+ }, TMoostMetadata & AtscriptDbMeta & {
1006
+ params: (TMateParamMeta & AtscriptDbParamsMeta)[];
1007
+ }>;
1008
+ /**
1009
+ * Returns the shared moost-mate instance, typed against every key that
1010
+ * `@atscript/moost-db` writes (see {@link AtscriptDbMeta} +
1011
+ * {@link AtscriptDbParamsMeta}).
1012
+ *
1013
+ * Prefer this over `getMoostMate()` from `moost` whenever you need to
1014
+ * read moost-db metadata — callers no longer have to retype the
1015
+ * `atscript_db_*` magic strings or hand-cast the result.
1016
+ *
1017
+ * @example
1018
+ * ```ts
1019
+ * import { getAtscriptDbMate } from "@atscript/moost-db";
1020
+ *
1021
+ * const mate = getAtscriptDbMate();
1022
+ * const meta = mate.read(controllerCtor.prototype, methodName);
1023
+ * const dbAction = meta?.atscript_db_action; // TDbActionMeta | undefined
1024
+ * const inputForm = meta?.params?.[0]?.atscript_db_action_input_form;
1025
+ * ```
1026
+ */
1027
+ declare function getAtscriptDbMate(): AtscriptDbMate;
1028
+ //#endregion
967
1029
  //#region src/permissions/crud-controls.d.ts
968
1030
  declare const QUERY_CONTROLS: readonly string[];
969
1031
  declare const PAGES_CONTROLS: readonly string[];
970
1032
  declare const ONE_CONTROLS: readonly string[];
971
1033
  //#endregion
972
- export { ActionDisabledError, type ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, type DbActionEnvelope, DbActionID, DbActionIDs, type DbActionOpts, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, type IdValidationSource, InputForm, MOOST_ATSCRIPT_TYPE, MOOST_DB_ACTION_INPUT_FORM, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionInputFormMeta, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbActionsEntry, type TDbActionsEntryUnpinned, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, dbActionBodySlot, dbActionInputSlot, discoverActions, getControllerFormType, perRow, useDbActionId, useDbActionIds, useDbActionInput, useDbActionRow, useDbActionRows, validationErrorTransform };
1034
+ export { ActionDisabledError, type ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, type AtscriptDbMate, type AtscriptDbMeta, type AtscriptDbParamsMeta, DbAction, DbActionDefault, type DbActionEnvelope, DbActionID, DbActionIDs, type DbActionOpts, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, type IdValidationSource, InputForm, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionInputFormMeta, type TDbActionIntent, type TDbActionLevel, type TDbActionMeta, type TDbActionParamKind, type TDbActionProcessor, type TDbActionsEntry, type TDbActionsEntryUnpinned, type TDbClassActionMeta, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, dbActionBodySlot, dbActionInputSlot, discoverActions, getAtscriptDbMate, getControllerFormType, perRow, useDbActionId, useDbActionIds, useDbActionInput, useDbActionRow, useDbActionRows, validationErrorTransform };
package/dist/index.mjs CHANGED
@@ -181,6 +181,30 @@ function findSortOffender(sort, isAllowed) {
181
181
  }
182
182
  }
183
183
  //#endregion
184
+ //#region src/mate.ts
185
+ /**
186
+ * Returns the shared moost-mate instance, typed against every key that
187
+ * `@atscript/moost-db` writes (see {@link AtscriptDbMeta} +
188
+ * {@link AtscriptDbParamsMeta}).
189
+ *
190
+ * Prefer this over `getMoostMate()` from `moost` whenever you need to
191
+ * read moost-db metadata — callers no longer have to retype the
192
+ * `atscript_db_*` magic strings or hand-cast the result.
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * import { getAtscriptDbMate } from "@atscript/moost-db";
197
+ *
198
+ * const mate = getAtscriptDbMate();
199
+ * const meta = mate.read(controllerCtor.prototype, methodName);
200
+ * const dbAction = meta?.atscript_db_action; // TDbActionMeta | undefined
201
+ * const inputForm = meta?.params?.[0]?.atscript_db_action_input_form;
202
+ * ```
203
+ */
204
+ function getAtscriptDbMate() {
205
+ return getMoostMate();
206
+ }
207
+ //#endregion
184
208
  //#region src/actions/controller-registry.ts
185
209
  let asDbReadableCtor = null;
186
210
  let asValueHelpCtor = null;
@@ -202,38 +226,14 @@ function isAsValueHelpControllerSubclass(ctor) {
202
226
  //#region src/actions/keys.ts
203
227
  /** Log-message prefix for warnings emitted from the actions subsystem. */
204
228
  const WARN_PREFIX = "[moost-db actions]";
205
- /** Method-level metadata key — written by `@DbAction(name, opts)`. */
206
- const MOOST_DB_ACTION = "atscript_db_action";
207
- /** Class-level metadata key — written by `@DbActions` and the level-pinned shortcuts. Stored as an array; decorators accumulate. */
208
- const MOOST_DB_ACTIONS = "atscript_db_actions";
209
- /** Param-level metadata key — written by `@DbActionID()` / `@DbActionIDs()`. Drives level inference. */
210
- const MOOST_DB_ACTION_PARAM = "atscript_db_action_param";
211
- /** Param-level marker keys — written by `@DbActionRow()` / `@DbActionRows()`. */
212
- const MOOST_DB_ACTION_ROW = "atscript_db_action_row";
213
- const MOOST_DB_ACTION_ROWS = "atscript_db_action_rows";
214
- /**
215
- * Param-level metadata key — written by `@InputForm(FormType)`. Carries the
216
- * compiled `.as` class plus its `.name` so {@link discoverActions} can both
217
- * emit `inputForm` on `/meta` and register the type in the controller's form
218
- * registry for `GET /meta/form/:name`.
219
- */
220
- const MOOST_DB_ACTION_INPUT_FORM = "atscript_db_action_input_form";
221
- /**
222
- * Generic param-level metadata key — written by `@InputForm(FormType)`
223
- * alongside {@link MOOST_DB_ACTION_INPUT_FORM}. Holds just the type ref so a
224
- * generic atscript-aware Moost pipe (installed globally via
225
- * `app.applyGlobalPipes(...)` or scoped via `@Pipe(...)`) can validate the
226
- * resolved value without knowing about the moost-db-specific key.
227
- */
228
- const MOOST_ATSCRIPT_TYPE = "atscript_type";
229
229
  /**
230
230
  * Shared method-decorator update used by `@DbAction` and `@DbActionDefault`:
231
- * read the existing `MOOST_DB_ACTION` slot, merge the patch (later-applied
231
+ * read the existing `atscript_db_action` slot, merge the patch (later-applied
232
232
  * fields win), and write it back. `name` is empty until `@DbAction` provides
233
233
  * one — `discoverActions` warns and drops actions with no name.
234
234
  */
235
235
  function mergeActionMeta(current, patch) {
236
- const existing = current[MOOST_DB_ACTION];
236
+ const existing = current.atscript_db_action;
237
237
  return {
238
238
  name: patch.name ?? existing?.name ?? "",
239
239
  opts: {
@@ -252,21 +252,19 @@ function scanParamLevel(params) {
252
252
  let inputForm;
253
253
  let hasDuplicateInputForm = false;
254
254
  for (const p of params) {
255
- const kind = p[MOOST_DB_ACTION_PARAM];
256
- if (kind === "id") single = true;
257
- else if (kind === "ids") multi = true;
258
- if (p["atscript_db_action_row"]) {
255
+ if (p.atscript_db_action_param === "id") single = true;
256
+ else if (p.atscript_db_action_param === "ids") multi = true;
257
+ if (p.atscript_db_action_row) {
259
258
  single = true;
260
259
  hasRowParam = true;
261
260
  }
262
- if (p["atscript_db_action_rows"]) {
261
+ if (p.atscript_db_action_rows) {
263
262
  multi = true;
264
263
  hasRowParam = true;
265
264
  }
266
265
  if (p.paramSource === "BODY") hasBody = true;
267
- const form = p[MOOST_DB_ACTION_INPUT_FORM];
268
- if (form) if (inputForm) hasDuplicateInputForm = true;
269
- else inputForm = form;
266
+ if (p.atscript_db_action_input_form) if (inputForm) hasDuplicateInputForm = true;
267
+ else inputForm = p.atscript_db_action_input_form;
270
268
  }
271
269
  return {
272
270
  level: single && multi ? "table" : single ? "row" : multi ? "rows" : "table",
@@ -295,7 +293,7 @@ const rowLevelActionsCache = /* @__PURE__ */ new WeakMap();
295
293
  /**
296
294
  * Per-controller registry of form names → compiled `.as` classes, populated
297
295
  * during {@link discoverActions} when a method param carries
298
- * {@link MOOST_DB_ACTION_INPUT_FORM}. Backs `GET /meta/form/:name`.
296
+ * `atscript_db_action_input_form`. Backs `GET /meta/form/:name`.
299
297
  *
300
298
  * Same name + same type ref across multiple actions is fine (forms can be
301
299
  * reused). Same name + *different* type refs is an ambiguity — discovery
@@ -351,7 +349,7 @@ function collectMethodActions(ctor, overview, logger, out, seen) {
351
349
  }
352
350
  for (const [methodName, handlers] of byMethod) {
353
351
  const methodMeta = handlers[0].meta;
354
- const action = methodMeta[MOOST_DB_ACTION];
352
+ const action = methodMeta.atscript_db_action;
355
353
  if (!action) continue;
356
354
  if (!action.name) {
357
355
  logger.warn(`${WARN_PREFIX} method "${methodName}" has @DbActionDefault() but no @DbAction(name) — dropping`);
@@ -432,7 +430,7 @@ function inferMethodLevel(params, actionName, logger) {
432
430
  };
433
431
  }
434
432
  function collectClassActions(ctor, logger, out, seen) {
435
- const list = getMoostMate().read(ctor)?.[MOOST_DB_ACTIONS];
433
+ const list = getAtscriptDbMate().read(ctor)?.atscript_db_actions;
436
434
  if (!list) return;
437
435
  for (const { name, entry } of list) {
438
436
  if (seen.has(name)) {
@@ -2020,7 +2018,7 @@ function readCurrentActionMeta(ctx) {
2020
2018
  return;
2021
2019
  }
2022
2020
  if (!ctrl || !methodName) return void 0;
2023
- return getMoostMate().read(ctrl.constructor, methodName)?.[MOOST_DB_ACTION];
2021
+ return getAtscriptDbMate().read(ctrl.constructor, methodName)?.atscript_db_action;
2024
2022
  }
2025
2023
  //#endregion
2026
2024
  //#region src/actions/input-form-cache.ts
@@ -2322,7 +2320,7 @@ function buildThinInterceptor(opts) {
2322
2320
  //#region src/actions/db-action.decorator.ts
2323
2321
  /**
2324
2322
  * Mark a controller method as a database action surfaced via `/meta`. Writes
2325
- * `MOOST_DB_ACTION` metadata and registers a Moost interceptor when needed
2323
+ * `atscript_db_action` metadata and registers a Moost interceptor when needed
2326
2324
  * (gate when `disabled` is set, thin bound-table injector when only
2327
2325
  * `@DbActionRow*` is present). Stacking two `@DbAction` on the same method
2328
2326
  * is undefined and emits a warning.
@@ -2333,20 +2331,17 @@ function buildThinInterceptor(opts) {
2333
2331
  * `Pick<FlatOf<TRow>, R[number]>[]`.
2334
2332
  */
2335
2333
  function DbAction(name, opts = {}) {
2336
- const mate = getMoostMate();
2334
+ const mate = getAtscriptDbMate();
2337
2335
  return ((target, propertyKey, descriptor) => {
2338
- const priorName = mate.read(target, propertyKey)?.[MOOST_DB_ACTION]?.name;
2336
+ const priorName = mate.read(target, propertyKey)?.atscript_db_action?.name;
2339
2337
  if (priorName) console.warn(`${WARN_PREFIX} stacking @DbAction on the same method is undefined; declare one per method. Detected: "${priorName}" and "${name}".`);
2340
- mate.decorate((current) => {
2341
- const meta = current;
2342
- return {
2343
- ...current,
2344
- [MOOST_DB_ACTION]: mergeActionMeta(meta, {
2345
- name,
2346
- opts
2347
- })
2348
- };
2349
- })(target, propertyKey, descriptor);
2338
+ mate.decorate((current) => ({
2339
+ ...current,
2340
+ atscript_db_action: mergeActionMeta(current, {
2341
+ name,
2342
+ opts
2343
+ })
2344
+ }))(target, propertyKey, descriptor);
2350
2345
  if (isAsValueHelpControllerSubclass(typeof target === "function" ? target : target.constructor)) return descriptor;
2351
2346
  const scan = scanParamLevel(mate.read(target, propertyKey)?.params ?? []);
2352
2347
  const rawOpts = opts;
@@ -2368,13 +2363,10 @@ function DbAction(name, opts = {}) {
2368
2363
  * Equivalent to passing `opts.default = true`. Decorator order does not matter.
2369
2364
  */
2370
2365
  function DbActionDefault() {
2371
- return getMoostMate().decorate((current) => {
2372
- const meta = current;
2373
- return {
2374
- ...current,
2375
- [MOOST_DB_ACTION]: mergeActionMeta(meta, { opts: { default: true } })
2376
- };
2377
- });
2366
+ return getAtscriptDbMate().decorate((current) => ({
2367
+ ...current,
2368
+ atscript_db_action: mergeActionMeta(current, { opts: { default: true } })
2369
+ }));
2378
2370
  }
2379
2371
  //#endregion
2380
2372
  //#region src/actions/id-source.ts
@@ -2387,10 +2379,9 @@ function DbActionDefault() {
2387
2379
  * Marks the param so {@link discoverActions} can infer the action's `level`.
2388
2380
  */
2389
2381
  function createIdParamDecorator(kind) {
2390
- const mate = getMoostMate();
2391
2382
  const resolverName = kind === "id" ? "dbActionId" : "dbActionIds";
2392
2383
  const resolver = kind === "id" ? async () => current().get(dbActionIdSlot) : async () => current().get(dbActionIdsSlot);
2393
- return ApplyDecorators(mate.decorate(MOOST_DB_ACTION_PARAM, kind), Resolve(resolver, resolverName));
2384
+ return ApplyDecorators(getAtscriptDbMate().decorate("atscript_db_action_param", kind), Resolve(resolver, resolverName));
2394
2385
  }
2395
2386
  //#endregion
2396
2387
  //#region src/actions/db-action-id.decorator.ts
@@ -2445,7 +2436,7 @@ function DbActionIDs() {
2445
2436
  //#endregion
2446
2437
  //#region src/actions/db-action-row.decorator.ts
2447
2438
  function createRowParamDecorator(metaKey, slot, resolverName) {
2448
- return ApplyDecorators(getMoostMate().decorate(metaKey, true), Resolve(async () => current().get(slot), resolverName));
2439
+ return ApplyDecorators(getAtscriptDbMate().decorate(metaKey, true), Resolve(async () => current().get(slot), resolverName));
2449
2440
  }
2450
2441
  /**
2451
2442
  * Parameter decorator that injects the row whose identifier was supplied in
@@ -2459,7 +2450,7 @@ function createRowParamDecorator(metaKey, slot, resolverName) {
2459
2450
  * request-body row is not retrievable.
2460
2451
  */
2461
2452
  function DbActionRow() {
2462
- return createRowParamDecorator(MOOST_DB_ACTION_ROW, dbActionRowSlot, "dbActionRow");
2453
+ return createRowParamDecorator("atscript_db_action_row", dbActionRowSlot, "dbActionRow");
2463
2454
  }
2464
2455
  /**
2465
2456
  * Parameter decorator that injects the rows fetched by the identifiers
@@ -2470,7 +2461,7 @@ function DbActionRow() {
2470
2461
  * gate's surviving rows.
2471
2462
  */
2472
2463
  function DbActionRows() {
2473
- return createRowParamDecorator(MOOST_DB_ACTION_ROWS, dbActionRowsSlot, "dbActionRows");
2464
+ return createRowParamDecorator("atscript_db_action_rows", dbActionRowsSlot, "dbActionRows");
2474
2465
  }
2475
2466
  //#endregion
2476
2467
  //#region src/actions/db-actions.decorator.ts
@@ -2515,13 +2506,10 @@ function classLevelActions(dict, forcedLevel) {
2515
2506
  entry: merged
2516
2507
  });
2517
2508
  }
2518
- return getMoostMate().decorate((current) => {
2519
- const existing = current["atscript_db_actions"] ?? [];
2520
- return {
2521
- ...current,
2522
- [MOOST_DB_ACTIONS]: [...existing, ...entries]
2523
- };
2524
- });
2509
+ return getAtscriptDbMate().decorate((current) => ({
2510
+ ...current,
2511
+ atscript_db_actions: [...current.atscript_db_actions ?? [], ...entries]
2512
+ }));
2525
2513
  }
2526
2514
  //#endregion
2527
2515
  //#region src/actions/db-action-input-form.decorator.ts
@@ -2531,19 +2519,19 @@ function classLevelActions(dict, forcedLevel) {
2531
2519
  *
2532
2520
  * Pairs the resolved value with two pieces of param-level metadata:
2533
2521
  *
2534
- * 1. {@link MOOST_DB_ACTION_INPUT_FORM} — the compiled `.as` class plus its
2535
- * name, consumed by {@link discoverActions} to:
2522
+ * 1. `atscript_db_action_input_form` — the compiled `.as` class plus its
2523
+ * name, consumed by `discoverActions` to:
2536
2524
  * - emit `inputForm: FormType.name` on the action's `/meta` entry, and
2537
2525
  * - register the type in the controller's form registry so
2538
2526
  * `GET /meta/form/:name` can serve the serialized schema.
2539
- * 2. {@link MOOST_ATSCRIPT_TYPE} — just the type ref, providing a generic
2540
- * hook any atscript-aware Moost pipe can read without knowing about the
2527
+ * 2. `atscript_type` — just the type ref, providing a generic hook any
2528
+ * atscript-aware Moost pipe can read without knowing about the
2541
2529
  * moost-db-specific key.
2542
2530
  *
2543
2531
  * Validation is intentionally *not* performed here. To validate `input`
2544
2532
  * against `FormType`, install an atscript validator pipe globally
2545
2533
  * (`app.applyGlobalPipes(...)`) or scope it via `@Pipe(...)`. The pipe reads
2546
- * `MOOST_ATSCRIPT_TYPE` off the param and runs `FormType.validator()`.
2534
+ * `atscript_type` off the param and runs `FormType.validator()`.
2547
2535
  *
2548
2536
  * Only one `@InputForm()` per action is supported. To collect multiple
2549
2537
  * structured inputs, compose them into a single `.as` interface and pass an
@@ -2558,7 +2546,7 @@ function InputForm(formType) {
2558
2546
  type: formType,
2559
2547
  name: formType.name
2560
2548
  };
2561
- return ApplyDecorators(mate.decorate(MOOST_DB_ACTION_INPUT_FORM, meta), mate.decorate(MOOST_ATSCRIPT_TYPE, formType), Resolve(async () => current().get(dbActionInputSlot), "dbActionInputForm"));
2549
+ return ApplyDecorators(mate.decorate("atscript_db_action_input_form", meta), mate.decorate("atscript_type", formType), Resolve(async () => current().get(dbActionInputSlot), "dbActionInputForm"));
2562
2550
  }
2563
2551
  //#endregion
2564
2552
  //#region src/actions/per-row.ts
@@ -2576,4 +2564,4 @@ function InputForm(formType) {
2576
2564
  */
2577
2565
  const perRow = (fn) => (rows) => rows.map(fn);
2578
2566
  //#endregion
2579
- export { ActionDisabledError, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionID, DbActionIDs, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, InputForm, MOOST_ATSCRIPT_TYPE, MOOST_DB_ACTION_INPUT_FORM, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, TABLE_DEF, TableController, UseValidationErrorTransform, ViewController, dbActionBodySlot, dbActionInputSlot, discoverActions, getControllerFormType, perRow, useDbActionId, useDbActionIds, useDbActionInput, useDbActionRow, useDbActionRows, validationErrorTransform };
2567
+ export { ActionDisabledError, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionID, DbActionIDs, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, InputForm, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, TABLE_DEF, TableController, UseValidationErrorTransform, ViewController, dbActionBodySlot, dbActionInputSlot, discoverActions, getAtscriptDbMate, getControllerFormType, perRow, useDbActionId, useDbActionIds, useDbActionInput, useDbActionRow, useDbActionRows, validationErrorTransform };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/moost-db",
3
- "version": "0.1.65",
3
+ "version": "0.1.67",
4
4
  "description": "Generic database controller for Moost with Atscript.",
5
5
  "keywords": [
6
6
  "annotations",
@@ -58,7 +58,7 @@
58
58
  "@wooksjs/event-core": "^0.7.10",
59
59
  "@wooksjs/http-body": "^0.7.10",
60
60
  "moost": "^0.6.8",
61
- "@atscript/db": "^0.1.65"
61
+ "@atscript/db": "^0.1.67"
62
62
  },
63
63
  "scripts": {
64
64
  "postinstall": "asc -f dts",