@atscript/moost-db 0.1.56 → 0.1.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +80 -32
- package/dist/index.d.cts +34 -21
- package/dist/index.d.mts +34 -21
- package/dist/index.mjs +78 -33
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -473,13 +473,6 @@ let AsReadableController = class AsReadableController {
|
|
|
473
473
|
}
|
|
474
474
|
};
|
|
475
475
|
}
|
|
476
|
-
/**
|
|
477
|
-
* Whether this controller is read-only (no write endpoints).
|
|
478
|
-
* Returns `true` by default; {@link AsDbController} overrides to `false`.
|
|
479
|
-
*/
|
|
480
|
-
_isReadOnly() {
|
|
481
|
-
return true;
|
|
482
|
-
}
|
|
483
476
|
_queryControlsValidator;
|
|
484
477
|
_pagesControlsValidator;
|
|
485
478
|
_getOneControlsValidator;
|
|
@@ -539,37 +532,31 @@ let AsReadableController = class AsReadableController {
|
|
|
539
532
|
return item;
|
|
540
533
|
}
|
|
541
534
|
/**
|
|
542
|
-
* **GET /meta** — returns the bound interface's metadata envelope.
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
* override to add source-specific fields (relations, searchable flags, etc.).
|
|
546
|
-
* The response is cached on the instance; async overrides must cache any
|
|
547
|
-
* extra enrichment themselves.
|
|
535
|
+
* **GET /meta** — returns the bound interface's metadata envelope. The
|
|
536
|
+
* static envelope is cached; {@link applyMetaOverlay} runs per request so
|
|
537
|
+
* subclasses can prune the response by principal.
|
|
548
538
|
*/
|
|
549
539
|
async meta() {
|
|
550
|
-
if (this._metaResponse)
|
|
551
|
-
|
|
552
|
-
this._metaResponse = response;
|
|
553
|
-
return response;
|
|
540
|
+
if (!this._metaResponse) this._metaResponse = this.buildMetaResponse();
|
|
541
|
+
return this.applyMetaOverlay(this._metaResponse);
|
|
554
542
|
}
|
|
555
543
|
/**
|
|
556
544
|
* Builds the `/meta` payload. Override in subclasses to populate source-specific
|
|
557
|
-
* fields.
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
* directly so `@DbAction*` decorators still surface.
|
|
545
|
+
* fields. Subclasses that fully replace the envelope must call
|
|
546
|
+
* {@link buildActions} and {@link buildCrud} directly so `@DbAction*`
|
|
547
|
+
* decorators and CRUD permissions still surface.
|
|
561
548
|
*/
|
|
562
|
-
|
|
549
|
+
buildMetaResponse() {
|
|
563
550
|
return {
|
|
564
551
|
searchable: false,
|
|
565
552
|
vectorSearchable: false,
|
|
566
553
|
searchIndexes: [],
|
|
567
554
|
primaryKeys: [],
|
|
568
|
-
readOnly: this._isReadOnly(),
|
|
569
555
|
relations: [],
|
|
570
556
|
fields: {},
|
|
571
557
|
type: this.getSerializedType(),
|
|
572
|
-
actions: this.buildActions()
|
|
558
|
+
actions: this.buildActions(),
|
|
559
|
+
crud: this.buildCrud()
|
|
573
560
|
};
|
|
574
561
|
}
|
|
575
562
|
/**
|
|
@@ -580,6 +567,25 @@ let AsReadableController = class AsReadableController {
|
|
|
580
567
|
buildActions() {
|
|
581
568
|
return discoverActions(this.constructor, this.app, this.logger);
|
|
582
569
|
}
|
|
570
|
+
/**
|
|
571
|
+
* Declares the built-in CRUD operations this controller exposes. Subclasses
|
|
572
|
+
* override to add their keys; the bare base only exposes `/meta`. See
|
|
573
|
+
* `docs/http/permissions.md` for the wire shape and overlay rules.
|
|
574
|
+
*/
|
|
575
|
+
buildCrud() {
|
|
576
|
+
return {};
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Per-request overlay applied to the cached `/meta` envelope. Default no-op.
|
|
580
|
+
* Subclasses may shallow-clone and prune `crud` keys, `crud[op]` arrays, or
|
|
581
|
+
* `actions[]` based on the current request principal (read via Moost
|
|
582
|
+
* composables). The cached envelope MUST NOT be mutated — see
|
|
583
|
+
* `docs/http/permissions.md` for the full contract, including the
|
|
584
|
+
* "discoverability only" caveat.
|
|
585
|
+
*/
|
|
586
|
+
applyMetaOverlay(meta) {
|
|
587
|
+
return meta;
|
|
588
|
+
}
|
|
583
589
|
};
|
|
584
590
|
__decorate([
|
|
585
591
|
(0, _moostjs_event_http.Get)("meta"),
|
|
@@ -658,6 +664,23 @@ const ReadableController = (readable, prefix) => {
|
|
|
658
664
|
*/
|
|
659
665
|
const ViewController = ReadableController;
|
|
660
666
|
//#endregion
|
|
667
|
+
//#region src/permissions/crud-controls.ts
|
|
668
|
+
/**
|
|
669
|
+
* Static control whitelists per read op. Each list is the matching DTO's
|
|
670
|
+
* `$`-properties (stripped) plus the URL-grammar extras (`filter`,
|
|
671
|
+
* `insights`, `groupBy`) that bypass the DTO. The DTO is the single source of
|
|
672
|
+
* truth — adding a `$control` there auto-extends the whitelist here.
|
|
673
|
+
*/
|
|
674
|
+
const dtoControls = (Dto) => [...Dto.type.props.keys()].map((k) => k.startsWith("$") ? k.slice(1) : k);
|
|
675
|
+
const QUERY_CONTROLS = [
|
|
676
|
+
"filter",
|
|
677
|
+
"insights",
|
|
678
|
+
...dtoControls(QueryControlsDto),
|
|
679
|
+
"groupBy"
|
|
680
|
+
];
|
|
681
|
+
const PAGES_CONTROLS = ["filter", ...dtoControls(PagesControlsDto)];
|
|
682
|
+
const ONE_CONTROLS = dtoControls(GetOneControlsDto);
|
|
683
|
+
//#endregion
|
|
661
684
|
//#region \0@oxc-project+runtime@0.120.0/helpers/decorateParam.js
|
|
662
685
|
function __decorateParam(paramIndex, decorator) {
|
|
663
686
|
return function(target, key) {
|
|
@@ -907,7 +930,7 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
|
|
|
907
930
|
* vector-searchable flags, field-descriptor-derived filter/sort hints, and
|
|
908
931
|
* the configured primary keys.
|
|
909
932
|
*/
|
|
910
|
-
|
|
933
|
+
buildMetaResponse() {
|
|
911
934
|
const relations = [];
|
|
912
935
|
for (const [name, rel] of this.readable.relations) relations.push({
|
|
913
936
|
name,
|
|
@@ -932,11 +955,19 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
|
|
|
932
955
|
vectorSearchable: this.readable.isVectorSearchable(),
|
|
933
956
|
searchIndexes: this.readable.getSearchIndexes(),
|
|
934
957
|
primaryKeys: [...this.readable.primaryKeys],
|
|
935
|
-
readOnly: this._isReadOnly(),
|
|
936
958
|
relations,
|
|
937
959
|
fields,
|
|
938
960
|
type: this.getSerializedType(),
|
|
939
|
-
actions: this.buildActions()
|
|
961
|
+
actions: this.buildActions(),
|
|
962
|
+
crud: this.buildCrud()
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
buildCrud() {
|
|
966
|
+
return {
|
|
967
|
+
...super.buildCrud(),
|
|
968
|
+
query: [...QUERY_CONTROLS],
|
|
969
|
+
pages: [...PAGES_CONTROLS],
|
|
970
|
+
one: [...ONE_CONTROLS]
|
|
940
971
|
};
|
|
941
972
|
}
|
|
942
973
|
};
|
|
@@ -986,8 +1017,14 @@ let AsDbController = class AsDbController extends AsDbReadableController {
|
|
|
986
1017
|
constructor(table, app) {
|
|
987
1018
|
super(table, app);
|
|
988
1019
|
}
|
|
989
|
-
|
|
990
|
-
return
|
|
1020
|
+
buildCrud() {
|
|
1021
|
+
return {
|
|
1022
|
+
...super.buildCrud(),
|
|
1023
|
+
insert: [],
|
|
1024
|
+
update: [],
|
|
1025
|
+
replace: [],
|
|
1026
|
+
remove: []
|
|
1027
|
+
};
|
|
991
1028
|
}
|
|
992
1029
|
/**
|
|
993
1030
|
* Intercepts write operations. Return `undefined` to abort.
|
|
@@ -1204,7 +1241,7 @@ let AsValueHelpController = class AsValueHelpController extends AsReadableContro
|
|
|
1204
1241
|
* client picker UI (which controls to render); the server does not enforce
|
|
1205
1242
|
* these flags at request time.
|
|
1206
1243
|
*/
|
|
1207
|
-
|
|
1244
|
+
buildMetaResponse() {
|
|
1208
1245
|
const fields = {};
|
|
1209
1246
|
for (const [path, meta] of this.fieldMeta) fields[path] = {
|
|
1210
1247
|
sortable: meta.has("ui.dict.sortable"),
|
|
@@ -1215,16 +1252,24 @@ let AsValueHelpController = class AsValueHelpController extends AsReadableContro
|
|
|
1215
1252
|
vectorSearchable: false,
|
|
1216
1253
|
searchIndexes: [],
|
|
1217
1254
|
primaryKeys: this.primaryKey ? [this.primaryKey] : [],
|
|
1218
|
-
readOnly: this._isReadOnly(),
|
|
1219
1255
|
relations: [],
|
|
1220
1256
|
fields,
|
|
1221
1257
|
type: this.getSerializedType(),
|
|
1222
|
-
actions: []
|
|
1258
|
+
actions: [],
|
|
1259
|
+
crud: this.buildCrud()
|
|
1223
1260
|
};
|
|
1224
1261
|
}
|
|
1225
1262
|
buildActions() {
|
|
1226
1263
|
return [];
|
|
1227
1264
|
}
|
|
1265
|
+
buildCrud() {
|
|
1266
|
+
return {
|
|
1267
|
+
...super.buildCrud(),
|
|
1268
|
+
query: [...QUERY_CONTROLS],
|
|
1269
|
+
pages: [...PAGES_CONTROLS],
|
|
1270
|
+
one: [...ONE_CONTROLS]
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1228
1273
|
};
|
|
1229
1274
|
__decorate([
|
|
1230
1275
|
(0, _moostjs_event_http.Get)("query"),
|
|
@@ -1705,6 +1750,9 @@ exports.DbActions = DbActions;
|
|
|
1705
1750
|
exports.DbRowActions = DbRowActions;
|
|
1706
1751
|
exports.DbRowsActions = DbRowsActions;
|
|
1707
1752
|
exports.DbTableActions = DbTableActions;
|
|
1753
|
+
exports.ONE_CONTROLS = ONE_CONTROLS;
|
|
1754
|
+
exports.PAGES_CONTROLS = PAGES_CONTROLS;
|
|
1755
|
+
exports.QUERY_CONTROLS = QUERY_CONTROLS;
|
|
1708
1756
|
exports.READABLE_DEF = READABLE_DEF;
|
|
1709
1757
|
exports.ReadableController = ReadableController;
|
|
1710
1758
|
exports.TABLE_DEF = TABLE_DEF;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _atscript_typescript_utils0 from "@atscript/typescript/utils";
|
|
2
2
|
import { TAtscriptAnnotatedType, TAtscriptDataType, TSerializeOptions, Validator } from "@atscript/typescript/utils";
|
|
3
3
|
import * as _uniqu_url0 from "@uniqu/url";
|
|
4
|
-
import { AtscriptDbReadable, AtscriptDbTable, FilterExpr, TDbActionInfo, TDbActionInfo as TDbActionInfo$1, TDbActionIntent, TDbActionIntent as TDbActionIntent$1, TDbActionLevel, TDbActionLevel as TDbActionLevel$1, TDbActionProcessor, TDbFieldMeta, TMetaResponse, Uniquery, UniqueryControls } from "@atscript/db";
|
|
4
|
+
import { AtscriptDbReadable, AtscriptDbTable, FilterExpr, TCrudOp, TCrudPermissions, TCrudPermissions as TCrudPermissions$1, TDbActionInfo, TDbActionInfo as TDbActionInfo$1, TDbActionIntent, TDbActionIntent as TDbActionIntent$1, TDbActionLevel, TDbActionLevel as TDbActionLevel$1, TDbActionProcessor, TDbFieldMeta, TMetaResponse, Uniquery, UniqueryControls } from "@atscript/db";
|
|
5
5
|
import { HttpError } from "@moostjs/event-http";
|
|
6
6
|
import * as moost from "moost";
|
|
7
7
|
import { Moost, TConsoleBase } from "moost";
|
|
@@ -88,11 +88,6 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
|
|
|
88
88
|
* to customise.
|
|
89
89
|
*/
|
|
90
90
|
protected getSerializeOptions(): TSerializeOptions;
|
|
91
|
-
/**
|
|
92
|
-
* Whether this controller is read-only (no write endpoints).
|
|
93
|
-
* Returns `true` by default; {@link AsDbController} overrides to `false`.
|
|
94
|
-
*/
|
|
95
|
-
protected _isReadOnly(): boolean;
|
|
96
91
|
private _queryControlsValidator?;
|
|
97
92
|
private _pagesControlsValidator?;
|
|
98
93
|
private _getOneControlsValidator?;
|
|
@@ -111,28 +106,39 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
|
|
|
111
106
|
protected parseQueryString(url: string): _uniqu_url0.UrlQuery;
|
|
112
107
|
protected returnOne(result: Promise<DataType | null>): Promise<DataType | HttpError>;
|
|
113
108
|
/**
|
|
114
|
-
* **GET /meta** — returns the bound interface's metadata envelope.
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* override to add source-specific fields (relations, searchable flags, etc.).
|
|
118
|
-
* The response is cached on the instance; async overrides must cache any
|
|
119
|
-
* extra enrichment themselves.
|
|
109
|
+
* **GET /meta** — returns the bound interface's metadata envelope. The
|
|
110
|
+
* static envelope is cached; {@link applyMetaOverlay} runs per request so
|
|
111
|
+
* subclasses can prune the response by principal.
|
|
120
112
|
*/
|
|
121
113
|
meta(): Promise<TMetaResponse>;
|
|
122
114
|
/**
|
|
123
115
|
* Builds the `/meta` payload. Override in subclasses to populate source-specific
|
|
124
|
-
* fields.
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* directly so `@DbAction*` decorators still surface.
|
|
116
|
+
* fields. Subclasses that fully replace the envelope must call
|
|
117
|
+
* {@link buildActions} and {@link buildCrud} directly so `@DbAction*`
|
|
118
|
+
* decorators and CRUD permissions still surface.
|
|
128
119
|
*/
|
|
129
|
-
protected buildMetaResponse():
|
|
120
|
+
protected buildMetaResponse(): TMetaResponse;
|
|
130
121
|
/**
|
|
131
122
|
* Discovers `@DbAction*` and `@DbActions`-style class metadata on this
|
|
132
123
|
* controller and produces the `actions` array. Returns `[]` for value-help
|
|
133
124
|
* controllers — see {@link AsValueHelpController#buildMetaResponse}.
|
|
134
125
|
*/
|
|
135
126
|
protected buildActions(): TDbActionInfo$1[];
|
|
127
|
+
/**
|
|
128
|
+
* Declares the built-in CRUD operations this controller exposes. Subclasses
|
|
129
|
+
* override to add their keys; the bare base only exposes `/meta`. See
|
|
130
|
+
* `docs/http/permissions.md` for the wire shape and overlay rules.
|
|
131
|
+
*/
|
|
132
|
+
protected buildCrud(): TCrudPermissions$1;
|
|
133
|
+
/**
|
|
134
|
+
* Per-request overlay applied to the cached `/meta` envelope. Default no-op.
|
|
135
|
+
* Subclasses may shallow-clone and prune `crud` keys, `crud[op]` arrays, or
|
|
136
|
+
* `actions[]` based on the current request principal (read via Moost
|
|
137
|
+
* composables). The cached envelope MUST NOT be mutated — see
|
|
138
|
+
* `docs/http/permissions.md` for the full contract, including the
|
|
139
|
+
* "discoverability only" caveat.
|
|
140
|
+
*/
|
|
141
|
+
protected applyMetaOverlay(meta: TMetaResponse): TMetaResponse | Promise<TMetaResponse>;
|
|
136
142
|
}
|
|
137
143
|
//#endregion
|
|
138
144
|
//#region src/as-db-readable.controller.d.ts
|
|
@@ -204,7 +210,8 @@ declare class AsDbReadableController<T extends TAtscriptAnnotatedType = TAtscrip
|
|
|
204
210
|
* vector-searchable flags, field-descriptor-derived filter/sort hints, and
|
|
205
211
|
* the configured primary keys.
|
|
206
212
|
*/
|
|
207
|
-
protected buildMetaResponse():
|
|
213
|
+
protected buildMetaResponse(): TMetaResponse;
|
|
214
|
+
protected buildCrud(): TCrudPermissions$1;
|
|
208
215
|
}
|
|
209
216
|
//#endregion
|
|
210
217
|
//#region src/as-db.controller.d.ts
|
|
@@ -222,7 +229,7 @@ declare class AsDbController<T extends TAtscriptAnnotatedType = TAtscriptAnnotat
|
|
|
222
229
|
/** Reference to the underlying table (typed for write access). */
|
|
223
230
|
protected get table(): AtscriptDbTable<T>;
|
|
224
231
|
constructor(table: AtscriptDbTable<T>, app: Moost);
|
|
225
|
-
protected
|
|
232
|
+
protected buildCrud(): TCrudPermissions$1;
|
|
226
233
|
/**
|
|
227
234
|
* Intercepts write operations. Return `undefined` to abort.
|
|
228
235
|
* May be async (e.g. to enrich payloads from session / permissions).
|
|
@@ -344,8 +351,9 @@ declare abstract class AsValueHelpController<T extends TAtscriptAnnotatedType =
|
|
|
344
351
|
* client picker UI (which controls to render); the server does not enforce
|
|
345
352
|
* these flags at request time.
|
|
346
353
|
*/
|
|
347
|
-
protected buildMetaResponse():
|
|
354
|
+
protected buildMetaResponse(): TMetaResponse;
|
|
348
355
|
protected buildActions(): never[];
|
|
356
|
+
protected buildCrud(): TCrudPermissions$1;
|
|
349
357
|
}
|
|
350
358
|
//#endregion
|
|
351
359
|
//#region src/as-json-value-help.controller.d.ts
|
|
@@ -599,4 +607,9 @@ interface PkValidationSource {
|
|
|
599
607
|
fieldDescriptors: readonly TDbFieldMeta[];
|
|
600
608
|
}
|
|
601
609
|
//#endregion
|
|
602
|
-
|
|
610
|
+
//#region src/permissions/crud-controls.d.ts
|
|
611
|
+
declare const QUERY_CONTROLS: readonly string[];
|
|
612
|
+
declare const PAGES_CONTROLS: readonly string[];
|
|
613
|
+
declare const ONE_CONTROLS: readonly string[];
|
|
614
|
+
//#endregion
|
|
615
|
+
export { AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionOpts, DbActionPK, DbActionPKs, DbActions, DbRowActions, DbRowsActions, DbTableActions, ONE_CONTROLS, PAGES_CONTROLS, PkValidationSource, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, TDbActionsEntry, TDbActionsEntryUnpinned, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, discoverActions, validationErrorTransform };
|
package/dist/index.d.mts
CHANGED
|
@@ -4,7 +4,7 @@ import { HttpError } from "@moostjs/event-http";
|
|
|
4
4
|
import * as moost from "moost";
|
|
5
5
|
import { Moost, TConsoleBase } from "moost";
|
|
6
6
|
import * as _uniqu_url0 from "@uniqu/url";
|
|
7
|
-
import { AtscriptDbReadable, AtscriptDbTable, FilterExpr, TDbActionInfo, TDbActionInfo as TDbActionInfo$1, TDbActionIntent, TDbActionIntent as TDbActionIntent$1, TDbActionLevel, TDbActionLevel as TDbActionLevel$1, TDbActionProcessor, TDbFieldMeta, TMetaResponse, Uniquery, UniqueryControls } from "@atscript/db";
|
|
7
|
+
import { AtscriptDbReadable, AtscriptDbTable, FilterExpr, TCrudOp, TCrudPermissions, TCrudPermissions as TCrudPermissions$1, TDbActionInfo, TDbActionInfo as TDbActionInfo$1, TDbActionIntent, TDbActionIntent as TDbActionIntent$1, TDbActionLevel, TDbActionLevel as TDbActionLevel$1, TDbActionProcessor, TDbFieldMeta, TMetaResponse, Uniquery, UniqueryControls } from "@atscript/db";
|
|
8
8
|
|
|
9
9
|
//#region src/as-readable.controller.d.ts
|
|
10
10
|
/**
|
|
@@ -88,11 +88,6 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
|
|
|
88
88
|
* to customise.
|
|
89
89
|
*/
|
|
90
90
|
protected getSerializeOptions(): TSerializeOptions;
|
|
91
|
-
/**
|
|
92
|
-
* Whether this controller is read-only (no write endpoints).
|
|
93
|
-
* Returns `true` by default; {@link AsDbController} overrides to `false`.
|
|
94
|
-
*/
|
|
95
|
-
protected _isReadOnly(): boolean;
|
|
96
91
|
private _queryControlsValidator?;
|
|
97
92
|
private _pagesControlsValidator?;
|
|
98
93
|
private _getOneControlsValidator?;
|
|
@@ -111,28 +106,39 @@ declare abstract class AsReadableController<T extends TAtscriptAnnotatedType = T
|
|
|
111
106
|
protected parseQueryString(url: string): _uniqu_url0.UrlQuery;
|
|
112
107
|
protected returnOne(result: Promise<DataType | null>): Promise<DataType | HttpError>;
|
|
113
108
|
/**
|
|
114
|
-
* **GET /meta** — returns the bound interface's metadata envelope.
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* override to add source-specific fields (relations, searchable flags, etc.).
|
|
118
|
-
* The response is cached on the instance; async overrides must cache any
|
|
119
|
-
* extra enrichment themselves.
|
|
109
|
+
* **GET /meta** — returns the bound interface's metadata envelope. The
|
|
110
|
+
* static envelope is cached; {@link applyMetaOverlay} runs per request so
|
|
111
|
+
* subclasses can prune the response by principal.
|
|
120
112
|
*/
|
|
121
113
|
meta(): Promise<TMetaResponse>;
|
|
122
114
|
/**
|
|
123
115
|
* Builds the `/meta` payload. Override in subclasses to populate source-specific
|
|
124
|
-
* fields.
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* directly so `@DbAction*` decorators still surface.
|
|
116
|
+
* fields. Subclasses that fully replace the envelope must call
|
|
117
|
+
* {@link buildActions} and {@link buildCrud} directly so `@DbAction*`
|
|
118
|
+
* decorators and CRUD permissions still surface.
|
|
128
119
|
*/
|
|
129
|
-
protected buildMetaResponse():
|
|
120
|
+
protected buildMetaResponse(): TMetaResponse;
|
|
130
121
|
/**
|
|
131
122
|
* Discovers `@DbAction*` and `@DbActions`-style class metadata on this
|
|
132
123
|
* controller and produces the `actions` array. Returns `[]` for value-help
|
|
133
124
|
* controllers — see {@link AsValueHelpController#buildMetaResponse}.
|
|
134
125
|
*/
|
|
135
126
|
protected buildActions(): TDbActionInfo$1[];
|
|
127
|
+
/**
|
|
128
|
+
* Declares the built-in CRUD operations this controller exposes. Subclasses
|
|
129
|
+
* override to add their keys; the bare base only exposes `/meta`. See
|
|
130
|
+
* `docs/http/permissions.md` for the wire shape and overlay rules.
|
|
131
|
+
*/
|
|
132
|
+
protected buildCrud(): TCrudPermissions$1;
|
|
133
|
+
/**
|
|
134
|
+
* Per-request overlay applied to the cached `/meta` envelope. Default no-op.
|
|
135
|
+
* Subclasses may shallow-clone and prune `crud` keys, `crud[op]` arrays, or
|
|
136
|
+
* `actions[]` based on the current request principal (read via Moost
|
|
137
|
+
* composables). The cached envelope MUST NOT be mutated — see
|
|
138
|
+
* `docs/http/permissions.md` for the full contract, including the
|
|
139
|
+
* "discoverability only" caveat.
|
|
140
|
+
*/
|
|
141
|
+
protected applyMetaOverlay(meta: TMetaResponse): TMetaResponse | Promise<TMetaResponse>;
|
|
136
142
|
}
|
|
137
143
|
//#endregion
|
|
138
144
|
//#region src/as-db-readable.controller.d.ts
|
|
@@ -204,7 +210,8 @@ declare class AsDbReadableController<T extends TAtscriptAnnotatedType = TAtscrip
|
|
|
204
210
|
* vector-searchable flags, field-descriptor-derived filter/sort hints, and
|
|
205
211
|
* the configured primary keys.
|
|
206
212
|
*/
|
|
207
|
-
protected buildMetaResponse():
|
|
213
|
+
protected buildMetaResponse(): TMetaResponse;
|
|
214
|
+
protected buildCrud(): TCrudPermissions$1;
|
|
208
215
|
}
|
|
209
216
|
//#endregion
|
|
210
217
|
//#region src/as-db.controller.d.ts
|
|
@@ -222,7 +229,7 @@ declare class AsDbController<T extends TAtscriptAnnotatedType = TAtscriptAnnotat
|
|
|
222
229
|
/** Reference to the underlying table (typed for write access). */
|
|
223
230
|
protected get table(): AtscriptDbTable<T>;
|
|
224
231
|
constructor(table: AtscriptDbTable<T>, app: Moost);
|
|
225
|
-
protected
|
|
232
|
+
protected buildCrud(): TCrudPermissions$1;
|
|
226
233
|
/**
|
|
227
234
|
* Intercepts write operations. Return `undefined` to abort.
|
|
228
235
|
* May be async (e.g. to enrich payloads from session / permissions).
|
|
@@ -344,8 +351,9 @@ declare abstract class AsValueHelpController<T extends TAtscriptAnnotatedType =
|
|
|
344
351
|
* client picker UI (which controls to render); the server does not enforce
|
|
345
352
|
* these flags at request time.
|
|
346
353
|
*/
|
|
347
|
-
protected buildMetaResponse():
|
|
354
|
+
protected buildMetaResponse(): TMetaResponse;
|
|
348
355
|
protected buildActions(): never[];
|
|
356
|
+
protected buildCrud(): TCrudPermissions$1;
|
|
349
357
|
}
|
|
350
358
|
//#endregion
|
|
351
359
|
//#region src/as-json-value-help.controller.d.ts
|
|
@@ -599,4 +607,9 @@ interface PkValidationSource {
|
|
|
599
607
|
fieldDescriptors: readonly TDbFieldMeta[];
|
|
600
608
|
}
|
|
601
609
|
//#endregion
|
|
602
|
-
|
|
610
|
+
//#region src/permissions/crud-controls.d.ts
|
|
611
|
+
declare const QUERY_CONTROLS: readonly string[];
|
|
612
|
+
declare const PAGES_CONTROLS: readonly string[];
|
|
613
|
+
declare const ONE_CONTROLS: readonly string[];
|
|
614
|
+
//#endregion
|
|
615
|
+
export { AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, type DbActionOpts, DbActionPK, DbActionPKs, DbActions, DbRowActions, DbRowsActions, DbTableActions, ONE_CONTROLS, PAGES_CONTROLS, type PkValidationSource, QUERY_CONTROLS, READABLE_DEF, ReadableController, ReadableGates, TABLE_DEF, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbActionsEntry, type TDbActionsEntryUnpinned, TableController, UseValidationErrorTransform, ValueHelpQuery, ViewController, discoverActions, validationErrorTransform };
|
package/dist/index.mjs
CHANGED
|
@@ -472,13 +472,6 @@ let AsReadableController = class AsReadableController {
|
|
|
472
472
|
}
|
|
473
473
|
};
|
|
474
474
|
}
|
|
475
|
-
/**
|
|
476
|
-
* Whether this controller is read-only (no write endpoints).
|
|
477
|
-
* Returns `true` by default; {@link AsDbController} overrides to `false`.
|
|
478
|
-
*/
|
|
479
|
-
_isReadOnly() {
|
|
480
|
-
return true;
|
|
481
|
-
}
|
|
482
475
|
_queryControlsValidator;
|
|
483
476
|
_pagesControlsValidator;
|
|
484
477
|
_getOneControlsValidator;
|
|
@@ -538,37 +531,31 @@ let AsReadableController = class AsReadableController {
|
|
|
538
531
|
return item;
|
|
539
532
|
}
|
|
540
533
|
/**
|
|
541
|
-
* **GET /meta** — returns the bound interface's metadata envelope.
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
* override to add source-specific fields (relations, searchable flags, etc.).
|
|
545
|
-
* The response is cached on the instance; async overrides must cache any
|
|
546
|
-
* extra enrichment themselves.
|
|
534
|
+
* **GET /meta** — returns the bound interface's metadata envelope. The
|
|
535
|
+
* static envelope is cached; {@link applyMetaOverlay} runs per request so
|
|
536
|
+
* subclasses can prune the response by principal.
|
|
547
537
|
*/
|
|
548
538
|
async meta() {
|
|
549
|
-
if (this._metaResponse)
|
|
550
|
-
|
|
551
|
-
this._metaResponse = response;
|
|
552
|
-
return response;
|
|
539
|
+
if (!this._metaResponse) this._metaResponse = this.buildMetaResponse();
|
|
540
|
+
return this.applyMetaOverlay(this._metaResponse);
|
|
553
541
|
}
|
|
554
542
|
/**
|
|
555
543
|
* Builds the `/meta` payload. Override in subclasses to populate source-specific
|
|
556
|
-
* fields.
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
* directly so `@DbAction*` decorators still surface.
|
|
544
|
+
* fields. Subclasses that fully replace the envelope must call
|
|
545
|
+
* {@link buildActions} and {@link buildCrud} directly so `@DbAction*`
|
|
546
|
+
* decorators and CRUD permissions still surface.
|
|
560
547
|
*/
|
|
561
|
-
|
|
548
|
+
buildMetaResponse() {
|
|
562
549
|
return {
|
|
563
550
|
searchable: false,
|
|
564
551
|
vectorSearchable: false,
|
|
565
552
|
searchIndexes: [],
|
|
566
553
|
primaryKeys: [],
|
|
567
|
-
readOnly: this._isReadOnly(),
|
|
568
554
|
relations: [],
|
|
569
555
|
fields: {},
|
|
570
556
|
type: this.getSerializedType(),
|
|
571
|
-
actions: this.buildActions()
|
|
557
|
+
actions: this.buildActions(),
|
|
558
|
+
crud: this.buildCrud()
|
|
572
559
|
};
|
|
573
560
|
}
|
|
574
561
|
/**
|
|
@@ -579,6 +566,25 @@ let AsReadableController = class AsReadableController {
|
|
|
579
566
|
buildActions() {
|
|
580
567
|
return discoverActions(this.constructor, this.app, this.logger);
|
|
581
568
|
}
|
|
569
|
+
/**
|
|
570
|
+
* Declares the built-in CRUD operations this controller exposes. Subclasses
|
|
571
|
+
* override to add their keys; the bare base only exposes `/meta`. See
|
|
572
|
+
* `docs/http/permissions.md` for the wire shape and overlay rules.
|
|
573
|
+
*/
|
|
574
|
+
buildCrud() {
|
|
575
|
+
return {};
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Per-request overlay applied to the cached `/meta` envelope. Default no-op.
|
|
579
|
+
* Subclasses may shallow-clone and prune `crud` keys, `crud[op]` arrays, or
|
|
580
|
+
* `actions[]` based on the current request principal (read via Moost
|
|
581
|
+
* composables). The cached envelope MUST NOT be mutated — see
|
|
582
|
+
* `docs/http/permissions.md` for the full contract, including the
|
|
583
|
+
* "discoverability only" caveat.
|
|
584
|
+
*/
|
|
585
|
+
applyMetaOverlay(meta) {
|
|
586
|
+
return meta;
|
|
587
|
+
}
|
|
582
588
|
};
|
|
583
589
|
__decorate([
|
|
584
590
|
Get("meta"),
|
|
@@ -657,6 +663,23 @@ const ReadableController = (readable, prefix) => {
|
|
|
657
663
|
*/
|
|
658
664
|
const ViewController = ReadableController;
|
|
659
665
|
//#endregion
|
|
666
|
+
//#region src/permissions/crud-controls.ts
|
|
667
|
+
/**
|
|
668
|
+
* Static control whitelists per read op. Each list is the matching DTO's
|
|
669
|
+
* `$`-properties (stripped) plus the URL-grammar extras (`filter`,
|
|
670
|
+
* `insights`, `groupBy`) that bypass the DTO. The DTO is the single source of
|
|
671
|
+
* truth — adding a `$control` there auto-extends the whitelist here.
|
|
672
|
+
*/
|
|
673
|
+
const dtoControls = (Dto) => [...Dto.type.props.keys()].map((k) => k.startsWith("$") ? k.slice(1) : k);
|
|
674
|
+
const QUERY_CONTROLS = [
|
|
675
|
+
"filter",
|
|
676
|
+
"insights",
|
|
677
|
+
...dtoControls(QueryControlsDto),
|
|
678
|
+
"groupBy"
|
|
679
|
+
];
|
|
680
|
+
const PAGES_CONTROLS = ["filter", ...dtoControls(PagesControlsDto)];
|
|
681
|
+
const ONE_CONTROLS = dtoControls(GetOneControlsDto);
|
|
682
|
+
//#endregion
|
|
660
683
|
//#region \0@oxc-project+runtime@0.120.0/helpers/decorateParam.js
|
|
661
684
|
function __decorateParam(paramIndex, decorator) {
|
|
662
685
|
return function(target, key) {
|
|
@@ -906,7 +929,7 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
|
|
|
906
929
|
* vector-searchable flags, field-descriptor-derived filter/sort hints, and
|
|
907
930
|
* the configured primary keys.
|
|
908
931
|
*/
|
|
909
|
-
|
|
932
|
+
buildMetaResponse() {
|
|
910
933
|
const relations = [];
|
|
911
934
|
for (const [name, rel] of this.readable.relations) relations.push({
|
|
912
935
|
name,
|
|
@@ -931,11 +954,19 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
|
|
|
931
954
|
vectorSearchable: this.readable.isVectorSearchable(),
|
|
932
955
|
searchIndexes: this.readable.getSearchIndexes(),
|
|
933
956
|
primaryKeys: [...this.readable.primaryKeys],
|
|
934
|
-
readOnly: this._isReadOnly(),
|
|
935
957
|
relations,
|
|
936
958
|
fields,
|
|
937
959
|
type: this.getSerializedType(),
|
|
938
|
-
actions: this.buildActions()
|
|
960
|
+
actions: this.buildActions(),
|
|
961
|
+
crud: this.buildCrud()
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
buildCrud() {
|
|
965
|
+
return {
|
|
966
|
+
...super.buildCrud(),
|
|
967
|
+
query: [...QUERY_CONTROLS],
|
|
968
|
+
pages: [...PAGES_CONTROLS],
|
|
969
|
+
one: [...ONE_CONTROLS]
|
|
939
970
|
};
|
|
940
971
|
}
|
|
941
972
|
};
|
|
@@ -985,8 +1016,14 @@ let AsDbController = class AsDbController extends AsDbReadableController {
|
|
|
985
1016
|
constructor(table, app) {
|
|
986
1017
|
super(table, app);
|
|
987
1018
|
}
|
|
988
|
-
|
|
989
|
-
return
|
|
1019
|
+
buildCrud() {
|
|
1020
|
+
return {
|
|
1021
|
+
...super.buildCrud(),
|
|
1022
|
+
insert: [],
|
|
1023
|
+
update: [],
|
|
1024
|
+
replace: [],
|
|
1025
|
+
remove: []
|
|
1026
|
+
};
|
|
990
1027
|
}
|
|
991
1028
|
/**
|
|
992
1029
|
* Intercepts write operations. Return `undefined` to abort.
|
|
@@ -1203,7 +1240,7 @@ let AsValueHelpController = class AsValueHelpController extends AsReadableContro
|
|
|
1203
1240
|
* client picker UI (which controls to render); the server does not enforce
|
|
1204
1241
|
* these flags at request time.
|
|
1205
1242
|
*/
|
|
1206
|
-
|
|
1243
|
+
buildMetaResponse() {
|
|
1207
1244
|
const fields = {};
|
|
1208
1245
|
for (const [path, meta] of this.fieldMeta) fields[path] = {
|
|
1209
1246
|
sortable: meta.has("ui.dict.sortable"),
|
|
@@ -1214,16 +1251,24 @@ let AsValueHelpController = class AsValueHelpController extends AsReadableContro
|
|
|
1214
1251
|
vectorSearchable: false,
|
|
1215
1252
|
searchIndexes: [],
|
|
1216
1253
|
primaryKeys: this.primaryKey ? [this.primaryKey] : [],
|
|
1217
|
-
readOnly: this._isReadOnly(),
|
|
1218
1254
|
relations: [],
|
|
1219
1255
|
fields,
|
|
1220
1256
|
type: this.getSerializedType(),
|
|
1221
|
-
actions: []
|
|
1257
|
+
actions: [],
|
|
1258
|
+
crud: this.buildCrud()
|
|
1222
1259
|
};
|
|
1223
1260
|
}
|
|
1224
1261
|
buildActions() {
|
|
1225
1262
|
return [];
|
|
1226
1263
|
}
|
|
1264
|
+
buildCrud() {
|
|
1265
|
+
return {
|
|
1266
|
+
...super.buildCrud(),
|
|
1267
|
+
query: [...QUERY_CONTROLS],
|
|
1268
|
+
pages: [...PAGES_CONTROLS],
|
|
1269
|
+
one: [...ONE_CONTROLS]
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1227
1272
|
};
|
|
1228
1273
|
__decorate([
|
|
1229
1274
|
Get("query"),
|
|
@@ -1666,4 +1711,4 @@ function classLevelActions(dict, forcedLevel) {
|
|
|
1666
1711
|
});
|
|
1667
1712
|
}
|
|
1668
1713
|
//#endregion
|
|
1669
|
-
export { AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionPK, DbActionPKs, DbActions, DbRowActions, DbRowsActions, DbTableActions, READABLE_DEF, ReadableController, TABLE_DEF, TableController, UseValidationErrorTransform, ViewController, discoverActions, validationErrorTransform };
|
|
1714
|
+
export { AsDbController, AsDbReadableController, AsJsonValueHelpController, AsReadableController, AsValueHelpController, DbAction, DbActionDefault, DbActionPK, DbActionPKs, DbActions, DbRowActions, DbRowsActions, DbTableActions, ONE_CONTROLS, PAGES_CONTROLS, QUERY_CONTROLS, READABLE_DEF, ReadableController, TABLE_DEF, TableController, UseValidationErrorTransform, ViewController, discoverActions, 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.57",
|
|
4
4
|
"description": "Generic database controller for Moost with Atscript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"annotations",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@uniqu/core": "^0.1.5",
|
|
56
56
|
"@wooksjs/http-body": "^0.7.10",
|
|
57
57
|
"moost": "^0.6.8",
|
|
58
|
-
"@atscript/db": "^0.1.
|
|
58
|
+
"@atscript/db": "^0.1.57"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"postinstall": "asc -f dts",
|