@atscript/moost-db 0.1.61 → 0.1.62
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 +163 -12
- package/dist/index.d.cts +136 -4
- package/dist/index.d.mts +136 -4
- package/dist/index.mjs +157 -13
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -213,6 +213,21 @@ const MOOST_DB_ACTION_PARAM = "atscript_db_action_param";
|
|
|
213
213
|
const MOOST_DB_ACTION_ROW = "atscript_db_action_row";
|
|
214
214
|
const MOOST_DB_ACTION_ROWS = "atscript_db_action_rows";
|
|
215
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
|
+
/**
|
|
216
231
|
* Shared method-decorator update used by `@DbAction` and `@DbActionDefault`:
|
|
217
232
|
* read the existing `MOOST_DB_ACTION` slot, merge the patch (later-applied
|
|
218
233
|
* fields win), and write it back. `name` is empty until `@DbAction` provides
|
|
@@ -235,6 +250,8 @@ function scanParamLevel(params) {
|
|
|
235
250
|
let multi = false;
|
|
236
251
|
let hasRowParam = false;
|
|
237
252
|
let hasBody = false;
|
|
253
|
+
let inputForm;
|
|
254
|
+
let hasDuplicateInputForm = false;
|
|
238
255
|
for (const p of params) {
|
|
239
256
|
const kind = p[MOOST_DB_ACTION_PARAM];
|
|
240
257
|
if (kind === "id") single = true;
|
|
@@ -248,13 +265,18 @@ function scanParamLevel(params) {
|
|
|
248
265
|
hasRowParam = true;
|
|
249
266
|
}
|
|
250
267
|
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;
|
|
251
271
|
}
|
|
252
272
|
return {
|
|
253
273
|
level: single && multi ? "table" : single ? "row" : multi ? "rows" : "table",
|
|
254
274
|
single,
|
|
255
275
|
multi,
|
|
256
276
|
hasRowParam,
|
|
257
|
-
hasBody
|
|
277
|
+
hasBody,
|
|
278
|
+
inputForm,
|
|
279
|
+
hasDuplicateInputForm
|
|
258
280
|
};
|
|
259
281
|
}
|
|
260
282
|
//#endregion
|
|
@@ -271,6 +293,34 @@ const OPTIONAL_FIELDS = [
|
|
|
271
293
|
];
|
|
272
294
|
const actionsCache = /* @__PURE__ */ new WeakMap();
|
|
273
295
|
const rowLevelActionsCache = /* @__PURE__ */ new WeakMap();
|
|
296
|
+
/**
|
|
297
|
+
* Per-controller registry of form names → compiled `.as` classes, populated
|
|
298
|
+
* during {@link discoverActions} when a method param carries
|
|
299
|
+
* {@link MOOST_DB_ACTION_INPUT_FORM}. Backs `GET /meta/form/:name`.
|
|
300
|
+
*
|
|
301
|
+
* Same name + same type ref across multiple actions is fine (forms can be
|
|
302
|
+
* reused). Same name + *different* type refs is an ambiguity — discovery
|
|
303
|
+
* warns and drops the second action.
|
|
304
|
+
*/
|
|
305
|
+
const formRegistry = /* @__PURE__ */ new WeakMap();
|
|
306
|
+
/** Lookup helper for `AsReadableController.metaForm()`. */
|
|
307
|
+
function getControllerFormType(ctor, name) {
|
|
308
|
+
return formRegistry.get(ctor)?.get(name);
|
|
309
|
+
}
|
|
310
|
+
function registerFormType(ctor, meta, actionName, logger) {
|
|
311
|
+
let map = formRegistry.get(ctor);
|
|
312
|
+
if (!map) {
|
|
313
|
+
map = /* @__PURE__ */ new Map();
|
|
314
|
+
formRegistry.set(ctor, map);
|
|
315
|
+
}
|
|
316
|
+
const existing = map.get(meta.name);
|
|
317
|
+
if (existing && existing !== meta.type) {
|
|
318
|
+
logger.warn(`${WARN_PREFIX} action "${actionName}" — form name "${meta.name}" already registered on this controller with a different type. Reusing the same FormType across actions is fine; clashing names are not — dropping`);
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
if (!existing) map.set(meta.name, meta.type);
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
274
324
|
/** Discover actions on a controller, memoized per ctor. `info`-only callers map `e => e.info`. */
|
|
275
325
|
function discoverActions(controllerCtor, app, logger) {
|
|
276
326
|
const cached = actionsCache.get(controllerCtor);
|
|
@@ -356,6 +406,10 @@ function collectMethodActions(ctor, overview, logger, out, seen) {
|
|
|
356
406
|
processor: "backend",
|
|
357
407
|
value: path
|
|
358
408
|
};
|
|
409
|
+
if (levelInfer.inputForm) {
|
|
410
|
+
if (!registerFormType(ctor, levelInfer.inputForm, action.name, logger)) continue;
|
|
411
|
+
info.inputForm = levelInfer.inputForm.name;
|
|
412
|
+
}
|
|
359
413
|
emitInfo(info, action.opts);
|
|
360
414
|
seen.add(action.name);
|
|
361
415
|
out.push({
|
|
@@ -370,10 +424,12 @@ function inferMethodLevel(params, actionName, logger) {
|
|
|
370
424
|
logger.warn(`${WARN_PREFIX} action "${actionName}" mixes single-cardinality and multi-cardinality decorators (@DbActionID / @DbActionRow vs @DbActionIDs / @DbActionRows) — dropping`);
|
|
371
425
|
return null;
|
|
372
426
|
}
|
|
427
|
+
if (scan.hasDuplicateInputForm) logger.warn(`${WARN_PREFIX} action "${actionName}" has more than one @InputForm() param — only the first is honored. Compose multiple inputs into a single form interface.`);
|
|
373
428
|
return {
|
|
374
429
|
level: scan.level,
|
|
375
430
|
bodyConflict: scan.hasBody && scan.level !== "table",
|
|
376
|
-
hasRowParam: scan.hasRowParam
|
|
431
|
+
hasRowParam: scan.hasRowParam,
|
|
432
|
+
inputForm: scan.inputForm
|
|
377
433
|
};
|
|
378
434
|
}
|
|
379
435
|
function collectClassActions(ctor, logger, out, seen) {
|
|
@@ -484,6 +540,13 @@ function __decorate(decorators, target, key, desc) {
|
|
|
484
540
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
485
541
|
}
|
|
486
542
|
//#endregion
|
|
543
|
+
//#region \0@oxc-project+runtime@0.120.0/helpers/decorateParam.js
|
|
544
|
+
function __decorateParam(paramIndex, decorator) {
|
|
545
|
+
return function(target, key) {
|
|
546
|
+
decorator(target, key, paramIndex);
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
//#endregion
|
|
487
550
|
//#region src/as-readable.controller.ts
|
|
488
551
|
var _ref$4;
|
|
489
552
|
let AsReadableController = class AsReadableController {
|
|
@@ -499,6 +562,8 @@ let AsReadableController = class AsReadableController {
|
|
|
499
562
|
_serializedType;
|
|
500
563
|
/** Cached full meta response (computed lazily on first meta() call). */
|
|
501
564
|
_metaResponse;
|
|
565
|
+
/** Cached serialized form schemas keyed by `FormType.name` — populated lazily by {@link metaForm}. */
|
|
566
|
+
_formSchemas = /* @__PURE__ */ new Map();
|
|
502
567
|
constructor(boundType, controllerName, app, kindTag = "readable") {
|
|
503
568
|
this.boundType = boundType;
|
|
504
569
|
this.controllerName = controllerName;
|
|
@@ -641,6 +706,25 @@ let AsReadableController = class AsReadableController {
|
|
|
641
706
|
return this.applyMetaOverlay(this._metaResponse);
|
|
642
707
|
}
|
|
643
708
|
/**
|
|
709
|
+
* **GET /meta/form/:name** — returns the serialized schema of a form
|
|
710
|
+
* referenced by an action's `inputForm` field. The form name is the
|
|
711
|
+
* compiled `.as` class's `.name`, registered when an action's parameter is
|
|
712
|
+
* decorated with `@InputForm(FormType)`. Schemas are serialized once and
|
|
713
|
+
* cached per controller; the response uses the same annotation-allowlist
|
|
714
|
+
* policy as {@link getSerializeOptions}.
|
|
715
|
+
*/
|
|
716
|
+
async metaForm(name) {
|
|
717
|
+
discoverActions(this.constructor, this.app, this.logger);
|
|
718
|
+
const formType = getControllerFormType(this.constructor, name);
|
|
719
|
+
if (!formType) throw new _moostjs_event_http.HttpError(404, `Unknown form "${name}"`);
|
|
720
|
+
let cached = this._formSchemas.get(name);
|
|
721
|
+
if (!cached) {
|
|
722
|
+
cached = (0, _atscript_typescript_utils.serializeAnnotatedType)(formType, this.getSerializeOptions());
|
|
723
|
+
this._formSchemas.set(name, cached);
|
|
724
|
+
}
|
|
725
|
+
return cached;
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
644
728
|
* Builds the `/meta` payload. Override in subclasses to populate source-specific
|
|
645
729
|
* fields. Subclasses that fully replace the envelope must call
|
|
646
730
|
* {@link buildActions} and {@link buildCrud} directly so `@DbAction*`
|
|
@@ -694,6 +778,13 @@ __decorate([
|
|
|
694
778
|
__decorateMetadata("design:paramtypes", []),
|
|
695
779
|
__decorateMetadata("design:returntype", Promise)
|
|
696
780
|
], AsReadableController.prototype, "meta", null);
|
|
781
|
+
__decorate([
|
|
782
|
+
(0, _moostjs_event_http.Get)("meta/form/:name"),
|
|
783
|
+
__decorateParam(0, (0, moost.Param)("name")),
|
|
784
|
+
__decorateMetadata("design:type", Function),
|
|
785
|
+
__decorateMetadata("design:paramtypes", [String]),
|
|
786
|
+
__decorateMetadata("design:returntype", Promise)
|
|
787
|
+
], AsReadableController.prototype, "metaForm", null);
|
|
697
788
|
AsReadableController = __decorate([UseValidationErrorTransform(), __decorateMetadata("design:paramtypes", [
|
|
698
789
|
Object,
|
|
699
790
|
String,
|
|
@@ -856,13 +947,6 @@ const QUERY_CONTROLS = [
|
|
|
856
947
|
const PAGES_CONTROLS = ["filter", ...dtoControls(PagesControlsDto)];
|
|
857
948
|
const ONE_CONTROLS = dtoControls(GetOneControlsDto);
|
|
858
949
|
//#endregion
|
|
859
|
-
//#region \0@oxc-project+runtime@0.120.0/helpers/decorateParam.js
|
|
860
|
-
function __decorateParam(paramIndex, decorator) {
|
|
861
|
-
return function(target, key) {
|
|
862
|
-
decorator(target, key, paramIndex);
|
|
863
|
-
};
|
|
864
|
-
}
|
|
865
|
-
//#endregion
|
|
866
950
|
//#region src/as-db-readable.controller.ts
|
|
867
951
|
var _ref$3, _ref2$2;
|
|
868
952
|
let AsDbReadableController = class AsDbReadableController extends AsReadableController {
|
|
@@ -1847,6 +1931,29 @@ function readCurrentActionMeta(ctx) {
|
|
|
1847
1931
|
return (0, moost.getMoostMate)().read(ctrl.constructor, methodName)?.[MOOST_DB_ACTION];
|
|
1848
1932
|
}
|
|
1849
1933
|
//#endregion
|
|
1934
|
+
//#region src/actions/input-form-cache.ts
|
|
1935
|
+
/**
|
|
1936
|
+
* Cached parse of the action request body. Centralises the shape check so
|
|
1937
|
+
* every per-param resolver (`@DbActionID*`, `@DbActionRow*`, `@InputForm`)
|
|
1938
|
+
* reads through the same gate. An array or scalar root is rejected with the
|
|
1939
|
+
* same `ValidatorError` envelope as today's strict-shape ID failures.
|
|
1940
|
+
*/
|
|
1941
|
+
const dbActionBodySlot = (0, _wooksjs_event_core.cached)(async (ctx) => {
|
|
1942
|
+
const raw = await (0, _wooksjs_http_body.useBody)(ctx).parseBody();
|
|
1943
|
+
if (raw == null) return {};
|
|
1944
|
+
if (typeof raw !== "object" || Array.isArray(raw)) throw new _atscript_typescript_utils.ValidatorError([{
|
|
1945
|
+
path: "",
|
|
1946
|
+
message: "Action body must be an object of shape { ids?, input? }"
|
|
1947
|
+
}]);
|
|
1948
|
+
return raw;
|
|
1949
|
+
});
|
|
1950
|
+
/** Cached `body.input` slot — consumed by `@InputForm()` and `useDbActionInput()`. */
|
|
1951
|
+
const dbActionInputSlot = (0, _wooksjs_event_core.cached)(async (ctx) => {
|
|
1952
|
+
return (await ctx.get(dbActionBodySlot)).input;
|
|
1953
|
+
});
|
|
1954
|
+
/** Composable for in-handler reads of the form input. */
|
|
1955
|
+
const useDbActionInput = (0, _wooksjs_event_core.defineWook)((ctx) => ({ load: () => ctx.get(dbActionInputSlot) }));
|
|
1956
|
+
//#endregion
|
|
1850
1957
|
//#region src/actions/id-validation.ts
|
|
1851
1958
|
const SOURCE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
1852
1959
|
function getSourceCache(source) {
|
|
@@ -1964,9 +2071,9 @@ function noTableError(ctx) {
|
|
|
1964
2071
|
async function resolveValidatedId(ctx, validate) {
|
|
1965
2072
|
const table = getActionTable(ctx);
|
|
1966
2073
|
if (!isIdValidationSource(table)) throw noTableError(ctx);
|
|
1967
|
-
const
|
|
1968
|
-
validate(
|
|
1969
|
-
return
|
|
2074
|
+
const env = await ctx.get(dbActionBodySlot);
|
|
2075
|
+
validate(env.ids, table);
|
|
2076
|
+
return env.ids;
|
|
1970
2077
|
}
|
|
1971
2078
|
const dbActionIdSlot = (0, _wooksjs_event_core.cached)((ctx) => resolveValidatedId(ctx, validateSingleId));
|
|
1972
2079
|
const dbActionIdsSlot = (0, _wooksjs_event_core.cached)(async (ctx) => {
|
|
@@ -2325,6 +2432,43 @@ function classLevelActions(dict, forcedLevel) {
|
|
|
2325
2432
|
});
|
|
2326
2433
|
}
|
|
2327
2434
|
//#endregion
|
|
2435
|
+
//#region src/actions/db-action-input-form.decorator.ts
|
|
2436
|
+
/**
|
|
2437
|
+
* Parameter decorator that injects the `input` field of the action request
|
|
2438
|
+
* envelope (`{ ids?, input? }`) into the handler.
|
|
2439
|
+
*
|
|
2440
|
+
* Pairs the resolved value with two pieces of param-level metadata:
|
|
2441
|
+
*
|
|
2442
|
+
* 1. {@link MOOST_DB_ACTION_INPUT_FORM} — the compiled `.as` class plus its
|
|
2443
|
+
* name, consumed by {@link discoverActions} to:
|
|
2444
|
+
* - emit `inputForm: FormType.name` on the action's `/meta` entry, and
|
|
2445
|
+
* - register the type in the controller's form registry so
|
|
2446
|
+
* `GET /meta/form/:name` can serve the serialized schema.
|
|
2447
|
+
* 2. {@link MOOST_ATSCRIPT_TYPE} — just the type ref, providing a generic
|
|
2448
|
+
* hook any atscript-aware Moost pipe can read without knowing about the
|
|
2449
|
+
* moost-db-specific key.
|
|
2450
|
+
*
|
|
2451
|
+
* Validation is intentionally *not* performed here. To validate `input`
|
|
2452
|
+
* against `FormType`, install an atscript validator pipe globally
|
|
2453
|
+
* (`app.applyGlobalPipes(...)`) or scope it via `@Pipe(...)`. The pipe reads
|
|
2454
|
+
* `MOOST_ATSCRIPT_TYPE` off the param and runs `FormType.validator()`.
|
|
2455
|
+
*
|
|
2456
|
+
* Only one `@InputForm()` per action is supported. To collect multiple
|
|
2457
|
+
* structured inputs, compose them into a single `.as` interface and pass an
|
|
2458
|
+
* array form on the field whose user-facing intent is "list of items".
|
|
2459
|
+
*
|
|
2460
|
+
* @param formType A compiled `.as` interface class (carries `.validator()`,
|
|
2461
|
+
* `.metadata`, etc.).
|
|
2462
|
+
*/
|
|
2463
|
+
function InputForm(formType) {
|
|
2464
|
+
const mate = (0, moost.getMoostMate)();
|
|
2465
|
+
const meta = {
|
|
2466
|
+
type: formType,
|
|
2467
|
+
name: formType.name
|
|
2468
|
+
};
|
|
2469
|
+
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"));
|
|
2470
|
+
}
|
|
2471
|
+
//#endregion
|
|
2328
2472
|
//#region src/actions/per-row.ts
|
|
2329
2473
|
/**
|
|
2330
2474
|
* Lift a per-row predicate into the batch shape required by
|
|
@@ -2381,6 +2525,9 @@ exports.DbActions = DbActions;
|
|
|
2381
2525
|
exports.DbRowActions = DbRowActions;
|
|
2382
2526
|
exports.DbRowsActions = DbRowsActions;
|
|
2383
2527
|
exports.DbTableActions = DbTableActions;
|
|
2528
|
+
exports.InputForm = InputForm;
|
|
2529
|
+
exports.MOOST_ATSCRIPT_TYPE = MOOST_ATSCRIPT_TYPE;
|
|
2530
|
+
exports.MOOST_DB_ACTION_INPUT_FORM = MOOST_DB_ACTION_INPUT_FORM;
|
|
2384
2531
|
exports.ONE_CONTROLS = ONE_CONTROLS;
|
|
2385
2532
|
exports.PAGES_CONTROLS = PAGES_CONTROLS;
|
|
2386
2533
|
exports.QUERY_CONTROLS = QUERY_CONTROLS;
|
|
@@ -2390,10 +2537,14 @@ exports.TABLE_DEF = TABLE_DEF;
|
|
|
2390
2537
|
exports.TableController = TableController;
|
|
2391
2538
|
exports.UseValidationErrorTransform = UseValidationErrorTransform;
|
|
2392
2539
|
exports.ViewController = ViewController;
|
|
2540
|
+
exports.dbActionBodySlot = dbActionBodySlot;
|
|
2541
|
+
exports.dbActionInputSlot = dbActionInputSlot;
|
|
2393
2542
|
exports.discoverActions = discoverActions;
|
|
2543
|
+
exports.getControllerFormType = getControllerFormType;
|
|
2394
2544
|
exports.perRow = perRow;
|
|
2395
2545
|
exports.useDbActionId = useDbActionId;
|
|
2396
2546
|
exports.useDbActionIds = useDbActionIds;
|
|
2547
|
+
exports.useDbActionInput = useDbActionInput;
|
|
2397
2548
|
exports.useDbActionRow = useDbActionRow;
|
|
2398
2549
|
exports.useDbActionRows = useDbActionRows;
|
|
2399
2550
|
exports.validationErrorTransform = validationErrorTransform;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import * as _atscript_typescript_utils0 from "@atscript/typescript/utils";
|
|
2
|
-
import { TAtscriptAnnotatedType, TAtscriptDataType, TSerializeOptions, Validator } from "@atscript/typescript/utils";
|
|
3
1
|
import * as _uniqu_url0 from "@uniqu/url";
|
|
2
|
+
import { TAtscriptAnnotatedType, TAtscriptDataType, TSerializeOptions, TSerializedAnnotatedType, Validator } from "@atscript/typescript/utils";
|
|
4
3
|
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
4
|
import { HttpError } from "@moostjs/event-http";
|
|
6
5
|
import * as moost from "moost";
|
|
@@ -61,13 +60,15 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
|
|
|
61
60
|
private _serializedType?;
|
|
62
61
|
/** Cached full meta response (computed lazily on first meta() call). */
|
|
63
62
|
private _metaResponse?;
|
|
63
|
+
/** Cached serialized form schemas keyed by `FormType.name` — populated lazily by {@link metaForm}. */
|
|
64
|
+
private _formSchemas;
|
|
64
65
|
constructor(boundType: T, controllerName: string, app: Moost, kindTag?: string);
|
|
65
66
|
/** Subclass contract: return `true` if `path` addresses a valid field on the bound source. */
|
|
66
67
|
protected abstract hasField(path: string): boolean;
|
|
67
68
|
/** Sets @db.http.path on the type metadata from the controller's computed prefix. */
|
|
68
69
|
private _resolveHttpPath;
|
|
69
70
|
/** Lazily serializes the bound type (after all controllers have set @db.http.path). */
|
|
70
|
-
protected getSerializedType():
|
|
71
|
+
protected getSerializedType(): TSerializedAnnotatedType;
|
|
71
72
|
/**
|
|
72
73
|
* One-time initialization hook. Override to seed data, register watchers, etc.
|
|
73
74
|
*/
|
|
@@ -112,6 +113,15 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
|
|
|
112
113
|
* subclasses can prune the response by principal.
|
|
113
114
|
*/
|
|
114
115
|
meta(): Promise<TMetaResponse>;
|
|
116
|
+
/**
|
|
117
|
+
* **GET /meta/form/:name** — returns the serialized schema of a form
|
|
118
|
+
* referenced by an action's `inputForm` field. The form name is the
|
|
119
|
+
* compiled `.as` class's `.name`, registered when an action's parameter is
|
|
120
|
+
* decorated with `@InputForm(FormType)`. Schemas are serialized once and
|
|
121
|
+
* cached per controller; the response uses the same annotation-allowlist
|
|
122
|
+
* policy as {@link getSerializeOptions}.
|
|
123
|
+
*/
|
|
124
|
+
metaForm(name: string): Promise<TSerializedAnnotatedType>;
|
|
115
125
|
/**
|
|
116
126
|
* Builds the `/meta` payload. Override in subclasses to populate source-specific
|
|
117
127
|
* fields. Subclasses that fully replace the envelope must call
|
|
@@ -716,6 +726,38 @@ declare function DbRowActions<TRow = unknown, const D extends Record<string, unk
|
|
|
716
726
|
/** Sugar for `@DbActions` with `level: 'rows'` injected into each entry. */
|
|
717
727
|
declare function DbRowsActions<TRow = unknown, const D extends Record<string, unknown> = {}>(dict: D & ValidatedUnpinnedDict<TRow, D>): ClassDecorator;
|
|
718
728
|
//#endregion
|
|
729
|
+
//#region src/actions/db-action-input-form.decorator.d.ts
|
|
730
|
+
/**
|
|
731
|
+
* Parameter decorator that injects the `input` field of the action request
|
|
732
|
+
* envelope (`{ ids?, input? }`) into the handler.
|
|
733
|
+
*
|
|
734
|
+
* Pairs the resolved value with two pieces of param-level metadata:
|
|
735
|
+
*
|
|
736
|
+
* 1. {@link MOOST_DB_ACTION_INPUT_FORM} — the compiled `.as` class plus its
|
|
737
|
+
* name, consumed by {@link discoverActions} to:
|
|
738
|
+
* - emit `inputForm: FormType.name` on the action's `/meta` entry, and
|
|
739
|
+
* - register the type in the controller's form registry so
|
|
740
|
+
* `GET /meta/form/:name` can serve the serialized schema.
|
|
741
|
+
* 2. {@link MOOST_ATSCRIPT_TYPE} — just the type ref, providing a generic
|
|
742
|
+
* hook any atscript-aware Moost pipe can read without knowing about the
|
|
743
|
+
* moost-db-specific key.
|
|
744
|
+
*
|
|
745
|
+
* Validation is intentionally *not* performed here. To validate `input`
|
|
746
|
+
* against `FormType`, install an atscript validator pipe globally
|
|
747
|
+
* (`app.applyGlobalPipes(...)`) or scope it via `@Pipe(...)`. The pipe reads
|
|
748
|
+
* `MOOST_ATSCRIPT_TYPE` off the param and runs `FormType.validator()`.
|
|
749
|
+
*
|
|
750
|
+
* Only one `@InputForm()` per action is supported. To collect multiple
|
|
751
|
+
* structured inputs, compose them into a single `.as` interface and pass an
|
|
752
|
+
* array form on the field whose user-facing intent is "list of items".
|
|
753
|
+
*
|
|
754
|
+
* @param formType A compiled `.as` interface class (carries `.validator()`,
|
|
755
|
+
* `.metadata`, etc.).
|
|
756
|
+
*/
|
|
757
|
+
declare function InputForm<T extends TAtscriptAnnotatedType & {
|
|
758
|
+
readonly name: string;
|
|
759
|
+
}>(formType: T): ParameterDecorator;
|
|
760
|
+
//#endregion
|
|
719
761
|
//#region src/actions/discover.d.ts
|
|
720
762
|
/**
|
|
721
763
|
* Pairs the wire-shaped `info` with the original decorator opts / dict entry,
|
|
@@ -726,6 +768,8 @@ interface TDbActionEnvelope {
|
|
|
726
768
|
info: TDbActionInfo$1;
|
|
727
769
|
raw: DbActionOpts | TDbActionsEntry;
|
|
728
770
|
}
|
|
771
|
+
/** Lookup helper for `AsReadableController.metaForm()`. */
|
|
772
|
+
declare function getControllerFormType(ctor: Function, name: string): TAtscriptAnnotatedType | undefined;
|
|
729
773
|
/** Discover actions on a controller, memoized per ctor. `info`-only callers map `e => e.info`. */
|
|
730
774
|
declare function discoverActions(controllerCtor: Function, app: Moost, logger: TConsoleBase): TDbActionEnvelope[];
|
|
731
775
|
//#endregion
|
|
@@ -752,6 +796,94 @@ declare const useDbActionRows: _wooksjs_event_core0.WookComposable<{
|
|
|
752
796
|
load: () => Promise<(Record<string, unknown> | undefined)[]>;
|
|
753
797
|
}>;
|
|
754
798
|
//#endregion
|
|
799
|
+
//#region src/actions/input-form-cache.d.ts
|
|
800
|
+
/**
|
|
801
|
+
* Wire-shape of an action request body. Both fields are optional:
|
|
802
|
+
*
|
|
803
|
+
* - `ids` — what previously sat at the body root: a single identifier object
|
|
804
|
+
* (`'row'`-level), an array of identifier objects (`'rows'`-level), or
|
|
805
|
+
* absent (`'table'`-level).
|
|
806
|
+
* - `input` — present only when the action declares an `@InputForm()`
|
|
807
|
+
* parameter; carries the form payload the user filled out.
|
|
808
|
+
*/
|
|
809
|
+
interface DbActionEnvelope {
|
|
810
|
+
ids?: unknown;
|
|
811
|
+
input?: unknown;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Cached parse of the action request body. Centralises the shape check so
|
|
815
|
+
* every per-param resolver (`@DbActionID*`, `@DbActionRow*`, `@InputForm`)
|
|
816
|
+
* reads through the same gate. An array or scalar root is rejected with the
|
|
817
|
+
* same `ValidatorError` envelope as today's strict-shape ID failures.
|
|
818
|
+
*/
|
|
819
|
+
declare const dbActionBodySlot: moost.Cached<Promise<DbActionEnvelope>>;
|
|
820
|
+
/** Cached `body.input` slot — consumed by `@InputForm()` and `useDbActionInput()`. */
|
|
821
|
+
declare const dbActionInputSlot: moost.Cached<Promise<unknown>>;
|
|
822
|
+
/** Composable for in-handler reads of the form input. */
|
|
823
|
+
declare const useDbActionInput: _wooksjs_event_core0.WookComposable<{
|
|
824
|
+
load: () => Promise<unknown>;
|
|
825
|
+
}>;
|
|
826
|
+
//#endregion
|
|
827
|
+
//#region src/actions/keys.d.ts
|
|
828
|
+
/** Method-level metadata key — written by `@DbAction(name, opts)`. */
|
|
829
|
+
declare const MOOST_DB_ACTION = "atscript_db_action";
|
|
830
|
+
/** Class-level metadata key — written by `@DbActions` and the level-pinned shortcuts. Stored as an array; decorators accumulate. */
|
|
831
|
+
declare const MOOST_DB_ACTIONS = "atscript_db_actions";
|
|
832
|
+
/** Param-level metadata key — written by `@DbActionID()` / `@DbActionIDs()`. Drives level inference. */
|
|
833
|
+
declare const MOOST_DB_ACTION_PARAM = "atscript_db_action_param";
|
|
834
|
+
/** Param-level marker keys — written by `@DbActionRow()` / `@DbActionRows()`. */
|
|
835
|
+
declare const MOOST_DB_ACTION_ROW = "atscript_db_action_row";
|
|
836
|
+
declare const MOOST_DB_ACTION_ROWS = "atscript_db_action_rows";
|
|
837
|
+
/**
|
|
838
|
+
* Param-level metadata key — written by `@InputForm(FormType)`. Carries the
|
|
839
|
+
* compiled `.as` class plus its `.name` so {@link discoverActions} can both
|
|
840
|
+
* emit `inputForm` on `/meta` and register the type in the controller's form
|
|
841
|
+
* registry for `GET /meta/form/:name`.
|
|
842
|
+
*/
|
|
843
|
+
declare const MOOST_DB_ACTION_INPUT_FORM = "atscript_db_action_input_form";
|
|
844
|
+
/**
|
|
845
|
+
* Generic param-level metadata key — written by `@InputForm(FormType)`
|
|
846
|
+
* alongside {@link MOOST_DB_ACTION_INPUT_FORM}. Holds just the type ref so a
|
|
847
|
+
* generic atscript-aware Moost pipe (installed globally via
|
|
848
|
+
* `app.applyGlobalPipes(...)` or scoped via `@Pipe(...)`) can validate the
|
|
849
|
+
* resolved value without knowing about the moost-db-specific key.
|
|
850
|
+
*/
|
|
851
|
+
declare const MOOST_ATSCRIPT_TYPE = "atscript_type";
|
|
852
|
+
type TDbActionRowMarker = true;
|
|
853
|
+
/** Stamped by `@InputForm(FormType)` — the compiled `.as` class + the wire name (`FormType.name`). */
|
|
854
|
+
interface TDbActionInputFormMeta {
|
|
855
|
+
type: TAtscriptAnnotatedType;
|
|
856
|
+
name: string;
|
|
857
|
+
}
|
|
858
|
+
/** Method-level action metadata written by `@DbAction(name, opts)`. */
|
|
859
|
+
interface TDbActionMeta {
|
|
860
|
+
name: string;
|
|
861
|
+
opts: DbActionOpts;
|
|
862
|
+
}
|
|
863
|
+
/** Class-level entry — a `TDbActionsEntry` plus its dictionary key. */
|
|
864
|
+
interface TDbClassActionMeta {
|
|
865
|
+
name: string;
|
|
866
|
+
entry: TDbActionsEntry;
|
|
867
|
+
}
|
|
868
|
+
/** Param marker kind — informs level inference and ID-resolution shape. */
|
|
869
|
+
type TDbActionParamKind = "id" | "ids";
|
|
870
|
+
declare module "moost" {
|
|
871
|
+
interface TMoostMetadata {
|
|
872
|
+
[MOOST_DB_ACTION]?: TDbActionMeta;
|
|
873
|
+
[MOOST_DB_ACTIONS]?: TDbClassActionMeta[];
|
|
874
|
+
[MOOST_DB_ACTION_PARAM]?: TDbActionParamKind;
|
|
875
|
+
[MOOST_DB_ACTION_ROW]?: TDbActionRowMarker;
|
|
876
|
+
[MOOST_DB_ACTION_ROWS]?: TDbActionRowMarker;
|
|
877
|
+
}
|
|
878
|
+
interface TMoostParamsMetadata {
|
|
879
|
+
[MOOST_DB_ACTION_PARAM]?: TDbActionParamKind;
|
|
880
|
+
[MOOST_DB_ACTION_ROW]?: TDbActionRowMarker;
|
|
881
|
+
[MOOST_DB_ACTION_ROWS]?: TDbActionRowMarker;
|
|
882
|
+
[MOOST_DB_ACTION_INPUT_FORM]?: TDbActionInputFormMeta;
|
|
883
|
+
[MOOST_ATSCRIPT_TYPE]?: TAtscriptAnnotatedType;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
//#endregion
|
|
755
887
|
//#region src/actions/action-disabled-error.d.ts
|
|
756
888
|
/**
|
|
757
889
|
* Wire-body shape for server-side gate rejections. The `name` discriminator
|
|
@@ -812,4 +944,4 @@ declare const QUERY_CONTROLS: readonly string[];
|
|
|
812
944
|
declare const PAGES_CONTROLS: readonly string[];
|
|
813
945
|
declare const ONE_CONTROLS: readonly string[];
|
|
814
946
|
//#endregion
|
|
815
|
-
export { ActionDisabledError, ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionID, DbActionIDs, DbActionOpts, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, IdValidationSource, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, TDbActionsEntry, TDbActionsEntryUnpinned, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, discoverActions, perRow, useDbActionId, useDbActionIds, useDbActionRow, useDbActionRows, validationErrorTransform };
|
|
947
|
+
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 };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { TAtscriptAnnotatedType, TAtscriptDataType, TSerializeOptions, Validator } from "@atscript/typescript/utils";
|
|
1
|
+
import { TAtscriptAnnotatedType, TAtscriptDataType, TSerializeOptions, TSerializedAnnotatedType, Validator } from "@atscript/typescript/utils";
|
|
3
2
|
import { HttpError } from "@moostjs/event-http";
|
|
4
3
|
import * as moost from "moost";
|
|
5
4
|
import { Moost, TConsoleBase } from "moost";
|
|
@@ -61,13 +60,15 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
|
|
|
61
60
|
private _serializedType?;
|
|
62
61
|
/** Cached full meta response (computed lazily on first meta() call). */
|
|
63
62
|
private _metaResponse?;
|
|
63
|
+
/** Cached serialized form schemas keyed by `FormType.name` — populated lazily by {@link metaForm}. */
|
|
64
|
+
private _formSchemas;
|
|
64
65
|
constructor(boundType: T, controllerName: string, app: Moost, kindTag?: string);
|
|
65
66
|
/** Subclass contract: return `true` if `path` addresses a valid field on the bound source. */
|
|
66
67
|
protected abstract hasField(path: string): boolean;
|
|
67
68
|
/** Sets @db.http.path on the type metadata from the controller's computed prefix. */
|
|
68
69
|
private _resolveHttpPath;
|
|
69
70
|
/** Lazily serializes the bound type (after all controllers have set @db.http.path). */
|
|
70
|
-
protected getSerializedType():
|
|
71
|
+
protected getSerializedType(): TSerializedAnnotatedType;
|
|
71
72
|
/**
|
|
72
73
|
* One-time initialization hook. Override to seed data, register watchers, etc.
|
|
73
74
|
*/
|
|
@@ -112,6 +113,15 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
|
|
|
112
113
|
* subclasses can prune the response by principal.
|
|
113
114
|
*/
|
|
114
115
|
meta(): Promise<TMetaResponse>;
|
|
116
|
+
/**
|
|
117
|
+
* **GET /meta/form/:name** — returns the serialized schema of a form
|
|
118
|
+
* referenced by an action's `inputForm` field. The form name is the
|
|
119
|
+
* compiled `.as` class's `.name`, registered when an action's parameter is
|
|
120
|
+
* decorated with `@InputForm(FormType)`. Schemas are serialized once and
|
|
121
|
+
* cached per controller; the response uses the same annotation-allowlist
|
|
122
|
+
* policy as {@link getSerializeOptions}.
|
|
123
|
+
*/
|
|
124
|
+
metaForm(name: string): Promise<TSerializedAnnotatedType>;
|
|
115
125
|
/**
|
|
116
126
|
* Builds the `/meta` payload. Override in subclasses to populate source-specific
|
|
117
127
|
* fields. Subclasses that fully replace the envelope must call
|
|
@@ -716,6 +726,38 @@ declare function DbRowActions<TRow = unknown, const D extends Record<string, unk
|
|
|
716
726
|
/** Sugar for `@DbActions` with `level: 'rows'` injected into each entry. */
|
|
717
727
|
declare function DbRowsActions<TRow = unknown, const D extends Record<string, unknown> = {}>(dict: D & ValidatedUnpinnedDict<TRow, D>): ClassDecorator;
|
|
718
728
|
//#endregion
|
|
729
|
+
//#region src/actions/db-action-input-form.decorator.d.ts
|
|
730
|
+
/**
|
|
731
|
+
* Parameter decorator that injects the `input` field of the action request
|
|
732
|
+
* envelope (`{ ids?, input? }`) into the handler.
|
|
733
|
+
*
|
|
734
|
+
* Pairs the resolved value with two pieces of param-level metadata:
|
|
735
|
+
*
|
|
736
|
+
* 1. {@link MOOST_DB_ACTION_INPUT_FORM} — the compiled `.as` class plus its
|
|
737
|
+
* name, consumed by {@link discoverActions} to:
|
|
738
|
+
* - emit `inputForm: FormType.name` on the action's `/meta` entry, and
|
|
739
|
+
* - register the type in the controller's form registry so
|
|
740
|
+
* `GET /meta/form/:name` can serve the serialized schema.
|
|
741
|
+
* 2. {@link MOOST_ATSCRIPT_TYPE} — just the type ref, providing a generic
|
|
742
|
+
* hook any atscript-aware Moost pipe can read without knowing about the
|
|
743
|
+
* moost-db-specific key.
|
|
744
|
+
*
|
|
745
|
+
* Validation is intentionally *not* performed here. To validate `input`
|
|
746
|
+
* against `FormType`, install an atscript validator pipe globally
|
|
747
|
+
* (`app.applyGlobalPipes(...)`) or scope it via `@Pipe(...)`. The pipe reads
|
|
748
|
+
* `MOOST_ATSCRIPT_TYPE` off the param and runs `FormType.validator()`.
|
|
749
|
+
*
|
|
750
|
+
* Only one `@InputForm()` per action is supported. To collect multiple
|
|
751
|
+
* structured inputs, compose them into a single `.as` interface and pass an
|
|
752
|
+
* array form on the field whose user-facing intent is "list of items".
|
|
753
|
+
*
|
|
754
|
+
* @param formType A compiled `.as` interface class (carries `.validator()`,
|
|
755
|
+
* `.metadata`, etc.).
|
|
756
|
+
*/
|
|
757
|
+
declare function InputForm<T extends TAtscriptAnnotatedType & {
|
|
758
|
+
readonly name: string;
|
|
759
|
+
}>(formType: T): ParameterDecorator;
|
|
760
|
+
//#endregion
|
|
719
761
|
//#region src/actions/discover.d.ts
|
|
720
762
|
/**
|
|
721
763
|
* Pairs the wire-shaped `info` with the original decorator opts / dict entry,
|
|
@@ -726,6 +768,8 @@ interface TDbActionEnvelope {
|
|
|
726
768
|
info: TDbActionInfo$1;
|
|
727
769
|
raw: DbActionOpts | TDbActionsEntry;
|
|
728
770
|
}
|
|
771
|
+
/** Lookup helper for `AsReadableController.metaForm()`. */
|
|
772
|
+
declare function getControllerFormType(ctor: Function, name: string): TAtscriptAnnotatedType | undefined;
|
|
729
773
|
/** Discover actions on a controller, memoized per ctor. `info`-only callers map `e => e.info`. */
|
|
730
774
|
declare function discoverActions(controllerCtor: Function, app: Moost, logger: TConsoleBase): TDbActionEnvelope[];
|
|
731
775
|
//#endregion
|
|
@@ -752,6 +796,94 @@ declare const useDbActionRows: _wooksjs_event_core0.WookComposable<{
|
|
|
752
796
|
load: () => Promise<(Record<string, unknown> | undefined)[]>;
|
|
753
797
|
}>;
|
|
754
798
|
//#endregion
|
|
799
|
+
//#region src/actions/input-form-cache.d.ts
|
|
800
|
+
/**
|
|
801
|
+
* Wire-shape of an action request body. Both fields are optional:
|
|
802
|
+
*
|
|
803
|
+
* - `ids` — what previously sat at the body root: a single identifier object
|
|
804
|
+
* (`'row'`-level), an array of identifier objects (`'rows'`-level), or
|
|
805
|
+
* absent (`'table'`-level).
|
|
806
|
+
* - `input` — present only when the action declares an `@InputForm()`
|
|
807
|
+
* parameter; carries the form payload the user filled out.
|
|
808
|
+
*/
|
|
809
|
+
interface DbActionEnvelope {
|
|
810
|
+
ids?: unknown;
|
|
811
|
+
input?: unknown;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Cached parse of the action request body. Centralises the shape check so
|
|
815
|
+
* every per-param resolver (`@DbActionID*`, `@DbActionRow*`, `@InputForm`)
|
|
816
|
+
* reads through the same gate. An array or scalar root is rejected with the
|
|
817
|
+
* same `ValidatorError` envelope as today's strict-shape ID failures.
|
|
818
|
+
*/
|
|
819
|
+
declare const dbActionBodySlot: moost.Cached<Promise<DbActionEnvelope>>;
|
|
820
|
+
/** Cached `body.input` slot — consumed by `@InputForm()` and `useDbActionInput()`. */
|
|
821
|
+
declare const dbActionInputSlot: moost.Cached<Promise<unknown>>;
|
|
822
|
+
/** Composable for in-handler reads of the form input. */
|
|
823
|
+
declare const useDbActionInput: _wooksjs_event_core0.WookComposable<{
|
|
824
|
+
load: () => Promise<unknown>;
|
|
825
|
+
}>;
|
|
826
|
+
//#endregion
|
|
827
|
+
//#region src/actions/keys.d.ts
|
|
828
|
+
/** Method-level metadata key — written by `@DbAction(name, opts)`. */
|
|
829
|
+
declare const MOOST_DB_ACTION = "atscript_db_action";
|
|
830
|
+
/** Class-level metadata key — written by `@DbActions` and the level-pinned shortcuts. Stored as an array; decorators accumulate. */
|
|
831
|
+
declare const MOOST_DB_ACTIONS = "atscript_db_actions";
|
|
832
|
+
/** Param-level metadata key — written by `@DbActionID()` / `@DbActionIDs()`. Drives level inference. */
|
|
833
|
+
declare const MOOST_DB_ACTION_PARAM = "atscript_db_action_param";
|
|
834
|
+
/** Param-level marker keys — written by `@DbActionRow()` / `@DbActionRows()`. */
|
|
835
|
+
declare const MOOST_DB_ACTION_ROW = "atscript_db_action_row";
|
|
836
|
+
declare const MOOST_DB_ACTION_ROWS = "atscript_db_action_rows";
|
|
837
|
+
/**
|
|
838
|
+
* Param-level metadata key — written by `@InputForm(FormType)`. Carries the
|
|
839
|
+
* compiled `.as` class plus its `.name` so {@link discoverActions} can both
|
|
840
|
+
* emit `inputForm` on `/meta` and register the type in the controller's form
|
|
841
|
+
* registry for `GET /meta/form/:name`.
|
|
842
|
+
*/
|
|
843
|
+
declare const MOOST_DB_ACTION_INPUT_FORM = "atscript_db_action_input_form";
|
|
844
|
+
/**
|
|
845
|
+
* Generic param-level metadata key — written by `@InputForm(FormType)`
|
|
846
|
+
* alongside {@link MOOST_DB_ACTION_INPUT_FORM}. Holds just the type ref so a
|
|
847
|
+
* generic atscript-aware Moost pipe (installed globally via
|
|
848
|
+
* `app.applyGlobalPipes(...)` or scoped via `@Pipe(...)`) can validate the
|
|
849
|
+
* resolved value without knowing about the moost-db-specific key.
|
|
850
|
+
*/
|
|
851
|
+
declare const MOOST_ATSCRIPT_TYPE = "atscript_type";
|
|
852
|
+
type TDbActionRowMarker = true;
|
|
853
|
+
/** Stamped by `@InputForm(FormType)` — the compiled `.as` class + the wire name (`FormType.name`). */
|
|
854
|
+
interface TDbActionInputFormMeta {
|
|
855
|
+
type: TAtscriptAnnotatedType;
|
|
856
|
+
name: string;
|
|
857
|
+
}
|
|
858
|
+
/** Method-level action metadata written by `@DbAction(name, opts)`. */
|
|
859
|
+
interface TDbActionMeta {
|
|
860
|
+
name: string;
|
|
861
|
+
opts: DbActionOpts;
|
|
862
|
+
}
|
|
863
|
+
/** Class-level entry — a `TDbActionsEntry` plus its dictionary key. */
|
|
864
|
+
interface TDbClassActionMeta {
|
|
865
|
+
name: string;
|
|
866
|
+
entry: TDbActionsEntry;
|
|
867
|
+
}
|
|
868
|
+
/** Param marker kind — informs level inference and ID-resolution shape. */
|
|
869
|
+
type TDbActionParamKind = "id" | "ids";
|
|
870
|
+
declare module "moost" {
|
|
871
|
+
interface TMoostMetadata {
|
|
872
|
+
[MOOST_DB_ACTION]?: TDbActionMeta;
|
|
873
|
+
[MOOST_DB_ACTIONS]?: TDbClassActionMeta[];
|
|
874
|
+
[MOOST_DB_ACTION_PARAM]?: TDbActionParamKind;
|
|
875
|
+
[MOOST_DB_ACTION_ROW]?: TDbActionRowMarker;
|
|
876
|
+
[MOOST_DB_ACTION_ROWS]?: TDbActionRowMarker;
|
|
877
|
+
}
|
|
878
|
+
interface TMoostParamsMetadata {
|
|
879
|
+
[MOOST_DB_ACTION_PARAM]?: TDbActionParamKind;
|
|
880
|
+
[MOOST_DB_ACTION_ROW]?: TDbActionRowMarker;
|
|
881
|
+
[MOOST_DB_ACTION_ROWS]?: TDbActionRowMarker;
|
|
882
|
+
[MOOST_DB_ACTION_INPUT_FORM]?: TDbActionInputFormMeta;
|
|
883
|
+
[MOOST_ATSCRIPT_TYPE]?: TAtscriptAnnotatedType;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
//#endregion
|
|
755
887
|
//#region src/actions/action-disabled-error.d.ts
|
|
756
888
|
/**
|
|
757
889
|
* Wire-body shape for server-side gate rejections. The `name` discriminator
|
|
@@ -812,4 +944,4 @@ declare const QUERY_CONTROLS: readonly string[];
|
|
|
812
944
|
declare const PAGES_CONTROLS: readonly string[];
|
|
813
945
|
declare const ONE_CONTROLS: readonly string[];
|
|
814
946
|
//#endregion
|
|
815
|
-
export { ActionDisabledError, type ActionDisabledErrorBody, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionID, DbActionIDs, type DbActionOpts, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, type IdValidationSource, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbActionsEntry, type TDbActionsEntryUnpinned, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, discoverActions, perRow, useDbActionId, useDbActionIds, useDbActionRow, useDbActionRows, validationErrorTransform };
|
|
947
|
+
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 };
|
package/dist/index.mjs
CHANGED
|
@@ -212,6 +212,21 @@ const MOOST_DB_ACTION_PARAM = "atscript_db_action_param";
|
|
|
212
212
|
const MOOST_DB_ACTION_ROW = "atscript_db_action_row";
|
|
213
213
|
const MOOST_DB_ACTION_ROWS = "atscript_db_action_rows";
|
|
214
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
|
+
/**
|
|
215
230
|
* Shared method-decorator update used by `@DbAction` and `@DbActionDefault`:
|
|
216
231
|
* read the existing `MOOST_DB_ACTION` slot, merge the patch (later-applied
|
|
217
232
|
* fields win), and write it back. `name` is empty until `@DbAction` provides
|
|
@@ -234,6 +249,8 @@ function scanParamLevel(params) {
|
|
|
234
249
|
let multi = false;
|
|
235
250
|
let hasRowParam = false;
|
|
236
251
|
let hasBody = false;
|
|
252
|
+
let inputForm;
|
|
253
|
+
let hasDuplicateInputForm = false;
|
|
237
254
|
for (const p of params) {
|
|
238
255
|
const kind = p[MOOST_DB_ACTION_PARAM];
|
|
239
256
|
if (kind === "id") single = true;
|
|
@@ -247,13 +264,18 @@ function scanParamLevel(params) {
|
|
|
247
264
|
hasRowParam = true;
|
|
248
265
|
}
|
|
249
266
|
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;
|
|
250
270
|
}
|
|
251
271
|
return {
|
|
252
272
|
level: single && multi ? "table" : single ? "row" : multi ? "rows" : "table",
|
|
253
273
|
single,
|
|
254
274
|
multi,
|
|
255
275
|
hasRowParam,
|
|
256
|
-
hasBody
|
|
276
|
+
hasBody,
|
|
277
|
+
inputForm,
|
|
278
|
+
hasDuplicateInputForm
|
|
257
279
|
};
|
|
258
280
|
}
|
|
259
281
|
//#endregion
|
|
@@ -270,6 +292,34 @@ const OPTIONAL_FIELDS = [
|
|
|
270
292
|
];
|
|
271
293
|
const actionsCache = /* @__PURE__ */ new WeakMap();
|
|
272
294
|
const rowLevelActionsCache = /* @__PURE__ */ new WeakMap();
|
|
295
|
+
/**
|
|
296
|
+
* Per-controller registry of form names → compiled `.as` classes, populated
|
|
297
|
+
* during {@link discoverActions} when a method param carries
|
|
298
|
+
* {@link MOOST_DB_ACTION_INPUT_FORM}. Backs `GET /meta/form/:name`.
|
|
299
|
+
*
|
|
300
|
+
* Same name + same type ref across multiple actions is fine (forms can be
|
|
301
|
+
* reused). Same name + *different* type refs is an ambiguity — discovery
|
|
302
|
+
* warns and drops the second action.
|
|
303
|
+
*/
|
|
304
|
+
const formRegistry = /* @__PURE__ */ new WeakMap();
|
|
305
|
+
/** Lookup helper for `AsReadableController.metaForm()`. */
|
|
306
|
+
function getControllerFormType(ctor, name) {
|
|
307
|
+
return formRegistry.get(ctor)?.get(name);
|
|
308
|
+
}
|
|
309
|
+
function registerFormType(ctor, meta, actionName, logger) {
|
|
310
|
+
let map = formRegistry.get(ctor);
|
|
311
|
+
if (!map) {
|
|
312
|
+
map = /* @__PURE__ */ new Map();
|
|
313
|
+
formRegistry.set(ctor, map);
|
|
314
|
+
}
|
|
315
|
+
const existing = map.get(meta.name);
|
|
316
|
+
if (existing && existing !== meta.type) {
|
|
317
|
+
logger.warn(`${WARN_PREFIX} action "${actionName}" — form name "${meta.name}" already registered on this controller with a different type. Reusing the same FormType across actions is fine; clashing names are not — dropping`);
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
if (!existing) map.set(meta.name, meta.type);
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
273
323
|
/** Discover actions on a controller, memoized per ctor. `info`-only callers map `e => e.info`. */
|
|
274
324
|
function discoverActions(controllerCtor, app, logger) {
|
|
275
325
|
const cached = actionsCache.get(controllerCtor);
|
|
@@ -355,6 +405,10 @@ function collectMethodActions(ctor, overview, logger, out, seen) {
|
|
|
355
405
|
processor: "backend",
|
|
356
406
|
value: path
|
|
357
407
|
};
|
|
408
|
+
if (levelInfer.inputForm) {
|
|
409
|
+
if (!registerFormType(ctor, levelInfer.inputForm, action.name, logger)) continue;
|
|
410
|
+
info.inputForm = levelInfer.inputForm.name;
|
|
411
|
+
}
|
|
358
412
|
emitInfo(info, action.opts);
|
|
359
413
|
seen.add(action.name);
|
|
360
414
|
out.push({
|
|
@@ -369,10 +423,12 @@ function inferMethodLevel(params, actionName, logger) {
|
|
|
369
423
|
logger.warn(`${WARN_PREFIX} action "${actionName}" mixes single-cardinality and multi-cardinality decorators (@DbActionID / @DbActionRow vs @DbActionIDs / @DbActionRows) — dropping`);
|
|
370
424
|
return null;
|
|
371
425
|
}
|
|
426
|
+
if (scan.hasDuplicateInputForm) logger.warn(`${WARN_PREFIX} action "${actionName}" has more than one @InputForm() param — only the first is honored. Compose multiple inputs into a single form interface.`);
|
|
372
427
|
return {
|
|
373
428
|
level: scan.level,
|
|
374
429
|
bodyConflict: scan.hasBody && scan.level !== "table",
|
|
375
|
-
hasRowParam: scan.hasRowParam
|
|
430
|
+
hasRowParam: scan.hasRowParam,
|
|
431
|
+
inputForm: scan.inputForm
|
|
376
432
|
};
|
|
377
433
|
}
|
|
378
434
|
function collectClassActions(ctor, logger, out, seen) {
|
|
@@ -483,6 +539,13 @@ function __decorate(decorators, target, key, desc) {
|
|
|
483
539
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
484
540
|
}
|
|
485
541
|
//#endregion
|
|
542
|
+
//#region \0@oxc-project+runtime@0.120.0/helpers/decorateParam.js
|
|
543
|
+
function __decorateParam(paramIndex, decorator) {
|
|
544
|
+
return function(target, key) {
|
|
545
|
+
decorator(target, key, paramIndex);
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
//#endregion
|
|
486
549
|
//#region src/as-readable.controller.ts
|
|
487
550
|
var _ref$4;
|
|
488
551
|
let AsReadableController = class AsReadableController {
|
|
@@ -498,6 +561,8 @@ let AsReadableController = class AsReadableController {
|
|
|
498
561
|
_serializedType;
|
|
499
562
|
/** Cached full meta response (computed lazily on first meta() call). */
|
|
500
563
|
_metaResponse;
|
|
564
|
+
/** Cached serialized form schemas keyed by `FormType.name` — populated lazily by {@link metaForm}. */
|
|
565
|
+
_formSchemas = /* @__PURE__ */ new Map();
|
|
501
566
|
constructor(boundType, controllerName, app, kindTag = "readable") {
|
|
502
567
|
this.boundType = boundType;
|
|
503
568
|
this.controllerName = controllerName;
|
|
@@ -640,6 +705,25 @@ let AsReadableController = class AsReadableController {
|
|
|
640
705
|
return this.applyMetaOverlay(this._metaResponse);
|
|
641
706
|
}
|
|
642
707
|
/**
|
|
708
|
+
* **GET /meta/form/:name** — returns the serialized schema of a form
|
|
709
|
+
* referenced by an action's `inputForm` field. The form name is the
|
|
710
|
+
* compiled `.as` class's `.name`, registered when an action's parameter is
|
|
711
|
+
* decorated with `@InputForm(FormType)`. Schemas are serialized once and
|
|
712
|
+
* cached per controller; the response uses the same annotation-allowlist
|
|
713
|
+
* policy as {@link getSerializeOptions}.
|
|
714
|
+
*/
|
|
715
|
+
async metaForm(name) {
|
|
716
|
+
discoverActions(this.constructor, this.app, this.logger);
|
|
717
|
+
const formType = getControllerFormType(this.constructor, name);
|
|
718
|
+
if (!formType) throw new HttpError(404, `Unknown form "${name}"`);
|
|
719
|
+
let cached = this._formSchemas.get(name);
|
|
720
|
+
if (!cached) {
|
|
721
|
+
cached = serializeAnnotatedType(formType, this.getSerializeOptions());
|
|
722
|
+
this._formSchemas.set(name, cached);
|
|
723
|
+
}
|
|
724
|
+
return cached;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
643
727
|
* Builds the `/meta` payload. Override in subclasses to populate source-specific
|
|
644
728
|
* fields. Subclasses that fully replace the envelope must call
|
|
645
729
|
* {@link buildActions} and {@link buildCrud} directly so `@DbAction*`
|
|
@@ -693,6 +777,13 @@ __decorate([
|
|
|
693
777
|
__decorateMetadata("design:paramtypes", []),
|
|
694
778
|
__decorateMetadata("design:returntype", Promise)
|
|
695
779
|
], AsReadableController.prototype, "meta", null);
|
|
780
|
+
__decorate([
|
|
781
|
+
Get("meta/form/:name"),
|
|
782
|
+
__decorateParam(0, Param("name")),
|
|
783
|
+
__decorateMetadata("design:type", Function),
|
|
784
|
+
__decorateMetadata("design:paramtypes", [String]),
|
|
785
|
+
__decorateMetadata("design:returntype", Promise)
|
|
786
|
+
], AsReadableController.prototype, "metaForm", null);
|
|
696
787
|
AsReadableController = __decorate([UseValidationErrorTransform(), __decorateMetadata("design:paramtypes", [
|
|
697
788
|
Object,
|
|
698
789
|
String,
|
|
@@ -855,13 +946,6 @@ const QUERY_CONTROLS = [
|
|
|
855
946
|
const PAGES_CONTROLS = ["filter", ...dtoControls(PagesControlsDto)];
|
|
856
947
|
const ONE_CONTROLS = dtoControls(GetOneControlsDto);
|
|
857
948
|
//#endregion
|
|
858
|
-
//#region \0@oxc-project+runtime@0.120.0/helpers/decorateParam.js
|
|
859
|
-
function __decorateParam(paramIndex, decorator) {
|
|
860
|
-
return function(target, key) {
|
|
861
|
-
decorator(target, key, paramIndex);
|
|
862
|
-
};
|
|
863
|
-
}
|
|
864
|
-
//#endregion
|
|
865
949
|
//#region src/as-db-readable.controller.ts
|
|
866
950
|
var _ref$3, _ref2$2;
|
|
867
951
|
let AsDbReadableController = class AsDbReadableController extends AsReadableController {
|
|
@@ -1846,6 +1930,29 @@ function readCurrentActionMeta(ctx) {
|
|
|
1846
1930
|
return getMoostMate().read(ctrl.constructor, methodName)?.[MOOST_DB_ACTION];
|
|
1847
1931
|
}
|
|
1848
1932
|
//#endregion
|
|
1933
|
+
//#region src/actions/input-form-cache.ts
|
|
1934
|
+
/**
|
|
1935
|
+
* Cached parse of the action request body. Centralises the shape check so
|
|
1936
|
+
* every per-param resolver (`@DbActionID*`, `@DbActionRow*`, `@InputForm`)
|
|
1937
|
+
* reads through the same gate. An array or scalar root is rejected with the
|
|
1938
|
+
* same `ValidatorError` envelope as today's strict-shape ID failures.
|
|
1939
|
+
*/
|
|
1940
|
+
const dbActionBodySlot = cached(async (ctx) => {
|
|
1941
|
+
const raw = await useBody(ctx).parseBody();
|
|
1942
|
+
if (raw == null) return {};
|
|
1943
|
+
if (typeof raw !== "object" || Array.isArray(raw)) throw new ValidatorError([{
|
|
1944
|
+
path: "",
|
|
1945
|
+
message: "Action body must be an object of shape { ids?, input? }"
|
|
1946
|
+
}]);
|
|
1947
|
+
return raw;
|
|
1948
|
+
});
|
|
1949
|
+
/** Cached `body.input` slot — consumed by `@InputForm()` and `useDbActionInput()`. */
|
|
1950
|
+
const dbActionInputSlot = cached(async (ctx) => {
|
|
1951
|
+
return (await ctx.get(dbActionBodySlot)).input;
|
|
1952
|
+
});
|
|
1953
|
+
/** Composable for in-handler reads of the form input. */
|
|
1954
|
+
const useDbActionInput = defineWook((ctx) => ({ load: () => ctx.get(dbActionInputSlot) }));
|
|
1955
|
+
//#endregion
|
|
1849
1956
|
//#region src/actions/id-validation.ts
|
|
1850
1957
|
const SOURCE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
1851
1958
|
function getSourceCache(source) {
|
|
@@ -1963,9 +2070,9 @@ function noTableError(ctx) {
|
|
|
1963
2070
|
async function resolveValidatedId(ctx, validate) {
|
|
1964
2071
|
const table = getActionTable(ctx);
|
|
1965
2072
|
if (!isIdValidationSource(table)) throw noTableError(ctx);
|
|
1966
|
-
const
|
|
1967
|
-
validate(
|
|
1968
|
-
return
|
|
2073
|
+
const env = await ctx.get(dbActionBodySlot);
|
|
2074
|
+
validate(env.ids, table);
|
|
2075
|
+
return env.ids;
|
|
1969
2076
|
}
|
|
1970
2077
|
const dbActionIdSlot = cached((ctx) => resolveValidatedId(ctx, validateSingleId));
|
|
1971
2078
|
const dbActionIdsSlot = cached(async (ctx) => {
|
|
@@ -2324,6 +2431,43 @@ function classLevelActions(dict, forcedLevel) {
|
|
|
2324
2431
|
});
|
|
2325
2432
|
}
|
|
2326
2433
|
//#endregion
|
|
2434
|
+
//#region src/actions/db-action-input-form.decorator.ts
|
|
2435
|
+
/**
|
|
2436
|
+
* Parameter decorator that injects the `input` field of the action request
|
|
2437
|
+
* envelope (`{ ids?, input? }`) into the handler.
|
|
2438
|
+
*
|
|
2439
|
+
* Pairs the resolved value with two pieces of param-level metadata:
|
|
2440
|
+
*
|
|
2441
|
+
* 1. {@link MOOST_DB_ACTION_INPUT_FORM} — the compiled `.as` class plus its
|
|
2442
|
+
* name, consumed by {@link discoverActions} to:
|
|
2443
|
+
* - emit `inputForm: FormType.name` on the action's `/meta` entry, and
|
|
2444
|
+
* - register the type in the controller's form registry so
|
|
2445
|
+
* `GET /meta/form/:name` can serve the serialized schema.
|
|
2446
|
+
* 2. {@link MOOST_ATSCRIPT_TYPE} — just the type ref, providing a generic
|
|
2447
|
+
* hook any atscript-aware Moost pipe can read without knowing about the
|
|
2448
|
+
* moost-db-specific key.
|
|
2449
|
+
*
|
|
2450
|
+
* Validation is intentionally *not* performed here. To validate `input`
|
|
2451
|
+
* against `FormType`, install an atscript validator pipe globally
|
|
2452
|
+
* (`app.applyGlobalPipes(...)`) or scope it via `@Pipe(...)`. The pipe reads
|
|
2453
|
+
* `MOOST_ATSCRIPT_TYPE` off the param and runs `FormType.validator()`.
|
|
2454
|
+
*
|
|
2455
|
+
* Only one `@InputForm()` per action is supported. To collect multiple
|
|
2456
|
+
* structured inputs, compose them into a single `.as` interface and pass an
|
|
2457
|
+
* array form on the field whose user-facing intent is "list of items".
|
|
2458
|
+
*
|
|
2459
|
+
* @param formType A compiled `.as` interface class (carries `.validator()`,
|
|
2460
|
+
* `.metadata`, etc.).
|
|
2461
|
+
*/
|
|
2462
|
+
function InputForm(formType) {
|
|
2463
|
+
const mate = getMoostMate();
|
|
2464
|
+
const meta = {
|
|
2465
|
+
type: formType,
|
|
2466
|
+
name: formType.name
|
|
2467
|
+
};
|
|
2468
|
+
return ApplyDecorators(mate.decorate(MOOST_DB_ACTION_INPUT_FORM, meta), mate.decorate(MOOST_ATSCRIPT_TYPE, formType), Resolve(async () => current().get(dbActionInputSlot), "dbActionInputForm"));
|
|
2469
|
+
}
|
|
2470
|
+
//#endregion
|
|
2327
2471
|
//#region src/actions/per-row.ts
|
|
2328
2472
|
/**
|
|
2329
2473
|
* Lift a per-row predicate into the batch shape required by
|
|
@@ -2339,4 +2483,4 @@ function classLevelActions(dict, forcedLevel) {
|
|
|
2339
2483
|
*/
|
|
2340
2484
|
const perRow = (fn) => (rows) => rows.map(fn);
|
|
2341
2485
|
//#endregion
|
|
2342
|
-
export { ActionDisabledError, AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionID, DbActionIDs, DbActionRow, DbActionRows, DbActions, DbRowActions, DbRowsActions, DbTableActions, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, TABLE_DEF, TableController, UseValidationErrorTransform, ViewController, discoverActions, perRow, useDbActionId, useDbActionIds, useDbActionRow, useDbActionRows, validationErrorTransform };
|
|
2486
|
+
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 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/moost-db",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.62",
|
|
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.
|
|
61
|
+
"@atscript/db": "^0.1.62"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
64
|
"postinstall": "asc -f dts",
|