@fitzzero/quickdraw-core 5.0.0 → 5.1.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 +343 -49
- package/dist/{admin-BiU4LRZS.d.ts → admin-DKwkIh5i.d.ts} +25 -10
- package/dist/{adminSchemas-k5a1Ov7b.d.ts → adminSchemas-2DUA_hZ8.d.ts} +15 -9
- package/dist/{auth-CMyRkfjZ.d.ts → auth-BhWqdyb-.d.ts} +2 -2
- package/dist/{caller-DHzK3oiI.d.ts → caller-CXTFswBO.d.ts} +28 -6
- package/dist/{chunk-2XJFNVHW.js → chunk-2PWMUVC7.js} +1 -1
- package/dist/{chunk-2XJFNVHW.js.map → chunk-2PWMUVC7.js.map} +1 -1
- package/dist/{chunk-5IC5VZ7T.js → chunk-2UELNHDD.js} +3 -3
- package/dist/{chunk-XFDOGTMC.js → chunk-3674EIRT.js} +4 -4
- package/dist/{chunk-DNCAI3KY.js → chunk-4DIQHASK.js} +1 -1
- package/dist/chunk-4DIQHASK.js.map +1 -0
- package/dist/{chunk-LLLYILEP.js → chunk-A6DJBGOG.js} +411 -43
- package/dist/chunk-A6DJBGOG.js.map +1 -0
- package/dist/{chunk-B2UQ27GH.js → chunk-CDKG4TFA.js} +25 -5
- package/dist/{chunk-B2UQ27GH.js.map → chunk-CDKG4TFA.js.map} +1 -1
- package/dist/{chunk-IRGAGRVG.js → chunk-JZBCLNDU.js} +4 -4
- package/dist/{chunk-XUSN5WKU.js → chunk-KNDDCVQJ.js} +4 -4
- package/dist/{chunk-5YRQ26LF.js → chunk-RT6OILOI.js} +1 -1
- package/dist/chunk-RT6OILOI.js.map +1 -0
- package/dist/{chunk-7QIY2DDX.js → chunk-VJTFXHOK.js} +2 -2
- package/dist/{chunk-7QIY2DDX.js.map → chunk-VJTFXHOK.js.map} +1 -1
- package/dist/chunk-XNLWBZIG.js +9 -0
- package/dist/chunk-XNLWBZIG.js.map +1 -0
- package/dist/cli/quickdraw-docs.js +241 -27
- package/dist/cli/quickdraw-docs.js.map +1 -1
- package/dist/client/index.d.ts +7 -7
- package/dist/client/index.js +5 -5
- package/dist/{clientTypes-B3o_99Xq.d.ts → clientTypes-Bc-G8n-U.d.ts} +3 -3
- package/dist/{connection-DuN8GvcD.d.ts → connection-Cr1BU07W.d.ts} +2 -2
- package/dist/{createServer-DUacdfKl.d.ts → createServer-CP9eDHZZ.d.ts} +30 -9
- package/dist/{createTestApp-DFLXoTKm.d.ts → createTestApp-UKVGEmOf.d.ts} +6 -6
- package/dist/{envelope-nf5eGB-a.d.ts → envelope-Cp3YcVxC.d.ts} +1 -1
- package/dist/{http--uoooIH5.d.ts → http-Djj2Inuu.d.ts} +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +27 -7
- package/dist/index.js.map +1 -1
- package/dist/{infer-Dw21kmLw.d.ts → infer-Teo1xpsd.d.ts} +17 -0
- package/dist/{metrics-C0WvB7-I.d.ts → metrics-BdBu5o8G.d.ts} +2 -2
- package/dist/prisma/index.d.ts +4 -4
- package/dist/prisma/index.js +1 -1
- package/dist/server/auth/index.d.ts +14 -5
- package/dist/server/auth/index.js +0 -5
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/index.d.ts +120 -33
- package/dist/server/index.js +146 -193
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/index.d.ts +51 -11
- package/dist/server/mcp/index.js +129 -8
- package/dist/server/mcp/index.js.map +1 -1
- package/dist/server/otel.d.ts +3 -3
- package/dist/{sharing-n4ss-ONM.d.ts → sharing-DVa8W-yR.d.ts} +3 -3
- package/dist/testing/client.d.ts +13 -13
- package/dist/testing/client.js +6 -6
- package/dist/testing/index.d.ts +156 -12
- package/dist/testing/index.js +1037 -22
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/mock.d.ts +5 -5
- package/dist/testing/mock.js +5 -5
- package/dist/{types-Bwg3kIEc.d.ts → types-Cu0vmx7c.d.ts} +8 -2
- package/dist/utils/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-5YRQ26LF.js.map +0 -1
- package/dist/chunk-DNCAI3KY.js.map +0 -1
- package/dist/chunk-LLLYILEP.js.map +0 -1
- /package/dist/{chunk-5IC5VZ7T.js.map → chunk-2UELNHDD.js.map} +0 -0
- /package/dist/{chunk-XFDOGTMC.js.map → chunk-3674EIRT.js.map} +0 -0
- /package/dist/{chunk-IRGAGRVG.js.map → chunk-JZBCLNDU.js.map} +0 -0
- /package/dist/{chunk-XUSN5WKU.js.map → chunk-KNDDCVQJ.js.map} +0 -0
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
quietly,
|
|
11
11
|
strictWarningsOf,
|
|
12
12
|
versionTime
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-4DIQHASK.js";
|
|
14
14
|
import {
|
|
15
15
|
isCallEnvelope,
|
|
16
16
|
isCancel
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
toQuickdrawError,
|
|
31
31
|
toWireIssues,
|
|
32
32
|
withSignal
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-2PWMUVC7.js";
|
|
34
34
|
import {
|
|
35
35
|
createRecorder,
|
|
36
36
|
describeError,
|
|
@@ -77,7 +77,7 @@ import {
|
|
|
77
77
|
streamRoom,
|
|
78
78
|
topicRoom,
|
|
79
79
|
userRoom
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-VJTFXHOK.js";
|
|
81
81
|
import {
|
|
82
82
|
hasJsonSchema
|
|
83
83
|
} from "./chunk-47AEXVDM.js";
|
|
@@ -424,9 +424,9 @@ function addBranchKeys(node, root, keys, seen) {
|
|
|
424
424
|
}
|
|
425
425
|
}
|
|
426
426
|
for (const keyword of BRANCHES) {
|
|
427
|
-
const
|
|
428
|
-
if (Array.isArray(
|
|
429
|
-
for (const member of
|
|
427
|
+
const members2 = target2[keyword];
|
|
428
|
+
if (Array.isArray(members2)) {
|
|
429
|
+
for (const member of members2) {
|
|
430
430
|
addBranchKeys(member, root, keys, seen);
|
|
431
431
|
}
|
|
432
432
|
}
|
|
@@ -673,12 +673,12 @@ async function membersAmong(storage, collection, scope, ids) {
|
|
|
673
673
|
}
|
|
674
674
|
async function readItemsById(storage, collection, scope, ids, rev) {
|
|
675
675
|
const wanted = [...new Set(ids)];
|
|
676
|
-
const
|
|
677
|
-
if (
|
|
676
|
+
const members2 = wanted.length === 0 ? void 0 : await membersAmong(storage, collection, scope, wanted);
|
|
677
|
+
if (members2 === void 0) {
|
|
678
678
|
return { rev, items: [] };
|
|
679
679
|
}
|
|
680
680
|
const rows = await storage.findMany(collection.model, {
|
|
681
|
-
where:
|
|
681
|
+
where: members2,
|
|
682
682
|
select: collection.item.select
|
|
683
683
|
});
|
|
684
684
|
const found = new Map(rows.flatMap((row) => typeof row.id === "string" ? [[row.id, row]] : []));
|
|
@@ -792,10 +792,10 @@ function indexRowFrom(collection, item, row, rev) {
|
|
|
792
792
|
const id = typeof row.id === "string" ? row.id : "";
|
|
793
793
|
return [id, version ?? rev, ...(collection.index ?? []).map((field) => values[field] ?? null)];
|
|
794
794
|
}
|
|
795
|
-
async function readIndex(storage, collection,
|
|
795
|
+
async function readIndex(storage, collection, members2, nullable, rev, max = INDEX_MAX_ROWS) {
|
|
796
796
|
const fields = collection.index ?? [];
|
|
797
797
|
const rows = await storage.findMany(collection.model, {
|
|
798
|
-
where:
|
|
798
|
+
where: members2,
|
|
799
799
|
select: indexSelect(collection, fields),
|
|
800
800
|
orderBy: orderByOf(collection.order, nullable),
|
|
801
801
|
take: max + 1
|
|
@@ -1056,8 +1056,17 @@ function bindingOf(state, contract) {
|
|
|
1056
1056
|
}
|
|
1057
1057
|
return binding;
|
|
1058
1058
|
}
|
|
1059
|
+
function sameRead(a, b) {
|
|
1060
|
+
const columns = ["model", "entry", "user", "level"].every((key) => a[key] === b[key]);
|
|
1061
|
+
if (!columns || a.levels === void 0 || b.levels === void 0) {
|
|
1062
|
+
return columns && a.levels === b.levels;
|
|
1063
|
+
}
|
|
1064
|
+
const mapped = b.levels;
|
|
1065
|
+
const roles = Object.entries(a.levels);
|
|
1066
|
+
return roles.length === Object.keys(mapped).length && roles.every(([role, level]) => Object.hasOwn(mapped, role) && mapped[role] === level);
|
|
1067
|
+
}
|
|
1059
1068
|
function membershipScope(scope, binding, read) {
|
|
1060
|
-
const declared = binding.memberships.get(read);
|
|
1069
|
+
const declared = binding.memberships.get(read) ?? [...binding.memberships].find(([known]) => sameRead(known, read))?.[1];
|
|
1061
1070
|
if (declared !== void 0) {
|
|
1062
1071
|
return [scope.cached, declared];
|
|
1063
1072
|
}
|
|
@@ -1538,8 +1547,11 @@ function receive(deps, state, frame) {
|
|
|
1538
1547
|
return;
|
|
1539
1548
|
}
|
|
1540
1549
|
const { principal } = state.socket.data;
|
|
1541
|
-
|
|
1542
|
-
|
|
1550
|
+
if (principal === null || channel.kinds?.has(principal.kind ?? "") === false) {
|
|
1551
|
+
return;
|
|
1552
|
+
}
|
|
1553
|
+
const parsed = parse(deps, channel, payload);
|
|
1554
|
+
if (parsed === void 0) {
|
|
1543
1555
|
return;
|
|
1544
1556
|
}
|
|
1545
1557
|
const room = allowed(channel, state.socket, principal, parsed.value);
|
|
@@ -2098,6 +2110,44 @@ var StreamIndex = class {
|
|
|
2098
2110
|
}
|
|
2099
2111
|
};
|
|
2100
2112
|
|
|
2113
|
+
// src/server/access/kinds.ts
|
|
2114
|
+
function isKindList(value) {
|
|
2115
|
+
return Array.isArray(value) && value.length > 0 && value.every((kind) => typeof kind === "string" && kind.length > 0);
|
|
2116
|
+
}
|
|
2117
|
+
function narrowKinds(value, above, fail5) {
|
|
2118
|
+
if (value === void 0) {
|
|
2119
|
+
return above?.kinds;
|
|
2120
|
+
}
|
|
2121
|
+
if (!isKindList(value)) {
|
|
2122
|
+
fail5(
|
|
2123
|
+
'kinds must be a non-empty list of principal kinds (strings), such as ["user"]; leave it out to admit every kind'
|
|
2124
|
+
);
|
|
2125
|
+
}
|
|
2126
|
+
if (above?.kinds !== void 0) {
|
|
2127
|
+
const { kinds, by } = above;
|
|
2128
|
+
const wider = value.find((kind) => !kinds.includes(kind));
|
|
2129
|
+
if (wider !== void 0) {
|
|
2130
|
+
fail5(
|
|
2131
|
+
`kinds may only narrow the kinds ${by} admits (${kinds.join(", ")}), and "${wider}" is not one of them`
|
|
2132
|
+
);
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
return Object.freeze([...new Set(value)]);
|
|
2136
|
+
}
|
|
2137
|
+
function checkKind(kinds, principal, what) {
|
|
2138
|
+
if (kinds === void 0 || principal === null) {
|
|
2139
|
+
return;
|
|
2140
|
+
}
|
|
2141
|
+
const { kind } = principal;
|
|
2142
|
+
if (typeof kind === "string" && kinds.includes(kind)) {
|
|
2143
|
+
return;
|
|
2144
|
+
}
|
|
2145
|
+
throw new QuickdrawError(
|
|
2146
|
+
"FORBIDDEN",
|
|
2147
|
+
kind === void 0 ? `${what} is not open to a principal without a kind` : `${what} is not open to principals of kind "${String(kind)}"`
|
|
2148
|
+
);
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2101
2151
|
// src/server/realtime/streamTargets.ts
|
|
2102
2152
|
function isName(value) {
|
|
2103
2153
|
return typeof value === "string" && value.length > 0;
|
|
@@ -2144,6 +2194,7 @@ function inStreamRoom(socket, access, scope) {
|
|
|
2144
2194
|
return room !== void 0 && joined !== void 0 && Object.hasOwn(joined, room);
|
|
2145
2195
|
}
|
|
2146
2196
|
async function authorizeStream(hub, socket, target2) {
|
|
2197
|
+
checkKind(target2.service.kinds, socket.data.principal, target2.service.name);
|
|
2147
2198
|
const { room } = target2.stream;
|
|
2148
2199
|
if (room !== void 0) {
|
|
2149
2200
|
if (!inStreamRoom(socket, room, target2.scope)) {
|
|
@@ -2336,6 +2387,220 @@ function createBasicAccessEngine(options = {}) {
|
|
|
2336
2387
|
});
|
|
2337
2388
|
}
|
|
2338
2389
|
|
|
2390
|
+
// src/server/access/policies/anyOf.ts
|
|
2391
|
+
function unionReads(policies) {
|
|
2392
|
+
const memberships = /* @__PURE__ */ new Set();
|
|
2393
|
+
for (const policy of policies) {
|
|
2394
|
+
for (const read of policy.reads.memberships) {
|
|
2395
|
+
memberships.add(read);
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
return {
|
|
2399
|
+
columns: [...new Set(policies.flatMap((policy) => policy.reads.columns))],
|
|
2400
|
+
memberships: [...memberships],
|
|
2401
|
+
inherits: [...new Set(policies.flatMap((policy) => policy.reads.inherits))],
|
|
2402
|
+
parents: policies.flatMap((policy) => policy.reads.parents ?? []),
|
|
2403
|
+
storage: policies.some((policy) => policy.reads.storage)
|
|
2404
|
+
};
|
|
2405
|
+
}
|
|
2406
|
+
var MEMBERS = /* @__PURE__ */ new WeakMap();
|
|
2407
|
+
function anyOfPolicies(policy) {
|
|
2408
|
+
return MEMBERS.get(policy);
|
|
2409
|
+
}
|
|
2410
|
+
function anyOf(...policies) {
|
|
2411
|
+
if (policies.length === 0 || !policies.every(isAccessPolicy)) {
|
|
2412
|
+
throw new TypeError("anyOf(...policies): pass one or more access policies");
|
|
2413
|
+
}
|
|
2414
|
+
const all = Object.freeze([...policies]);
|
|
2415
|
+
const combined = definePolicy({
|
|
2416
|
+
kind: "anyOf",
|
|
2417
|
+
policies: all,
|
|
2418
|
+
reads: unionReads(all),
|
|
2419
|
+
async levelsFor(principal, ids, tools) {
|
|
2420
|
+
const each = await Promise.all(all.map((policy) => policy.levelsFor(principal, ids, tools)));
|
|
2421
|
+
const levels = /* @__PURE__ */ new Map();
|
|
2422
|
+
for (const id of ids) {
|
|
2423
|
+
levels.set(
|
|
2424
|
+
id,
|
|
2425
|
+
each.reduce((level, granted) => maxLevel(level, granted.get(id)), null)
|
|
2426
|
+
);
|
|
2427
|
+
}
|
|
2428
|
+
return levels;
|
|
2429
|
+
},
|
|
2430
|
+
async accessWhere(principal, level, tools) {
|
|
2431
|
+
const filters = await Promise.all(
|
|
2432
|
+
all.map((policy) => policy.accessWhere(principal, level, tools))
|
|
2433
|
+
);
|
|
2434
|
+
const matching = filters.filter((filter) => filter !== "none");
|
|
2435
|
+
if (matching.some((filter) => Object.keys(filter).length === 0)) {
|
|
2436
|
+
return {};
|
|
2437
|
+
}
|
|
2438
|
+
if (matching.length <= 1) {
|
|
2439
|
+
return matching[0] ?? "none";
|
|
2440
|
+
}
|
|
2441
|
+
return { OR: matching };
|
|
2442
|
+
}
|
|
2443
|
+
});
|
|
2444
|
+
MEMBERS.set(combined, all);
|
|
2445
|
+
return combined;
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
// src/server/access/policies/members.ts
|
|
2449
|
+
function membershipOf(policy) {
|
|
2450
|
+
return policy.kind === "members" ? policy.reads.memberships[0] : void 0;
|
|
2451
|
+
}
|
|
2452
|
+
function checkLevels(owner, levels) {
|
|
2453
|
+
if (levels === void 0) {
|
|
2454
|
+
return void 0;
|
|
2455
|
+
}
|
|
2456
|
+
const valid = typeof levels === "object" && levels !== null && !Array.isArray(levels) && Object.values(levels).every(isAccessLevel);
|
|
2457
|
+
if (!valid) {
|
|
2458
|
+
throw new TypeError(
|
|
2459
|
+
`${owner}: levels must map stored roles to access levels, as in { editor: "Moderate" }`
|
|
2460
|
+
);
|
|
2461
|
+
}
|
|
2462
|
+
return Object.freeze({ ...levels });
|
|
2463
|
+
}
|
|
2464
|
+
function membershipRead(options, owner) {
|
|
2465
|
+
const { model, entry, user, level, levels } = options;
|
|
2466
|
+
return Object.freeze({
|
|
2467
|
+
model: checkName(owner("model"), "model", model),
|
|
2468
|
+
entry: checkName(owner("entry"), "entry", entry),
|
|
2469
|
+
user: checkName(owner("user"), "user", user),
|
|
2470
|
+
level: checkName(owner("level"), "level", level),
|
|
2471
|
+
levels: checkLevels(owner("levels"), levels)
|
|
2472
|
+
});
|
|
2473
|
+
}
|
|
2474
|
+
function rolesAtLeast(read, level) {
|
|
2475
|
+
const enough = new Set(levelsAtLeast(level));
|
|
2476
|
+
if (read.levels === void 0) {
|
|
2477
|
+
return [...enough];
|
|
2478
|
+
}
|
|
2479
|
+
return Object.entries(read.levels).filter(([, mapped]) => enough.has(mapped)).map(([role]) => role);
|
|
2480
|
+
}
|
|
2481
|
+
function members(options) {
|
|
2482
|
+
if (typeof options !== "object" || options === null) {
|
|
2483
|
+
throw new TypeError("members(options): options must be { model, entry, user, level }");
|
|
2484
|
+
}
|
|
2485
|
+
const read = membershipRead(options, (option) => `members({ ${option} })`);
|
|
2486
|
+
return definePolicy({
|
|
2487
|
+
kind: "members",
|
|
2488
|
+
membership: read,
|
|
2489
|
+
reads: { columns: [], memberships: [read], inherits: [], storage: true },
|
|
2490
|
+
levelsFor: (principal, ids, tools) => tools.memberships(read, principal.userId, ids),
|
|
2491
|
+
async accessWhere(principal, level, tools) {
|
|
2492
|
+
const roles = rolesAtLeast(read, level);
|
|
2493
|
+
if (roles.length === 0) {
|
|
2494
|
+
return "none";
|
|
2495
|
+
}
|
|
2496
|
+
const rows = await tools.storage.findMany(read.model, {
|
|
2497
|
+
where: { [read.user]: principal.userId, [read.level]: { in: roles } },
|
|
2498
|
+
select: { [read.entry]: true }
|
|
2499
|
+
});
|
|
2500
|
+
const entries = rows.map((row) => row[read.entry]);
|
|
2501
|
+
return idFilter(entries.filter((entry) => typeof entry === "string"));
|
|
2502
|
+
}
|
|
2503
|
+
});
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
// src/server/access/policies/resolver.ts
|
|
2507
|
+
var UNDECLARED = /* @__PURE__ */ new WeakSet();
|
|
2508
|
+
function declaresNoReads(policy) {
|
|
2509
|
+
return UNDECLARED.has(policy);
|
|
2510
|
+
}
|
|
2511
|
+
function noReads() {
|
|
2512
|
+
return { columns: [], memberships: [], inherits: [], storage: false };
|
|
2513
|
+
}
|
|
2514
|
+
var READ_KEYS = ["columns", "memberships"];
|
|
2515
|
+
function readsProblem(message) {
|
|
2516
|
+
throw new TypeError(`resolver({ reads }): ${message}`);
|
|
2517
|
+
}
|
|
2518
|
+
function checkColumns(columns) {
|
|
2519
|
+
if (columns === void 0) {
|
|
2520
|
+
return [];
|
|
2521
|
+
}
|
|
2522
|
+
const valid = Array.isArray(columns) && columns.every((column) => typeof column === "string" && column.length > 0);
|
|
2523
|
+
return valid ? Object.freeze([...new Set(columns)]) : readsProblem("columns must be a list of column names");
|
|
2524
|
+
}
|
|
2525
|
+
function checkMemberships(memberships) {
|
|
2526
|
+
if (memberships === void 0) {
|
|
2527
|
+
return [];
|
|
2528
|
+
}
|
|
2529
|
+
const valid = Array.isArray(memberships) && memberships.every((each) => typeof each === "object" && each !== null && !Array.isArray(each));
|
|
2530
|
+
if (!valid) {
|
|
2531
|
+
readsProblem("memberships must be a list of { model, entry, user, level, levels? }");
|
|
2532
|
+
}
|
|
2533
|
+
return Object.freeze(
|
|
2534
|
+
memberships.map(
|
|
2535
|
+
(each) => membershipRead(each, () => "resolver({ reads: { memberships } })")
|
|
2536
|
+
)
|
|
2537
|
+
);
|
|
2538
|
+
}
|
|
2539
|
+
function checkReads(reads) {
|
|
2540
|
+
if (reads === void 0) {
|
|
2541
|
+
return void 0;
|
|
2542
|
+
}
|
|
2543
|
+
if (reads === "none") {
|
|
2544
|
+
return noReads();
|
|
2545
|
+
}
|
|
2546
|
+
if (typeof reads !== "object" || reads === null || Array.isArray(reads)) {
|
|
2547
|
+
readsProblem('reads must be { columns?, memberships? } or "none"');
|
|
2548
|
+
}
|
|
2549
|
+
const given = reads;
|
|
2550
|
+
const unknownKey = Object.keys(given).find((key) => !READ_KEYS.includes(key));
|
|
2551
|
+
if (unknownKey !== void 0) {
|
|
2552
|
+
readsProblem(`reads has an unknown key "${unknownKey}"; the keys are columns and memberships`);
|
|
2553
|
+
}
|
|
2554
|
+
const columns = checkColumns(given.columns);
|
|
2555
|
+
const memberships = checkMemberships(given.memberships);
|
|
2556
|
+
if (columns.length === 0 && memberships.length === 0) {
|
|
2557
|
+
readsProblem('name a column or a membership table, or pass "none"');
|
|
2558
|
+
}
|
|
2559
|
+
return { columns, memberships, inherits: [], storage: true };
|
|
2560
|
+
}
|
|
2561
|
+
function levelIn(levels, id) {
|
|
2562
|
+
let level;
|
|
2563
|
+
if (levels instanceof Map) {
|
|
2564
|
+
level = levels.get(id);
|
|
2565
|
+
} else if (Object.hasOwn(levels, id)) {
|
|
2566
|
+
level = levels[id];
|
|
2567
|
+
}
|
|
2568
|
+
return isAccessLevel(level) ? level : null;
|
|
2569
|
+
}
|
|
2570
|
+
function resolver(options) {
|
|
2571
|
+
const valid = typeof options === "object" && options !== null && typeof options.levelsFor === "function" && (options.where === void 0 || typeof options.where === "function");
|
|
2572
|
+
if (!valid) {
|
|
2573
|
+
throw new TypeError(
|
|
2574
|
+
"resolver({ levelsFor, where?, reads? }): levelsFor and where must be functions"
|
|
2575
|
+
);
|
|
2576
|
+
}
|
|
2577
|
+
const { levelsFor, where: where2 } = options;
|
|
2578
|
+
const reads = checkReads(options.reads);
|
|
2579
|
+
const policy = definePolicy({
|
|
2580
|
+
kind: "resolver",
|
|
2581
|
+
reads: reads ?? noReads(),
|
|
2582
|
+
async levelsFor(principal, ids, tools) {
|
|
2583
|
+
const levels = await levelsFor(principal, ids, tools);
|
|
2584
|
+
if (typeof levels !== "object" || levels === null) {
|
|
2585
|
+
return levelsById(ids, () => null);
|
|
2586
|
+
}
|
|
2587
|
+
return levelsById(ids, (id) => levelIn(levels, id));
|
|
2588
|
+
},
|
|
2589
|
+
async accessWhere(principal, level, tools) {
|
|
2590
|
+
if (where2 === void 0) {
|
|
2591
|
+
return "none";
|
|
2592
|
+
}
|
|
2593
|
+
const filter = await where2(principal, level, tools);
|
|
2594
|
+
const isFilter = typeof filter === "object" && filter !== null && !Array.isArray(filter);
|
|
2595
|
+
return isFilter ? filter : "none";
|
|
2596
|
+
}
|
|
2597
|
+
});
|
|
2598
|
+
if (reads === void 0) {
|
|
2599
|
+
UNDECLARED.add(policy);
|
|
2600
|
+
}
|
|
2601
|
+
return policy;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2339
2604
|
// src/server/collections/scopes.ts
|
|
2340
2605
|
function serviceOf2(anchor) {
|
|
2341
2606
|
return anchor.slice(0, anchor.indexOf("\0"));
|
|
@@ -4146,6 +4411,8 @@ function mayWatchService(service, principal) {
|
|
|
4146
4411
|
return meetsLevel(serviceGrant(principal, service.name), form.service);
|
|
4147
4412
|
}
|
|
4148
4413
|
async function authorizeWatch(hub, principal, target2) {
|
|
4414
|
+
const service = target2.kind === "service" ? target2.service : target2.collection.service;
|
|
4415
|
+
checkKind(service.kinds, principal, service.name);
|
|
4149
4416
|
if (target2.kind === "service" && target2.service.watchAccess === void 0) {
|
|
4150
4417
|
throw new QuickdrawError(
|
|
4151
4418
|
"FORBIDDEN",
|
|
@@ -4211,9 +4478,9 @@ async function nullableColumns(storage, collection, values) {
|
|
|
4211
4478
|
return nullable;
|
|
4212
4479
|
}
|
|
4213
4480
|
async function readRows4(storage, collection, read) {
|
|
4214
|
-
const { members, values, nullable, limit } = read;
|
|
4481
|
+
const { members: members2, values, nullable, limit } = read;
|
|
4215
4482
|
const { order } = collection;
|
|
4216
|
-
const where2 = values === void 0 ?
|
|
4483
|
+
const where2 = values === void 0 ? members2 : { AND: [members2, afterCursor(order, values, nullable)] };
|
|
4217
4484
|
const [rows, total] = await Promise.allSettled([
|
|
4218
4485
|
storage.findMany(collection.model, {
|
|
4219
4486
|
where: where2,
|
|
@@ -4224,7 +4491,7 @@ async function readRows4(storage, collection, read) {
|
|
|
4224
4491
|
orderBy: orderByOf(order, nullable),
|
|
4225
4492
|
take: limit + 1
|
|
4226
4493
|
}),
|
|
4227
|
-
storage.count(collection.model, { where:
|
|
4494
|
+
storage.count(collection.model, { where: members2 })
|
|
4228
4495
|
]);
|
|
4229
4496
|
if (total.status === "rejected") {
|
|
4230
4497
|
throw total.reason;
|
|
@@ -4244,15 +4511,15 @@ async function readPage(storage, collection, request, rev) {
|
|
|
4244
4511
|
const { order } = collection;
|
|
4245
4512
|
const values = request.cursor === void 0 ? void 0 : decodeCursor(order, request.cursor);
|
|
4246
4513
|
const nullable = await nullableColumns(storage, collection, values);
|
|
4247
|
-
const
|
|
4514
|
+
const members2 = await membersWhere(storage, collection, request.scope);
|
|
4248
4515
|
const page = { ok: true, rev, limit, ...clamped ? { clamped: true } : {} };
|
|
4249
4516
|
const indexed = values === void 0 && collection.index !== void 0;
|
|
4250
|
-
if (
|
|
4517
|
+
if (members2 === void 0) {
|
|
4251
4518
|
return { ...page, items: [], total: 0, cursor: null, ...indexed ? { index: [] } : {} };
|
|
4252
4519
|
}
|
|
4253
4520
|
const [{ rows, total }, index] = await Promise.all([
|
|
4254
|
-
readRows4(storage, collection, { members, values, nullable, limit }),
|
|
4255
|
-
indexed ? readIndex(storage, collection,
|
|
4521
|
+
readRows4(storage, collection, { members: members2, values, nullable, limit }),
|
|
4522
|
+
indexed ? readIndex(storage, collection, members2, nullable, rev) : void 0
|
|
4256
4523
|
]);
|
|
4257
4524
|
const shown = rows.slice(0, limit);
|
|
4258
4525
|
const last = shown.at(-1);
|
|
@@ -4423,6 +4690,7 @@ function collectionSubscriptions(hub) {
|
|
|
4423
4690
|
answerEvent(socket, context, CLIENT_EVENTS.collectionSub, async (frame) => {
|
|
4424
4691
|
const request = readSubscribe(frame);
|
|
4425
4692
|
const { collection } = servedCollection(hub, socket, request);
|
|
4693
|
+
checkKind(collection.service.kinds, socket.data.principal, collection.service.name);
|
|
4426
4694
|
return await subscribeScope(hub, socket, collection, request);
|
|
4427
4695
|
});
|
|
4428
4696
|
answerEvent(socket, context, CLIENT_EVENTS.collectionItems, async (frame) => {
|
|
@@ -5074,13 +5342,18 @@ function createRealtime(hub) {
|
|
|
5074
5342
|
rooms.disconnected(socket);
|
|
5075
5343
|
});
|
|
5076
5344
|
},
|
|
5345
|
+
legacyExtension(socket, context) {
|
|
5346
|
+
onDisconnect(socket, context, () => {
|
|
5347
|
+
rooms.disconnected(socket);
|
|
5348
|
+
});
|
|
5349
|
+
},
|
|
5077
5350
|
presence,
|
|
5078
5351
|
rooms: rooms.server,
|
|
5079
5352
|
onRoomLeave: (hooks, run2) => {
|
|
5080
5353
|
rooms.onLeave(hooks, run2);
|
|
5081
5354
|
},
|
|
5082
5355
|
roomsFor(transport, connectionId, share) {
|
|
5083
|
-
const socket = transport === "socket" && connectionId !== void 0 ? hub.io?.sockets.sockets.get(connectionId) : void 0;
|
|
5356
|
+
const socket = (transport === "socket" || transport === "legacy") && connectionId !== void 0 ? hub.io?.sockets.sockets.get(connectionId) : void 0;
|
|
5084
5357
|
const own = socket === void 0 ? rooms.detached : rooms.of(socket);
|
|
5085
5358
|
return share === void 0 ? own : unjoinable(own, share);
|
|
5086
5359
|
},
|
|
@@ -5686,6 +5959,7 @@ async function onSubscribe(hub, socket, frame) {
|
|
|
5686
5959
|
if (socket.data.principal === null) {
|
|
5687
5960
|
throw new QuickdrawError("UNAUTHENTICATED", "Authentication required");
|
|
5688
5961
|
}
|
|
5962
|
+
checkKind(target2.service.kinds, socket.data.principal, target2.service.name);
|
|
5689
5963
|
if (hub.storage === void 0) {
|
|
5690
5964
|
throw new QuickdrawError(
|
|
5691
5965
|
"INTERNAL",
|
|
@@ -5932,6 +6206,7 @@ function createLive(options) {
|
|
|
5932
6206
|
topics.extension(...args);
|
|
5933
6207
|
realtime.extension(...args);
|
|
5934
6208
|
},
|
|
6209
|
+
legacyExtension: realtime.legacyExtension,
|
|
5935
6210
|
realtime,
|
|
5936
6211
|
revisions: hub.revisions,
|
|
5937
6212
|
attach(io, probe, cluster, broadcasts) {
|
|
@@ -6477,11 +6752,41 @@ function createPolicyEngine(options) {
|
|
|
6477
6752
|
});
|
|
6478
6753
|
}
|
|
6479
6754
|
|
|
6755
|
+
// src/server/access/resolverReads.ts
|
|
6756
|
+
function hasUndeclaredResolver(policy) {
|
|
6757
|
+
return declaresNoReads(policy) || (anyOfPolicies(policy)?.some(hasUndeclaredResolver) ?? false);
|
|
6758
|
+
}
|
|
6759
|
+
function resolverReadsWarnings(service) {
|
|
6760
|
+
const { access, model } = service;
|
|
6761
|
+
if (access === void 0 || model === void 0 || !hasUndeclaredResolver(access)) {
|
|
6762
|
+
return [];
|
|
6763
|
+
}
|
|
6764
|
+
return [
|
|
6765
|
+
{
|
|
6766
|
+
kind: "resolver-without-reads",
|
|
6767
|
+
service: service.name,
|
|
6768
|
+
message: `${service.name}: its access policy uses a resolver that declares no reads, so no tracked write re-checks the levels it gives: a live row, collection scope or change topic it authorized stays open after the user loses access. Declare what the levels depend on, resolver({ levelsFor, reads: { columns, memberships } }) (columns of the ${model} model, membership tables as members() takes them), or reads: "none" when nothing a tracked write changes can change them`,
|
|
6769
|
+
meta: { model }
|
|
6770
|
+
}
|
|
6771
|
+
];
|
|
6772
|
+
}
|
|
6773
|
+
function warnResolverReads(registry, warnings) {
|
|
6774
|
+
if (!warnings.enabled) {
|
|
6775
|
+
return;
|
|
6776
|
+
}
|
|
6777
|
+
for (const service of registry.services.values()) {
|
|
6778
|
+
for (const warning of resolverReadsWarnings(service)) {
|
|
6779
|
+
warnings.warn(warning);
|
|
6780
|
+
}
|
|
6781
|
+
}
|
|
6782
|
+
}
|
|
6783
|
+
|
|
6480
6784
|
// src/server/pipeline/accessSettings.ts
|
|
6481
6785
|
function isAccessEngine(value) {
|
|
6482
6786
|
return typeof value === "object" && value !== null && typeof value.authorize === "function";
|
|
6483
6787
|
}
|
|
6484
|
-
function resolveAccess2(access, registry, storage,
|
|
6788
|
+
function resolveAccess2(access, registry, storage, report) {
|
|
6789
|
+
const { logger, warnings } = report;
|
|
6485
6790
|
if (access !== void 0 && (typeof access !== "object" || access === null)) {
|
|
6486
6791
|
throw new TypeError("createDispatcher: access must be an access engine or { cacheMs }");
|
|
6487
6792
|
}
|
|
@@ -6493,6 +6798,7 @@ function resolveAccess2(access, registry, storage, logger) {
|
|
|
6493
6798
|
logger,
|
|
6494
6799
|
cacheMs: accessOptions.cacheMs
|
|
6495
6800
|
});
|
|
6801
|
+
warnResolverReads(registry, warnings);
|
|
6496
6802
|
return { access: engine ?? createBasicAccessEngine({ rows: policies.rows }), policies };
|
|
6497
6803
|
}
|
|
6498
6804
|
|
|
@@ -6626,7 +6932,10 @@ function resolveSettings(options, registry, db, accessSinks = []) {
|
|
|
6626
6932
|
const warnings = createDevWarnings({ logger, development, strict: strictWarningsOf(options) });
|
|
6627
6933
|
warnTieredOutputs(registry, warnings);
|
|
6628
6934
|
const storage = storageFor(options, db);
|
|
6629
|
-
const { access, policies } = resolveAccess2(options.access, registry, storage,
|
|
6935
|
+
const { access, policies } = resolveAccess2(options.access, registry, storage, {
|
|
6936
|
+
logger,
|
|
6937
|
+
warnings
|
|
6938
|
+
});
|
|
6630
6939
|
const outputValidation = options.outputValidation ?? development;
|
|
6631
6940
|
const live = createLive({
|
|
6632
6941
|
registry,
|
|
@@ -7086,7 +7395,7 @@ function contextFor(settings, request, requestId, target2, signal, dispatch) {
|
|
|
7086
7395
|
log,
|
|
7087
7396
|
requestId,
|
|
7088
7397
|
transport: request.transport,
|
|
7089
|
-
...request.transport === "socket" && request.connectionId !== void 0 ? { socketId: request.connectionId } : {},
|
|
7398
|
+
...(request.transport === "socket" || request.transport === "legacy") && request.connectionId !== void 0 ? { socketId: request.connectionId } : {},
|
|
7090
7399
|
...request.mcp === void 0 ? {} : { mcp: request.mcp },
|
|
7091
7400
|
touch: settings.touch,
|
|
7092
7401
|
rooms: realtime.roomsFor(request.transport, request.connectionId, target2.method.share),
|
|
@@ -7134,6 +7443,7 @@ async function proceed(pipeline, call, target2) {
|
|
|
7134
7443
|
const { request } = call;
|
|
7135
7444
|
const label = `${target2.service.name}.${target2.method.name}`;
|
|
7136
7445
|
const input = await stage(call, parseInput(target2.method.input, request.input, label));
|
|
7446
|
+
checkKind(target2.method.kinds, request.principal, label);
|
|
7137
7447
|
const ctx = contextFor(settings, request, call.requestId, target2, call.signal, pipeline.dispatch);
|
|
7138
7448
|
const access = {
|
|
7139
7449
|
service: target2.service,
|
|
@@ -8021,17 +8331,58 @@ function toLegacyReply(result) {
|
|
|
8021
8331
|
return { success: true, data: result.notModified === true ? void 0 : result.data };
|
|
8022
8332
|
}
|
|
8023
8333
|
var LEGACY_INTERNAL = Object.freeze(legacyFailure("INTERNAL", "Internal error"));
|
|
8024
|
-
function
|
|
8334
|
+
function resolveLegacyWire(option, registered) {
|
|
8335
|
+
if (option === void 0 || option === false) {
|
|
8336
|
+
return void 0;
|
|
8337
|
+
}
|
|
8338
|
+
if (option === true) {
|
|
8339
|
+
return { aliases: /* @__PURE__ */ new Map() };
|
|
8340
|
+
}
|
|
8341
|
+
if (typeof option !== "object" || option === null || Array.isArray(option)) {
|
|
8342
|
+
throw new TypeError("createServer: legacyWire must be a boolean or { aliases }");
|
|
8343
|
+
}
|
|
8344
|
+
for (const key of Object.keys(option)) {
|
|
8345
|
+
if (key !== "aliases") {
|
|
8346
|
+
throw new TypeError(`createServer: legacyWire has an unknown option "${key}"`);
|
|
8347
|
+
}
|
|
8348
|
+
}
|
|
8349
|
+
const { aliases = {} } = option;
|
|
8350
|
+
if (typeof aliases !== "object" || aliases === null || Array.isArray(aliases)) {
|
|
8351
|
+
throw new TypeError("createServer: legacyWire.aliases must map old service names to new ones");
|
|
8352
|
+
}
|
|
8353
|
+
const services = new Set(registered.map((service) => service.name));
|
|
8354
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
8355
|
+
for (const [alias, target2] of Object.entries(aliases)) {
|
|
8356
|
+
const entry = `legacyWire.aliases[${JSON.stringify(alias)}]`;
|
|
8357
|
+
if (alias === "" || alias.includes(":")) {
|
|
8358
|
+
throw new TypeError(`createServer: ${entry} must be a service name without ":"`);
|
|
8359
|
+
}
|
|
8360
|
+
if (services.has(alias)) {
|
|
8361
|
+
throw new TypeError(
|
|
8362
|
+
`createServer: ${entry} is a registered service's own name, so it cannot be an alias`
|
|
8363
|
+
);
|
|
8364
|
+
}
|
|
8365
|
+
if (typeof target2 !== "string" || !services.has(target2)) {
|
|
8366
|
+
throw new TypeError(
|
|
8367
|
+
`createServer: ${entry} names ${JSON.stringify(target2)}, which is not a registered service`
|
|
8368
|
+
);
|
|
8369
|
+
}
|
|
8370
|
+
resolved.set(alias, target2);
|
|
8371
|
+
}
|
|
8372
|
+
return { aliases: resolved };
|
|
8373
|
+
}
|
|
8374
|
+
function targetOf5(event, registry, aliases) {
|
|
8025
8375
|
if (typeof event !== "string") {
|
|
8026
8376
|
return void 0;
|
|
8027
8377
|
}
|
|
8028
8378
|
const colon = event.indexOf(":");
|
|
8029
|
-
const
|
|
8379
|
+
const called = event.slice(0, colon);
|
|
8030
8380
|
const method = event.slice(colon + 1);
|
|
8031
|
-
|
|
8381
|
+
const service = aliases.get(called);
|
|
8382
|
+
if (colon <= 0 || registry.find(service ?? called, method) === void 0) {
|
|
8032
8383
|
return void 0;
|
|
8033
8384
|
}
|
|
8034
|
-
return { service, method };
|
|
8385
|
+
return service === void 0 ? { service: called, method } : { service, method, alias: called };
|
|
8035
8386
|
}
|
|
8036
8387
|
function principalKind(principal) {
|
|
8037
8388
|
if (principal === null) {
|
|
@@ -8041,15 +8392,18 @@ function principalKind(principal) {
|
|
|
8041
8392
|
}
|
|
8042
8393
|
function noteCaller(context, seen, target2, principal) {
|
|
8043
8394
|
const kind = principalKind(principal);
|
|
8044
|
-
const
|
|
8395
|
+
const { service, method, alias } = target2;
|
|
8396
|
+
const key = `${alias ?? service}\0${method}\0${kind}`;
|
|
8045
8397
|
if (seen.has(key)) {
|
|
8046
8398
|
return;
|
|
8047
8399
|
}
|
|
8048
8400
|
seen.add(key);
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8401
|
+
const as = alias === void 0 ? "" : ` as ${alias}.${method}`;
|
|
8402
|
+
context.logger.warn(`A 4.x client called ${service}.${method}${as} through the legacy shim`, {
|
|
8403
|
+
category: "quickdraw.legacy",
|
|
8404
|
+
...target2,
|
|
8405
|
+
principalKind: kind
|
|
8406
|
+
});
|
|
8053
8407
|
}
|
|
8054
8408
|
function serve2(socket, context, calls, call) {
|
|
8055
8409
|
const controller = new AbortController();
|
|
@@ -8075,19 +8429,20 @@ function serve2(socket, context, calls, call) {
|
|
|
8075
8429
|
respond: (result) => acknowledge(context.meter, call.ack, toLegacyReply(result), LEGACY_INTERNAL, report)
|
|
8076
8430
|
}).then(release3, release3);
|
|
8077
8431
|
}
|
|
8078
|
-
function attachLegacyShim(socket, context, seen) {
|
|
8432
|
+
function attachLegacyShim(socket, context, seen, wire) {
|
|
8079
8433
|
const calls = /* @__PURE__ */ new Set();
|
|
8080
8434
|
socket.use((packet, next) => {
|
|
8081
8435
|
const [event, ...args] = packet;
|
|
8082
8436
|
const ack = args.at(-1);
|
|
8083
|
-
const target2 = targetOf5(event, context.dispatcher.registry);
|
|
8437
|
+
const target2 = targetOf5(event, context.dispatcher.registry, wire.aliases);
|
|
8084
8438
|
if (target2 === void 0 || typeof ack !== "function") {
|
|
8085
8439
|
next();
|
|
8086
8440
|
return;
|
|
8087
8441
|
}
|
|
8088
8442
|
noteCaller(context, seen, target2, socket.data.principal);
|
|
8089
8443
|
const input = args.length > 1 ? args[0] : void 0;
|
|
8090
|
-
|
|
8444
|
+
const { service, method } = target2;
|
|
8445
|
+
serve2(socket, context, calls, { service, method, input, ack });
|
|
8091
8446
|
});
|
|
8092
8447
|
socket.on("disconnect", () => {
|
|
8093
8448
|
for (const controller of calls) {
|
|
@@ -8549,7 +8904,10 @@ function onConnection(settings) {
|
|
|
8549
8904
|
void socket.join(userRoom(principal.userId));
|
|
8550
8905
|
}
|
|
8551
8906
|
if (socket.data.protocol === "legacy") {
|
|
8552
|
-
attachLegacyShim(socket, settings, settings.legacyCallers);
|
|
8907
|
+
attachLegacyShim(socket, settings, settings.legacyCallers, settings.legacyWire);
|
|
8908
|
+
for (const extension of settings.legacyExtensions) {
|
|
8909
|
+
extension(socket, settings);
|
|
8910
|
+
}
|
|
8553
8911
|
return;
|
|
8554
8912
|
}
|
|
8555
8913
|
attachCallListeners(socket, settings);
|
|
@@ -8605,7 +8963,7 @@ function createSocketServer(httpServer, settings) {
|
|
|
8605
8963
|
settings.live?.attach(io, probe, settings.cluster, broadcasts);
|
|
8606
8964
|
listenForGrants(io, settings.live, settings.logger);
|
|
8607
8965
|
listenForDisconnects(io);
|
|
8608
|
-
io.use(protocolMiddleware(settings.legacyWire, context));
|
|
8966
|
+
io.use(protocolMiddleware(settings.legacyWire !== void 0, context));
|
|
8609
8967
|
io.use(authMiddleware(settings.resolvePrincipal, context));
|
|
8610
8968
|
if (settings.rateLimit !== false) {
|
|
8611
8969
|
applySocketRateLimit(io, settings.rateLimit, { ...context, loops: settings.loops });
|
|
@@ -8616,7 +8974,10 @@ function createSocketServer(httpServer, settings) {
|
|
|
8616
8974
|
...context,
|
|
8617
8975
|
hello: helloFrame(settings),
|
|
8618
8976
|
extensions: settings.live === void 0 ? settings.extensions : [...settings.extensions, settings.live.extension],
|
|
8619
|
-
|
|
8977
|
+
legacyExtensions: settings.live === void 0 ? [] : [settings.live.legacyExtension],
|
|
8978
|
+
legacyCallers: /* @__PURE__ */ new Set(),
|
|
8979
|
+
// A server that refuses 4.x clients has no 4.x socket to read it.
|
|
8980
|
+
legacyWire: settings.legacyWire ?? { aliases: /* @__PURE__ */ new Map() }
|
|
8620
8981
|
})
|
|
8621
8982
|
);
|
|
8622
8983
|
return {
|
|
@@ -8705,6 +9066,7 @@ function warnUnsourcedGrants(services, sourced, logger) {
|
|
|
8705
9066
|
}
|
|
8706
9067
|
function createServer(options) {
|
|
8707
9068
|
checkOptions(options);
|
|
9069
|
+
const legacyWire = resolveLegacyWire(options.legacyWire, options.services);
|
|
8708
9070
|
const logger = options.logger ?? consoleLogger;
|
|
8709
9071
|
warnUnsourcedGrants(options.services, options.auth?.serviceAccessSource !== void 0, logger);
|
|
8710
9072
|
const watchdog = prepareWatchdog(options, options.stallWatchdog);
|
|
@@ -8725,7 +9087,7 @@ function createServer(options) {
|
|
|
8725
9087
|
resolvePrincipal,
|
|
8726
9088
|
loadServiceAccess: options.auth?.loadServiceAccess,
|
|
8727
9089
|
binary: options.binary === true,
|
|
8728
|
-
legacyWire
|
|
9090
|
+
legacyWire,
|
|
8729
9091
|
cors: options.cors,
|
|
8730
9092
|
socket: options.socket,
|
|
8731
9093
|
rateLimit: options.rateLimit ?? {},
|
|
@@ -8782,6 +9144,7 @@ export {
|
|
|
8782
9144
|
custom,
|
|
8783
9145
|
isCustomAccess,
|
|
8784
9146
|
accessFormProblem,
|
|
9147
|
+
accessIds,
|
|
8785
9148
|
meetsLevel,
|
|
8786
9149
|
maxLevel,
|
|
8787
9150
|
levelsAtLeast,
|
|
@@ -8806,7 +9169,6 @@ export {
|
|
|
8806
9169
|
isAccessPolicy,
|
|
8807
9170
|
checkName,
|
|
8808
9171
|
levelsById,
|
|
8809
|
-
idFilter,
|
|
8810
9172
|
encodeCursor,
|
|
8811
9173
|
decodeCursor,
|
|
8812
9174
|
orderByOf,
|
|
@@ -8814,6 +9176,7 @@ export {
|
|
|
8814
9176
|
MAX_ITEM_IDS,
|
|
8815
9177
|
selectWith,
|
|
8816
9178
|
INDEX_MAX_ROWS,
|
|
9179
|
+
narrowKinds,
|
|
8817
9180
|
allowedScopes,
|
|
8818
9181
|
membersWhere,
|
|
8819
9182
|
CHANNEL_ABUSE_WINDOW_MS,
|
|
@@ -8823,6 +9186,11 @@ export {
|
|
|
8823
9186
|
STREAM_MAX_SCOPES,
|
|
8824
9187
|
MAX_STREAMS_PER_SOCKET,
|
|
8825
9188
|
createBasicAccessEngine,
|
|
9189
|
+
anyOfPolicies,
|
|
9190
|
+
anyOf,
|
|
9191
|
+
membershipOf,
|
|
9192
|
+
members,
|
|
9193
|
+
resolver,
|
|
8826
9194
|
DEFAULT_LIMITS,
|
|
8827
9195
|
MAX_TIMEOUT_MS,
|
|
8828
9196
|
createDispatcher,
|
|
@@ -8838,4 +9206,4 @@ export {
|
|
|
8838
9206
|
watchAdapterClients,
|
|
8839
9207
|
createServer
|
|
8840
9208
|
};
|
|
8841
|
-
//# sourceMappingURL=chunk-
|
|
9209
|
+
//# sourceMappingURL=chunk-A6DJBGOG.js.map
|