@web-ts-toolkit/access-router 0.42.2 → 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.mjs
CHANGED
|
@@ -784,6 +784,29 @@ var cloneConfigValue = (value) => {
|
|
|
784
784
|
])
|
|
785
785
|
);
|
|
786
786
|
};
|
|
787
|
+
var cloneForRead = (value) => {
|
|
788
|
+
if (Array.isArray(value)) {
|
|
789
|
+
if (Object.isFrozen(value)) {
|
|
790
|
+
return value;
|
|
791
|
+
}
|
|
792
|
+
return value.map((item) => cloneForRead(item));
|
|
793
|
+
}
|
|
794
|
+
if (!value || typeof value !== "object") {
|
|
795
|
+
return value;
|
|
796
|
+
}
|
|
797
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) {
|
|
798
|
+
return value;
|
|
799
|
+
}
|
|
800
|
+
if (Object.isFrozen(value)) {
|
|
801
|
+
return value;
|
|
802
|
+
}
|
|
803
|
+
return Object.fromEntries(
|
|
804
|
+
Object.entries(value).map(([entryKey, entryValue]) => [
|
|
805
|
+
entryKey,
|
|
806
|
+
cloneForRead(entryValue)
|
|
807
|
+
])
|
|
808
|
+
);
|
|
809
|
+
};
|
|
787
810
|
var freezeConfigValue = (value) => {
|
|
788
811
|
if (!value || typeof value !== "object") {
|
|
789
812
|
return value;
|
|
@@ -799,6 +822,7 @@ var freezeConfigValue = (value) => {
|
|
|
799
822
|
}
|
|
800
823
|
return value;
|
|
801
824
|
};
|
|
825
|
+
var cloneAndFreezeForStore = (value) => freezeConfigValue(cloneForRead(value));
|
|
802
826
|
var getNestedOption = (manager, key, defaultValue) => {
|
|
803
827
|
const keys2 = String(key).split(".");
|
|
804
828
|
if (keys2.length === 1) {
|
|
@@ -828,6 +852,14 @@ var OptionsManager = class {
|
|
|
828
852
|
target[keystr] = value;
|
|
829
853
|
_this.listeners[keystr] && _this.listeners[keystr].call(_this, value, keystr, target, oldvalue);
|
|
830
854
|
return true;
|
|
855
|
+
},
|
|
856
|
+
defineProperty(target, key, descriptor) {
|
|
857
|
+
const keystr = String(key);
|
|
858
|
+
const oldvalue = target[keystr];
|
|
859
|
+
const result = Reflect.defineProperty(target, key, descriptor);
|
|
860
|
+
const newValue = target[keystr];
|
|
861
|
+
_this.listeners[keystr] && _this.listeners[keystr].call(_this, newValue, keystr, target, oldvalue);
|
|
862
|
+
return result;
|
|
831
863
|
}
|
|
832
864
|
});
|
|
833
865
|
}
|
|
@@ -841,18 +873,18 @@ var OptionsManager = class {
|
|
|
841
873
|
set(key, value) {
|
|
842
874
|
const path = toPath(key);
|
|
843
875
|
if (path.length <= 1) {
|
|
844
|
-
set2(this.currentOptions, path, this.preserveKeys.has(String(path[0])) ? value :
|
|
876
|
+
set2(this.currentOptions, path, this.preserveKeys.has(String(path[0])) ? value : cloneAndFreezeForStore(value));
|
|
845
877
|
return;
|
|
846
878
|
}
|
|
847
879
|
const [rootKey, ...nestedPath] = path;
|
|
848
880
|
const currentRoot = get2(this.currentOptions, [rootKey], void 0);
|
|
849
881
|
const baseRoot = isPlainObject8(currentRoot) ? currentRoot : {};
|
|
850
882
|
const nextRoot = cloneConfigValue(baseRoot);
|
|
851
|
-
set2(nextRoot, nestedPath,
|
|
852
|
-
set2(this.currentOptions, [rootKey], nextRoot);
|
|
883
|
+
set2(nextRoot, nestedPath, cloneForRead(value));
|
|
884
|
+
set2(this.currentOptions, [rootKey], freezeConfigValue(nextRoot));
|
|
853
885
|
}
|
|
854
886
|
fetch() {
|
|
855
|
-
const cloned =
|
|
887
|
+
const cloned = cloneForRead(this.currentOptions);
|
|
856
888
|
for (const key of this.preserveKeys) {
|
|
857
889
|
if (key in this.currentOptions) {
|
|
858
890
|
cloned[key] = this.currentOptions[key];
|
|
@@ -861,20 +893,20 @@ var OptionsManager = class {
|
|
|
861
893
|
return freezeConfigValue(cloned);
|
|
862
894
|
}
|
|
863
895
|
assign(options) {
|
|
864
|
-
const cloned =
|
|
896
|
+
const cloned = cloneForRead(options);
|
|
865
897
|
for (const key of this.preserveKeys) {
|
|
866
898
|
if (key in options) {
|
|
867
899
|
cloned[key] = options[key];
|
|
868
900
|
}
|
|
869
901
|
}
|
|
870
|
-
assign(this.currentOptions, cloned);
|
|
902
|
+
assign(this.currentOptions, freezeConfigValue(cloned));
|
|
871
903
|
}
|
|
872
904
|
onchange(key, func) {
|
|
873
905
|
set2(this.listeners, key, func);
|
|
874
906
|
return this;
|
|
875
907
|
}
|
|
876
908
|
snapshot() {
|
|
877
|
-
const cloned =
|
|
909
|
+
const cloned = cloneForRead(this.currentOptions);
|
|
878
910
|
for (const key of this.preserveKeys) {
|
|
879
911
|
if (key in this.currentOptions) {
|
|
880
912
|
cloned[key] = this.currentOptions[key];
|
|
@@ -890,13 +922,13 @@ var OptionsManager = class {
|
|
|
890
922
|
delete current[key];
|
|
891
923
|
}
|
|
892
924
|
}
|
|
893
|
-
const cloned =
|
|
925
|
+
const cloned = cloneForRead(snap);
|
|
894
926
|
for (const key of this.preserveKeys) {
|
|
895
927
|
if (key in snap) {
|
|
896
928
|
cloned[key] = snap[key];
|
|
897
929
|
}
|
|
898
930
|
}
|
|
899
|
-
assign(current, cloned);
|
|
931
|
+
assign(current, freezeConfigValue(cloned));
|
|
900
932
|
}
|
|
901
933
|
};
|
|
902
934
|
|
|
@@ -1366,8 +1398,7 @@ var AccessRuntime = class {
|
|
|
1366
1398
|
}
|
|
1367
1399
|
setDataOptions(dataName, options) {
|
|
1368
1400
|
const manager = this.getOrCreateDataOptions(dataName);
|
|
1369
|
-
|
|
1370
|
-
manager.assign({ ...currentDataOptions, ...options });
|
|
1401
|
+
manager.assign(options);
|
|
1371
1402
|
}
|
|
1372
1403
|
setDataOption(dataName, key, value) {
|
|
1373
1404
|
const manager = this.getOrCreateDataOptions(dataName);
|
|
@@ -1377,6 +1408,11 @@ var AccessRuntime = class {
|
|
|
1377
1408
|
const manager = this.getOrCreateDataOptions(dataName);
|
|
1378
1409
|
return manager.fetch();
|
|
1379
1410
|
}
|
|
1411
|
+
getDataSnapshot(dataName) {
|
|
1412
|
+
const manager = this.getOrCreateDataOptions(dataName);
|
|
1413
|
+
const snapshot = manager.get("data");
|
|
1414
|
+
return snapshot ?? [];
|
|
1415
|
+
}
|
|
1380
1416
|
getDataOption(dataName, key, defaultValue) {
|
|
1381
1417
|
const manager = this.getOrCreateDataOptions(dataName);
|
|
1382
1418
|
return getNestedOption(manager, key, defaultValue);
|
|
@@ -1498,6 +1534,9 @@ var getRuntime4 = () => getActiveRuntime() ?? defaultRuntime;
|
|
|
1498
1534
|
var getDataOptions = (dataName) => {
|
|
1499
1535
|
return getRuntime4().getDataOptions(dataName);
|
|
1500
1536
|
};
|
|
1537
|
+
var getDataSnapshot = (dataName) => {
|
|
1538
|
+
return getRuntime4().getDataSnapshot(dataName);
|
|
1539
|
+
};
|
|
1501
1540
|
var getDataOption = (dataName, key, defaultValue) => {
|
|
1502
1541
|
return getRuntime4().getDataOption(dataName, key, defaultValue);
|
|
1503
1542
|
};
|
|
@@ -1507,9 +1546,6 @@ var getRuntime5 = () => getActiveRuntime() ?? defaultRuntime;
|
|
|
1507
1546
|
var getModelRef = (modelName, refPath) => {
|
|
1508
1547
|
return getRuntime5().getModelRef(modelName, refPath);
|
|
1509
1548
|
};
|
|
1510
|
-
var getModelSub = (modelName) => {
|
|
1511
|
-
return getRuntime5().getModelSub(modelName);
|
|
1512
|
-
};
|
|
1513
1549
|
|
|
1514
1550
|
// src/services/base.ts
|
|
1515
1551
|
import {
|
|
@@ -3436,7 +3472,7 @@ var DataService = class {
|
|
|
3436
3472
|
this.req = req;
|
|
3437
3473
|
this.dataName = dataName;
|
|
3438
3474
|
this.options = getDataOptions(dataName);
|
|
3439
|
-
this.data =
|
|
3475
|
+
this.data = getDataSnapshot(dataName);
|
|
3440
3476
|
}
|
|
3441
3477
|
async findOne(filter2, args, options) {
|
|
3442
3478
|
const filterErrors = validateClientFilter(filter2);
|
|
@@ -3617,8 +3653,11 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
3617
3653
|
if (!isPlainObject13(target)) return ret;
|
|
3618
3654
|
const targetObject = target;
|
|
3619
3655
|
const next = targetObject[seg];
|
|
3620
|
-
if (isArray8(next))
|
|
3621
|
-
|
|
3656
|
+
if (isArray8(next)) {
|
|
3657
|
+
for (const item of next) {
|
|
3658
|
+
ret.push(item);
|
|
3659
|
+
}
|
|
3660
|
+
} else if (next !== null && next !== void 0) ret.push(next);
|
|
3622
3661
|
return ret;
|
|
3623
3662
|
}, []);
|
|
3624
3663
|
}
|
|
@@ -3804,11 +3843,12 @@ async function resolveAccessFilter({
|
|
|
3804
3843
|
}) {
|
|
3805
3844
|
let nextFilter = normalizeFilter(filter2);
|
|
3806
3845
|
const overrideFilterFn = getOption(`overrideFilter.${access}`, null);
|
|
3807
|
-
if (isFunction4(overrideFilterFn)) {
|
|
3846
|
+
if (nextFilter !== false && isFunction4(overrideFilterFn)) {
|
|
3808
3847
|
nextFilter = normalizeFilter(await overrideFilterFn.call(req, nextFilter, permissions));
|
|
3809
3848
|
}
|
|
3849
|
+
if (nextFilter === false) return false;
|
|
3810
3850
|
const baseFilterFn = getOption(`baseFilter.${access}`, null);
|
|
3811
|
-
if (!isFunction4(baseFilterFn)) return nextFilter
|
|
3851
|
+
if (!isFunction4(baseFilterFn)) return nextFilter ?? {};
|
|
3812
3852
|
const baseFilter = normalizeFilter(
|
|
3813
3853
|
cache.has(cacheKey) ? cache.get(cacheKey) : await baseFilterFn.call(req, permissions)
|
|
3814
3854
|
);
|
|
@@ -3816,7 +3856,7 @@ async function resolveAccessFilter({
|
|
|
3816
3856
|
cache.set(cacheKey, baseFilter);
|
|
3817
3857
|
}
|
|
3818
3858
|
if (baseFilter === false) return false;
|
|
3819
|
-
if (!baseFilter) return nextFilter
|
|
3859
|
+
if (!baseFilter) return nextFilter ?? {};
|
|
3820
3860
|
if (!nextFilter) return baseFilter;
|
|
3821
3861
|
return optimizeAndFilter([baseFilter, nextFilter]);
|
|
3822
3862
|
}
|
|
@@ -3824,15 +3864,30 @@ function getRequestPermissions(req) {
|
|
|
3824
3864
|
const requestPermissionField = getGlobalOption("requestPermissionField");
|
|
3825
3865
|
return new permission_default(req[requestPermissionField] || {});
|
|
3826
3866
|
}
|
|
3867
|
+
var permissionFieldOwners = /* @__PURE__ */ new WeakMap();
|
|
3868
|
+
function getPermissionFieldOwnerMap(req) {
|
|
3869
|
+
let owners = permissionFieldOwners.get(req);
|
|
3870
|
+
if (!owners) {
|
|
3871
|
+
owners = /* @__PURE__ */ new Map();
|
|
3872
|
+
permissionFieldOwners.set(req, owners);
|
|
3873
|
+
}
|
|
3874
|
+
return owners;
|
|
3875
|
+
}
|
|
3827
3876
|
async function setRequestPermissions(req) {
|
|
3828
3877
|
const requestPermissionField = getGlobalOption("requestPermissionField");
|
|
3829
|
-
|
|
3878
|
+
const activeRuntime = getActiveRuntime();
|
|
3879
|
+
const owners = getPermissionFieldOwnerMap(req);
|
|
3880
|
+
const owner = owners.get(requestPermissionField);
|
|
3881
|
+
const hasFieldValue = Boolean(req[requestPermissionField]);
|
|
3882
|
+
if (owner === activeRuntime) return;
|
|
3883
|
+
if (hasFieldValue && owner === void 0) return;
|
|
3830
3884
|
const globalPermissions = getGlobalOption("globalPermissions");
|
|
3831
3885
|
if (!isFunction4(globalPermissions)) return;
|
|
3832
3886
|
const permissions = await globalPermissions.call(req, req);
|
|
3833
3887
|
if (isPlainObject14(permissions)) req[requestPermissionField] = permissions;
|
|
3834
3888
|
else if (isArray9(permissions)) req[requestPermissionField] = arrayToRecord(permissions);
|
|
3835
3889
|
else if (isString5(permissions)) req[requestPermissionField] = { [permissions]: true };
|
|
3890
|
+
owners.set(requestPermissionField, activeRuntime);
|
|
3836
3891
|
}
|
|
3837
3892
|
async function evaluateRouteGuard(req, permissions, routeGuard) {
|
|
3838
3893
|
const phas = (key) => permissions.has(key);
|
|
@@ -3900,17 +3955,14 @@ function getResolvedRequestPermissions(req) {
|
|
|
3900
3955
|
async function setResolvedRequestPermissions(req) {
|
|
3901
3956
|
await setRequestPermissions(req);
|
|
3902
3957
|
}
|
|
3903
|
-
async function canActivateRequest(req, routeGuard) {
|
|
3904
|
-
const permissions = getGlobalPermissions(req);
|
|
3905
|
-
return evaluateRouteGuard(req, permissions, routeGuard);
|
|
3906
|
-
}
|
|
3907
3958
|
async function initializeAclRequest({
|
|
3908
3959
|
req,
|
|
3909
3960
|
flag,
|
|
3961
|
+
runtime,
|
|
3910
3962
|
createCore,
|
|
3911
3963
|
assignCore
|
|
3912
3964
|
}) {
|
|
3913
|
-
if (req[flag]) {
|
|
3965
|
+
if (req[flag] === runtime) {
|
|
3914
3966
|
return null;
|
|
3915
3967
|
}
|
|
3916
3968
|
const core = createCore(req);
|
|
@@ -3918,7 +3970,7 @@ async function initializeAclRequest({
|
|
|
3918
3970
|
assignCore(core);
|
|
3919
3971
|
req[PERMISSIONS] = core.getPermissions();
|
|
3920
3972
|
req[PERMISSION_KEYS] = [...req[PERMISSIONS].keys];
|
|
3921
|
-
req[flag] =
|
|
3973
|
+
req[flag] = runtime;
|
|
3922
3974
|
return core;
|
|
3923
3975
|
}
|
|
3924
3976
|
|
|
@@ -4054,6 +4106,7 @@ async function resolveSelectForRequest({
|
|
|
4054
4106
|
// src/core.ts
|
|
4055
4107
|
var Core = class {
|
|
4056
4108
|
constructor(req) {
|
|
4109
|
+
this.cachedPermissions = null;
|
|
4057
4110
|
this.req = req;
|
|
4058
4111
|
this.caches = {
|
|
4059
4112
|
baseFilter: new Cache()
|
|
@@ -4337,13 +4390,15 @@ var Core = class {
|
|
|
4337
4390
|
return docObject;
|
|
4338
4391
|
}
|
|
4339
4392
|
getPermissions() {
|
|
4393
|
+
if (this.cachedPermissions) return this.cachedPermissions;
|
|
4340
4394
|
return getResolvedRequestPermissions(this.req);
|
|
4341
4395
|
}
|
|
4342
4396
|
async setPermissions() {
|
|
4343
4397
|
await setResolvedRequestPermissions(this.req);
|
|
4398
|
+
this.cachedPermissions = getResolvedRequestPermissions(this.req);
|
|
4344
4399
|
}
|
|
4345
4400
|
async canActivate(routeGuard) {
|
|
4346
|
-
return
|
|
4401
|
+
return evaluateRouteGuard(this.req, this.getGlobalPermissions(), routeGuard);
|
|
4347
4402
|
}
|
|
4348
4403
|
async isAllowed(modelName, access) {
|
|
4349
4404
|
if (access.startsWith("subs")) {
|
|
@@ -4379,6 +4434,7 @@ var Core = class {
|
|
|
4379
4434
|
return this.getPublicService(modelName);
|
|
4380
4435
|
}
|
|
4381
4436
|
getGlobalPermissions() {
|
|
4437
|
+
if (this.cachedPermissions) return this.cachedPermissions;
|
|
4382
4438
|
return getGlobalPermissions(this.req);
|
|
4383
4439
|
}
|
|
4384
4440
|
};
|
|
@@ -4388,6 +4444,7 @@ var createSetCore = (runtime = defaultRuntime) => {
|
|
|
4388
4444
|
await initializeAclRequest({
|
|
4389
4445
|
req,
|
|
4390
4446
|
flag: MIDDLEWARE,
|
|
4447
|
+
runtime,
|
|
4391
4448
|
createCore: (request) => new Core(request),
|
|
4392
4449
|
assignCore: (core) => {
|
|
4393
4450
|
req.macl = core;
|
|
@@ -4768,8 +4825,9 @@ function defineRequestSchema(validator, options = {}) {
|
|
|
4768
4825
|
};
|
|
4769
4826
|
}
|
|
4770
4827
|
function fromZod(schema) {
|
|
4771
|
-
return (value) => {
|
|
4772
|
-
const
|
|
4828
|
+
return async (value) => {
|
|
4829
|
+
const candidate = schema;
|
|
4830
|
+
const result = typeof candidate.safeParseAsync === "function" ? await candidate.safeParseAsync.call(schema, value) : schema.safeParse(value);
|
|
4773
4831
|
if (result.success) {
|
|
4774
4832
|
return {
|
|
4775
4833
|
success: true,
|
|
@@ -4806,6 +4864,9 @@ function fromYup(schema) {
|
|
|
4806
4864
|
data
|
|
4807
4865
|
};
|
|
4808
4866
|
} catch (error2) {
|
|
4867
|
+
if (!isYupValidationError(error2)) {
|
|
4868
|
+
throw error2;
|
|
4869
|
+
}
|
|
4809
4870
|
return {
|
|
4810
4871
|
success: false,
|
|
4811
4872
|
issues: normalizeYupIssues(error2)
|
|
@@ -4830,8 +4891,32 @@ function fromJoi(schema) {
|
|
|
4830
4891
|
}
|
|
4831
4892
|
function fromAjv(validator) {
|
|
4832
4893
|
return async (value) => {
|
|
4833
|
-
const
|
|
4834
|
-
if (
|
|
4894
|
+
const outcome = validator(value);
|
|
4895
|
+
if (isThenable(outcome)) {
|
|
4896
|
+
try {
|
|
4897
|
+
const data = await outcome;
|
|
4898
|
+
if (data === false) {
|
|
4899
|
+
return {
|
|
4900
|
+
success: false,
|
|
4901
|
+
issues: normalizeAjvIssues(validator.errors ?? [])
|
|
4902
|
+
};
|
|
4903
|
+
}
|
|
4904
|
+
return {
|
|
4905
|
+
success: true,
|
|
4906
|
+
data: data === true ? value : data
|
|
4907
|
+
};
|
|
4908
|
+
} catch (error2) {
|
|
4909
|
+
if (!isAjvValidationError(error2)) {
|
|
4910
|
+
throw error2;
|
|
4911
|
+
}
|
|
4912
|
+
return {
|
|
4913
|
+
success: false,
|
|
4914
|
+
issues: normalizeAjvIssues(error2.errors ?? [])
|
|
4915
|
+
};
|
|
4916
|
+
}
|
|
4917
|
+
}
|
|
4918
|
+
const errorsSnapshot = validator.errors ? [...validator.errors] : [];
|
|
4919
|
+
if (outcome) {
|
|
4835
4920
|
return {
|
|
4836
4921
|
success: true,
|
|
4837
4922
|
data: value
|
|
@@ -4839,7 +4924,7 @@ function fromAjv(validator) {
|
|
|
4839
4924
|
}
|
|
4840
4925
|
return {
|
|
4841
4926
|
success: false,
|
|
4842
|
-
issues: normalizeAjvIssues(
|
|
4927
|
+
issues: normalizeAjvIssues(errorsSnapshot)
|
|
4843
4928
|
};
|
|
4844
4929
|
};
|
|
4845
4930
|
}
|
|
@@ -4860,6 +4945,25 @@ function fromValibot(schema, safeParse) {
|
|
|
4860
4945
|
}
|
|
4861
4946
|
function fromArkType(type) {
|
|
4862
4947
|
return async (value) => {
|
|
4948
|
+
if (isStandardSchema(type)) {
|
|
4949
|
+
const result2 = await type["~standard"].validate(value);
|
|
4950
|
+
if (isArkTypeErrors(result2)) {
|
|
4951
|
+
return {
|
|
4952
|
+
success: false,
|
|
4953
|
+
issues: normalizeArkTypeIssues(result2)
|
|
4954
|
+
};
|
|
4955
|
+
}
|
|
4956
|
+
if (isStandardSchemaFailure(result2)) {
|
|
4957
|
+
return {
|
|
4958
|
+
success: false,
|
|
4959
|
+
issues: normalizeArkTypeStandardIssues(result2.issues)
|
|
4960
|
+
};
|
|
4961
|
+
}
|
|
4962
|
+
return {
|
|
4963
|
+
success: true,
|
|
4964
|
+
data: result2.value
|
|
4965
|
+
};
|
|
4966
|
+
}
|
|
4863
4967
|
const result = await type(value);
|
|
4864
4968
|
if (!isArkTypeErrors(result)) {
|
|
4865
4969
|
return {
|
|
@@ -4912,6 +5016,9 @@ function fromVine(validator) {
|
|
|
4912
5016
|
data: output
|
|
4913
5017
|
};
|
|
4914
5018
|
} catch (error2) {
|
|
5019
|
+
if (!isVineValidationError(error2)) {
|
|
5020
|
+
throw error2;
|
|
5021
|
+
}
|
|
4915
5022
|
return {
|
|
4916
5023
|
success: false,
|
|
4917
5024
|
issues: normalizeVineError(error2)
|
|
@@ -4972,6 +5079,13 @@ function normalizeArkTypeIssues(issues) {
|
|
|
4972
5079
|
}));
|
|
4973
5080
|
return normalized.length ? normalized : [{ message: issues.summary ?? "Validation failed" }];
|
|
4974
5081
|
}
|
|
5082
|
+
function normalizeArkTypeStandardIssues(issues) {
|
|
5083
|
+
const normalized = issues.map((issue) => ({
|
|
5084
|
+
message: issue.message ?? issue.problem ?? "Validation failed",
|
|
5085
|
+
path: issue.path?.flatMap((segment) => normalizePathSegment(segment))
|
|
5086
|
+
}));
|
|
5087
|
+
return normalized.length ? normalized : [{ message: "Validation failed" }];
|
|
5088
|
+
}
|
|
4975
5089
|
function normalizeIoTsIssues(issues) {
|
|
4976
5090
|
return issues.map((issue) => ({
|
|
4977
5091
|
message: issue.message ?? "Validation failed",
|
|
@@ -5006,25 +5120,64 @@ function normalizeVineField(message) {
|
|
|
5006
5120
|
}
|
|
5007
5121
|
return path.length ? path : void 0;
|
|
5008
5122
|
}
|
|
5123
|
+
function decodeAjvSegment(segment) {
|
|
5124
|
+
return segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
5125
|
+
}
|
|
5126
|
+
function encodePointerSegment(segment) {
|
|
5127
|
+
return encodeURIComponent(segment.replace(/~/g, "~0").replace(/\//g, "~1"));
|
|
5128
|
+
}
|
|
5009
5129
|
function parseAjvPath(issue) {
|
|
5010
|
-
const
|
|
5011
|
-
|
|
5012
|
-
|
|
5130
|
+
const raw = issue.instancePath;
|
|
5131
|
+
const base = raw == null || raw === "" ? [] : (raw.startsWith("/") ? raw.slice(1) : raw).split("/").map(decodeAjvSegment);
|
|
5132
|
+
const missing = issue.params?.missingProperty;
|
|
5133
|
+
if (typeof missing === "string") {
|
|
5134
|
+
return [...base, missing];
|
|
5013
5135
|
}
|
|
5014
|
-
return
|
|
5136
|
+
return base;
|
|
5015
5137
|
}
|
|
5016
5138
|
function parsePathString(path) {
|
|
5017
5139
|
if (!path) return void 0;
|
|
5018
5140
|
return path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
|
|
5019
5141
|
}
|
|
5020
5142
|
function isYupValidationError(error2) {
|
|
5021
|
-
|
|
5143
|
+
if (typeof error2 !== "object" || error2 === null || !("message" in error2)) {
|
|
5144
|
+
return false;
|
|
5145
|
+
}
|
|
5146
|
+
const candidate = error2;
|
|
5147
|
+
return candidate.name === "ValidationError" && typeof candidate.message === "string" && Array.isArray(candidate.errors) && Array.isArray(candidate.inner);
|
|
5022
5148
|
}
|
|
5023
5149
|
function isArkTypeErrors(value) {
|
|
5024
|
-
|
|
5150
|
+
if (typeof value !== "object" || value === null) {
|
|
5151
|
+
return false;
|
|
5152
|
+
}
|
|
5153
|
+
const record = value;
|
|
5154
|
+
return record.arkKind === "errors" || record[" arkKind"] === "errors";
|
|
5155
|
+
}
|
|
5156
|
+
function isThenable(value) {
|
|
5157
|
+
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
5158
|
+
}
|
|
5159
|
+
function isAjvValidationError(error2) {
|
|
5160
|
+
if (typeof error2 !== "object" || error2 === null || !("errors" in error2)) {
|
|
5161
|
+
return false;
|
|
5162
|
+
}
|
|
5163
|
+
const errors = error2.errors;
|
|
5164
|
+
return errors == null || Array.isArray(errors);
|
|
5025
5165
|
}
|
|
5026
5166
|
function isVineValidationError(error2) {
|
|
5027
|
-
|
|
5167
|
+
if (typeof error2 !== "object" || error2 === null || !("messages" in error2)) {
|
|
5168
|
+
return false;
|
|
5169
|
+
}
|
|
5170
|
+
const candidate = error2;
|
|
5171
|
+
if (!Array.isArray(candidate.messages) || candidate.messages.length === 0) {
|
|
5172
|
+
return false;
|
|
5173
|
+
}
|
|
5174
|
+
const hasDiscriminator = candidate.code === "E_VALIDATION_ERROR" || candidate.name === "ValidationError";
|
|
5175
|
+
if (!hasDiscriminator) {
|
|
5176
|
+
return false;
|
|
5177
|
+
}
|
|
5178
|
+
return candidate.messages.every(
|
|
5179
|
+
(message) => typeof message === "object" && message !== null && typeof message.message === "string" && typeof message.field === "string"
|
|
5180
|
+
);
|
|
5028
5181
|
}
|
|
5029
5182
|
function formatIssue(issue, key, location = "pointer") {
|
|
5030
5183
|
const path = (issue.path ?? []).map(String);
|
|
@@ -5041,7 +5194,7 @@ function formatIssue(issue, key, location = "pointer") {
|
|
|
5041
5194
|
};
|
|
5042
5195
|
}
|
|
5043
5196
|
function buildPointer(path) {
|
|
5044
|
-
return path.length === 0 ? "#" : `#/${path.join("/")}`;
|
|
5197
|
+
return path.length === 0 ? "#" : `#/${path.map(encodePointerSegment).join("/")}`;
|
|
5045
5198
|
}
|
|
5046
5199
|
|
|
5047
5200
|
// src/validation/model-router.ts
|
|
@@ -5542,24 +5695,26 @@ function setModelCollectionRoutes(context) {
|
|
|
5542
5695
|
router.post(`/${options.mutationRouteSegment}`, async (req) => {
|
|
5543
5696
|
await context.assertAllowed(req, "create");
|
|
5544
5697
|
const { include_permissions } = parseQuery(requestSchemas.createQuery, req.query);
|
|
5545
|
-
const
|
|
5698
|
+
const intermediateBody = await parseNestedBodyWithSchema(
|
|
5546
5699
|
advancedCreateBodySchema,
|
|
5547
5700
|
req.body,
|
|
5548
5701
|
"data",
|
|
5549
5702
|
context.getRequestSchema("requestSchemas.advancedCreate.data")
|
|
5550
5703
|
);
|
|
5551
|
-
const { data, select, populate, tasks } =
|
|
5552
|
-
const
|
|
5553
|
-
await parseBodyWithSchema(
|
|
5704
|
+
const { data: nestedData, select: nestedSelect, populate: nestedPopulate, tasks: nestedTasks } = intermediateBody;
|
|
5705
|
+
const nestedOptions = intermediateBody.options ?? {};
|
|
5706
|
+
const finalBody = await parseBodyWithSchema(
|
|
5554
5707
|
advancedCreateBodySchema,
|
|
5555
|
-
{ data, select, populate, tasks, options:
|
|
5708
|
+
{ data: nestedData, select: nestedSelect, populate: nestedPopulate, tasks: nestedTasks, options: nestedOptions },
|
|
5556
5709
|
context.getRequestSchema("requestSchemas.advancedCreate.default") ?? context.getRequestSchema("requestSchemas.advancedCreate")
|
|
5557
5710
|
);
|
|
5558
|
-
const {
|
|
5711
|
+
const { data: finalData, select: finalSelect, populate: finalPopulate, tasks: finalTasks } = finalBody;
|
|
5712
|
+
const finalOptions = finalBody.options ?? {};
|
|
5713
|
+
const { includePermissions, populateAccess } = finalOptions;
|
|
5559
5714
|
const svc = context.getPublicService(req);
|
|
5560
5715
|
const result = await svc._create(
|
|
5561
|
-
|
|
5562
|
-
{ select, populate, tasks },
|
|
5716
|
+
finalData,
|
|
5717
|
+
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
5563
5718
|
{
|
|
5564
5719
|
includePermissions: includePermissions ?? parseBooleanString(include_permissions),
|
|
5565
5720
|
populateAccess
|
|
@@ -5758,25 +5913,33 @@ function setModelDocumentRoutes(context) {
|
|
|
5758
5913
|
await context.assertAllowed(req, "update");
|
|
5759
5914
|
const id = parsePathParam(req.params[options.idParam], options.idParam);
|
|
5760
5915
|
const { returning_all, include_permissions } = parseQuery(requestSchemas.updateQuery, req.query);
|
|
5761
|
-
const
|
|
5916
|
+
const intermediateBody = await parseNestedBodyWithSchema(
|
|
5762
5917
|
advancedUpdateBodySchema,
|
|
5763
5918
|
req.body,
|
|
5764
5919
|
"data",
|
|
5765
5920
|
context.getRequestSchema("requestSchemas.advancedUpdate.data")
|
|
5766
5921
|
);
|
|
5767
|
-
const { data, select, populate, tasks } =
|
|
5768
|
-
const
|
|
5769
|
-
await parseBodyWithSchema(
|
|
5922
|
+
const { data: nestedData, select: nestedSelect, populate: nestedPopulate, tasks: nestedTasks } = intermediateBody;
|
|
5923
|
+
const nestedOptions = intermediateBody.options ?? {};
|
|
5924
|
+
const finalBody = await parseBodyWithSchema(
|
|
5770
5925
|
advancedUpdateBodySchema,
|
|
5771
|
-
{
|
|
5926
|
+
{
|
|
5927
|
+
data: nestedData,
|
|
5928
|
+
select: nestedSelect,
|
|
5929
|
+
populate: nestedPopulate,
|
|
5930
|
+
tasks: nestedTasks,
|
|
5931
|
+
options: nestedOptions
|
|
5932
|
+
},
|
|
5772
5933
|
context.getRequestSchema("requestSchemas.advancedUpdate.default") ?? context.getRequestSchema("requestSchemas.advancedUpdate")
|
|
5773
5934
|
);
|
|
5774
|
-
const {
|
|
5935
|
+
const { data: finalData, select: finalSelect, populate: finalPopulate, tasks: finalTasks } = finalBody;
|
|
5936
|
+
const finalOptions = finalBody.options ?? {};
|
|
5937
|
+
const { returningAll, includePermissions, populateAccess } = finalOptions;
|
|
5775
5938
|
const svc = context.getPublicService(req);
|
|
5776
5939
|
const result = await svc._update(
|
|
5777
5940
|
id,
|
|
5778
|
-
|
|
5779
|
-
{ select, populate, tasks },
|
|
5941
|
+
finalData,
|
|
5942
|
+
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
5780
5943
|
{
|
|
5781
5944
|
returningAll: returningAll ?? parseBooleanString(returning_all),
|
|
5782
5945
|
includePermissions: includePermissions ?? parseBooleanString(include_permissions),
|
|
@@ -5826,23 +5989,31 @@ function setModelDocumentRoutes(context) {
|
|
|
5826
5989
|
await context.assertAllowed(req, "upsert");
|
|
5827
5990
|
const svc = context.getPublicService(req);
|
|
5828
5991
|
const { returning_all, include_permissions } = parseQuery(requestSchemas.upsertQuery, req.query);
|
|
5829
|
-
const
|
|
5992
|
+
const intermediateBody = await parseNestedBodyWithSchema(
|
|
5830
5993
|
advancedUpsertBodySchema,
|
|
5831
5994
|
req.body,
|
|
5832
5995
|
"data",
|
|
5833
5996
|
context.getRequestSchema("requestSchemas.advancedUpsert.data")
|
|
5834
5997
|
);
|
|
5835
|
-
const { data, select, populate, tasks } =
|
|
5836
|
-
const
|
|
5837
|
-
await parseBodyWithSchema(
|
|
5998
|
+
const { data: nestedData, select: nestedSelect, populate: nestedPopulate, tasks: nestedTasks } = intermediateBody;
|
|
5999
|
+
const nestedOptions = intermediateBody.options ?? {};
|
|
6000
|
+
const finalBody = await parseBodyWithSchema(
|
|
5838
6001
|
advancedUpsertBodySchema,
|
|
5839
|
-
{
|
|
6002
|
+
{
|
|
6003
|
+
data: nestedData,
|
|
6004
|
+
select: nestedSelect,
|
|
6005
|
+
populate: nestedPopulate,
|
|
6006
|
+
tasks: nestedTasks,
|
|
6007
|
+
options: nestedOptions
|
|
6008
|
+
},
|
|
5840
6009
|
context.getRequestSchema("requestSchemas.advancedUpsert.default") ?? context.getRequestSchema("requestSchemas.advancedUpsert")
|
|
5841
6010
|
);
|
|
5842
|
-
const {
|
|
6011
|
+
const { data: finalData, select: finalSelect, populate: finalPopulate, tasks: finalTasks } = finalBody;
|
|
6012
|
+
const finalOptions = finalBody.options ?? {};
|
|
6013
|
+
const { returningAll, includePermissions, populateAccess } = finalOptions;
|
|
5843
6014
|
const result = await svc._upsert(
|
|
5844
|
-
|
|
5845
|
-
{ select, populate, tasks },
|
|
6015
|
+
finalData,
|
|
6016
|
+
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
5846
6017
|
{
|
|
5847
6018
|
returningAll: returningAll ?? parseBooleanString(returning_all),
|
|
5848
6019
|
includePermissions: includePermissions ?? parseBooleanString(include_permissions),
|
|
@@ -5912,7 +6083,7 @@ function setModelDocumentRoutes(context) {
|
|
|
5912
6083
|
|
|
5913
6084
|
// src/routers/model-router-subdocument-routes.ts
|
|
5914
6085
|
function setModelSubDocumentRoutes(context) {
|
|
5915
|
-
const subs = getModelSub(context.modelName);
|
|
6086
|
+
const subs = context.runtime.getModelSub(context.modelName);
|
|
5916
6087
|
for (let x = 0; x < subs.length; x++) {
|
|
5917
6088
|
const sub = subs[x];
|
|
5918
6089
|
context.router.get(`/:${context.options.idParam}/${sub}`, async (req) => {
|
|
@@ -6137,7 +6308,9 @@ var ModelRouter = class _ModelRouter {
|
|
|
6137
6308
|
"baseFilter"
|
|
6138
6309
|
);
|
|
6139
6310
|
/**
|
|
6140
|
-
*
|
|
6311
|
+
* Trusted filter replacements applied before base-filter composition.
|
|
6312
|
+
* They may replace ordinary filters, but cannot replace an existing `false` denial.
|
|
6313
|
+
* Returning `false` denies the transaction.
|
|
6141
6314
|
* @operation `list`, `read`, `update`, `delete`
|
|
6142
6315
|
*/
|
|
6143
6316
|
this.overrideFilter = setOption.bind(this, "overrideFilter");
|
|
@@ -6297,6 +6470,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
6297
6470
|
modelName: this.modelName,
|
|
6298
6471
|
router: this.router,
|
|
6299
6472
|
options: this.options,
|
|
6473
|
+
runtime: this.runtime,
|
|
6300
6474
|
getRequestSchema: this.getRequestSchema.bind(this),
|
|
6301
6475
|
getPublicService: this.getPublicService.bind(this),
|
|
6302
6476
|
assertAllowed: this.assertAllowed.bind(this),
|
|
@@ -6311,6 +6485,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
6311
6485
|
modelName: this.modelName,
|
|
6312
6486
|
router: this.router,
|
|
6313
6487
|
options: this.options,
|
|
6488
|
+
runtime: this.runtime,
|
|
6314
6489
|
getRequestSchema: this.getRequestSchema.bind(this),
|
|
6315
6490
|
getPublicService: this.getPublicService.bind(this),
|
|
6316
6491
|
assertAllowed: this.assertAllowed.bind(this),
|
|
@@ -6325,6 +6500,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
6325
6500
|
modelName: this.modelName,
|
|
6326
6501
|
router: this.router,
|
|
6327
6502
|
options: this.options,
|
|
6503
|
+
runtime: this.runtime,
|
|
6328
6504
|
getRequestSchema: this.getRequestSchema.bind(this),
|
|
6329
6505
|
getPublicService: this.getPublicService.bind(this),
|
|
6330
6506
|
assertAllowed: this.assertAllowed.bind(this),
|
|
@@ -6375,6 +6551,7 @@ import { isNumber as _isNumber, normalizeUrlPath as normalizeUrlPath3, orderBy a
|
|
|
6375
6551
|
// src/core-data.ts
|
|
6376
6552
|
var DataCore = class {
|
|
6377
6553
|
constructor(req) {
|
|
6554
|
+
this.cachedPermissions = null;
|
|
6378
6555
|
this.req = req;
|
|
6379
6556
|
this.caches = {
|
|
6380
6557
|
baseFilter: new Cache()
|
|
@@ -6468,13 +6645,15 @@ var DataCore = class {
|
|
|
6468
6645
|
});
|
|
6469
6646
|
}
|
|
6470
6647
|
getPermissions() {
|
|
6648
|
+
if (this.cachedPermissions) return this.cachedPermissions;
|
|
6471
6649
|
return getResolvedRequestPermissions(this.req);
|
|
6472
6650
|
}
|
|
6473
6651
|
async setPermissions() {
|
|
6474
6652
|
await setResolvedRequestPermissions(this.req);
|
|
6653
|
+
this.cachedPermissions = getResolvedRequestPermissions(this.req);
|
|
6475
6654
|
}
|
|
6476
6655
|
async canActivate(routeGuard) {
|
|
6477
|
-
return
|
|
6656
|
+
return evaluateRouteGuard(this.req, this.getGlobalPermissions(), routeGuard);
|
|
6478
6657
|
}
|
|
6479
6658
|
async isAllowed(dataName, access) {
|
|
6480
6659
|
const operationAccess = getDataOption(dataName, `operationAccess.${access}`);
|
|
@@ -6490,6 +6669,7 @@ var DataCore = class {
|
|
|
6490
6669
|
return this.getService(dataName);
|
|
6491
6670
|
}
|
|
6492
6671
|
getGlobalPermissions() {
|
|
6672
|
+
if (this.cachedPermissions) return this.cachedPermissions;
|
|
6493
6673
|
return getGlobalPermissions(this.req);
|
|
6494
6674
|
}
|
|
6495
6675
|
};
|
|
@@ -6499,6 +6679,7 @@ var createSetDataCore = (runtime = defaultRuntime) => {
|
|
|
6499
6679
|
await initializeAclRequest({
|
|
6500
6680
|
req,
|
|
6501
6681
|
flag: DATA_MIDDLEWARE,
|
|
6682
|
+
runtime,
|
|
6502
6683
|
createCore: (request) => new DataCore(request),
|
|
6503
6684
|
assignCore: (core) => {
|
|
6504
6685
|
req.dacl = core;
|
|
@@ -6803,6 +6984,11 @@ var DataRouter = class {
|
|
|
6803
6984
|
this,
|
|
6804
6985
|
"baseFilter"
|
|
6805
6986
|
);
|
|
6987
|
+
/**
|
|
6988
|
+
* Trusted filter replacements applied before base-filter composition.
|
|
6989
|
+
* They may replace ordinary filters, but cannot replace an existing `false` denial.
|
|
6990
|
+
* Returning `false` denies the transaction.
|
|
6991
|
+
*/
|
|
6806
6992
|
this.overrideFilter = setOption2.bind(this, "overrideFilter");
|
|
6807
6993
|
this.decorate = setOption2.bind(
|
|
6808
6994
|
this,
|