@web-ts-toolkit/access-router 0.56.0 → 0.58.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 +177 -120
- package/advanced.d.mts +1 -1
- package/advanced.d.ts +1 -1
- package/advanced.js +95 -66
- package/advanced.mjs +62 -33
- package/index.d.mts +2 -2
- package/index.d.ts +2 -2
- package/index.js +965 -623
- package/index.mjs +703 -361
- package/llms.txt +2 -2
- package/package.json +3 -3
- package/{parsers-BXKoUKMa.d.mts → parsers-CngKnVjW.d.mts} +65 -37
- package/{parsers-BXKoUKMa.d.ts → parsers-CngKnVjW.d.ts} +65 -37
package/advanced.js
CHANGED
|
@@ -260,7 +260,7 @@ function normalizeHydrationUpdate(current, key, value) {
|
|
|
260
260
|
|
|
261
261
|
// src/runtime.ts
|
|
262
262
|
var import_mongoose_schema_jsonschema = __toESM(require("mongoose-schema-jsonschema"));
|
|
263
|
-
var
|
|
263
|
+
var import_utils13 = require("@web-ts-toolkit/utils");
|
|
264
264
|
|
|
265
265
|
// src/helpers/query.ts
|
|
266
266
|
var import_utils2 = require("@web-ts-toolkit/utils");
|
|
@@ -1237,7 +1237,7 @@ function resolveSnapshotDescriptor(scopeVirtuals, virtualName, access) {
|
|
|
1237
1237
|
}
|
|
1238
1238
|
|
|
1239
1239
|
// src/acl/virtual-populate-dependencies.ts
|
|
1240
|
-
var
|
|
1240
|
+
var import_utils12 = require("@web-ts-toolkit/utils");
|
|
1241
1241
|
|
|
1242
1242
|
// src/acl/authorization-snapshot.ts
|
|
1243
1243
|
var import_node_util3 = require("util");
|
|
@@ -1445,6 +1445,25 @@ function captureAuthorizationFieldCatalog(schema, virtuals, documentPermissionFi
|
|
|
1445
1445
|
});
|
|
1446
1446
|
}
|
|
1447
1447
|
|
|
1448
|
+
// src/acl/populate-target-configuration.ts
|
|
1449
|
+
var import_utils11 = require("@web-ts-toolkit/utils");
|
|
1450
|
+
function capturePopulateTargetConfiguration(runtime, modelName, source, proposedOptions) {
|
|
1451
|
+
const label = `Populate target "${modelName}" for ${source}`;
|
|
1452
|
+
if (!proposedOptions && !runtime.hasModel(modelName))
|
|
1453
|
+
authorizationError(
|
|
1454
|
+
`${label} must be configured first in this runtime; register its Mongoose model and setModelOptions with an object permissionSchema`
|
|
1455
|
+
);
|
|
1456
|
+
const model = runtime.getModelInstance(modelName);
|
|
1457
|
+
if (!model) authorizationError(`${label} requires an actual registered Mongoose model in this runtime`);
|
|
1458
|
+
const options = proposedOptions ?? runtime.getModelOptions(modelName);
|
|
1459
|
+
const permissionSchema = options.permissionSchema === void 0 ? runtime.getDefaultModelOption("permissionSchema") : options.permissionSchema;
|
|
1460
|
+
if (!(0, import_utils11.isPlainObject)(permissionSchema))
|
|
1461
|
+
authorizationError(
|
|
1462
|
+
`${label} requires an effective object permissionSchema; configure the model or runtime model defaults ({} explicitly closes business fields)`
|
|
1463
|
+
);
|
|
1464
|
+
return { model, options: { ...options, permissionSchema } };
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1448
1467
|
// src/acl/virtual-populate-dependencies.ts
|
|
1449
1468
|
var elementType = (type) => type.$embeddedSchemaType ?? type.embeddedSchemaType ?? type.caster;
|
|
1450
1469
|
var join = (prefix, path) => prefix ? `${prefix}.${path}` : path;
|
|
@@ -1456,7 +1475,7 @@ var fail = (label, message) => {
|
|
|
1456
1475
|
var varyingSchema = (schema) => Object.keys(schema.discriminators ?? {}).length > 0 || schema.discriminatorMapping?.isRoot === false;
|
|
1457
1476
|
var varyingModel = (model) => !!model.baseModelName || Object.keys(model.discriminators ?? {}).length > 0 || varyingSchema(model.schema);
|
|
1458
1477
|
function record(value, label) {
|
|
1459
|
-
if (!(0,
|
|
1478
|
+
if (!(0, import_utils12.isPlainObject)(value)) return fail(label, "entries must be plain { path, select? } objects");
|
|
1460
1479
|
for (const key of Reflect.ownKeys(value)) {
|
|
1461
1480
|
const property = Object.getOwnPropertyDescriptor(value, key);
|
|
1462
1481
|
if (typeof key !== "string" || !property.enumerable || !("value" in property))
|
|
@@ -1545,7 +1564,8 @@ function normalizeSelection(select, catalog, label) {
|
|
|
1545
1564
|
};
|
|
1546
1565
|
}
|
|
1547
1566
|
function captureVirtualPopulateDependencies(runtime, modelName, options, globalOptions = runtime.getGlobalOptions()) {
|
|
1548
|
-
const
|
|
1567
|
+
const requireOperationAccessForPopulateDependencies = globalOptions.requireOperationAccessForPopulateDependencies !== false;
|
|
1568
|
+
const requireOperationAccessForPopulateQueries = globalOptions.requireOperationAccessForPopulateQueries !== false;
|
|
1549
1569
|
const model = runtime.getModelInstance(modelName);
|
|
1550
1570
|
const targets = /* @__PURE__ */ new Map();
|
|
1551
1571
|
const scopes = [];
|
|
@@ -1585,16 +1605,23 @@ function captureVirtualPopulateDependencies(runtime, modelName, options, globalO
|
|
|
1585
1605
|
label,
|
|
1586
1606
|
`target "${ref}" requires a registered same-connection non-discriminator ObjectId model bound to the source ref`
|
|
1587
1607
|
);
|
|
1588
|
-
const
|
|
1608
|
+
const { options: targetOptions } = capturePopulateTargetConfiguration(
|
|
1609
|
+
runtime,
|
|
1610
|
+
ref,
|
|
1611
|
+
`dependsOnPopulate virtual "${label}"`,
|
|
1612
|
+
ref === modelName ? options : void 0
|
|
1613
|
+
);
|
|
1589
1614
|
const defaults = runtime.getDefaultModelOptions();
|
|
1590
|
-
const readOption = (key) => resolveNestedOption((path2, fallback) => (0,
|
|
1615
|
+
const readOption = (key) => resolveNestedOption((path2, fallback) => (0, import_utils12.get)(targetOptions, path2, fallback), key, (0, import_utils12.get)(defaults, key));
|
|
1591
1616
|
const documentPermissionField = targetOptions.documentPermissionField ?? defaults.documentPermissionField;
|
|
1592
1617
|
const catalog = captureAuthorizationFieldCatalog(targetModel.schema, void 0, documentPermissionField);
|
|
1593
1618
|
const configuration = copyAuthorizationValue(
|
|
1594
1619
|
{
|
|
1595
1620
|
catalog,
|
|
1596
1621
|
documentPermissionField,
|
|
1597
|
-
|
|
1622
|
+
requireOperationAccessForPopulateDependencies,
|
|
1623
|
+
requireOperationAccessForPopulateQueries,
|
|
1624
|
+
permissionSchema: targetOptions.permissionSchema,
|
|
1598
1625
|
operationAccess: { read: readOption("operationAccess.read") },
|
|
1599
1626
|
baseFilter: { read: readOption("baseFilter.read") },
|
|
1600
1627
|
overrideFilter: { read: readOption("overrideFilter.read") },
|
|
@@ -1643,13 +1670,13 @@ function captureVirtualPopulateDependencies(runtime, modelName, options, globalO
|
|
|
1643
1670
|
);
|
|
1644
1671
|
continue;
|
|
1645
1672
|
}
|
|
1646
|
-
if (!(0,
|
|
1673
|
+
if (!(0, import_utils12.isPlainObject)(raw)) continue;
|
|
1647
1674
|
const entry = raw;
|
|
1648
1675
|
const label = join(sourcePrefix, name);
|
|
1649
1676
|
captureList(entry.dependsOnPopulate, label);
|
|
1650
1677
|
if (!("get" in entry))
|
|
1651
1678
|
for (const access of accesses) {
|
|
1652
|
-
if ((0,
|
|
1679
|
+
if ((0, import_utils12.isPlainObject)(entry[access]))
|
|
1653
1680
|
captureList(entry[access].dependsOnPopulate, `${label}.${access}`);
|
|
1654
1681
|
}
|
|
1655
1682
|
const byAccess = {};
|
|
@@ -1695,44 +1722,44 @@ var defaultDataOptions = {
|
|
|
1695
1722
|
listHardLimit: DEFAULT_LIST_HARD_LIMIT
|
|
1696
1723
|
};
|
|
1697
1724
|
var normalizeBasePath = (name, value) => {
|
|
1698
|
-
if ((0,
|
|
1725
|
+
if ((0, import_utils13.isNil)(value)) {
|
|
1699
1726
|
return `/${pluralize(name)}`;
|
|
1700
1727
|
}
|
|
1701
|
-
return (0,
|
|
1728
|
+
return (0, import_utils13.isString)(value) ? (0, import_utils13.addLeadingSlash)(value) : "";
|
|
1702
1729
|
};
|
|
1703
1730
|
var hasModelPermission = (value, modelPermissionPrefix) => {
|
|
1704
1731
|
if (!modelPermissionPrefix) {
|
|
1705
1732
|
return true;
|
|
1706
1733
|
}
|
|
1707
|
-
if ((0,
|
|
1734
|
+
if ((0, import_utils13.isString)(value)) {
|
|
1708
1735
|
return value.trim().split(" ").some((item) => item.startsWith(modelPermissionPrefix));
|
|
1709
1736
|
}
|
|
1710
|
-
if ((0,
|
|
1737
|
+
if ((0, import_utils13.isArray)(value)) {
|
|
1711
1738
|
return value.some((item) => {
|
|
1712
|
-
if ((0,
|
|
1739
|
+
if ((0, import_utils13.isString)(item) || (0, import_utils13.isArray)(item)) {
|
|
1713
1740
|
return hasModelPermission(item, modelPermissionPrefix);
|
|
1714
1741
|
}
|
|
1715
1742
|
return true;
|
|
1716
1743
|
});
|
|
1717
1744
|
}
|
|
1718
|
-
return (0,
|
|
1745
|
+
return (0, import_utils13.isFunction)(value);
|
|
1719
1746
|
};
|
|
1720
1747
|
var classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
|
|
1721
1748
|
const schemaKeys = Object.keys(permissionSchema);
|
|
1722
1749
|
const globalPermissionKeys = {};
|
|
1723
1750
|
const modelPermissionKeys = {};
|
|
1724
|
-
(0,
|
|
1751
|
+
(0, import_utils13.forEach)(schemaKeys, (schemaKey) => {
|
|
1725
1752
|
const schemaRule = permissionSchema[schemaKey];
|
|
1726
|
-
const ruleEntries = (0,
|
|
1753
|
+
const ruleEntries = (0, import_utils13.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
|
|
1727
1754
|
for (let x = 0; x < ruleEntries.length; x++) {
|
|
1728
1755
|
const [accessKey, value] = ruleEntries[x];
|
|
1729
|
-
if (!(0,
|
|
1756
|
+
if (!(0, import_utils13.isArray)(globalPermissionKeys[accessKey])) {
|
|
1730
1757
|
globalPermissionKeys[accessKey] = [];
|
|
1731
1758
|
}
|
|
1732
|
-
if (!(0,
|
|
1759
|
+
if (!(0, import_utils13.isArray)(modelPermissionKeys[accessKey])) {
|
|
1733
1760
|
modelPermissionKeys[accessKey] = [];
|
|
1734
1761
|
}
|
|
1735
|
-
if ((0,
|
|
1762
|
+
if ((0, import_utils13.isBoolean)(value)) {
|
|
1736
1763
|
globalPermissionKeys[accessKey].push(schemaKey);
|
|
1737
1764
|
continue;
|
|
1738
1765
|
}
|
|
@@ -1764,13 +1791,13 @@ var VIRTUAL_UNSUPPORTED_ACCESSES = ["delete", "distinct", "count"];
|
|
|
1764
1791
|
var VIRTUAL_RESERVED_NAMES = /* @__PURE__ */ new Set(["_id", "__v", "id"]);
|
|
1765
1792
|
var VIRTUAL_DANGEROUS_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
1766
1793
|
var VIRTUAL_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
1767
|
-
var isVirtualContainerValue2 = (value) => (0,
|
|
1794
|
+
var isVirtualContainerValue2 = (value) => (0, import_utils13.isPlainObject)(value) && "sub" in value;
|
|
1768
1795
|
var virtualFullPath = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
1769
1796
|
var virtualPathsOverlap = (virtualPath, permissionField) => {
|
|
1770
1797
|
if (!virtualPath || !permissionField) return false;
|
|
1771
1798
|
try {
|
|
1772
|
-
if ((0,
|
|
1773
|
-
if ((0,
|
|
1799
|
+
if ((0, import_utils13.get)((0, import_utils13.set)({}, virtualPath, true), permissionField) !== void 0) return true;
|
|
1800
|
+
if ((0, import_utils13.get)((0, import_utils13.set)({}, permissionField, true), virtualPath) !== void 0) return true;
|
|
1774
1801
|
} catch {
|
|
1775
1802
|
return false;
|
|
1776
1803
|
}
|
|
@@ -1831,12 +1858,12 @@ var cloneVirtualsForValidation = (value) => {
|
|
|
1831
1858
|
};
|
|
1832
1859
|
var validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirtualNames) => {
|
|
1833
1860
|
if (dependsOn === void 0) return [];
|
|
1834
|
-
if (!(0,
|
|
1861
|
+
if (!(0, import_utils13.isArray)(dependsOn)) {
|
|
1835
1862
|
throw new Error(`Virtual ${entryLabel}: dependsOn must be an array of top-level persisted field names`);
|
|
1836
1863
|
}
|
|
1837
1864
|
const list = dependsOn;
|
|
1838
1865
|
for (const dep of list) {
|
|
1839
|
-
if (!(0,
|
|
1866
|
+
if (!(0, import_utils13.isString)(dep) || dep.length === 0) {
|
|
1840
1867
|
throw new Error(`Virtual ${entryLabel}: dependsOn entries must be non-empty strings`);
|
|
1841
1868
|
}
|
|
1842
1869
|
if (dep.includes(".")) {
|
|
@@ -1858,12 +1885,12 @@ var validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirt
|
|
|
1858
1885
|
return list;
|
|
1859
1886
|
};
|
|
1860
1887
|
var validateVirtualLeafValue = (value, entryLabel, storedFields, siblingVirtualNames, sharedDependsOn) => {
|
|
1861
|
-
if ((0,
|
|
1862
|
-
if (!(0,
|
|
1888
|
+
if ((0, import_utils13.isFunction)(value)) return;
|
|
1889
|
+
if (!(0, import_utils13.isPlainObject)(value)) {
|
|
1863
1890
|
throw new Error(`Virtual ${entryLabel}: descriptor must be a getter function or { get, dependsOn }`);
|
|
1864
1891
|
}
|
|
1865
1892
|
const record2 = value;
|
|
1866
|
-
if (!(0,
|
|
1893
|
+
if (!(0, import_utils13.isFunction)(record2.get)) {
|
|
1867
1894
|
throw new Error(`Virtual ${entryLabel}: descriptor.get must be a callable getter function`);
|
|
1868
1895
|
}
|
|
1869
1896
|
validateVirtualDependsOn(record2.dependsOn ?? sharedDependsOn, entryLabel, storedFields, siblingVirtualNames);
|
|
@@ -1905,7 +1932,7 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
|
|
|
1905
1932
|
`Virtual ${scopeLabel}${name}: scope-container must only hold "sub" (embedded container "${name}" is not a virtual-leaf collision)`
|
|
1906
1933
|
);
|
|
1907
1934
|
}
|
|
1908
|
-
if (!(0,
|
|
1935
|
+
if (!(0, import_utils13.isPlainObject)(record3.sub)) {
|
|
1909
1936
|
throw new Error(`Virtual ${scopeLabel}${name}: scope-container "sub" must be a plain object`);
|
|
1910
1937
|
}
|
|
1911
1938
|
continue;
|
|
@@ -1915,8 +1942,8 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
|
|
|
1915
1942
|
`Virtual ${scopeLabel}${name}: collides with a stored path (inspected actual Mongoose schema/child scope; getModelAtt alone is insufficient)`
|
|
1916
1943
|
);
|
|
1917
1944
|
}
|
|
1918
|
-
if ((0,
|
|
1919
|
-
if (!(0,
|
|
1945
|
+
if ((0, import_utils13.isFunction)(raw)) continue;
|
|
1946
|
+
if (!(0, import_utils13.isPlainObject)(raw)) {
|
|
1920
1947
|
throw new Error(
|
|
1921
1948
|
`Virtual ${scopeLabel}${name}: malformed descriptor (expected getter, { get, dependsOn }, or per-access record)`
|
|
1922
1949
|
);
|
|
@@ -1970,7 +1997,7 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
|
|
|
1970
1997
|
};
|
|
1971
1998
|
var validateVirtualsTree = (model, virtuals, documentPermissionField, modelName) => {
|
|
1972
1999
|
if (virtuals === void 0 || virtuals === null) return;
|
|
1973
|
-
if (!(0,
|
|
2000
|
+
if (!(0, import_utils13.isPlainObject)(virtuals)) {
|
|
1974
2001
|
throw new Error(`Virtuals for model "${modelName}": virtuals must be a plain object mapping names to descriptors`);
|
|
1975
2002
|
}
|
|
1976
2003
|
const rootSchema = model?.schema ?? null;
|
|
@@ -2022,8 +2049,8 @@ var AccessRuntime = class {
|
|
|
2022
2049
|
{
|
|
2023
2050
|
requestPermissionField: "_permissions",
|
|
2024
2051
|
globalPermissions: () => ({}),
|
|
2025
|
-
|
|
2026
|
-
|
|
2052
|
+
requireOperationAccessForPopulateQueries: true,
|
|
2053
|
+
requireOperationAccessForPopulateDependencies: true,
|
|
2027
2054
|
logger: defaultLogger,
|
|
2028
2055
|
requestComplexity: defaultRequestComplexity
|
|
2029
2056
|
},
|
|
@@ -2078,7 +2105,7 @@ var AccessRuntime = class {
|
|
|
2078
2105
|
}
|
|
2079
2106
|
registerOpenApiRoute(route) {
|
|
2080
2107
|
this.openApiRegistry.register(
|
|
2081
|
-
this.openApiPathPrefix ? { ...route, path: (0,
|
|
2108
|
+
this.openApiPathPrefix ? { ...route, path: (0, import_utils13.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
|
|
2082
2109
|
);
|
|
2083
2110
|
}
|
|
2084
2111
|
/**
|
|
@@ -2089,7 +2116,7 @@ var AccessRuntime = class {
|
|
|
2089
2116
|
*/
|
|
2090
2117
|
withOpenApiPathPrefix(prefix, build) {
|
|
2091
2118
|
const previous = this.openApiPathPrefix;
|
|
2092
|
-
this.openApiPathPrefix = (0,
|
|
2119
|
+
this.openApiPathPrefix = (0, import_utils13.normalizeUrlPath)(`${previous}/${prefix}`);
|
|
2093
2120
|
try {
|
|
2094
2121
|
return build();
|
|
2095
2122
|
} finally {
|
|
@@ -2197,13 +2224,15 @@ var AccessRuntime = class {
|
|
|
2197
2224
|
/** Shallowly replace supplied global values; nested objects such as requestComplexity are not deep-merged. */
|
|
2198
2225
|
setGlobalOptions(options) {
|
|
2199
2226
|
const next = { ...options };
|
|
2200
|
-
if ("
|
|
2201
|
-
next.
|
|
2227
|
+
if ("requireOperationAccessForPopulateQueries" in next)
|
|
2228
|
+
next.requireOperationAccessForPopulateQueries = next.requireOperationAccessForPopulateQueries !== false;
|
|
2229
|
+
if ("requireOperationAccessForPopulateDependencies" in next)
|
|
2230
|
+
next.requireOperationAccessForPopulateDependencies = next.requireOperationAccessForPopulateDependencies !== false;
|
|
2202
2231
|
this.globalOptions.assign(next);
|
|
2203
2232
|
}
|
|
2204
2233
|
setGlobalOption(key, value) {
|
|
2205
|
-
if (key === "
|
|
2206
|
-
this.globalOptions.set(
|
|
2234
|
+
if (key === "requireOperationAccessForPopulateQueries" || key === "requireOperationAccessForPopulateDependencies") {
|
|
2235
|
+
this.globalOptions.set(key, value !== false);
|
|
2207
2236
|
return;
|
|
2208
2237
|
}
|
|
2209
2238
|
this.globalOptions.set(key, value);
|
|
@@ -2232,7 +2261,7 @@ var AccessRuntime = class {
|
|
|
2232
2261
|
if (keyStr === "defaults") assertPublicDefaults(value);
|
|
2233
2262
|
else if (keyStr.startsWith("defaults.")) {
|
|
2234
2263
|
const proposed = {};
|
|
2235
|
-
(0,
|
|
2264
|
+
(0, import_utils13.set)(proposed, keyStr.slice("defaults.".length), value);
|
|
2236
2265
|
assertPublicDefaults(proposed);
|
|
2237
2266
|
}
|
|
2238
2267
|
this.defaultModelOptions.set(key, value);
|
|
@@ -2261,7 +2290,7 @@ var AccessRuntime = class {
|
|
|
2261
2290
|
}).onchange("basePath", function(newval, key, target) {
|
|
2262
2291
|
target[key] = normalizeBasePath(
|
|
2263
2292
|
modelName,
|
|
2264
|
-
(0,
|
|
2293
|
+
(0, import_utils13.isString)(newval) || (0, import_utils13.isNil)(newval) ? newval : void 0
|
|
2265
2294
|
);
|
|
2266
2295
|
}).build();
|
|
2267
2296
|
this.modelJsonSchemas[modelName] = model.jsonSchema();
|
|
@@ -2305,7 +2334,7 @@ var AccessRuntime = class {
|
|
|
2305
2334
|
if (keyStr === "defaults") assertPublicDefaults(value);
|
|
2306
2335
|
else if (keyStr.startsWith("defaults.")) {
|
|
2307
2336
|
const proposed = {};
|
|
2308
|
-
(0,
|
|
2337
|
+
(0, import_utils13.set)(proposed, keyStr.slice("defaults.".length), value);
|
|
2309
2338
|
assertPublicDefaults(proposed);
|
|
2310
2339
|
}
|
|
2311
2340
|
const manager = this.modelOptions[modelName];
|
|
@@ -2326,15 +2355,15 @@ var AccessRuntime = class {
|
|
|
2326
2355
|
const segments = nestedPath.split(".");
|
|
2327
2356
|
let cursor = cloned;
|
|
2328
2357
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
2329
|
-
if (!(0,
|
|
2358
|
+
if (!(0, import_utils13.isPlainObject)(cursor)) break;
|
|
2330
2359
|
cursor = cursor[segments[i]];
|
|
2331
2360
|
}
|
|
2332
|
-
if ((0,
|
|
2361
|
+
if ((0, import_utils13.isPlainObject)(cursor)) {
|
|
2333
2362
|
delete cursor[segments[segments.length - 1]];
|
|
2334
2363
|
}
|
|
2335
2364
|
proposedVirtuals = cloned;
|
|
2336
2365
|
} else {
|
|
2337
|
-
(0,
|
|
2366
|
+
(0, import_utils13.set)(cloned, nestedPath, value);
|
|
2338
2367
|
proposedVirtuals = cloned;
|
|
2339
2368
|
}
|
|
2340
2369
|
}
|
|
@@ -2435,7 +2464,7 @@ var AccessRuntime = class {
|
|
|
2435
2464
|
manager.onchange("basePath", function(newval, key, target) {
|
|
2436
2465
|
target[key] = normalizeBasePath(
|
|
2437
2466
|
dataName,
|
|
2438
|
-
(0,
|
|
2467
|
+
(0, import_utils13.isString)(newval) || (0, import_utils13.isNil)(newval) ? newval : void 0
|
|
2439
2468
|
);
|
|
2440
2469
|
}).build();
|
|
2441
2470
|
return manager;
|
|
@@ -2495,20 +2524,20 @@ var AccessRuntime = class {
|
|
|
2495
2524
|
const schema = model.schema;
|
|
2496
2525
|
this.modelRefs[modelName] = buildRefs(schema.tree);
|
|
2497
2526
|
this.modelSubs[modelName] = buildSubPaths(schema.tree);
|
|
2498
|
-
this.modelAtts[modelName] = (0,
|
|
2527
|
+
this.modelAtts[modelName] = (0, import_utils13.keys)(schema.obj);
|
|
2499
2528
|
}
|
|
2500
2529
|
getModelRef(modelName, refPath) {
|
|
2501
2530
|
this.ensureModelMeta(modelName);
|
|
2502
|
-
const value = (0,
|
|
2503
|
-
return (0,
|
|
2531
|
+
const value = (0, import_utils13.get)(this.modelRefs, `${modelName}.${refPath}`, null);
|
|
2532
|
+
return (0, import_utils13.isString)(value) ? value : null;
|
|
2504
2533
|
}
|
|
2505
2534
|
getModelSub(modelName) {
|
|
2506
2535
|
this.ensureModelMeta(modelName);
|
|
2507
|
-
return (0,
|
|
2536
|
+
return (0, import_utils13.get)(this.modelSubs, modelName, []);
|
|
2508
2537
|
}
|
|
2509
2538
|
getModelAtt(modelName) {
|
|
2510
2539
|
this.ensureModelMeta(modelName);
|
|
2511
|
-
return (0,
|
|
2540
|
+
return (0, import_utils13.get)(this.modelAtts, modelName, []);
|
|
2512
2541
|
}
|
|
2513
2542
|
};
|
|
2514
2543
|
var defaultRuntime = new AccessRuntime({ allowGlobalModelLookup: true });
|
|
@@ -2528,7 +2557,7 @@ var getGlobalOption = (key, defaultValue) => {
|
|
|
2528
2557
|
|
|
2529
2558
|
// src/validation/common.ts
|
|
2530
2559
|
var import_zod2 = require("zod");
|
|
2531
|
-
var
|
|
2560
|
+
var import_utils15 = require("@web-ts-toolkit/utils");
|
|
2532
2561
|
|
|
2533
2562
|
// src/validation/public-admission-schema.ts
|
|
2534
2563
|
var admissions = /* @__PURE__ */ new WeakMap();
|
|
@@ -2550,7 +2579,7 @@ function assertTransformedPublicAdmission(schema, value) {
|
|
|
2550
2579
|
}
|
|
2551
2580
|
|
|
2552
2581
|
// src/correlated-includes.ts
|
|
2553
|
-
var
|
|
2582
|
+
var import_utils14 = require("@web-ts-toolkit/utils");
|
|
2554
2583
|
var PARENT_MARKER_KEY = "$parent";
|
|
2555
2584
|
var ESCAPE_WRAPPER_KEY = "$escape";
|
|
2556
2585
|
var SUBQUERY_PAYLOAD_KEYS = /* @__PURE__ */ new Set(["$$sq", "$$date"]);
|
|
@@ -2561,10 +2590,10 @@ var FIELD_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
|
2561
2590
|
var ARRAY_INDEX_SEGMENT_PATTERN = /^(0|[1-9]\d*)$/;
|
|
2562
2591
|
var ownKeys = (value) => Object.keys(value);
|
|
2563
2592
|
function isParentRefMarker(value) {
|
|
2564
|
-
return (0,
|
|
2593
|
+
return (0, import_utils14.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
|
|
2565
2594
|
}
|
|
2566
2595
|
function isEscapedParentRef(value) {
|
|
2567
|
-
return (0,
|
|
2596
|
+
return (0, import_utils14.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
|
|
2568
2597
|
}
|
|
2569
2598
|
function hasMarkerKey(value) {
|
|
2570
2599
|
return ownKeys(value).includes(PARENT_MARKER_KEY) || ownKeys(value).includes(ESCAPE_WRAPPER_KEY);
|
|
@@ -2583,12 +2612,12 @@ function containsParentMarkerShape(value) {
|
|
|
2583
2612
|
const seen = /* @__PURE__ */ new Set();
|
|
2584
2613
|
const visit = (current) => {
|
|
2585
2614
|
if (isParentRefMarker(current) || isEscapedParentRef(current)) return true;
|
|
2586
|
-
if ((0,
|
|
2615
|
+
if ((0, import_utils14.isArray)(current)) {
|
|
2587
2616
|
if (seen.has(current)) return false;
|
|
2588
2617
|
seen.add(current);
|
|
2589
2618
|
return current.some(visit);
|
|
2590
2619
|
}
|
|
2591
|
-
if ((0,
|
|
2620
|
+
if ((0, import_utils14.isPlainObject)(current)) {
|
|
2592
2621
|
if (seen.has(current)) return false;
|
|
2593
2622
|
seen.add(current);
|
|
2594
2623
|
if (hasMarkerKey(current)) return true;
|
|
@@ -2618,7 +2647,7 @@ function scanTemplateValueNode(value, path, issues) {
|
|
|
2618
2647
|
}
|
|
2619
2648
|
return;
|
|
2620
2649
|
}
|
|
2621
|
-
if ((0,
|
|
2650
|
+
if ((0, import_utils14.isPlainObject)(value)) {
|
|
2622
2651
|
if (hasMarkerKey(value)) {
|
|
2623
2652
|
issues.push({
|
|
2624
2653
|
message: 'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }',
|
|
@@ -2629,7 +2658,7 @@ function scanTemplateValueNode(value, path, issues) {
|
|
|
2629
2658
|
scanTemplateObjectEntries(value, path, issues);
|
|
2630
2659
|
return;
|
|
2631
2660
|
}
|
|
2632
|
-
if ((0,
|
|
2661
|
+
if ((0, import_utils14.isArray)(value)) {
|
|
2633
2662
|
value.forEach((item, index) => scanTemplateValueNode(item, [...path, index], issues));
|
|
2634
2663
|
}
|
|
2635
2664
|
}
|
|
@@ -2670,7 +2699,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
2670
2699
|
continue;
|
|
2671
2700
|
}
|
|
2672
2701
|
if (LOGICAL_CLAUSE_KEYS.has(key)) {
|
|
2673
|
-
if (!(0,
|
|
2702
|
+
if (!(0, import_utils14.isArray)(child)) {
|
|
2674
2703
|
scanTemplateValueNode(child, childPath, issues);
|
|
2675
2704
|
continue;
|
|
2676
2705
|
}
|
|
@@ -2683,7 +2712,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
2683
2712
|
});
|
|
2684
2713
|
return;
|
|
2685
2714
|
}
|
|
2686
|
-
if ((0,
|
|
2715
|
+
if ((0, import_utils14.isPlainObject)(clause)) {
|
|
2687
2716
|
scanTemplateObjectEntries(clause, clausePath, issues);
|
|
2688
2717
|
}
|
|
2689
2718
|
});
|
|
@@ -2694,7 +2723,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
2694
2723
|
}
|
|
2695
2724
|
function validateCorrelatedFilterTemplate(filter) {
|
|
2696
2725
|
const issues = [];
|
|
2697
|
-
if (!(0,
|
|
2726
|
+
if (!(0, import_utils14.isPlainObject)(filter)) {
|
|
2698
2727
|
issues.push({ message: "Correlated include filter must be an object", path: [] });
|
|
2699
2728
|
return issues;
|
|
2700
2729
|
}
|
|
@@ -2822,7 +2851,7 @@ var correlatedFilterSchema = import_zod2.z.record(import_zod2.z.string(), import
|
|
|
2822
2851
|
}
|
|
2823
2852
|
});
|
|
2824
2853
|
var correlatedEmptyOptionsSchema = import_zod2.z.unknown().refine(
|
|
2825
|
-
(value) => value === void 0 || (0,
|
|
2854
|
+
(value) => value === void 0 || (0, import_utils15.isPlainObject)(value) && Object.keys(value).length === 0,
|
|
2826
2855
|
"Correlated include options must be absent or empty"
|
|
2827
2856
|
).optional();
|
|
2828
2857
|
var correlatedPathSchema = import_zod2.z.string().min(1).superRefine((path, ctx) => {
|
|
@@ -2859,7 +2888,7 @@ var correlatedListArgsSchema = import_zod2.z.object({
|
|
|
2859
2888
|
include: import_zod2.z.lazy(() => correlatedNestedIncludeSchema).optional()
|
|
2860
2889
|
}).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
|
|
2861
2890
|
var correlatedCountArgsSchema = import_zod2.z.unknown().refine(
|
|
2862
|
-
(value) => value === void 0 || (0,
|
|
2891
|
+
(value) => value === void 0 || (0, import_utils15.isPlainObject)(value) && Object.keys(value).length === 0,
|
|
2863
2892
|
"Count includes accept no args"
|
|
2864
2893
|
).optional();
|
|
2865
2894
|
var correlatedReadByIdSchema = import_zod2.z.object({
|
|
@@ -2912,7 +2941,7 @@ var correlatedNestedIncludeSchema = import_zod2.z.union([includeItemSchema, impo
|
|
|
2912
2941
|
var rejectDuplicateCorrelatedPaths = (items, ctx) => {
|
|
2913
2942
|
const seen = /* @__PURE__ */ new Set();
|
|
2914
2943
|
items.forEach((item, index) => {
|
|
2915
|
-
if ((0,
|
|
2944
|
+
if ((0, import_utils15.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
|
|
2916
2945
|
if (seen.has(item.path)) {
|
|
2917
2946
|
ctx.addIssue({
|
|
2918
2947
|
code: import_zod2.z.ZodIssueCode.custom,
|