@classytic/arc 1.1.0 → 2.1.2
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 +247 -794
- package/bin/arc.js +91 -52
- package/dist/EventTransport-BD2U0BTc.d.mts +100 -0
- package/dist/EventTransport-BD2U0BTc.d.mts.map +1 -0
- package/dist/HookSystem-BsGV-j2l.mjs +405 -0
- package/dist/HookSystem-BsGV-j2l.mjs.map +1 -0
- package/dist/ResourceRegistry-DsN4KJjV.mjs +250 -0
- package/dist/ResourceRegistry-DsN4KJjV.mjs.map +1 -0
- package/dist/adapters/index.d.mts +5 -0
- package/dist/adapters/index.mjs +3 -0
- package/dist/audit/index.d.mts +82 -0
- package/dist/audit/index.d.mts.map +1 -0
- package/dist/audit/index.mjs +276 -0
- package/dist/audit/index.mjs.map +1 -0
- package/dist/audit/mongodb.d.mts +5 -0
- package/dist/audit/mongodb.mjs +3 -0
- package/dist/audited-C3T5DTUx.mjs +141 -0
- package/dist/audited-C3T5DTUx.mjs.map +1 -0
- package/dist/auth/index.d.mts +189 -0
- package/dist/auth/index.d.mts.map +1 -0
- package/dist/auth/index.mjs +1102 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/auth/redis-session.d.mts +44 -0
- package/dist/auth/redis-session.d.mts.map +1 -0
- package/dist/auth/redis-session.mjs +76 -0
- package/dist/auth/redis-session.mjs.map +1 -0
- package/dist/betterAuthOpenApi-BrHKeSAx.mjs +250 -0
- package/dist/betterAuthOpenApi-BrHKeSAx.mjs.map +1 -0
- package/dist/cache/index.d.mts +146 -0
- package/dist/cache/index.d.mts.map +1 -0
- package/dist/cache/index.mjs +92 -0
- package/dist/cache/index.mjs.map +1 -0
- package/dist/caching-Bl28lYsR.mjs +94 -0
- package/dist/caching-Bl28lYsR.mjs.map +1 -0
- package/dist/chunk-C7Uep-_p.mjs +20 -0
- package/dist/circuitBreaker-DeY4FCjs.mjs +1097 -0
- package/dist/circuitBreaker-DeY4FCjs.mjs.map +1 -0
- package/dist/cli/commands/describe.d.mts +19 -0
- package/dist/cli/commands/describe.d.mts.map +1 -0
- package/dist/cli/commands/describe.mjs +239 -0
- package/dist/cli/commands/describe.mjs.map +1 -0
- package/dist/cli/commands/docs.d.mts +14 -0
- package/dist/cli/commands/docs.d.mts.map +1 -0
- package/dist/cli/commands/docs.mjs +53 -0
- package/dist/cli/commands/docs.mjs.map +1 -0
- package/dist/cli/commands/{generate.d.ts → generate.d.mts} +3 -1
- package/dist/cli/commands/generate.d.mts.map +1 -0
- package/dist/cli/commands/generate.mjs +358 -0
- package/dist/cli/commands/generate.mjs.map +1 -0
- package/dist/cli/commands/{init.d.ts → init.d.mts} +12 -8
- package/dist/cli/commands/init.d.mts.map +1 -0
- package/dist/cli/commands/{init.js → init.mjs} +807 -616
- package/dist/cli/commands/init.mjs.map +1 -0
- package/dist/cli/commands/introspect.d.mts +11 -0
- package/dist/cli/commands/introspect.d.mts.map +1 -0
- package/dist/cli/commands/introspect.mjs +76 -0
- package/dist/cli/commands/introspect.mjs.map +1 -0
- package/dist/cli/index.d.mts +17 -0
- package/dist/cli/index.d.mts.map +1 -0
- package/dist/cli/index.mjs +157 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/constants-DdXFXQtN.mjs +85 -0
- package/dist/constants-DdXFXQtN.mjs.map +1 -0
- package/dist/core/index.d.mts +5 -0
- package/dist/core/index.mjs +4 -0
- package/dist/createApp-CUgNqegw.mjs +560 -0
- package/dist/createApp-CUgNqegw.mjs.map +1 -0
- package/dist/defineResource-k0_BDn8v.mjs +2197 -0
- package/dist/defineResource-k0_BDn8v.mjs.map +1 -0
- package/dist/discovery/index.d.mts +47 -0
- package/dist/discovery/index.d.mts.map +1 -0
- package/dist/discovery/index.mjs +110 -0
- package/dist/discovery/index.mjs.map +1 -0
- package/dist/docs/index.d.mts +163 -0
- package/dist/docs/index.d.mts.map +1 -0
- package/dist/docs/index.mjs +73 -0
- package/dist/docs/index.mjs.map +1 -0
- package/dist/elevation-BRy3yFWT.mjs +113 -0
- package/dist/elevation-BRy3yFWT.mjs.map +1 -0
- package/dist/elevation-B_2dRLVP.d.mts +88 -0
- package/dist/elevation-B_2dRLVP.d.mts.map +1 -0
- package/dist/errorHandler-BbcgBmIH.d.mts +73 -0
- package/dist/errorHandler-BbcgBmIH.d.mts.map +1 -0
- package/dist/errorHandler-C1okiriz.mjs +109 -0
- package/dist/errorHandler-C1okiriz.mjs.map +1 -0
- package/dist/errors-B9bZok84.mjs +212 -0
- package/dist/errors-B9bZok84.mjs.map +1 -0
- package/dist/errors-ChKiFz62.d.mts +125 -0
- package/dist/errors-ChKiFz62.d.mts.map +1 -0
- package/dist/eventPlugin-CTrLH3mt.d.mts +125 -0
- package/dist/eventPlugin-CTrLH3mt.d.mts.map +1 -0
- package/dist/eventPlugin-DGR_B2on.mjs +230 -0
- package/dist/eventPlugin-DGR_B2on.mjs.map +1 -0
- package/dist/events/index.d.mts +54 -0
- package/dist/events/index.d.mts.map +1 -0
- package/dist/events/index.mjs +52 -0
- package/dist/events/index.mjs.map +1 -0
- package/dist/events/transports/redis-stream-entry.d.mts +2 -0
- package/dist/events/transports/redis-stream-entry.mjs +178 -0
- package/dist/events/transports/redis-stream-entry.mjs.map +1 -0
- package/dist/events/transports/redis.d.mts +77 -0
- package/dist/events/transports/redis.d.mts.map +1 -0
- package/dist/events/transports/redis.mjs +125 -0
- package/dist/events/transports/redis.mjs.map +1 -0
- package/dist/externalPaths-DlINfKbP.d.mts +51 -0
- package/dist/externalPaths-DlINfKbP.d.mts.map +1 -0
- package/dist/factory/index.d.mts +64 -0
- package/dist/factory/index.d.mts.map +1 -0
- package/dist/factory/index.mjs +3 -0
- package/dist/fastifyAdapter-BkrGrlFi.d.mts +217 -0
- package/dist/fastifyAdapter-BkrGrlFi.d.mts.map +1 -0
- package/dist/fields-DyaDVX4J.d.mts +110 -0
- package/dist/fields-DyaDVX4J.d.mts.map +1 -0
- package/dist/fields-iagOozy0.mjs +115 -0
- package/dist/fields-iagOozy0.mjs.map +1 -0
- package/dist/hooks/index.d.mts +4 -0
- package/dist/hooks/index.mjs +3 -0
- package/dist/idempotency/index.d.mts +97 -0
- package/dist/idempotency/index.d.mts.map +1 -0
- package/dist/idempotency/index.mjs +320 -0
- package/dist/idempotency/index.mjs.map +1 -0
- package/dist/idempotency/mongodb.d.mts +2 -0
- package/dist/idempotency/mongodb.mjs +115 -0
- package/dist/idempotency/mongodb.mjs.map +1 -0
- package/dist/idempotency/redis.d.mts +2 -0
- package/dist/idempotency/redis.mjs +104 -0
- package/dist/idempotency/redis.mjs.map +1 -0
- package/dist/index.d.mts +261 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +105 -0
- package/dist/index.mjs.map +1 -0
- package/dist/integrations/event-gateway.d.mts +47 -0
- package/dist/integrations/event-gateway.d.mts.map +1 -0
- package/dist/integrations/event-gateway.mjs +44 -0
- package/dist/integrations/event-gateway.mjs.map +1 -0
- package/dist/integrations/index.d.mts +5 -0
- package/dist/integrations/index.mjs +1 -0
- package/dist/integrations/jobs.d.mts +104 -0
- package/dist/integrations/jobs.d.mts.map +1 -0
- package/dist/integrations/jobs.mjs +124 -0
- package/dist/integrations/jobs.mjs.map +1 -0
- package/dist/integrations/streamline.d.mts +61 -0
- package/dist/integrations/streamline.d.mts.map +1 -0
- package/dist/integrations/streamline.mjs +126 -0
- package/dist/integrations/streamline.mjs.map +1 -0
- package/dist/integrations/websocket.d.mts +83 -0
- package/dist/integrations/websocket.d.mts.map +1 -0
- package/dist/integrations/websocket.mjs +289 -0
- package/dist/integrations/websocket.mjs.map +1 -0
- package/dist/interface-B01JvPVc.d.mts +78 -0
- package/dist/interface-B01JvPVc.d.mts.map +1 -0
- package/dist/interface-CZe8IkMf.d.mts +55 -0
- package/dist/interface-CZe8IkMf.d.mts.map +1 -0
- package/dist/interface-Ch8HU9uM.d.mts +1098 -0
- package/dist/interface-Ch8HU9uM.d.mts.map +1 -0
- package/dist/introspectionPlugin-rFdO8ZUa.mjs +54 -0
- package/dist/introspectionPlugin-rFdO8ZUa.mjs.map +1 -0
- package/dist/keys-BqNejWup.mjs +43 -0
- package/dist/keys-BqNejWup.mjs.map +1 -0
- package/dist/logger-Df2O2WsW.mjs +79 -0
- package/dist/logger-Df2O2WsW.mjs.map +1 -0
- package/dist/memory-cQgelFOj.mjs +144 -0
- package/dist/memory-cQgelFOj.mjs.map +1 -0
- package/dist/migrations/index.d.mts +157 -0
- package/dist/migrations/index.d.mts.map +1 -0
- package/dist/migrations/index.mjs +261 -0
- package/dist/migrations/index.mjs.map +1 -0
- package/dist/mongodb-BfJVlUJH.mjs +94 -0
- package/dist/mongodb-BfJVlUJH.mjs.map +1 -0
- package/dist/mongodb-CGzRbfAK.d.mts +119 -0
- package/dist/mongodb-CGzRbfAK.d.mts.map +1 -0
- package/dist/mongodb-JN-9JA7K.d.mts +72 -0
- package/dist/mongodb-JN-9JA7K.d.mts.map +1 -0
- package/dist/openapi-G3Cw7XuM.mjs +524 -0
- package/dist/openapi-G3Cw7XuM.mjs.map +1 -0
- package/dist/org/index.d.mts +69 -0
- package/dist/org/index.d.mts.map +1 -0
- package/dist/org/index.mjs +514 -0
- package/dist/org/index.mjs.map +1 -0
- package/dist/org/types.d.mts +83 -0
- package/dist/org/types.d.mts.map +1 -0
- package/dist/org/types.mjs +1 -0
- package/dist/permissions/index.d.mts +279 -0
- package/dist/permissions/index.d.mts.map +1 -0
- package/dist/permissions/index.mjs +579 -0
- package/dist/permissions/index.mjs.map +1 -0
- package/dist/plugins/index.d.mts +173 -0
- package/dist/plugins/index.d.mts.map +1 -0
- package/dist/plugins/index.mjs +523 -0
- package/dist/plugins/index.mjs.map +1 -0
- package/dist/plugins/response-cache.d.mts +88 -0
- package/dist/plugins/response-cache.d.mts.map +1 -0
- package/dist/plugins/response-cache.mjs +284 -0
- package/dist/plugins/response-cache.mjs.map +1 -0
- package/dist/plugins/tracing-entry.d.mts +2 -0
- package/dist/plugins/tracing-entry.mjs +186 -0
- package/dist/plugins/tracing-entry.mjs.map +1 -0
- package/dist/pluralize-CEweyOEm.mjs +87 -0
- package/dist/pluralize-CEweyOEm.mjs.map +1 -0
- package/dist/policies/{index.d.ts → index.d.mts} +204 -169
- package/dist/policies/index.d.mts.map +1 -0
- package/dist/policies/index.mjs +322 -0
- package/dist/policies/index.mjs.map +1 -0
- package/dist/presets/{index.d.ts → index.d.mts} +63 -131
- package/dist/presets/index.d.mts.map +1 -0
- package/dist/presets/index.mjs +144 -0
- package/dist/presets/index.mjs.map +1 -0
- package/dist/presets/multiTenant.d.mts +25 -0
- package/dist/presets/multiTenant.d.mts.map +1 -0
- package/dist/presets/multiTenant.mjs +114 -0
- package/dist/presets/multiTenant.mjs.map +1 -0
- package/dist/presets-BITljm96.mjs +120 -0
- package/dist/presets-BITljm96.mjs.map +1 -0
- package/dist/presets-DzSMwlKj.d.mts +58 -0
- package/dist/presets-DzSMwlKj.d.mts.map +1 -0
- package/dist/prisma-DJbMt3yf.mjs +628 -0
- package/dist/prisma-DJbMt3yf.mjs.map +1 -0
- package/dist/prisma-Dg9GoVdj.d.mts +275 -0
- package/dist/prisma-Dg9GoVdj.d.mts.map +1 -0
- package/dist/queryCachePlugin-7THaI5mt.d.mts +72 -0
- package/dist/queryCachePlugin-7THaI5mt.d.mts.map +1 -0
- package/dist/queryCachePlugin-DMBnp2Q0.mjs +139 -0
- package/dist/queryCachePlugin-DMBnp2Q0.mjs.map +1 -0
- package/dist/redis-D-JAeLtm.d.mts +50 -0
- package/dist/redis-D-JAeLtm.d.mts.map +1 -0
- package/dist/redis-stream-Bdh_vUU8.d.mts +104 -0
- package/dist/redis-stream-Bdh_vUU8.d.mts.map +1 -0
- package/dist/registry/index.d.mts +12 -0
- package/dist/registry/index.d.mts.map +1 -0
- package/dist/registry/index.mjs +4 -0
- package/dist/requestContext-QQD6ROJc.mjs +56 -0
- package/dist/requestContext-QQD6ROJc.mjs.map +1 -0
- package/dist/schemaConverter-BwrmWroW.mjs +99 -0
- package/dist/schemaConverter-BwrmWroW.mjs.map +1 -0
- package/dist/schemas/index.d.mts +64 -0
- package/dist/schemas/index.d.mts.map +1 -0
- package/dist/schemas/index.mjs +83 -0
- package/dist/schemas/index.mjs.map +1 -0
- package/dist/scope/index.d.mts +22 -0
- package/dist/scope/index.d.mts.map +1 -0
- package/dist/scope/index.mjs +66 -0
- package/dist/scope/index.mjs.map +1 -0
- package/dist/sessionManager-jPKLbHE0.d.mts +187 -0
- package/dist/sessionManager-jPKLbHE0.d.mts.map +1 -0
- package/dist/sse-B3c3_yZp.mjs +124 -0
- package/dist/sse-B3c3_yZp.mjs.map +1 -0
- package/dist/testing/index.d.mts +908 -0
- package/dist/testing/index.d.mts.map +1 -0
- package/dist/testing/index.mjs +1977 -0
- package/dist/testing/index.mjs.map +1 -0
- package/dist/tracing-Cc7vVQPp.d.mts +71 -0
- package/dist/tracing-Cc7vVQPp.d.mts.map +1 -0
- package/dist/typeGuards-DhMNLuvU.mjs +10 -0
- package/dist/typeGuards-DhMNLuvU.mjs.map +1 -0
- package/dist/types/index.d.mts +947 -0
- package/dist/types/index.d.mts.map +1 -0
- package/dist/types/index.mjs +15 -0
- package/dist/types/index.mjs.map +1 -0
- package/dist/types-Beqn1Un7.mjs +39 -0
- package/dist/types-Beqn1Un7.mjs.map +1 -0
- package/dist/types-CIgB7UUl.d.mts +446 -0
- package/dist/types-CIgB7UUl.d.mts.map +1 -0
- package/dist/types-aYB4V7uN.d.mts +87 -0
- package/dist/types-aYB4V7uN.d.mts.map +1 -0
- package/dist/utils/index.d.mts +748 -0
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +6 -0
- package/package.json +194 -68
- package/dist/BaseController-DVAiHxEQ.d.ts +0 -233
- package/dist/adapters/index.d.ts +0 -237
- package/dist/adapters/index.js +0 -668
- package/dist/arcCorePlugin-CsShQdyP.d.ts +0 -273
- package/dist/audit/index.d.ts +0 -195
- package/dist/audit/index.js +0 -319
- package/dist/auth/index.d.ts +0 -47
- package/dist/auth/index.js +0 -174
- package/dist/cli/commands/docs.d.ts +0 -11
- package/dist/cli/commands/docs.js +0 -474
- package/dist/cli/commands/generate.js +0 -334
- package/dist/cli/commands/introspect.d.ts +0 -8
- package/dist/cli/commands/introspect.js +0 -338
- package/dist/cli/index.d.ts +0 -4
- package/dist/cli/index.js +0 -3269
- package/dist/core/index.d.ts +0 -220
- package/dist/core/index.js +0 -2786
- package/dist/createApp-Ce9wl8W9.d.ts +0 -77
- package/dist/docs/index.d.ts +0 -166
- package/dist/docs/index.js +0 -658
- package/dist/errors-8WIxGS_6.d.ts +0 -122
- package/dist/events/index.d.ts +0 -117
- package/dist/events/index.js +0 -89
- package/dist/factory/index.d.ts +0 -38
- package/dist/factory/index.js +0 -1652
- package/dist/hooks/index.d.ts +0 -4
- package/dist/hooks/index.js +0 -199
- package/dist/idempotency/index.d.ts +0 -323
- package/dist/idempotency/index.js +0 -500
- package/dist/index-B4t03KQ0.d.ts +0 -1366
- package/dist/index.d.ts +0 -135
- package/dist/index.js +0 -4756
- package/dist/migrations/index.d.ts +0 -185
- package/dist/migrations/index.js +0 -274
- package/dist/org/index.d.ts +0 -129
- package/dist/org/index.js +0 -220
- package/dist/permissions/index.d.ts +0 -144
- package/dist/permissions/index.js +0 -103
- package/dist/plugins/index.d.ts +0 -46
- package/dist/plugins/index.js +0 -1069
- package/dist/policies/index.js +0 -196
- package/dist/presets/index.js +0 -384
- package/dist/presets/multiTenant.d.ts +0 -39
- package/dist/presets/multiTenant.js +0 -112
- package/dist/registry/index.d.ts +0 -16
- package/dist/registry/index.js +0 -253
- package/dist/testing/index.d.ts +0 -618
- package/dist/testing/index.js +0 -48020
- package/dist/types/index.d.ts +0 -4
- package/dist/types/index.js +0 -8
- package/dist/types-B99TBmFV.d.ts +0 -76
- package/dist/types-BvckRbs2.d.ts +0 -143
- package/dist/utils/index.d.ts +0 -679
- package/dist/utils/index.js +0 -931
package/dist/policies/index.js
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
// src/policies/helpers.ts
|
|
2
|
-
function createPolicyMiddleware(policy, operation) {
|
|
3
|
-
return async function policyMiddleware(request, reply) {
|
|
4
|
-
const context = {
|
|
5
|
-
document: request.document,
|
|
6
|
-
body: request.body,
|
|
7
|
-
params: request.params,
|
|
8
|
-
query: request.query
|
|
9
|
-
};
|
|
10
|
-
const result = await policy.can(request.user, operation, context);
|
|
11
|
-
if (!result.allowed) {
|
|
12
|
-
return reply.code(403).send({
|
|
13
|
-
success: false,
|
|
14
|
-
error: "Access denied",
|
|
15
|
-
message: result.reason || "You do not have permission to perform this action"
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
request.policyResult = result;
|
|
19
|
-
if (result.filters && Object.keys(result.filters).length > 0) {
|
|
20
|
-
request.query = request.query || {};
|
|
21
|
-
request.query._policyFilters = result.filters;
|
|
22
|
-
}
|
|
23
|
-
if (result.fieldMask) {
|
|
24
|
-
request.fieldMask = result.fieldMask;
|
|
25
|
-
}
|
|
26
|
-
if (result.metadata) {
|
|
27
|
-
request.policyMetadata = result.metadata;
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function combinePolicies(...policies) {
|
|
32
|
-
if (policies.length === 0) {
|
|
33
|
-
throw new Error("combinePolicies requires at least one policy");
|
|
34
|
-
}
|
|
35
|
-
if (policies.length === 1) {
|
|
36
|
-
return policies[0];
|
|
37
|
-
}
|
|
38
|
-
return {
|
|
39
|
-
async can(user, operation, context) {
|
|
40
|
-
const results = [];
|
|
41
|
-
for (const policy of policies) {
|
|
42
|
-
const result = await policy.can(user, operation, context);
|
|
43
|
-
if (!result.allowed) {
|
|
44
|
-
return result;
|
|
45
|
-
}
|
|
46
|
-
results.push(result);
|
|
47
|
-
}
|
|
48
|
-
const mergedResult = {
|
|
49
|
-
allowed: true,
|
|
50
|
-
filters: {},
|
|
51
|
-
metadata: {}
|
|
52
|
-
};
|
|
53
|
-
for (const result of results) {
|
|
54
|
-
if (result.filters) {
|
|
55
|
-
Object.assign(mergedResult.filters, result.filters);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
const allExcludes = /* @__PURE__ */ new Set();
|
|
59
|
-
const allIncludes = [];
|
|
60
|
-
for (const result of results) {
|
|
61
|
-
if (result.fieldMask?.exclude) {
|
|
62
|
-
result.fieldMask.exclude.forEach((field) => allExcludes.add(field));
|
|
63
|
-
}
|
|
64
|
-
if (result.fieldMask?.include) {
|
|
65
|
-
allIncludes.push(new Set(result.fieldMask.include));
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (allExcludes.size > 0 || allIncludes.length > 0) {
|
|
69
|
-
mergedResult.fieldMask = {};
|
|
70
|
-
if (allExcludes.size > 0) {
|
|
71
|
-
mergedResult.fieldMask.exclude = Array.from(allExcludes);
|
|
72
|
-
}
|
|
73
|
-
if (allIncludes.length > 0) {
|
|
74
|
-
const intersection = allIncludes.reduce((acc, set) => {
|
|
75
|
-
return new Set([...acc].filter((x) => set.has(x)));
|
|
76
|
-
});
|
|
77
|
-
if (intersection.size > 0) {
|
|
78
|
-
mergedResult.fieldMask.include = Array.from(intersection);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
for (const result of results) {
|
|
83
|
-
if (result.metadata) {
|
|
84
|
-
Object.assign(mergedResult.metadata, result.metadata);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (Object.keys(mergedResult.filters).length === 0) {
|
|
88
|
-
delete mergedResult.filters;
|
|
89
|
-
}
|
|
90
|
-
if (Object.keys(mergedResult.metadata).length === 0) {
|
|
91
|
-
delete mergedResult.metadata;
|
|
92
|
-
}
|
|
93
|
-
return mergedResult;
|
|
94
|
-
},
|
|
95
|
-
toMiddleware(operation) {
|
|
96
|
-
const middlewares = policies.map((p) => p.toMiddleware(operation));
|
|
97
|
-
return async (request, reply) => {
|
|
98
|
-
for (const middleware of middlewares) {
|
|
99
|
-
await middleware(request, reply);
|
|
100
|
-
if (reply.sent) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
function anyPolicy(...policies) {
|
|
109
|
-
if (policies.length === 0) {
|
|
110
|
-
throw new Error("anyPolicy requires at least one policy");
|
|
111
|
-
}
|
|
112
|
-
if (policies.length === 1) {
|
|
113
|
-
return policies[0];
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
async can(user, operation, context) {
|
|
117
|
-
let firstDenial = null;
|
|
118
|
-
for (const policy of policies) {
|
|
119
|
-
const result = await policy.can(user, operation, context);
|
|
120
|
-
if (result.allowed) {
|
|
121
|
-
return result;
|
|
122
|
-
}
|
|
123
|
-
if (!firstDenial) {
|
|
124
|
-
firstDenial = result;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return firstDenial;
|
|
128
|
-
},
|
|
129
|
-
toMiddleware(operation) {
|
|
130
|
-
return async (request, reply) => {
|
|
131
|
-
const results = [];
|
|
132
|
-
for (const policy of policies) {
|
|
133
|
-
const result = await policy.can(
|
|
134
|
-
request.user,
|
|
135
|
-
operation,
|
|
136
|
-
{
|
|
137
|
-
document: request.document,
|
|
138
|
-
body: request.body,
|
|
139
|
-
params: request.params,
|
|
140
|
-
query: request.query
|
|
141
|
-
}
|
|
142
|
-
);
|
|
143
|
-
if (result.allowed) {
|
|
144
|
-
request.policyResult = result;
|
|
145
|
-
if (result.filters) {
|
|
146
|
-
request.query = request.query || {};
|
|
147
|
-
request.query._policyFilters = result.filters;
|
|
148
|
-
}
|
|
149
|
-
if (result.fieldMask) {
|
|
150
|
-
request.fieldMask = result.fieldMask;
|
|
151
|
-
}
|
|
152
|
-
if (result.metadata) {
|
|
153
|
-
request.policyMetadata = result.metadata;
|
|
154
|
-
}
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
results.push(result);
|
|
158
|
-
}
|
|
159
|
-
return reply.code(403).send({
|
|
160
|
-
success: false,
|
|
161
|
-
error: "Access denied",
|
|
162
|
-
message: results[0]?.reason || "You do not have permission to perform this action"
|
|
163
|
-
});
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
function allowAll() {
|
|
169
|
-
return {
|
|
170
|
-
can() {
|
|
171
|
-
return { allowed: true };
|
|
172
|
-
},
|
|
173
|
-
toMiddleware() {
|
|
174
|
-
return async () => {
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
function denyAll(reason = "Operation not allowed") {
|
|
180
|
-
return {
|
|
181
|
-
can() {
|
|
182
|
-
return { allowed: false, reason };
|
|
183
|
-
},
|
|
184
|
-
toMiddleware() {
|
|
185
|
-
return async (request, reply) => {
|
|
186
|
-
return reply.code(403).send({
|
|
187
|
-
success: false,
|
|
188
|
-
error: "Access denied",
|
|
189
|
-
message: reason
|
|
190
|
-
});
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export { allowAll, anyPolicy, combinePolicies, createPolicyMiddleware, denyAll };
|
package/dist/presets/index.js
DELETED
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
// src/permissions/index.ts
|
|
2
|
-
function allowPublic() {
|
|
3
|
-
const check = () => true;
|
|
4
|
-
check._isPublic = true;
|
|
5
|
-
return check;
|
|
6
|
-
}
|
|
7
|
-
function requireRoles(roles, options) {
|
|
8
|
-
const check = (ctx) => {
|
|
9
|
-
if (!ctx.user) {
|
|
10
|
-
return { granted: false, reason: "Authentication required" };
|
|
11
|
-
}
|
|
12
|
-
const userRoles = ctx.user.roles ?? [];
|
|
13
|
-
if (roles.some((r) => userRoles.includes(r))) {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
return {
|
|
17
|
-
granted: false,
|
|
18
|
-
reason: `Required roles: ${roles.join(", ")}`
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
check._roles = roles;
|
|
22
|
-
return check;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// src/presets/softDelete.ts
|
|
26
|
-
function softDeletePreset(options = {}) {
|
|
27
|
-
const { deletedField: _deletedField = "deletedAt" } = options;
|
|
28
|
-
return {
|
|
29
|
-
name: "softDelete",
|
|
30
|
-
additionalRoutes: (permissions) => [
|
|
31
|
-
{
|
|
32
|
-
method: "GET",
|
|
33
|
-
path: "/deleted",
|
|
34
|
-
handler: "getDeleted",
|
|
35
|
-
summary: "Get soft-deleted items",
|
|
36
|
-
permissions: permissions.list ?? requireRoles(["admin"]),
|
|
37
|
-
wrapHandler: true
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
method: "POST",
|
|
41
|
-
path: "/:id/restore",
|
|
42
|
-
handler: "restore",
|
|
43
|
-
summary: "Restore soft-deleted item",
|
|
44
|
-
permissions: permissions.update ?? requireRoles(["admin"]),
|
|
45
|
-
wrapHandler: true
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// src/presets/slugLookup.ts
|
|
52
|
-
function slugLookupPreset(options = {}) {
|
|
53
|
-
const { slugField = "slug" } = options;
|
|
54
|
-
return {
|
|
55
|
-
name: "slugLookup",
|
|
56
|
-
additionalRoutes: (permissions) => [
|
|
57
|
-
{
|
|
58
|
-
method: "GET",
|
|
59
|
-
path: `/slug/:${slugField}`,
|
|
60
|
-
handler: "getBySlug",
|
|
61
|
-
summary: "Get by slug",
|
|
62
|
-
permissions: permissions.get ?? allowPublic(),
|
|
63
|
-
wrapHandler: true
|
|
64
|
-
// Handler is a ControllerHandler
|
|
65
|
-
}
|
|
66
|
-
],
|
|
67
|
-
// Pass to controller so it knows which param to read
|
|
68
|
-
controllerOptions: {
|
|
69
|
-
slugField
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// src/presets/ownedByUser.ts
|
|
75
|
-
function createOwnershipCheck(ownerField, bypassRoles) {
|
|
76
|
-
return async (request, _reply) => {
|
|
77
|
-
const user = request.user;
|
|
78
|
-
if (!user) return;
|
|
79
|
-
const userWithRoles = user;
|
|
80
|
-
if (userWithRoles.roles && bypassRoles.some((r) => userWithRoles.roles.includes(r))) return;
|
|
81
|
-
const userWithId = user;
|
|
82
|
-
const userId = userWithId._id ?? userWithId.id;
|
|
83
|
-
if (userId) {
|
|
84
|
-
request._ownershipCheck = {
|
|
85
|
-
field: ownerField,
|
|
86
|
-
userId
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
function ownedByUserPreset(options = {}) {
|
|
92
|
-
const {
|
|
93
|
-
ownerField = "userId",
|
|
94
|
-
bypassRoles = ["admin", "superadmin"]
|
|
95
|
-
} = options;
|
|
96
|
-
const ownershipMiddleware = createOwnershipCheck(ownerField, bypassRoles);
|
|
97
|
-
return {
|
|
98
|
-
name: "ownedByUser",
|
|
99
|
-
middlewares: {
|
|
100
|
-
update: [ownershipMiddleware],
|
|
101
|
-
delete: [ownershipMiddleware]
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// src/presets/multiTenant.ts
|
|
107
|
-
function defaultExtractOrganizationId(request) {
|
|
108
|
-
const context = request.context;
|
|
109
|
-
if (context?.organizationId) {
|
|
110
|
-
return context.organizationId;
|
|
111
|
-
}
|
|
112
|
-
const user = request.user;
|
|
113
|
-
if (user?.organizationId) {
|
|
114
|
-
return user.organizationId;
|
|
115
|
-
}
|
|
116
|
-
if (user?.organization) {
|
|
117
|
-
const org = user.organization;
|
|
118
|
-
return org._id || org.id || org;
|
|
119
|
-
}
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
function createTenantFilter(tenantField, bypassRoles, extractOrganizationId) {
|
|
123
|
-
return async (request, reply) => {
|
|
124
|
-
const user = request.user;
|
|
125
|
-
if (!user) {
|
|
126
|
-
reply.code(401).send({
|
|
127
|
-
success: false,
|
|
128
|
-
error: "Unauthorized",
|
|
129
|
-
message: "Authentication required for multi-tenant resources"
|
|
130
|
-
});
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
const userWithRoles = user;
|
|
134
|
-
if (userWithRoles.roles && bypassRoles.some((r) => userWithRoles.roles.includes(r))) return;
|
|
135
|
-
const orgId = extractOrganizationId(request);
|
|
136
|
-
if (!orgId) {
|
|
137
|
-
reply.code(403).send({
|
|
138
|
-
success: false,
|
|
139
|
-
error: "Forbidden",
|
|
140
|
-
message: "Organization context required for this operation"
|
|
141
|
-
});
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
request.query = request.query ?? {};
|
|
145
|
-
request.query._policyFilters = {
|
|
146
|
-
...request.query._policyFilters ?? {},
|
|
147
|
-
[tenantField]: orgId
|
|
148
|
-
};
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
function createFlexibleTenantFilter(tenantField, bypassRoles, extractOrganizationId) {
|
|
152
|
-
return async (request, reply) => {
|
|
153
|
-
const user = request.user;
|
|
154
|
-
const orgId = extractOrganizationId(request);
|
|
155
|
-
if (!orgId) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
if (!user) {
|
|
159
|
-
reply.code(401).send({
|
|
160
|
-
success: false,
|
|
161
|
-
error: "Unauthorized",
|
|
162
|
-
message: "Authentication required for organization-scoped data"
|
|
163
|
-
});
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
const userWithRoles = user;
|
|
167
|
-
if (userWithRoles.roles && bypassRoles.some((r) => userWithRoles.roles.includes(r))) {
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
request.query = request.query ?? {};
|
|
171
|
-
request.query._policyFilters = {
|
|
172
|
-
...request.query._policyFilters ?? {},
|
|
173
|
-
[tenantField]: orgId
|
|
174
|
-
};
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
function createTenantInjection(tenantField, extractOrganizationId) {
|
|
178
|
-
return async (request, reply) => {
|
|
179
|
-
const orgId = extractOrganizationId(request);
|
|
180
|
-
if (!orgId) {
|
|
181
|
-
reply.code(403).send({
|
|
182
|
-
success: false,
|
|
183
|
-
error: "Forbidden",
|
|
184
|
-
message: "Organization context required to create resources"
|
|
185
|
-
});
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
if (request.body) {
|
|
189
|
-
request.body[tenantField] = orgId;
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
function multiTenantPreset(options = {}) {
|
|
194
|
-
const {
|
|
195
|
-
tenantField = "organizationId",
|
|
196
|
-
bypassRoles = ["superadmin"],
|
|
197
|
-
extractOrganizationId = defaultExtractOrganizationId,
|
|
198
|
-
allowPublic: allowPublic2 = []
|
|
199
|
-
} = options;
|
|
200
|
-
const strictTenantFilter = createTenantFilter(tenantField, bypassRoles, extractOrganizationId);
|
|
201
|
-
const flexibleTenantFilter = createFlexibleTenantFilter(tenantField, bypassRoles, extractOrganizationId);
|
|
202
|
-
const tenantInjection = createTenantInjection(tenantField, extractOrganizationId);
|
|
203
|
-
const getFilter = (route) => allowPublic2.includes(route) ? flexibleTenantFilter : strictTenantFilter;
|
|
204
|
-
return {
|
|
205
|
-
name: "multiTenant",
|
|
206
|
-
middlewares: {
|
|
207
|
-
list: [getFilter("list")],
|
|
208
|
-
get: [getFilter("get")],
|
|
209
|
-
create: [tenantInjection],
|
|
210
|
-
update: [getFilter("update")],
|
|
211
|
-
delete: [getFilter("delete")]
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// src/presets/tree.ts
|
|
217
|
-
function treePreset(options = {}) {
|
|
218
|
-
const { parentField = "parent" } = options;
|
|
219
|
-
return {
|
|
220
|
-
name: "tree",
|
|
221
|
-
additionalRoutes: (permissions) => [
|
|
222
|
-
{
|
|
223
|
-
method: "GET",
|
|
224
|
-
path: "/tree",
|
|
225
|
-
handler: "getTree",
|
|
226
|
-
summary: "Get hierarchical tree",
|
|
227
|
-
permissions: permissions.list ?? allowPublic(),
|
|
228
|
-
wrapHandler: true
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
method: "GET",
|
|
232
|
-
path: `/:${parentField}/children`,
|
|
233
|
-
handler: "getChildren",
|
|
234
|
-
summary: "Get children of parent",
|
|
235
|
-
permissions: permissions.list ?? allowPublic(),
|
|
236
|
-
wrapHandler: true
|
|
237
|
-
}
|
|
238
|
-
],
|
|
239
|
-
// Pass to controller so it knows which param to read
|
|
240
|
-
controllerOptions: {
|
|
241
|
-
parentField
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// src/presets/audited.ts
|
|
247
|
-
function auditedPreset(options = {}) {
|
|
248
|
-
const { createdByField = "createdBy", updatedByField = "updatedBy" } = options;
|
|
249
|
-
const injectCreatedBy = async (request, _reply) => {
|
|
250
|
-
const userWithId = request.user;
|
|
251
|
-
if (userWithId?._id || userWithId?.id) {
|
|
252
|
-
const userId = userWithId._id ?? userWithId.id;
|
|
253
|
-
request.body[createdByField] = userId;
|
|
254
|
-
request.body[updatedByField] = userId;
|
|
255
|
-
}
|
|
256
|
-
return void 0;
|
|
257
|
-
};
|
|
258
|
-
const injectUpdatedBy = async (request, _reply) => {
|
|
259
|
-
const userWithId = request.user;
|
|
260
|
-
if (userWithId?._id || userWithId?.id) {
|
|
261
|
-
request.body[updatedByField] = userWithId._id ?? userWithId.id;
|
|
262
|
-
}
|
|
263
|
-
return void 0;
|
|
264
|
-
};
|
|
265
|
-
return {
|
|
266
|
-
name: "audited",
|
|
267
|
-
schemaOptions: {
|
|
268
|
-
fieldRules: {
|
|
269
|
-
[createdByField]: { systemManaged: true },
|
|
270
|
-
[updatedByField]: { systemManaged: true },
|
|
271
|
-
createdAt: { systemManaged: true },
|
|
272
|
-
updatedAt: { systemManaged: true }
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
middlewares: {
|
|
276
|
-
create: [injectCreatedBy],
|
|
277
|
-
update: [injectUpdatedBy]
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// src/presets/index.ts
|
|
283
|
-
var flexibleMultiTenantPreset = (options = {}) => multiTenantPreset({ ...options, allowPublic: ["list", "get"] });
|
|
284
|
-
var presetRegistry = {
|
|
285
|
-
softDelete: softDeletePreset,
|
|
286
|
-
slugLookup: slugLookupPreset,
|
|
287
|
-
ownedByUser: ownedByUserPreset,
|
|
288
|
-
multiTenant: multiTenantPreset,
|
|
289
|
-
tree: treePreset,
|
|
290
|
-
audited: auditedPreset
|
|
291
|
-
};
|
|
292
|
-
function getPreset(nameOrConfig) {
|
|
293
|
-
if (typeof nameOrConfig === "object" && nameOrConfig.name) {
|
|
294
|
-
const { name, ...options } = nameOrConfig;
|
|
295
|
-
return resolvePreset(name, options);
|
|
296
|
-
}
|
|
297
|
-
return resolvePreset(nameOrConfig);
|
|
298
|
-
}
|
|
299
|
-
function resolvePreset(name, options = {}) {
|
|
300
|
-
const factory = presetRegistry[name];
|
|
301
|
-
if (!factory) {
|
|
302
|
-
const available = Object.keys(presetRegistry).join(", ");
|
|
303
|
-
throw new Error(
|
|
304
|
-
`Unknown preset: '${name}'
|
|
305
|
-
Available presets: ${available}
|
|
306
|
-
Docs: https://github.com/classytic/arc#presets`
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
return factory(options);
|
|
310
|
-
}
|
|
311
|
-
function registerPreset(name, factory) {
|
|
312
|
-
if (presetRegistry[name]) {
|
|
313
|
-
throw new Error(`Preset '${name}' already exists`);
|
|
314
|
-
}
|
|
315
|
-
presetRegistry[name] = factory;
|
|
316
|
-
}
|
|
317
|
-
function getAvailablePresets() {
|
|
318
|
-
return Object.keys(presetRegistry);
|
|
319
|
-
}
|
|
320
|
-
function applyPresets(config, presets = []) {
|
|
321
|
-
let result = { ...config };
|
|
322
|
-
for (const preset of presets) {
|
|
323
|
-
const resolved = resolvePresetInput(preset);
|
|
324
|
-
result = mergePreset(result, resolved);
|
|
325
|
-
}
|
|
326
|
-
return result;
|
|
327
|
-
}
|
|
328
|
-
function resolvePresetInput(preset) {
|
|
329
|
-
if (typeof preset === "object" && ("middlewares" in preset || "additionalRoutes" in preset)) {
|
|
330
|
-
return preset;
|
|
331
|
-
}
|
|
332
|
-
if (typeof preset === "object" && "name" in preset) {
|
|
333
|
-
const { name, ...options } = preset;
|
|
334
|
-
return resolvePreset(name, options);
|
|
335
|
-
}
|
|
336
|
-
return resolvePreset(preset);
|
|
337
|
-
}
|
|
338
|
-
function mergePreset(config, preset) {
|
|
339
|
-
const result = { ...config };
|
|
340
|
-
if (preset.additionalRoutes) {
|
|
341
|
-
const routes = typeof preset.additionalRoutes === "function" ? preset.additionalRoutes(config.permissions ?? {}) : preset.additionalRoutes;
|
|
342
|
-
result.additionalRoutes = [
|
|
343
|
-
...result.additionalRoutes ?? [],
|
|
344
|
-
...routes
|
|
345
|
-
];
|
|
346
|
-
}
|
|
347
|
-
if (preset.middlewares) {
|
|
348
|
-
result.middlewares = result.middlewares ?? {};
|
|
349
|
-
for (const [op, mws] of Object.entries(preset.middlewares)) {
|
|
350
|
-
const key = op;
|
|
351
|
-
result.middlewares[key] = [
|
|
352
|
-
...result.middlewares[key] ?? [],
|
|
353
|
-
...mws ?? []
|
|
354
|
-
];
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
if (preset.schemaOptions) {
|
|
358
|
-
result.schemaOptions = {
|
|
359
|
-
...result.schemaOptions,
|
|
360
|
-
...preset.schemaOptions
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
if (preset.controllerOptions) {
|
|
364
|
-
result._controllerOptions = {
|
|
365
|
-
...result._controllerOptions,
|
|
366
|
-
...preset.controllerOptions
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
if (preset.hooks && preset.hooks.length > 0) {
|
|
370
|
-
result._hooks = result._hooks ?? [];
|
|
371
|
-
for (const hook of preset.hooks) {
|
|
372
|
-
result._hooks.push({
|
|
373
|
-
presetName: preset.name,
|
|
374
|
-
operation: hook.operation,
|
|
375
|
-
phase: hook.phase,
|
|
376
|
-
handler: hook.handler,
|
|
377
|
-
priority: hook.priority
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
return result;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
export { applyPresets, auditedPreset, flexibleMultiTenantPreset, getAvailablePresets, getPreset, multiTenantPreset, ownedByUserPreset, registerPreset, slugLookupPreset, softDeletePreset, treePreset };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { d as RequestWithExtras, e as CrudRouteKey, f as PresetResult } from '../index-B4t03KQ0.js';
|
|
2
|
-
import 'mongoose';
|
|
3
|
-
import 'fastify';
|
|
4
|
-
import '../types-B99TBmFV.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Multi-Tenant Preset
|
|
8
|
-
*
|
|
9
|
-
* Adds tenant (organization) filtering and injection middlewares.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
interface MultiTenantOptions {
|
|
13
|
-
/** Field name in database (default: 'organizationId') */
|
|
14
|
-
tenantField?: string;
|
|
15
|
-
/** Roles that bypass tenant isolation (default: ['superadmin']) */
|
|
16
|
-
bypassRoles?: string[];
|
|
17
|
-
/**
|
|
18
|
-
* Custom function to extract organizationId from request
|
|
19
|
-
* If not provided, tries in order:
|
|
20
|
-
* 1. request.context.organizationId
|
|
21
|
-
* 2. request.user.organizationId
|
|
22
|
-
* 3. request.user.organization
|
|
23
|
-
*/
|
|
24
|
-
extractOrganizationId?: (request: RequestWithExtras) => string | null | undefined;
|
|
25
|
-
/**
|
|
26
|
-
* Routes that allow public access (no auth required)
|
|
27
|
-
* When a route is in this array:
|
|
28
|
-
* - If no org context: allow through without filtering (public data)
|
|
29
|
-
* - If org context present: require auth and apply filter
|
|
30
|
-
*
|
|
31
|
-
* @default [] (strict mode - all routes require auth)
|
|
32
|
-
* @example
|
|
33
|
-
* multiTenantPreset({ allowPublic: ['list', 'get'] })
|
|
34
|
-
*/
|
|
35
|
-
allowPublic?: CrudRouteKey[];
|
|
36
|
-
}
|
|
37
|
-
declare function multiTenantPreset(options?: MultiTenantOptions): PresetResult;
|
|
38
|
-
|
|
39
|
-
export { type MultiTenantOptions, multiTenantPreset as default, multiTenantPreset };
|