@classytic/arc 2.28.0 → 2.30.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/dist/{BaseController-B65zbz9m.mjs → BaseController-B5DwufbB.mjs} +12 -10
- package/dist/EventTransport-C6YA8xY9.mjs +103 -0
- package/dist/{HookSystem-C1vB_Gc9.mjs → HookSystem-WkIougo6.mjs} +15 -35
- package/dist/applyPermissionResult-Cf6zUCvb.mjs +257 -0
- package/dist/audit/index.d.mts +2 -2
- package/dist/audit/index.mjs +1 -1
- package/dist/auth/index.d.mts +2 -2
- package/dist/auth/index.mjs +1 -1
- package/dist/{buildHandler-Dtwd8fdz.mjs → buildHandler-BYS3Vkfz.mjs} +32 -6
- package/dist/cleanup/index.d.mts +2 -2
- package/dist/cleanup/index.mjs +1 -1
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/docs.mjs +1 -1
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +5 -4
- package/dist/{core-BGa8TXJR.mjs → core-poalJLvp.mjs} +2 -48
- package/dist/{createActionRouter-C-N7z2EL.mjs → createActionRouter-BxuywVRB.mjs} +2 -2
- package/dist/{createAggregationRouter-wzwFa_dW.mjs → createAggregationRouter-BiY-lGdY.mjs} +7 -20
- package/dist/{createApp-Du5G54TM.mjs → createApp-CXrKFciH.mjs} +24 -3
- package/dist/defineAggregation-ufWjUwml.mjs +47 -0
- package/dist/{defineResource-2zvVVpxg.mjs → defineResource-CxWqDCAy.mjs} +35 -42
- package/dist/docs/index.d.mts +1 -1
- package/dist/docs/index.mjs +1 -1
- package/dist/{eventPlugin-DrQ_FesK.mjs → eventPlugin-D2NNR4py.mjs} +2 -103
- package/dist/events/index.mjs +4 -339
- package/dist/factory/index.d.mts +4 -4
- package/dist/factory/index.mjs +1 -1
- package/dist/{fastify-augmentation-OzYGIiU1.d.mts → fastify-augmentation-0WhPnUH7.d.mts} +3 -3
- package/dist/{applyPermissionResult-BnyVE9eD.mjs → fields-CQ_7KQWw.mjs} +1 -107
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.mjs +1 -1
- package/dist/{index-CZY4EGga.d.mts → index-CCzVR-N3.d.mts} +1 -1
- package/dist/{index-BMnbzvtO.d.mts → index-Ch16aAah.d.mts} +201 -21
- package/dist/{index-CjVg-Epg.d.mts → index-Cx7bro4R.d.mts} +4 -4
- package/dist/{index-DPRH0Cme.d.mts → index-Q5gzEIWY.d.mts} +97 -66
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +8 -7
- package/dist/integrations/index.d.mts +1 -1
- package/dist/integrations/mcp/index.d.mts +6 -6
- package/dist/integrations/mcp/index.mjs +1 -1
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/{mcpPlugin-Cs6nRGCt.mjs → mcpPlugin-nRzm5g2s.mjs} +36 -43
- package/dist/middleware/index.d.mts +1 -1
- package/dist/migrations/index.d.mts +0 -3
- package/dist/migrations/index.mjs +0 -3
- package/dist/{openapi-BLV4OMXb.mjs → openapi-B8Vkbxbn.mjs} +1 -1
- package/dist/permissions/index.d.mts +3 -3
- package/dist/permissions/index.mjs +4 -3
- package/dist/{permissions-BrtiBKGs.mjs → permissions-Bfu_8y1U.mjs} +318 -289
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/{pipeline-BGRnV-To.mjs → pipeline-BJnpkY9i.mjs} +4 -18
- package/dist/plugins/index.d.mts +4 -4
- package/dist/plugins/index.mjs +2 -2
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/{preloadResources-CM4uUaFv.d.mts → preloadResources-DCfa2egz.d.mts} +3 -3
- package/dist/presets/filesUpload.d.mts +2 -2
- package/dist/presets/filesUpload.mjs +1 -1
- package/dist/presets/index.d.mts +14 -2
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-DwFDVKP0.mjs → presets-CJOEXLuk.mjs} +25 -9
- package/dist/projection-UBDgfMwu.mjs +17 -0
- package/dist/{realtime-DEuDu9io.mjs → realtime-B9nmIY5V.mjs} +2 -1
- package/dist/{registerRoute-DTp18Ah_.mjs → registerRoute-JkxIEBJq.mjs} +3 -1
- package/dist/registry/index.d.mts +2 -2
- package/dist/registry/index.mjs +1 -1
- package/dist/{registry-9km_w1aP.mjs → registry-BYXUUg21.mjs} +1 -1
- package/dist/repositoryFilter-Dz8k3S4P.mjs +44 -0
- package/dist/subscribe-helpers-DfzsivM6.mjs +339 -0
- package/dist/testing/index.d.mts +34 -6
- package/dist/testing/index.mjs +314 -211
- package/dist/types/index.d.mts +3 -3
- package/dist/{types-QFGc3Cjv.d.mts → types-Bmmn-fO0.d.mts} +1 -1
- package/dist/{types-Dmw-6Qeo.d.mts → types-ChvvVNP8.d.mts} +93 -88
- package/dist/{types-Cu6vVJmh.d.mts → types-D_n8L6VY.d.mts} +32 -1
- package/dist/usage/index.d.mts +1 -1
- package/dist/usage/index.mjs +0 -0
- package/dist/utils/index.d.mts +2 -5
- package/package.json +539 -539
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as CacheStore, t as CacheLogger } from "./interface-BGZCzOGL.mjs";
|
|
2
2
|
import { i as RequestScope, n as Mandate } from "./types-DjC-KUCz.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { i as PermissionContext, r as PermissionCheck, t as AuthorizationDecision } from "./types-ChvvVNP8.mjs";
|
|
4
4
|
import { FastifyReply, FastifyRequest } from "fastify";
|
|
5
5
|
//#region src/permissions/agent.d.ts
|
|
6
6
|
/**
|
|
@@ -164,11 +164,35 @@ declare function requireAgentScope<TDoc = Record<string, unknown>>(opts: Require
|
|
|
164
164
|
//#endregion
|
|
165
165
|
//#region src/permissions/applyPermissionResult.d.ts
|
|
166
166
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
167
|
+
* A permission check returns either a bare boolean (terse allow/deny sugar) or
|
|
168
|
+
* a full {@link AuthorizationDecision}. There is no legacy `PermissionResult` —
|
|
169
|
+
* `AuthorizationDecision` is arc's single authorization contract.
|
|
170
170
|
*/
|
|
171
|
-
|
|
171
|
+
type PermissionCheckReturn = boolean | AuthorizationDecision;
|
|
172
|
+
/**
|
|
173
|
+
* Normalize a check return into the canonical {@link AuthorizationDecision}.
|
|
174
|
+
* A boolean promotes to `{ effect: "allow" | "deny" }`; a decision passes
|
|
175
|
+
* through. This is the ONE place booleans are promoted, so the rest of the
|
|
176
|
+
* pipeline only ever handles decisions.
|
|
177
|
+
*/
|
|
178
|
+
declare function normalizeToDecision(result: PermissionCheckReturn): AuthorizationDecision;
|
|
179
|
+
/**
|
|
180
|
+
* Run a permission check and return a canonical {@link AuthorizationDecision} —
|
|
181
|
+
* the transport-neutral PDP (HTTP, aggregation, MCP, and any future transport).
|
|
182
|
+
* A thin mapper over {@link evaluatePermissionOutcome}:
|
|
183
|
+
*
|
|
184
|
+
* - a structured `ArcError` is RE-THROWN so the transport surfaces it verbatim
|
|
185
|
+
* (e.g. a tier gate throwing `arc.tier_required` with machine-readable meta);
|
|
186
|
+
* - any OTHER throw is fail-closed to a `deny` decision (a broken check must
|
|
187
|
+
* never fall open to a 500 that skips authorization).
|
|
188
|
+
*
|
|
189
|
+
* Pure w.r.t. the request — it neither reads a reply nor mutates the request.
|
|
190
|
+
* Callers translate the returned decision into their own response mechanism and
|
|
191
|
+
* apply side-effects via {@link applyAuthorizationDecision}. HTTP additionally
|
|
192
|
+
* hardens a *thrown* check to 403-even-when-anonymous — that transport-specific
|
|
193
|
+
* nuance lives in {@link evaluateAndApplyPermission}, not here.
|
|
194
|
+
*/
|
|
195
|
+
declare function evaluatePermissionDecision(check: PermissionCheck, context: PermissionContext): Promise<AuthorizationDecision>;
|
|
172
196
|
/**
|
|
173
197
|
* Minimal shape of a Fastify request that can receive permission side-effects.
|
|
174
198
|
* We avoid depending on the full augmented `FastifyRequest` type here because
|
|
@@ -180,8 +204,9 @@ type RequestSink = FastifyRequest & {
|
|
|
180
204
|
scope?: RequestScope;
|
|
181
205
|
};
|
|
182
206
|
/**
|
|
183
|
-
* Apply
|
|
184
|
-
*
|
|
207
|
+
* Apply an allowed {@link AuthorizationDecision} to a Fastify request — conjoins
|
|
208
|
+
* the decision's row-level `policy` into `_policyFilters` and conditionally
|
|
209
|
+
* installs the `scope`.
|
|
185
210
|
*
|
|
186
211
|
* **Scope install rule:** only writes `scope` when the current request scope
|
|
187
212
|
* is absent or `public`. This prevents downgrading an already-authenticated
|
|
@@ -189,13 +214,47 @@ type RequestSink = FastifyRequest & {
|
|
|
189
214
|
* narrower `service` scope — the original `member` wins because it came from
|
|
190
215
|
* a more authoritative source).
|
|
191
216
|
*
|
|
192
|
-
* Safe to call with a
|
|
193
|
-
*
|
|
194
|
-
*
|
|
217
|
+
* Safe to call with a denied decision — it simply no-ops. Callers should still
|
|
218
|
+
* check `decision.effect` and send an error response before reaching here, but
|
|
219
|
+
* this function tolerates the misuse defensively.
|
|
220
|
+
*
|
|
221
|
+
* This is the enforcement point (PEP) — the ONE place scope + data policy are
|
|
222
|
+
* installed (and the obligation seam lives).
|
|
223
|
+
*/
|
|
224
|
+
declare function applyAuthorizationDecision(decision: AuthorizationDecision, request: RequestSink): void;
|
|
225
|
+
/**
|
|
226
|
+
* @deprecated Renamed to {@link applyAuthorizationDecision} — the contract is an
|
|
227
|
+
* `AuthorizationDecision`, not a `PermissionResult`. This alias is kept for
|
|
228
|
+
* back-compat and will be removed in a future major.
|
|
195
229
|
*/
|
|
196
|
-
declare
|
|
230
|
+
declare const applyPermissionResult: typeof applyAuthorizationDecision;
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/permissions/context.d.ts
|
|
233
|
+
/**
|
|
234
|
+
* Resolve the request scope for a permission check. Prefers the context's
|
|
235
|
+
* first-class `scope`; falls back to the raw HTTP `request.scope` when present,
|
|
236
|
+
* else `PUBLIC_SCOPE`. Primitives MUST use this instead of touching
|
|
237
|
+
* `ctx.request` so scope threads through combinators and non-HTTP transports
|
|
238
|
+
* (MCP, jobs) — which have no request — resolve identity correctly.
|
|
239
|
+
*/
|
|
240
|
+
declare function scopeOf(ctx: PermissionContext): RequestScope;
|
|
197
241
|
//#endregion
|
|
198
242
|
//#region src/permissions/core.d.ts
|
|
243
|
+
/**
|
|
244
|
+
* Build an `allow` {@link AuthorizationDecision}, optionally attaching a row-level
|
|
245
|
+
* `policy` and/or a `scope` to install. The idiomatic "grant" return for arc
|
|
246
|
+
* 2.30 checks (parallels Cedar's `permit`).
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* return allow(); // simple grant
|
|
250
|
+
* return allow({ policy: { ownerId: userId } }); // grant + row policy
|
|
251
|
+
*/
|
|
252
|
+
declare function allow(extra?: Omit<AuthorizationDecision, "effect">): AuthorizationDecision;
|
|
253
|
+
/**
|
|
254
|
+
* Build a `deny` {@link AuthorizationDecision} with an optional human-readable
|
|
255
|
+
* reason (parallels Cedar's `forbid`). The idiomatic "refuse" return.
|
|
256
|
+
*/
|
|
257
|
+
declare function deny(reason?: string): AuthorizationDecision;
|
|
199
258
|
/**
|
|
200
259
|
* Allow public access (no authentication required).
|
|
201
260
|
*
|
|
@@ -272,11 +331,18 @@ declare function requireOwnership<TDoc = Record<string, unknown>>(ownerField?: E
|
|
|
272
331
|
/**
|
|
273
332
|
* Combine multiple checks — ALL must pass (AND logic).
|
|
274
333
|
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
334
|
+
* Evaluation is PURE — nothing is written to the request. Each child runs
|
|
335
|
+
* against the accumulated state of previous children, threaded through a fresh
|
|
336
|
+
* child context:
|
|
337
|
+
* - `policy` from earlier children is CONJOINED (logical AND) — a later child
|
|
338
|
+
* can add or narrow restrictions but never silently replaces an earlier
|
|
339
|
+
* child's constraint on the same key (conflicting values are preserved under
|
|
340
|
+
* `$and`; see `conjoinPolicyFilters`)
|
|
341
|
+
* - `scope` installed by an earlier child is visible to the next through
|
|
342
|
+
* `scopeOf(ctx)`, and never downgrades an already-authoritative scope
|
|
278
343
|
*
|
|
279
|
-
* The
|
|
344
|
+
* The returned decision carries the merged `policy` + `scope`; the enforcement
|
|
345
|
+
* point (`applyAuthorizationDecision`) applies them to the request once.
|
|
280
346
|
*
|
|
281
347
|
* @example
|
|
282
348
|
* ```typescript
|
|
@@ -449,6 +515,120 @@ declare function createOrgPermissions(config: {
|
|
|
449
515
|
*/
|
|
450
516
|
declare function createDynamicPermissionMatrix(config: DynamicPermissionMatrixConfig): DynamicPermissionMatrix;
|
|
451
517
|
//#endregion
|
|
518
|
+
//#region src/permissions/explain.d.ts
|
|
519
|
+
/**
|
|
520
|
+
* The statically-known requirement of a permission check.
|
|
521
|
+
*
|
|
522
|
+
* - `public` — `allowPublic()`; anyone passes.
|
|
523
|
+
* - `roles` — grants if the caller holds ANY of these (platform OR org roles,
|
|
524
|
+
* unioned — matches how `requireRoles`/`requireOrgRole`/`anyOf` compose).
|
|
525
|
+
* - `authenticated` — the check reads request-time facts (custom auth, service
|
|
526
|
+
* scope, ownership, scope-context, grants) that no static analysis can decide;
|
|
527
|
+
* the definitive answer is computed per request. Treat as "server decides".
|
|
528
|
+
*/
|
|
529
|
+
type PermissionRequirement = {
|
|
530
|
+
readonly kind: "public";
|
|
531
|
+
} | {
|
|
532
|
+
readonly kind: "roles";
|
|
533
|
+
readonly roles: readonly string[];
|
|
534
|
+
} | {
|
|
535
|
+
readonly kind: "authenticated";
|
|
536
|
+
};
|
|
537
|
+
/**
|
|
538
|
+
* Extract a check's static requirement from its `PermissionCheckMeta`. Public
|
|
539
|
+
* wins; then the union of platform + org roles a role gate declares; otherwise
|
|
540
|
+
* "authenticated" (auth-required / custom / request-time checks).
|
|
541
|
+
*/
|
|
542
|
+
declare function describePermission(check: PermissionCheck): PermissionRequirement;
|
|
543
|
+
/** Result of {@link explainAccess}. */
|
|
544
|
+
interface AccessExplanation {
|
|
545
|
+
/**
|
|
546
|
+
* `allow` / `deny` are DEFINITIVE from static metadata (public, or a role
|
|
547
|
+
* match against the supplied principal). `conditional` means the gate reads
|
|
548
|
+
* request-time state, so the real decision is made per request — this is not a
|
|
549
|
+
* denial, it is "cannot be determined statically".
|
|
550
|
+
*/
|
|
551
|
+
decision: "allow" | "deny" | "conditional";
|
|
552
|
+
/** Human-readable rationale, safe to surface in a UI or an audit report. */
|
|
553
|
+
reason: string;
|
|
554
|
+
/** The check's static requirement (the same value {@link describePermission} returns). */
|
|
555
|
+
requirement: PermissionRequirement;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Explain whether a principal (by roles) passes a permission check, from static
|
|
559
|
+
* metadata alone — for permission-matrix UIs, docs, and audits. Omit `principal`
|
|
560
|
+
* to get the requirement-only view (roles → `conditional`).
|
|
561
|
+
*
|
|
562
|
+
* @example
|
|
563
|
+
* explainAccess(requireRoles("admin"), { roles: ["editor"] })
|
|
564
|
+
* // → { decision: "deny", reason: "requires one of: admin", requirement: { kind: "roles", roles: ["admin"] } }
|
|
565
|
+
*/
|
|
566
|
+
declare function explainAccess(check: PermissionCheck, principal?: {
|
|
567
|
+
roles?: readonly string[];
|
|
568
|
+
orgRoles?: readonly string[];
|
|
569
|
+
}): AccessExplanation;
|
|
570
|
+
/**
|
|
571
|
+
* Introspect a whole permission map (`{ list, get, create, ... }` or any
|
|
572
|
+
* action→check record) into `action → requirement`. The reusable core of a
|
|
573
|
+
* `/permissions/matrix` endpoint or an access audit — framework-owned, so a host
|
|
574
|
+
* never hand-rolls `(check as any)._roles` peeking. Undefined slots (a CRUD op
|
|
575
|
+
* with no gate = public-by-omission) surface as `public` so the inventory is
|
|
576
|
+
* honest about what's exposed.
|
|
577
|
+
*/
|
|
578
|
+
declare function describePermissionMap(permissions: Readonly<Record<string, PermissionCheck | undefined>>): Record<string, PermissionRequirement>;
|
|
579
|
+
/**
|
|
580
|
+
* The public attack surface of a permission map — the actions reachable with NO
|
|
581
|
+
* authentication (explicit `allowPublic()` or public-by-omission). Empty is the
|
|
582
|
+
* healthy default for a protected resource; a non-empty list is what a
|
|
583
|
+
* "what's exposed?" audit report should show.
|
|
584
|
+
*/
|
|
585
|
+
declare function collectPublicSurface(permissions: Readonly<Record<string, PermissionCheck | undefined>>): string[];
|
|
586
|
+
//#endregion
|
|
587
|
+
//#region src/permissions/filter-merge.d.ts
|
|
588
|
+
/**
|
|
589
|
+
* Policy-filter composition — logical AND, never last-writer-wins.
|
|
590
|
+
*
|
|
591
|
+
* Row-level policy filters can arrive from several INDEPENDENT sources for one
|
|
592
|
+
* request: a tenant preset, an `ownedByUser` grant, an `allOf(...)` branch, a
|
|
593
|
+
* host permission check. Every one of them is a RESTRICTION the row must
|
|
594
|
+
* satisfy, so composing them is logical AND.
|
|
595
|
+
*
|
|
596
|
+
* The historical `{ ...base, ...incoming }` shallow spread did NOT implement AND:
|
|
597
|
+
* when two sources constrained the SAME key with different values, the later one
|
|
598
|
+
* silently REPLACED the earlier one — widening (or erasing) a restriction another
|
|
599
|
+
* layer deliberately imposed. That is a defense-in-depth defect, not a
|
|
600
|
+
* refinement. "Later can refine" is only sound when the refinement is provably
|
|
601
|
+
* narrower, and a bare overwrite proves nothing.
|
|
602
|
+
*
|
|
603
|
+
* {@link conjoinPolicyFilters} composes with AND semantics while preserving the
|
|
604
|
+
* common case byte-for-byte:
|
|
605
|
+
*
|
|
606
|
+
* - key present on only one side → carried through flat. Non-overlapping
|
|
607
|
+
* filters (the ~99% case) produce exactly the same object the old spread did,
|
|
608
|
+
* so there is ZERO behavior change for them.
|
|
609
|
+
* - same key, deep-equal value → kept once (idempotent — e.g. two checks
|
|
610
|
+
* both pinning the same `organizationId`).
|
|
611
|
+
* - same key, DIFFERENT value → BOTH constraints are preserved under an
|
|
612
|
+
* `$and`, so a row must satisfy both. For flat equality that conjunction is
|
|
613
|
+
* unsatisfiable, so the query returns nothing — the safe, correct outcome for
|
|
614
|
+
* contradictory policies (deny), and the earlier restriction is never dropped.
|
|
615
|
+
*
|
|
616
|
+
* Adapter safety: mongokit / sqlitekit compile `$and` natively at the DB layer,
|
|
617
|
+
* and arc's in-memory `simpleEqualityMatcher` (AccessControl.checkPolicyFilters)
|
|
618
|
+
* already fail-closes on operator-shaped filters. So a produced `$and` is either
|
|
619
|
+
* evaluated correctly by the DB or rejected fail-closed in memory — both safe.
|
|
620
|
+
*
|
|
621
|
+
* This is the pragmatic, adapter-neutral form of the AND semantics. A canonical
|
|
622
|
+
* filter IR in `repo-core` (nested and/or/not nodes each adapter compiles) is the
|
|
623
|
+
* fuller design, but this closes the security defect without one.
|
|
624
|
+
*/
|
|
625
|
+
/**
|
|
626
|
+
* Conjoin two policy-filter maps with AND semantics. Never silently overwrites a
|
|
627
|
+
* same-key constraint with a different value — conflicting keys are preserved
|
|
628
|
+
* under `$and`. See the module doc for the full contract.
|
|
629
|
+
*/
|
|
630
|
+
declare function conjoinPolicyFilters(base: Record<string, unknown> | undefined, incoming: Record<string, unknown> | undefined): Record<string, unknown>;
|
|
631
|
+
//#endregion
|
|
452
632
|
//#region src/permissions/grants.d.ts
|
|
453
633
|
/**
|
|
454
634
|
* The grant-mode lattice, weakest → strongest. Holding a mode satisfies
|
|
@@ -474,7 +654,7 @@ declare function modeSatisfies(held: string | undefined, required: GrantMode): b
|
|
|
474
654
|
* - `{ mode }` — the strongest mode the caller holds on `ctx.resourceId`;
|
|
475
655
|
* the combinator applies the lattice against the required mode.
|
|
476
656
|
* - `{ filters }` — list-shaped resolution: row filters that scope the
|
|
477
|
-
* query to visible records (flows through `
|
|
657
|
+
* query to visible records (flows through the decision's `policy` →
|
|
478
658
|
* `_policyFilters` → the repository query). Grants access with the
|
|
479
659
|
* filters attached.
|
|
480
660
|
* - `{ mode, filters }` — mode gates; filters ride along when it passes.
|
|
@@ -655,8 +835,8 @@ declare function requireScopeContext<TDoc = Record<string, unknown>>(keyOrMap: s
|
|
|
655
835
|
*
|
|
656
836
|
* **Two call shapes:**
|
|
657
837
|
* ```typescript
|
|
658
|
-
* requireOrgInScope('acme-holding')
|
|
659
|
-
* requireOrgInScope((ctx) => ctx.
|
|
838
|
+
* requireOrgInScope('acme-holding') // static
|
|
839
|
+
* requireOrgInScope((ctx) => ctx.params?.orgId) // dynamic — from ctx facts, not the raw request
|
|
660
840
|
* ```
|
|
661
841
|
*
|
|
662
842
|
* `elevated` scope grants unconditionally (cross-org bypass).
|
|
@@ -664,9 +844,9 @@ declare function requireScopeContext<TDoc = Record<string, unknown>>(keyOrMap: s
|
|
|
664
844
|
* @example
|
|
665
845
|
* ```typescript
|
|
666
846
|
* permissions: {
|
|
667
|
-
* list: requireOrgInScope((ctx) => ctx.
|
|
847
|
+
* list: requireOrgInScope((ctx) => ctx.params?.orgId),
|
|
668
848
|
* create: allOf(
|
|
669
|
-
* requireOrgInScope((ctx) => ctx.
|
|
849
|
+
* requireOrgInScope((ctx) => (ctx.data as { organizationId?: string })?.organizationId),
|
|
670
850
|
* requireOrgRole('admin'),
|
|
671
851
|
* ),
|
|
672
852
|
* }
|
|
@@ -772,4 +952,4 @@ declare function fullPublic<TDoc = Record<string, unknown>>(overrides?: Permissi
|
|
|
772
952
|
*/
|
|
773
953
|
declare function readOnly<TDoc = Record<string, unknown>>(overrides?: PermissionOverrides<TDoc>): ResourcePermissions<TDoc>;
|
|
774
954
|
//#endregion
|
|
775
|
-
export {
|
|
955
|
+
export { evaluatePermissionDecision as $, explainAccess as A, anyOf as B, requireGrant as C, collectPublicSurface as D, PermissionRequirement as E, createDynamicPermissionMatrix as F, requireOwnership as G, denyAll as H, createOrgPermissions as I, when as J, requireRoles as K, allOf as L, DynamicPermissionMatrix as M, DynamicPermissionMatrixConfig as N, describePermission as O, PermissionEventBus as P, applyPermissionResult as Q, allow as R, modeSatisfies as S, AccessExplanation as T, not as U, deny as V, requireAuth as W, PermissionCheckReturn as X, scopeOf as Y, applyAuthorizationDecision as Z, createRoleHierarchy as _, permissionMatrix as a, requireMandate as at, GrantResolution as b, publicReadAdminWrite as c, requireOrgMembership as d, normalizeToDecision as et, requireOrgRole as f, RoleHierarchy as g, requireTeamMembership as h, ownerWithAdminBypass as i, requireDPoP as it, ConnectEventsOptions as j, describePermissionMap as k, readOnly as l, requireServiceScope as m, authenticated as n, RequireMandateOptions as nt, presets_d_exports as o, requireScopeContext as p, roles as q, fullPublic as r, requireAgentScope as rt, publicRead as s, adminOnly as t, RequireAgentScopeOptions as tt, requireOrgInScope as u, GRANT_MODES as v, conjoinPolicyFilters as w, RequireGrantOptions as x, GrantMode as y, allowPublic as z };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { C as RequestContext, Et as ActionDefinition, F as FastifyWithDecorators, H as CrudController, L as RequestWithExtras, Lt as IController, Rt as IControllerResponse, T as CrudRouterOptions, U as ResourceConfig, V as ResourceDefinition, et as RouteSchemaOptions, jt as RouteMcpConfig, tt as ArcFieldRule, ut as AggregationConfig, zt as IRequestContext } from "./index-
|
|
1
|
+
import { C as RequestContext, Et as ActionDefinition, F as FastifyWithDecorators, H as CrudController, L as RequestWithExtras, Lt as IController, Rt as IControllerResponse, T as CrudRouterOptions, U as ResourceConfig, V as ResourceDefinition, et as RouteSchemaOptions, jt as RouteMcpConfig, tt as ArcFieldRule, ut as AggregationConfig, zt as IRequestContext } from "./index-Q5gzEIWY.mjs";
|
|
2
2
|
import { i as RequestScope } from "./types-DjC-KUCz.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import "./fastify-augmentation-
|
|
3
|
+
import { l as AnyRecord, r as PermissionCheck } from "./types-ChvvVNP8.mjs";
|
|
4
|
+
import "./fastify-augmentation-0WhPnUH7.mjs";
|
|
5
5
|
import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { DataAdapter } from "@classytic/repo-core/adapter";
|
|
@@ -170,7 +170,7 @@ declare function defineAction<TSchema extends z.ZodTypeAny | undefined = undefin
|
|
|
170
170
|
//#endregion
|
|
171
171
|
//#region src/core/defineResource/seams.d.ts
|
|
172
172
|
/**
|
|
173
|
-
* Structural adapter boundary — the `ControllerLike` pattern
|
|
173
|
+
* Structural adapter boundary — the `ControllerLike` pattern
|
|
174
174
|
* applied to adapters. `DataAdapter<T>` is invariant in `T`, so a
|
|
175
175
|
* `DataAdapter<HydratedDocument<IProduct>>` built by the HOST does not
|
|
176
176
|
* assign to a module's `DataAdapter<AnyRecord>` slot; before this type,
|