@web-ts-toolkit/access-router 0.43.0 → 0.44.0
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/README.md +20 -0
- package/advanced.d.mts +1 -1
- package/advanced.d.ts +1 -1
- package/advanced.js +156 -24
- package/advanced.mjs +156 -24
- package/index.d.mts +18 -10
- package/index.d.ts +18 -10
- package/index.js +254 -68
- package/index.mjs +254 -68
- package/llms.txt +3 -0
- package/package.json +18 -6
- package/{parsers-PMWujHUV.d.mts → parsers-B5dbVmjm.d.mts} +68 -22
- package/{parsers-PMWujHUV.d.ts → parsers-B5dbVmjm.d.ts} +68 -22
- package/processors.js +5 -2
- package/processors.mjs +5 -2
package/index.js
CHANGED
|
@@ -841,6 +841,29 @@ var cloneConfigValue = (value) => {
|
|
|
841
841
|
])
|
|
842
842
|
);
|
|
843
843
|
};
|
|
844
|
+
var cloneForRead = (value) => {
|
|
845
|
+
if (Array.isArray(value)) {
|
|
846
|
+
if (Object.isFrozen(value)) {
|
|
847
|
+
return value;
|
|
848
|
+
}
|
|
849
|
+
return value.map((item) => cloneForRead(item));
|
|
850
|
+
}
|
|
851
|
+
if (!value || typeof value !== "object") {
|
|
852
|
+
return value;
|
|
853
|
+
}
|
|
854
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) {
|
|
855
|
+
return value;
|
|
856
|
+
}
|
|
857
|
+
if (Object.isFrozen(value)) {
|
|
858
|
+
return value;
|
|
859
|
+
}
|
|
860
|
+
return Object.fromEntries(
|
|
861
|
+
Object.entries(value).map(([entryKey, entryValue]) => [
|
|
862
|
+
entryKey,
|
|
863
|
+
cloneForRead(entryValue)
|
|
864
|
+
])
|
|
865
|
+
);
|
|
866
|
+
};
|
|
844
867
|
var freezeConfigValue = (value) => {
|
|
845
868
|
if (!value || typeof value !== "object") {
|
|
846
869
|
return value;
|
|
@@ -856,6 +879,7 @@ var freezeConfigValue = (value) => {
|
|
|
856
879
|
}
|
|
857
880
|
return value;
|
|
858
881
|
};
|
|
882
|
+
var cloneAndFreezeForStore = (value) => freezeConfigValue(cloneForRead(value));
|
|
859
883
|
var getNestedOption = (manager, key, defaultValue) => {
|
|
860
884
|
const keys2 = String(key).split(".");
|
|
861
885
|
if (keys2.length === 1) {
|
|
@@ -885,6 +909,14 @@ var OptionsManager = class {
|
|
|
885
909
|
target[keystr] = value;
|
|
886
910
|
_this.listeners[keystr] && _this.listeners[keystr].call(_this, value, keystr, target, oldvalue);
|
|
887
911
|
return true;
|
|
912
|
+
},
|
|
913
|
+
defineProperty(target, key, descriptor) {
|
|
914
|
+
const keystr = String(key);
|
|
915
|
+
const oldvalue = target[keystr];
|
|
916
|
+
const result = Reflect.defineProperty(target, key, descriptor);
|
|
917
|
+
const newValue = target[keystr];
|
|
918
|
+
_this.listeners[keystr] && _this.listeners[keystr].call(_this, newValue, keystr, target, oldvalue);
|
|
919
|
+
return result;
|
|
888
920
|
}
|
|
889
921
|
});
|
|
890
922
|
}
|
|
@@ -898,18 +930,18 @@ var OptionsManager = class {
|
|
|
898
930
|
set(key, value) {
|
|
899
931
|
const path = toPath(key);
|
|
900
932
|
if (path.length <= 1) {
|
|
901
|
-
(0, import_utils9.set)(this.currentOptions, path, this.preserveKeys.has(String(path[0])) ? value :
|
|
933
|
+
(0, import_utils9.set)(this.currentOptions, path, this.preserveKeys.has(String(path[0])) ? value : cloneAndFreezeForStore(value));
|
|
902
934
|
return;
|
|
903
935
|
}
|
|
904
936
|
const [rootKey, ...nestedPath] = path;
|
|
905
937
|
const currentRoot = (0, import_utils9.get)(this.currentOptions, [rootKey], void 0);
|
|
906
938
|
const baseRoot = (0, import_utils9.isPlainObject)(currentRoot) ? currentRoot : {};
|
|
907
939
|
const nextRoot = cloneConfigValue(baseRoot);
|
|
908
|
-
(0, import_utils9.set)(nextRoot, nestedPath,
|
|
909
|
-
(0, import_utils9.set)(this.currentOptions, [rootKey], nextRoot);
|
|
940
|
+
(0, import_utils9.set)(nextRoot, nestedPath, cloneForRead(value));
|
|
941
|
+
(0, import_utils9.set)(this.currentOptions, [rootKey], freezeConfigValue(nextRoot));
|
|
910
942
|
}
|
|
911
943
|
fetch() {
|
|
912
|
-
const cloned =
|
|
944
|
+
const cloned = cloneForRead(this.currentOptions);
|
|
913
945
|
for (const key of this.preserveKeys) {
|
|
914
946
|
if (key in this.currentOptions) {
|
|
915
947
|
cloned[key] = this.currentOptions[key];
|
|
@@ -918,20 +950,20 @@ var OptionsManager = class {
|
|
|
918
950
|
return freezeConfigValue(cloned);
|
|
919
951
|
}
|
|
920
952
|
assign(options) {
|
|
921
|
-
const cloned =
|
|
953
|
+
const cloned = cloneForRead(options);
|
|
922
954
|
for (const key of this.preserveKeys) {
|
|
923
955
|
if (key in options) {
|
|
924
956
|
cloned[key] = options[key];
|
|
925
957
|
}
|
|
926
958
|
}
|
|
927
|
-
(0, import_utils9.assign)(this.currentOptions, cloned);
|
|
959
|
+
(0, import_utils9.assign)(this.currentOptions, freezeConfigValue(cloned));
|
|
928
960
|
}
|
|
929
961
|
onchange(key, func) {
|
|
930
962
|
(0, import_utils9.set)(this.listeners, key, func);
|
|
931
963
|
return this;
|
|
932
964
|
}
|
|
933
965
|
snapshot() {
|
|
934
|
-
const cloned =
|
|
966
|
+
const cloned = cloneForRead(this.currentOptions);
|
|
935
967
|
for (const key of this.preserveKeys) {
|
|
936
968
|
if (key in this.currentOptions) {
|
|
937
969
|
cloned[key] = this.currentOptions[key];
|
|
@@ -947,13 +979,13 @@ var OptionsManager = class {
|
|
|
947
979
|
delete current[key];
|
|
948
980
|
}
|
|
949
981
|
}
|
|
950
|
-
const cloned =
|
|
982
|
+
const cloned = cloneForRead(snap);
|
|
951
983
|
for (const key of this.preserveKeys) {
|
|
952
984
|
if (key in snap) {
|
|
953
985
|
cloned[key] = snap[key];
|
|
954
986
|
}
|
|
955
987
|
}
|
|
956
|
-
(0, import_utils9.assign)(current, cloned);
|
|
988
|
+
(0, import_utils9.assign)(current, freezeConfigValue(cloned));
|
|
957
989
|
}
|
|
958
990
|
};
|
|
959
991
|
|
|
@@ -1423,8 +1455,7 @@ var AccessRuntime = class {
|
|
|
1423
1455
|
}
|
|
1424
1456
|
setDataOptions(dataName, options) {
|
|
1425
1457
|
const manager = this.getOrCreateDataOptions(dataName);
|
|
1426
|
-
|
|
1427
|
-
manager.assign({ ...currentDataOptions, ...options });
|
|
1458
|
+
manager.assign(options);
|
|
1428
1459
|
}
|
|
1429
1460
|
setDataOption(dataName, key, value) {
|
|
1430
1461
|
const manager = this.getOrCreateDataOptions(dataName);
|
|
@@ -1434,6 +1465,11 @@ var AccessRuntime = class {
|
|
|
1434
1465
|
const manager = this.getOrCreateDataOptions(dataName);
|
|
1435
1466
|
return manager.fetch();
|
|
1436
1467
|
}
|
|
1468
|
+
getDataSnapshot(dataName) {
|
|
1469
|
+
const manager = this.getOrCreateDataOptions(dataName);
|
|
1470
|
+
const snapshot = manager.get("data");
|
|
1471
|
+
return snapshot ?? [];
|
|
1472
|
+
}
|
|
1437
1473
|
getDataOption(dataName, key, defaultValue) {
|
|
1438
1474
|
const manager = this.getOrCreateDataOptions(dataName);
|
|
1439
1475
|
return getNestedOption(manager, key, defaultValue);
|
|
@@ -1555,6 +1591,9 @@ var getRuntime4 = () => getActiveRuntime() ?? defaultRuntime;
|
|
|
1555
1591
|
var getDataOptions = (dataName) => {
|
|
1556
1592
|
return getRuntime4().getDataOptions(dataName);
|
|
1557
1593
|
};
|
|
1594
|
+
var getDataSnapshot = (dataName) => {
|
|
1595
|
+
return getRuntime4().getDataSnapshot(dataName);
|
|
1596
|
+
};
|
|
1558
1597
|
var getDataOption = (dataName, key, defaultValue) => {
|
|
1559
1598
|
return getRuntime4().getDataOption(dataName, key, defaultValue);
|
|
1560
1599
|
};
|
|
@@ -1564,9 +1603,6 @@ var getRuntime5 = () => getActiveRuntime() ?? defaultRuntime;
|
|
|
1564
1603
|
var getModelRef = (modelName, refPath) => {
|
|
1565
1604
|
return getRuntime5().getModelRef(modelName, refPath);
|
|
1566
1605
|
};
|
|
1567
|
-
var getModelSub = (modelName) => {
|
|
1568
|
-
return getRuntime5().getModelSub(modelName);
|
|
1569
|
-
};
|
|
1570
1606
|
|
|
1571
1607
|
// src/services/base.ts
|
|
1572
1608
|
var import_utils12 = require("@web-ts-toolkit/utils");
|
|
@@ -3474,7 +3510,7 @@ var DataService = class {
|
|
|
3474
3510
|
this.req = req;
|
|
3475
3511
|
this.dataName = dataName;
|
|
3476
3512
|
this.options = getDataOptions(dataName);
|
|
3477
|
-
this.data =
|
|
3513
|
+
this.data = getDataSnapshot(dataName);
|
|
3478
3514
|
}
|
|
3479
3515
|
async findOne(filter2, args, options) {
|
|
3480
3516
|
const filterErrors = validateClientFilter(filter2);
|
|
@@ -3655,8 +3691,11 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
3655
3691
|
if (!(0, import_utils17.isPlainObject)(target)) return ret;
|
|
3656
3692
|
const targetObject = target;
|
|
3657
3693
|
const next = targetObject[seg];
|
|
3658
|
-
if ((0, import_utils17.isArray)(next))
|
|
3659
|
-
|
|
3694
|
+
if ((0, import_utils17.isArray)(next)) {
|
|
3695
|
+
for (const item of next) {
|
|
3696
|
+
ret.push(item);
|
|
3697
|
+
}
|
|
3698
|
+
} else if (next !== null && next !== void 0) ret.push(next);
|
|
3660
3699
|
return ret;
|
|
3661
3700
|
}, []);
|
|
3662
3701
|
}
|
|
@@ -3831,11 +3870,12 @@ async function resolveAccessFilter({
|
|
|
3831
3870
|
}) {
|
|
3832
3871
|
let nextFilter = normalizeFilter(filter2);
|
|
3833
3872
|
const overrideFilterFn = getOption(`overrideFilter.${access}`, null);
|
|
3834
|
-
if ((0, import_utils19.isFunction)(overrideFilterFn)) {
|
|
3873
|
+
if (nextFilter !== false && (0, import_utils19.isFunction)(overrideFilterFn)) {
|
|
3835
3874
|
nextFilter = normalizeFilter(await overrideFilterFn.call(req, nextFilter, permissions));
|
|
3836
3875
|
}
|
|
3876
|
+
if (nextFilter === false) return false;
|
|
3837
3877
|
const baseFilterFn = getOption(`baseFilter.${access}`, null);
|
|
3838
|
-
if (!(0, import_utils19.isFunction)(baseFilterFn)) return nextFilter
|
|
3878
|
+
if (!(0, import_utils19.isFunction)(baseFilterFn)) return nextFilter ?? {};
|
|
3839
3879
|
const baseFilter = normalizeFilter(
|
|
3840
3880
|
cache.has(cacheKey) ? cache.get(cacheKey) : await baseFilterFn.call(req, permissions)
|
|
3841
3881
|
);
|
|
@@ -3843,7 +3883,7 @@ async function resolveAccessFilter({
|
|
|
3843
3883
|
cache.set(cacheKey, baseFilter);
|
|
3844
3884
|
}
|
|
3845
3885
|
if (baseFilter === false) return false;
|
|
3846
|
-
if (!baseFilter) return nextFilter
|
|
3886
|
+
if (!baseFilter) return nextFilter ?? {};
|
|
3847
3887
|
if (!nextFilter) return baseFilter;
|
|
3848
3888
|
return optimizeAndFilter([baseFilter, nextFilter]);
|
|
3849
3889
|
}
|
|
@@ -3851,15 +3891,30 @@ function getRequestPermissions(req) {
|
|
|
3851
3891
|
const requestPermissionField = getGlobalOption("requestPermissionField");
|
|
3852
3892
|
return new permission_default(req[requestPermissionField] || {});
|
|
3853
3893
|
}
|
|
3894
|
+
var permissionFieldOwners = /* @__PURE__ */ new WeakMap();
|
|
3895
|
+
function getPermissionFieldOwnerMap(req) {
|
|
3896
|
+
let owners = permissionFieldOwners.get(req);
|
|
3897
|
+
if (!owners) {
|
|
3898
|
+
owners = /* @__PURE__ */ new Map();
|
|
3899
|
+
permissionFieldOwners.set(req, owners);
|
|
3900
|
+
}
|
|
3901
|
+
return owners;
|
|
3902
|
+
}
|
|
3854
3903
|
async function setRequestPermissions(req) {
|
|
3855
3904
|
const requestPermissionField = getGlobalOption("requestPermissionField");
|
|
3856
|
-
|
|
3905
|
+
const activeRuntime = getActiveRuntime();
|
|
3906
|
+
const owners = getPermissionFieldOwnerMap(req);
|
|
3907
|
+
const owner = owners.get(requestPermissionField);
|
|
3908
|
+
const hasFieldValue = Boolean(req[requestPermissionField]);
|
|
3909
|
+
if (owner === activeRuntime) return;
|
|
3910
|
+
if (hasFieldValue && owner === void 0) return;
|
|
3857
3911
|
const globalPermissions = getGlobalOption("globalPermissions");
|
|
3858
3912
|
if (!(0, import_utils19.isFunction)(globalPermissions)) return;
|
|
3859
3913
|
const permissions = await globalPermissions.call(req, req);
|
|
3860
3914
|
if ((0, import_utils19.isPlainObject)(permissions)) req[requestPermissionField] = permissions;
|
|
3861
3915
|
else if ((0, import_utils19.isArray)(permissions)) req[requestPermissionField] = (0, import_utils19.arrayToRecord)(permissions);
|
|
3862
3916
|
else if ((0, import_utils19.isString)(permissions)) req[requestPermissionField] = { [permissions]: true };
|
|
3917
|
+
owners.set(requestPermissionField, activeRuntime);
|
|
3863
3918
|
}
|
|
3864
3919
|
async function evaluateRouteGuard(req, permissions, routeGuard) {
|
|
3865
3920
|
const phas = (key) => permissions.has(key);
|
|
@@ -3927,17 +3982,14 @@ function getResolvedRequestPermissions(req) {
|
|
|
3927
3982
|
async function setResolvedRequestPermissions(req) {
|
|
3928
3983
|
await setRequestPermissions(req);
|
|
3929
3984
|
}
|
|
3930
|
-
async function canActivateRequest(req, routeGuard) {
|
|
3931
|
-
const permissions = getGlobalPermissions(req);
|
|
3932
|
-
return evaluateRouteGuard(req, permissions, routeGuard);
|
|
3933
|
-
}
|
|
3934
3985
|
async function initializeAclRequest({
|
|
3935
3986
|
req,
|
|
3936
3987
|
flag,
|
|
3988
|
+
runtime,
|
|
3937
3989
|
createCore,
|
|
3938
3990
|
assignCore
|
|
3939
3991
|
}) {
|
|
3940
|
-
if (req[flag]) {
|
|
3992
|
+
if (req[flag] === runtime) {
|
|
3941
3993
|
return null;
|
|
3942
3994
|
}
|
|
3943
3995
|
const core = createCore(req);
|
|
@@ -3945,7 +3997,7 @@ async function initializeAclRequest({
|
|
|
3945
3997
|
assignCore(core);
|
|
3946
3998
|
req[PERMISSIONS] = core.getPermissions();
|
|
3947
3999
|
req[PERMISSION_KEYS] = [...req[PERMISSIONS].keys];
|
|
3948
|
-
req[flag] =
|
|
4000
|
+
req[flag] = runtime;
|
|
3949
4001
|
return core;
|
|
3950
4002
|
}
|
|
3951
4003
|
|
|
@@ -4081,6 +4133,7 @@ async function resolveSelectForRequest({
|
|
|
4081
4133
|
// src/core.ts
|
|
4082
4134
|
var Core = class {
|
|
4083
4135
|
constructor(req) {
|
|
4136
|
+
this.cachedPermissions = null;
|
|
4084
4137
|
this.req = req;
|
|
4085
4138
|
this.caches = {
|
|
4086
4139
|
baseFilter: new Cache()
|
|
@@ -4364,13 +4417,15 @@ var Core = class {
|
|
|
4364
4417
|
return docObject;
|
|
4365
4418
|
}
|
|
4366
4419
|
getPermissions() {
|
|
4420
|
+
if (this.cachedPermissions) return this.cachedPermissions;
|
|
4367
4421
|
return getResolvedRequestPermissions(this.req);
|
|
4368
4422
|
}
|
|
4369
4423
|
async setPermissions() {
|
|
4370
4424
|
await setResolvedRequestPermissions(this.req);
|
|
4425
|
+
this.cachedPermissions = getResolvedRequestPermissions(this.req);
|
|
4371
4426
|
}
|
|
4372
4427
|
async canActivate(routeGuard) {
|
|
4373
|
-
return
|
|
4428
|
+
return evaluateRouteGuard(this.req, this.getGlobalPermissions(), routeGuard);
|
|
4374
4429
|
}
|
|
4375
4430
|
async isAllowed(modelName, access) {
|
|
4376
4431
|
if (access.startsWith("subs")) {
|
|
@@ -4406,6 +4461,7 @@ var Core = class {
|
|
|
4406
4461
|
return this.getPublicService(modelName);
|
|
4407
4462
|
}
|
|
4408
4463
|
getGlobalPermissions() {
|
|
4464
|
+
if (this.cachedPermissions) return this.cachedPermissions;
|
|
4409
4465
|
return getGlobalPermissions(this.req);
|
|
4410
4466
|
}
|
|
4411
4467
|
};
|
|
@@ -4415,6 +4471,7 @@ var createSetCore = (runtime = defaultRuntime) => {
|
|
|
4415
4471
|
await initializeAclRequest({
|
|
4416
4472
|
req,
|
|
4417
4473
|
flag: MIDDLEWARE,
|
|
4474
|
+
runtime,
|
|
4418
4475
|
createCore: (request) => new Core(request),
|
|
4419
4476
|
assignCore: (core) => {
|
|
4420
4477
|
req.macl = core;
|
|
@@ -4795,8 +4852,9 @@ function defineRequestSchema(validator, options = {}) {
|
|
|
4795
4852
|
};
|
|
4796
4853
|
}
|
|
4797
4854
|
function fromZod(schema) {
|
|
4798
|
-
return (value) => {
|
|
4799
|
-
const
|
|
4855
|
+
return async (value) => {
|
|
4856
|
+
const candidate = schema;
|
|
4857
|
+
const result = typeof candidate.safeParseAsync === "function" ? await candidate.safeParseAsync.call(schema, value) : schema.safeParse(value);
|
|
4800
4858
|
if (result.success) {
|
|
4801
4859
|
return {
|
|
4802
4860
|
success: true,
|
|
@@ -4833,6 +4891,9 @@ function fromYup(schema) {
|
|
|
4833
4891
|
data
|
|
4834
4892
|
};
|
|
4835
4893
|
} catch (error2) {
|
|
4894
|
+
if (!isYupValidationError(error2)) {
|
|
4895
|
+
throw error2;
|
|
4896
|
+
}
|
|
4836
4897
|
return {
|
|
4837
4898
|
success: false,
|
|
4838
4899
|
issues: normalizeYupIssues(error2)
|
|
@@ -4857,8 +4918,32 @@ function fromJoi(schema) {
|
|
|
4857
4918
|
}
|
|
4858
4919
|
function fromAjv(validator) {
|
|
4859
4920
|
return async (value) => {
|
|
4860
|
-
const
|
|
4861
|
-
if (
|
|
4921
|
+
const outcome = validator(value);
|
|
4922
|
+
if (isThenable(outcome)) {
|
|
4923
|
+
try {
|
|
4924
|
+
const data = await outcome;
|
|
4925
|
+
if (data === false) {
|
|
4926
|
+
return {
|
|
4927
|
+
success: false,
|
|
4928
|
+
issues: normalizeAjvIssues(validator.errors ?? [])
|
|
4929
|
+
};
|
|
4930
|
+
}
|
|
4931
|
+
return {
|
|
4932
|
+
success: true,
|
|
4933
|
+
data: data === true ? value : data
|
|
4934
|
+
};
|
|
4935
|
+
} catch (error2) {
|
|
4936
|
+
if (!isAjvValidationError(error2)) {
|
|
4937
|
+
throw error2;
|
|
4938
|
+
}
|
|
4939
|
+
return {
|
|
4940
|
+
success: false,
|
|
4941
|
+
issues: normalizeAjvIssues(error2.errors ?? [])
|
|
4942
|
+
};
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
const errorsSnapshot = validator.errors ? [...validator.errors] : [];
|
|
4946
|
+
if (outcome) {
|
|
4862
4947
|
return {
|
|
4863
4948
|
success: true,
|
|
4864
4949
|
data: value
|
|
@@ -4866,7 +4951,7 @@ function fromAjv(validator) {
|
|
|
4866
4951
|
}
|
|
4867
4952
|
return {
|
|
4868
4953
|
success: false,
|
|
4869
|
-
issues: normalizeAjvIssues(
|
|
4954
|
+
issues: normalizeAjvIssues(errorsSnapshot)
|
|
4870
4955
|
};
|
|
4871
4956
|
};
|
|
4872
4957
|
}
|
|
@@ -4887,6 +4972,25 @@ function fromValibot(schema, safeParse) {
|
|
|
4887
4972
|
}
|
|
4888
4973
|
function fromArkType(type) {
|
|
4889
4974
|
return async (value) => {
|
|
4975
|
+
if (isStandardSchema(type)) {
|
|
4976
|
+
const result2 = await type["~standard"].validate(value);
|
|
4977
|
+
if (isArkTypeErrors(result2)) {
|
|
4978
|
+
return {
|
|
4979
|
+
success: false,
|
|
4980
|
+
issues: normalizeArkTypeIssues(result2)
|
|
4981
|
+
};
|
|
4982
|
+
}
|
|
4983
|
+
if (isStandardSchemaFailure(result2)) {
|
|
4984
|
+
return {
|
|
4985
|
+
success: false,
|
|
4986
|
+
issues: normalizeArkTypeStandardIssues(result2.issues)
|
|
4987
|
+
};
|
|
4988
|
+
}
|
|
4989
|
+
return {
|
|
4990
|
+
success: true,
|
|
4991
|
+
data: result2.value
|
|
4992
|
+
};
|
|
4993
|
+
}
|
|
4890
4994
|
const result = await type(value);
|
|
4891
4995
|
if (!isArkTypeErrors(result)) {
|
|
4892
4996
|
return {
|
|
@@ -4939,6 +5043,9 @@ function fromVine(validator) {
|
|
|
4939
5043
|
data: output
|
|
4940
5044
|
};
|
|
4941
5045
|
} catch (error2) {
|
|
5046
|
+
if (!isVineValidationError(error2)) {
|
|
5047
|
+
throw error2;
|
|
5048
|
+
}
|
|
4942
5049
|
return {
|
|
4943
5050
|
success: false,
|
|
4944
5051
|
issues: normalizeVineError(error2)
|
|
@@ -4999,6 +5106,13 @@ function normalizeArkTypeIssues(issues) {
|
|
|
4999
5106
|
}));
|
|
5000
5107
|
return normalized.length ? normalized : [{ message: issues.summary ?? "Validation failed" }];
|
|
5001
5108
|
}
|
|
5109
|
+
function normalizeArkTypeStandardIssues(issues) {
|
|
5110
|
+
const normalized = issues.map((issue) => ({
|
|
5111
|
+
message: issue.message ?? issue.problem ?? "Validation failed",
|
|
5112
|
+
path: issue.path?.flatMap((segment) => normalizePathSegment(segment))
|
|
5113
|
+
}));
|
|
5114
|
+
return normalized.length ? normalized : [{ message: "Validation failed" }];
|
|
5115
|
+
}
|
|
5002
5116
|
function normalizeIoTsIssues(issues) {
|
|
5003
5117
|
return issues.map((issue) => ({
|
|
5004
5118
|
message: issue.message ?? "Validation failed",
|
|
@@ -5033,25 +5147,64 @@ function normalizeVineField(message) {
|
|
|
5033
5147
|
}
|
|
5034
5148
|
return path.length ? path : void 0;
|
|
5035
5149
|
}
|
|
5150
|
+
function decodeAjvSegment(segment) {
|
|
5151
|
+
return segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
5152
|
+
}
|
|
5153
|
+
function encodePointerSegment(segment) {
|
|
5154
|
+
return encodeURIComponent(segment.replace(/~/g, "~0").replace(/\//g, "~1"));
|
|
5155
|
+
}
|
|
5036
5156
|
function parseAjvPath(issue) {
|
|
5037
|
-
const
|
|
5038
|
-
|
|
5039
|
-
|
|
5157
|
+
const raw = issue.instancePath;
|
|
5158
|
+
const base = raw == null || raw === "" ? [] : (raw.startsWith("/") ? raw.slice(1) : raw).split("/").map(decodeAjvSegment);
|
|
5159
|
+
const missing = issue.params?.missingProperty;
|
|
5160
|
+
if (typeof missing === "string") {
|
|
5161
|
+
return [...base, missing];
|
|
5040
5162
|
}
|
|
5041
|
-
return
|
|
5163
|
+
return base;
|
|
5042
5164
|
}
|
|
5043
5165
|
function parsePathString(path) {
|
|
5044
5166
|
if (!path) return void 0;
|
|
5045
5167
|
return path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
|
|
5046
5168
|
}
|
|
5047
5169
|
function isYupValidationError(error2) {
|
|
5048
|
-
|
|
5170
|
+
if (typeof error2 !== "object" || error2 === null || !("message" in error2)) {
|
|
5171
|
+
return false;
|
|
5172
|
+
}
|
|
5173
|
+
const candidate = error2;
|
|
5174
|
+
return candidate.name === "ValidationError" && typeof candidate.message === "string" && Array.isArray(candidate.errors) && Array.isArray(candidate.inner);
|
|
5049
5175
|
}
|
|
5050
5176
|
function isArkTypeErrors(value) {
|
|
5051
|
-
|
|
5177
|
+
if (typeof value !== "object" || value === null) {
|
|
5178
|
+
return false;
|
|
5179
|
+
}
|
|
5180
|
+
const record = value;
|
|
5181
|
+
return record.arkKind === "errors" || record[" arkKind"] === "errors";
|
|
5182
|
+
}
|
|
5183
|
+
function isThenable(value) {
|
|
5184
|
+
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
5185
|
+
}
|
|
5186
|
+
function isAjvValidationError(error2) {
|
|
5187
|
+
if (typeof error2 !== "object" || error2 === null || !("errors" in error2)) {
|
|
5188
|
+
return false;
|
|
5189
|
+
}
|
|
5190
|
+
const errors = error2.errors;
|
|
5191
|
+
return errors == null || Array.isArray(errors);
|
|
5052
5192
|
}
|
|
5053
5193
|
function isVineValidationError(error2) {
|
|
5054
|
-
|
|
5194
|
+
if (typeof error2 !== "object" || error2 === null || !("messages" in error2)) {
|
|
5195
|
+
return false;
|
|
5196
|
+
}
|
|
5197
|
+
const candidate = error2;
|
|
5198
|
+
if (!Array.isArray(candidate.messages) || candidate.messages.length === 0) {
|
|
5199
|
+
return false;
|
|
5200
|
+
}
|
|
5201
|
+
const hasDiscriminator = candidate.code === "E_VALIDATION_ERROR" || candidate.name === "ValidationError";
|
|
5202
|
+
if (!hasDiscriminator) {
|
|
5203
|
+
return false;
|
|
5204
|
+
}
|
|
5205
|
+
return candidate.messages.every(
|
|
5206
|
+
(message) => typeof message === "object" && message !== null && typeof message.message === "string" && typeof message.field === "string"
|
|
5207
|
+
);
|
|
5055
5208
|
}
|
|
5056
5209
|
function formatIssue(issue, key, location = "pointer") {
|
|
5057
5210
|
const path = (issue.path ?? []).map(String);
|
|
@@ -5068,7 +5221,7 @@ function formatIssue(issue, key, location = "pointer") {
|
|
|
5068
5221
|
};
|
|
5069
5222
|
}
|
|
5070
5223
|
function buildPointer(path) {
|
|
5071
|
-
return path.length === 0 ? "#" : `#/${path.join("/")}`;
|
|
5224
|
+
return path.length === 0 ? "#" : `#/${path.map(encodePointerSegment).join("/")}`;
|
|
5072
5225
|
}
|
|
5073
5226
|
|
|
5074
5227
|
// src/validation/model-router.ts
|
|
@@ -5569,24 +5722,26 @@ function setModelCollectionRoutes(context) {
|
|
|
5569
5722
|
router.post(`/${options.mutationRouteSegment}`, async (req) => {
|
|
5570
5723
|
await context.assertAllowed(req, "create");
|
|
5571
5724
|
const { include_permissions } = parseQuery(requestSchemas.createQuery, req.query);
|
|
5572
|
-
const
|
|
5725
|
+
const intermediateBody = await parseNestedBodyWithSchema(
|
|
5573
5726
|
advancedCreateBodySchema,
|
|
5574
5727
|
req.body,
|
|
5575
5728
|
"data",
|
|
5576
5729
|
context.getRequestSchema("requestSchemas.advancedCreate.data")
|
|
5577
5730
|
);
|
|
5578
|
-
const { data, select, populate, tasks } =
|
|
5579
|
-
const
|
|
5580
|
-
await parseBodyWithSchema(
|
|
5731
|
+
const { data: nestedData, select: nestedSelect, populate: nestedPopulate, tasks: nestedTasks } = intermediateBody;
|
|
5732
|
+
const nestedOptions = intermediateBody.options ?? {};
|
|
5733
|
+
const finalBody = await parseBodyWithSchema(
|
|
5581
5734
|
advancedCreateBodySchema,
|
|
5582
|
-
{ data, select, populate, tasks, options:
|
|
5735
|
+
{ data: nestedData, select: nestedSelect, populate: nestedPopulate, tasks: nestedTasks, options: nestedOptions },
|
|
5583
5736
|
context.getRequestSchema("requestSchemas.advancedCreate.default") ?? context.getRequestSchema("requestSchemas.advancedCreate")
|
|
5584
5737
|
);
|
|
5585
|
-
const {
|
|
5738
|
+
const { data: finalData, select: finalSelect, populate: finalPopulate, tasks: finalTasks } = finalBody;
|
|
5739
|
+
const finalOptions = finalBody.options ?? {};
|
|
5740
|
+
const { includePermissions, populateAccess } = finalOptions;
|
|
5586
5741
|
const svc = context.getPublicService(req);
|
|
5587
5742
|
const result = await svc._create(
|
|
5588
|
-
|
|
5589
|
-
{ select, populate, tasks },
|
|
5743
|
+
finalData,
|
|
5744
|
+
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
5590
5745
|
{
|
|
5591
5746
|
includePermissions: includePermissions ?? (0, import_utils23.parseBooleanString)(include_permissions),
|
|
5592
5747
|
populateAccess
|
|
@@ -5785,25 +5940,33 @@ function setModelDocumentRoutes(context) {
|
|
|
5785
5940
|
await context.assertAllowed(req, "update");
|
|
5786
5941
|
const id = parsePathParam(req.params[options.idParam], options.idParam);
|
|
5787
5942
|
const { returning_all, include_permissions } = parseQuery(requestSchemas.updateQuery, req.query);
|
|
5788
|
-
const
|
|
5943
|
+
const intermediateBody = await parseNestedBodyWithSchema(
|
|
5789
5944
|
advancedUpdateBodySchema,
|
|
5790
5945
|
req.body,
|
|
5791
5946
|
"data",
|
|
5792
5947
|
context.getRequestSchema("requestSchemas.advancedUpdate.data")
|
|
5793
5948
|
);
|
|
5794
|
-
const { data, select, populate, tasks } =
|
|
5795
|
-
const
|
|
5796
|
-
await parseBodyWithSchema(
|
|
5949
|
+
const { data: nestedData, select: nestedSelect, populate: nestedPopulate, tasks: nestedTasks } = intermediateBody;
|
|
5950
|
+
const nestedOptions = intermediateBody.options ?? {};
|
|
5951
|
+
const finalBody = await parseBodyWithSchema(
|
|
5797
5952
|
advancedUpdateBodySchema,
|
|
5798
|
-
{
|
|
5953
|
+
{
|
|
5954
|
+
data: nestedData,
|
|
5955
|
+
select: nestedSelect,
|
|
5956
|
+
populate: nestedPopulate,
|
|
5957
|
+
tasks: nestedTasks,
|
|
5958
|
+
options: nestedOptions
|
|
5959
|
+
},
|
|
5799
5960
|
context.getRequestSchema("requestSchemas.advancedUpdate.default") ?? context.getRequestSchema("requestSchemas.advancedUpdate")
|
|
5800
5961
|
);
|
|
5801
|
-
const {
|
|
5962
|
+
const { data: finalData, select: finalSelect, populate: finalPopulate, tasks: finalTasks } = finalBody;
|
|
5963
|
+
const finalOptions = finalBody.options ?? {};
|
|
5964
|
+
const { returningAll, includePermissions, populateAccess } = finalOptions;
|
|
5802
5965
|
const svc = context.getPublicService(req);
|
|
5803
5966
|
const result = await svc._update(
|
|
5804
5967
|
id,
|
|
5805
|
-
|
|
5806
|
-
{ select, populate, tasks },
|
|
5968
|
+
finalData,
|
|
5969
|
+
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
5807
5970
|
{
|
|
5808
5971
|
returningAll: returningAll ?? (0, import_utils23.parseBooleanString)(returning_all),
|
|
5809
5972
|
includePermissions: includePermissions ?? (0, import_utils23.parseBooleanString)(include_permissions),
|
|
@@ -5853,23 +6016,31 @@ function setModelDocumentRoutes(context) {
|
|
|
5853
6016
|
await context.assertAllowed(req, "upsert");
|
|
5854
6017
|
const svc = context.getPublicService(req);
|
|
5855
6018
|
const { returning_all, include_permissions } = parseQuery(requestSchemas.upsertQuery, req.query);
|
|
5856
|
-
const
|
|
6019
|
+
const intermediateBody = await parseNestedBodyWithSchema(
|
|
5857
6020
|
advancedUpsertBodySchema,
|
|
5858
6021
|
req.body,
|
|
5859
6022
|
"data",
|
|
5860
6023
|
context.getRequestSchema("requestSchemas.advancedUpsert.data")
|
|
5861
6024
|
);
|
|
5862
|
-
const { data, select, populate, tasks } =
|
|
5863
|
-
const
|
|
5864
|
-
await parseBodyWithSchema(
|
|
6025
|
+
const { data: nestedData, select: nestedSelect, populate: nestedPopulate, tasks: nestedTasks } = intermediateBody;
|
|
6026
|
+
const nestedOptions = intermediateBody.options ?? {};
|
|
6027
|
+
const finalBody = await parseBodyWithSchema(
|
|
5865
6028
|
advancedUpsertBodySchema,
|
|
5866
|
-
{
|
|
6029
|
+
{
|
|
6030
|
+
data: nestedData,
|
|
6031
|
+
select: nestedSelect,
|
|
6032
|
+
populate: nestedPopulate,
|
|
6033
|
+
tasks: nestedTasks,
|
|
6034
|
+
options: nestedOptions
|
|
6035
|
+
},
|
|
5867
6036
|
context.getRequestSchema("requestSchemas.advancedUpsert.default") ?? context.getRequestSchema("requestSchemas.advancedUpsert")
|
|
5868
6037
|
);
|
|
5869
|
-
const {
|
|
6038
|
+
const { data: finalData, select: finalSelect, populate: finalPopulate, tasks: finalTasks } = finalBody;
|
|
6039
|
+
const finalOptions = finalBody.options ?? {};
|
|
6040
|
+
const { returningAll, includePermissions, populateAccess } = finalOptions;
|
|
5870
6041
|
const result = await svc._upsert(
|
|
5871
|
-
|
|
5872
|
-
{ select, populate, tasks },
|
|
6042
|
+
finalData,
|
|
6043
|
+
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
5873
6044
|
{
|
|
5874
6045
|
returningAll: returningAll ?? (0, import_utils23.parseBooleanString)(returning_all),
|
|
5875
6046
|
includePermissions: includePermissions ?? (0, import_utils23.parseBooleanString)(include_permissions),
|
|
@@ -5939,7 +6110,7 @@ function setModelDocumentRoutes(context) {
|
|
|
5939
6110
|
|
|
5940
6111
|
// src/routers/model-router-subdocument-routes.ts
|
|
5941
6112
|
function setModelSubDocumentRoutes(context) {
|
|
5942
|
-
const subs = getModelSub(context.modelName);
|
|
6113
|
+
const subs = context.runtime.getModelSub(context.modelName);
|
|
5943
6114
|
for (let x = 0; x < subs.length; x++) {
|
|
5944
6115
|
const sub = subs[x];
|
|
5945
6116
|
context.router.get(`/:${context.options.idParam}/${sub}`, async (req) => {
|
|
@@ -6164,7 +6335,9 @@ var ModelRouter = class _ModelRouter {
|
|
|
6164
6335
|
"baseFilter"
|
|
6165
6336
|
);
|
|
6166
6337
|
/**
|
|
6167
|
-
*
|
|
6338
|
+
* Trusted filter replacements applied before base-filter composition.
|
|
6339
|
+
* They may replace ordinary filters, but cannot replace an existing `false` denial.
|
|
6340
|
+
* Returning `false` denies the transaction.
|
|
6168
6341
|
* @operation `list`, `read`, `update`, `delete`
|
|
6169
6342
|
*/
|
|
6170
6343
|
this.overrideFilter = setOption.bind(this, "overrideFilter");
|
|
@@ -6324,6 +6497,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
6324
6497
|
modelName: this.modelName,
|
|
6325
6498
|
router: this.router,
|
|
6326
6499
|
options: this.options,
|
|
6500
|
+
runtime: this.runtime,
|
|
6327
6501
|
getRequestSchema: this.getRequestSchema.bind(this),
|
|
6328
6502
|
getPublicService: this.getPublicService.bind(this),
|
|
6329
6503
|
assertAllowed: this.assertAllowed.bind(this),
|
|
@@ -6338,6 +6512,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
6338
6512
|
modelName: this.modelName,
|
|
6339
6513
|
router: this.router,
|
|
6340
6514
|
options: this.options,
|
|
6515
|
+
runtime: this.runtime,
|
|
6341
6516
|
getRequestSchema: this.getRequestSchema.bind(this),
|
|
6342
6517
|
getPublicService: this.getPublicService.bind(this),
|
|
6343
6518
|
assertAllowed: this.assertAllowed.bind(this),
|
|
@@ -6352,6 +6527,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
6352
6527
|
modelName: this.modelName,
|
|
6353
6528
|
router: this.router,
|
|
6354
6529
|
options: this.options,
|
|
6530
|
+
runtime: this.runtime,
|
|
6355
6531
|
getRequestSchema: this.getRequestSchema.bind(this),
|
|
6356
6532
|
getPublicService: this.getPublicService.bind(this),
|
|
6357
6533
|
assertAllowed: this.assertAllowed.bind(this),
|
|
@@ -6402,6 +6578,7 @@ var import_utils26 = require("@web-ts-toolkit/utils");
|
|
|
6402
6578
|
// src/core-data.ts
|
|
6403
6579
|
var DataCore = class {
|
|
6404
6580
|
constructor(req) {
|
|
6581
|
+
this.cachedPermissions = null;
|
|
6405
6582
|
this.req = req;
|
|
6406
6583
|
this.caches = {
|
|
6407
6584
|
baseFilter: new Cache()
|
|
@@ -6495,13 +6672,15 @@ var DataCore = class {
|
|
|
6495
6672
|
});
|
|
6496
6673
|
}
|
|
6497
6674
|
getPermissions() {
|
|
6675
|
+
if (this.cachedPermissions) return this.cachedPermissions;
|
|
6498
6676
|
return getResolvedRequestPermissions(this.req);
|
|
6499
6677
|
}
|
|
6500
6678
|
async setPermissions() {
|
|
6501
6679
|
await setResolvedRequestPermissions(this.req);
|
|
6680
|
+
this.cachedPermissions = getResolvedRequestPermissions(this.req);
|
|
6502
6681
|
}
|
|
6503
6682
|
async canActivate(routeGuard) {
|
|
6504
|
-
return
|
|
6683
|
+
return evaluateRouteGuard(this.req, this.getGlobalPermissions(), routeGuard);
|
|
6505
6684
|
}
|
|
6506
6685
|
async isAllowed(dataName, access) {
|
|
6507
6686
|
const operationAccess = getDataOption(dataName, `operationAccess.${access}`);
|
|
@@ -6517,6 +6696,7 @@ var DataCore = class {
|
|
|
6517
6696
|
return this.getService(dataName);
|
|
6518
6697
|
}
|
|
6519
6698
|
getGlobalPermissions() {
|
|
6699
|
+
if (this.cachedPermissions) return this.cachedPermissions;
|
|
6520
6700
|
return getGlobalPermissions(this.req);
|
|
6521
6701
|
}
|
|
6522
6702
|
};
|
|
@@ -6526,6 +6706,7 @@ var createSetDataCore = (runtime = defaultRuntime) => {
|
|
|
6526
6706
|
await initializeAclRequest({
|
|
6527
6707
|
req,
|
|
6528
6708
|
flag: DATA_MIDDLEWARE,
|
|
6709
|
+
runtime,
|
|
6529
6710
|
createCore: (request) => new DataCore(request),
|
|
6530
6711
|
assignCore: (core) => {
|
|
6531
6712
|
req.dacl = core;
|
|
@@ -6830,6 +7011,11 @@ var DataRouter = class {
|
|
|
6830
7011
|
this,
|
|
6831
7012
|
"baseFilter"
|
|
6832
7013
|
);
|
|
7014
|
+
/**
|
|
7015
|
+
* Trusted filter replacements applied before base-filter composition.
|
|
7016
|
+
* They may replace ordinary filters, but cannot replace an existing `false` denial.
|
|
7017
|
+
* Returning `false` denies the transaction.
|
|
7018
|
+
*/
|
|
6833
7019
|
this.overrideFilter = setOption2.bind(this, "overrideFilter");
|
|
6834
7020
|
this.decorate = setOption2.bind(
|
|
6835
7021
|
this,
|