permdock 0.0.0 → 0.2.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 +327 -1
- package/dist/a2a/index.d.ts +169 -0
- package/dist/a2a/index.js +232 -0
- package/dist/adapter-context-mlWsVGGg.js +23 -0
- package/dist/ai-sdk/index.d.ts +95 -0
- package/dist/ai-sdk/index.js +154 -0
- package/dist/approval-required-TzNB9oQA.js +6 -0
- package/dist/approvals/index.d.ts +3 -0
- package/dist/approvals/index.js +5 -0
- package/dist/approvals-DbYAuNkG.js +224 -0
- package/dist/approvers-DT4AVyIg.js +52 -0
- package/dist/arazzo-BAgw9ap6.js +70 -0
- package/dist/arazzo-cmvX2jDe.js +54 -0
- package/dist/authzen/index.d.ts +39 -0
- package/dist/authzen/index.js +302 -0
- package/dist/better-auth/index.d.ts +109 -0
- package/dist/better-auth/index.js +344 -0
- package/dist/better-supabase/index.d.ts +206 -0
- package/dist/better-supabase/index.js +620 -0
- package/dist/bind-CVy3Espv.d.ts +25 -0
- package/dist/bind-VnYn2HKq.js +97 -0
- package/dist/boundary-BM8a_P6E.js +13 -0
- package/dist/boundary-BmHxVH1J.d.ts +15 -0
- package/dist/budget-JqcRqyhK.d.ts +11 -0
- package/dist/budget-NbEtbJC_.js +11 -0
- package/dist/canonical-json-DemiK4Vp.js +26 -0
- package/dist/capability-4qPdO9gk.js +173 -0
- package/dist/capability-Dq43tT1u.d.ts +99 -0
- package/dist/catalog/index.d.ts +12 -0
- package/dist/catalog/index.js +2 -0
- package/dist/catalog-BjZSovXQ.js +2 -0
- package/dist/catalog-doc-Dsc9y7sd.js +309 -0
- package/dist/catalog-h2tlKFkq.js +48 -0
- package/dist/catalog-path-CnI0XTFK.js +12 -0
- package/dist/catalog-z8q6bi_r.js +55 -0
- package/dist/claude-agent/index.d.ts +72 -0
- package/dist/claude-agent/index.js +77 -0
- package/dist/clerk/index.d.ts +65 -0
- package/dist/clerk/index.js +301 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +20 -0
- package/dist/cli/index.d.ts +46 -0
- package/dist/cli/index.js +5 -0
- package/dist/clients-C7zLFuWT.d.ts +12 -0
- package/dist/clients-DjU5ABMy.js +23 -0
- package/dist/cloud/index.d.ts +90 -0
- package/dist/cloud/index.js +404 -0
- package/dist/cloud-BGhHS-lY.js +50 -0
- package/dist/cloud-Bo3e9Ak3.js +118 -0
- package/dist/collect-DDDv_ESs.js +502 -0
- package/dist/collect-DLlujdHC.js +83 -0
- package/dist/collect-rG2IQ3t0.js +2 -0
- package/dist/commands-DWOrSQic.js +97 -0
- package/dist/compact-y6vfu2_f.js +19 -0
- package/dist/compare-pfyVnBjE.js +12 -0
- package/dist/compile/index.d.ts +3 -0
- package/dist/compile/index.js +2 -0
- package/dist/compile-Ba4blROR.js +613 -0
- package/dist/compile-CNnl6uIt.d.ts +94 -0
- package/dist/config-BJiM-xAm.js +157 -0
- package/dist/config-Bn00Z3ks.js +36 -0
- package/dist/config-report-Dw_JcUqT.js +44 -0
- package/dist/connection-CU8MQxRi.js +194 -0
- package/dist/context-Ttp0ekMT.js +82 -0
- package/dist/convex/index.d.ts +45 -0
- package/dist/convex/index.js +65 -0
- package/dist/create-BWyx3jua.d.ts +245 -0
- package/dist/create-CPhDL6qx.js +253 -0
- package/dist/credential-8P81ff4u.js +306 -0
- package/dist/delegation-D8pUEuce.js +103 -0
- package/dist/describe-B_gVZEVi.js +94 -0
- package/dist/describe-PdoqESvg.d.ts +36 -0
- package/dist/diff-B8Tunc3o.js +451 -0
- package/dist/diff-CzqLxZ77.js +48 -0
- package/dist/digest-B3kc_PgQ.d.ts +19 -0
- package/dist/digest-BI-6aa6d.js +27 -0
- package/dist/doctor-WpvG6p4k.js +1194 -0
- package/dist/doctor-collect-ByfYlNv1.js +664 -0
- package/dist/doctor-rOr-4ZfS.js +53 -0
- package/dist/drizzle/index.d.ts +73 -0
- package/dist/drizzle/index.js +160 -0
- package/dist/duration-xK2jGFVc.js +25 -0
- package/dist/elysia/index.d.ts +49 -0
- package/dist/elysia/index.js +59 -0
- package/dist/errors-CWfoNg9N.js +47 -0
- package/dist/errors-Cz5zn0mW.js +123 -0
- package/dist/errors-DAqevpNk.d.ts +125 -0
- package/dist/errors-DRnGZHzF.js +30 -0
- package/dist/evaluation-items-CfCCejQd.js +40 -0
- package/dist/evaluations-tz6D9A2G.js +461 -0
- package/dist/eve/index.d.ts +86 -0
- package/dist/eve/index.js +176 -0
- package/dist/expiry-BoBJ8Tvc.js +7 -0
- package/dist/express/index.d.ts +23 -0
- package/dist/express/index.js +78 -0
- package/dist/fastify/index.d.ts +33 -0
- package/dist/fastify/index.js +92 -0
- package/dist/fields-BMl1RxoX.js +26 -0
- package/dist/files-DWUN9PzI.js +125 -0
- package/dist/fixtures-ht28Cplr.js +67 -0
- package/dist/freeze-CrU8nQeX.js +60 -0
- package/dist/from-snapshot-C3sHpZNS.js +569 -0
- package/dist/generate-CH7ThJ14.js +173 -0
- package/dist/grantee-Cv5Sogfv.js +602 -0
- package/dist/graph-sql-B-dsAT6j.d.ts +29 -0
- package/dist/headers-BZSDieNT.js +6 -0
- package/dist/headers-Cf-zWvsO.d.ts +6 -0
- package/dist/helpers-H_KARDVC.js +421 -0
- package/dist/hono/index.d.ts +48 -0
- package/dist/hono/index.js +99 -0
- package/dist/hosted-DJQw46hn.js +266 -0
- package/dist/http-BIhmLfCc.js +95 -0
- package/dist/http-DPuDaChb.d.ts +13 -0
- package/dist/http-SO7qGttf.js +44 -0
- package/dist/ids-DC4V4CFu.js +18 -0
- package/dist/index-A0YNL8jZ.d.ts +177 -0
- package/dist/index-CtE07CBF.d.ts +6 -0
- package/dist/index-D3vbkoSI.d.ts +483 -0
- package/dist/index-D6_cSa1z.d.ts +201 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +26 -0
- package/dist/instance-options-BK_rNOSC.d.ts +11 -0
- package/dist/instance-options-Dhhcnm3y.js +22 -0
- package/dist/json-schema-BsAflUGW.js +106 -0
- package/dist/jwt/index.d.ts +91 -0
- package/dist/jwt/index.js +590 -0
- package/dist/kernel-GSQnMz3O.js +208 -0
- package/dist/kysely/index.d.ts +78 -0
- package/dist/kysely/index.js +129 -0
- package/dist/live-options-H2eG8dfJ.js +60 -0
- package/dist/load-DhWEB9P1.js +75 -0
- package/dist/load-DwJUafYN.js +2 -0
- package/dist/load-jose-BL6LH4bL.js +11 -0
- package/dist/lru-8q4WZjBV.js +28 -0
- package/dist/manifest-iaoBXHKc.js +783 -0
- package/dist/manifest-uDS9y5de.d.ts +206 -0
- package/dist/map-AcxK9o_D.js +147 -0
- package/dist/map-claims-Z4QZOiFF.js +369 -0
- package/dist/map-error-pgUWNNtG.js +23 -0
- package/dist/markers-B0hYLvMD.js +60 -0
- package/dist/may-use-DndQ5tQ-.js +77 -0
- package/dist/mcp/index.d.ts +159 -0
- package/dist/mcp/index.js +603 -0
- package/dist/nest/index.d.ts +75 -0
- package/dist/nest/index.js +261 -0
- package/dist/next/client.d.ts +23 -0
- package/dist/next/client.js +33 -0
- package/dist/next/index.d.ts +93 -0
- package/dist/next/index.js +180 -0
- package/dist/next/plugin.d.ts +14 -0
- package/dist/next/plugin.js +33 -0
- package/dist/node/index.d.ts +24 -0
- package/dist/node/index.js +34 -0
- package/dist/openai/index.d.ts +62 -0
- package/dist/openai/index.js +92 -0
- package/dist/openapi/index.d.ts +176 -0
- package/dist/openapi/index.js +3 -0
- package/dist/openapi-Bbg4wGVL.js +164 -0
- package/dist/openapi-BqRBvAng.js +538 -0
- package/dist/openapi-CqqEbHsL.js +250 -0
- package/dist/openapi-import-cmwetbzw.js +5959 -0
- package/dist/openapi-schema--ARjyfQr.js +6902 -0
- package/dist/orpc/index.d.ts +51 -0
- package/dist/orpc/index.js +145 -0
- package/dist/otel/index.d.ts +13 -0
- package/dist/otel/index.js +202 -0
- package/dist/package-root-zGkxO3oN.js +30 -0
- package/dist/parse-BuyjxhZV.js +53 -0
- package/dist/parse-local-manifest-BkGQNzAh.d.ts +10 -0
- package/dist/parse-local-manifest-BrMozJCo.js +36 -0
- package/dist/pdp/index.d.ts +22 -0
- package/dist/pdp/index.js +682 -0
- package/dist/peer-BOr_kJE1.js +31 -0
- package/dist/permdock-CzqXjCpU.js +3471 -0
- package/dist/permissions-CDgvKG5L.d.ts +52 -0
- package/dist/permissions-CpZrivYv.js +142 -0
- package/dist/permissions-DVoF6dMt.js +662 -0
- package/dist/permissions-DttnqqxC.d.ts +214 -0
- package/dist/pins-8ILTftC9.js +12 -0
- package/dist/policy-CFZAr_Al.d.ts +2252 -0
- package/dist/policy-D8UFyERw.d.ts +20 -0
- package/dist/policy-xyWg7QdR.js +1122 -0
- package/dist/powersync-A8x_Yyvh.js +2 -0
- package/dist/powersync-C7kLglqX.js +540 -0
- package/dist/powersync-yW1UUFzp.js +62 -0
- package/dist/prisma/index.d.ts +136 -0
- package/dist/prisma/index.js +455 -0
- package/dist/problem-B43ztKIm.js +191 -0
- package/dist/problem-details-CkL50EEf.d.ts +7 -0
- package/dist/problem-details-_AMOYz-w.js +144 -0
- package/dist/prompt-CXYhLfsS.js +32 -0
- package/dist/protected-CNsMzrVd.d.ts +27 -0
- package/dist/protected-Cs6kTaHo.js +100 -0
- package/dist/protected-bZs6rbT1.d.ts +40 -0
- package/dist/provider-Cjr62YMV.d.ts +6 -0
- package/dist/provider-DLzpb2Xz.js +52 -0
- package/dist/provider-store-DNyC1y48.js +43 -0
- package/dist/react/index.d.ts +8 -0
- package/dist/react/index.js +7 -0
- package/dist/react/provider-client.d.ts +2 -0
- package/dist/react/provider-client.js +3 -0
- package/dist/react-native/index.d.ts +198 -0
- package/dist/react-native/index.js +696 -0
- package/dist/refs-KYb4ntaz.js +91 -0
- package/dist/relations-cjOL01hZ.js +505 -0
- package/dist/replay-BsOyTrdV.js +28 -0
- package/dist/replay-sqBGMnNs.d.ts +5 -0
- package/dist/resource-ref-CaS9yVPi.js +20 -0
- package/dist/revocations-Bhr0aMIC.js +27 -0
- package/dist/revocations-Cy06JNx2.d.ts +21 -0
- package/dist/rls-BMNydpHk.js +2521 -0
- package/dist/rls-CEvs64Kj.js +238 -0
- package/dist/rls-fields-BMasREhR.js +3502 -0
- package/dist/rls-graph-pc9fuXYm.js +435 -0
- package/dist/rls-import-D8F7j35Q.js +943 -0
- package/dist/rls-migrate-7wikfrVI.js +367 -0
- package/dist/rls-ownership-B5Lkq62W.js +843 -0
- package/dist/rls-shared-aOQ4hGTO.js +493 -0
- package/dist/rls-verify-D8B7dOTh.js +745 -0
- package/dist/row-check-Dt35czLy.d.ts +40 -0
- package/dist/rpc-DOK54_CS.js +89 -0
- package/dist/run-YXCJDNYk.js +174 -0
- package/dist/runtime-CB8gQFvS.js +11 -0
- package/dist/saas-Bj_FFkjN.js +1203 -0
- package/dist/schema-D3MnDMxa.js +300 -0
- package/dist/scim/index.d.ts +2 -0
- package/dist/scim/index.js +2 -0
- package/dist/scim-BFGBBAqR.js +1445 -0
- package/dist/scopes-CVdPrWN-.js +239 -0
- package/dist/server/index.d.ts +134 -0
- package/dist/server/index.js +11 -0
- package/dist/server-DlZ28Oz5.js +268 -0
- package/dist/sha256-BO0swRXL.js +150 -0
- package/dist/shared-DRu8VFVM.js +123 -0
- package/dist/sink-Bd9PSyfq.js +141 -0
- package/dist/sink-Gs6TTVa-.d.ts +104 -0
- package/dist/skills-Biq5uup3.js +192 -0
- package/dist/skills-JaymNCdK.js +56 -0
- package/dist/snapshot-Enxd0n-s.js +975 -0
- package/dist/snapshot-cache-D6jLelln.js +44 -0
- package/dist/snapshot-cache-DwQH8ufx.d.ts +45 -0
- package/dist/solid/index.d.ts +93 -0
- package/dist/solid/index.js +188 -0
- package/dist/sources-B0UvrJ21.js +534 -0
- package/dist/sources-BcJgw0lt.d.ts +192 -0
- package/dist/sql-xdg5f4Fi.js +27 -0
- package/dist/src-CSbUiozF.js +568 -0
- package/dist/ssf/index.d.ts +4 -0
- package/dist/ssf/index.js +596 -0
- package/dist/store-DMAWwAJV.js +371 -0
- package/dist/store-D_pjn91-.d.ts +36 -0
- package/dist/store-options-yO0V6gRn.js +716 -0
- package/dist/stores-4_sqiOA1.js +87 -0
- package/dist/stores-DVR5NHLE.d.ts +52 -0
- package/dist/stream-DDpvynSB.js +66 -0
- package/dist/stream-DlvG2hs-.d.ts +12 -0
- package/dist/style-CTm1AXDT.js +22 -0
- package/dist/subject-C6dLxqHU.js +24 -0
- package/dist/subject-settings-BwBmCdTR.js +128 -0
- package/dist/supabase/index.d.ts +183 -0
- package/dist/supabase/index.js +5 -0
- package/dist/supabase/middleware.d.ts +82 -0
- package/dist/supabase/middleware.js +102 -0
- package/dist/supabase-CwafwxxF.js +83 -0
- package/dist/supabase-DTBaC20O.js +774 -0
- package/dist/supabase-config-Bs44dare.js +472 -0
- package/dist/supabase-hook-BuxLQLpU.js +1814 -0
- package/dist/supabase-hook-D5qVd_D8.js +2 -0
- package/dist/supautils-DYZnzRWV.js +91 -0
- package/dist/svelte/PermissionBoundary.svelte +37 -0
- package/dist/svelte/Protected.svelte +40 -0
- package/dist/svelte/index.d.ts +13 -0
- package/dist/svelte/index.js +107 -0
- package/dist/svelte/runtime.d.ts +7 -0
- package/dist/svelte/runtime.js +4 -0
- package/dist/svelte/source.d.ts +13 -0
- package/dist/svelte/source.js +11 -0
- package/dist/terminal/index.d.ts +163 -0
- package/dist/terminal/index.js +833 -0
- package/dist/testing/index.d.ts +745 -0
- package/dist/testing/index.js +3672 -0
- package/dist/testing/saas/index.d.ts +194 -0
- package/dist/testing/saas/index.js +3 -0
- package/dist/testing/saas/permissions.d.ts +2 -0
- package/dist/testing/saas/permissions.js +2 -0
- package/dist/text-diff-BdkkYSbi.js +15 -0
- package/dist/thenable-okc2xDsj.js +10 -0
- package/dist/timeout-D51niuQP.js +8 -0
- package/dist/token-CIWxJOCh.js +50 -0
- package/dist/trpc/index.d.ts +61 -0
- package/dist/trpc/index.js +122 -0
- package/dist/types-9AWO9EGt.d.ts +197 -0
- package/dist/types-BPxgszlT.d.ts +550 -0
- package/dist/types-BVyImy5I.d.ts +120 -0
- package/dist/types-Bvc4oWT6.d.ts +9 -0
- package/dist/types-C3s9xVJG.d.ts +48 -0
- package/dist/types-Dnemwd77.d.ts +183 -0
- package/dist/types-kxznc7cn.d.ts +52 -0
- package/dist/types-vKyAMtcX.d.ts +157 -0
- package/dist/types-vNSDF7Dq.d.ts +66 -0
- package/dist/types-yF5LmQVD.d.ts +306 -0
- package/dist/unplugin/index.d.ts +7 -0
- package/dist/unplugin/index.js +31 -0
- package/dist/usage-D07N9QJ3.js +42 -0
- package/dist/usage-D82l1CwK.js +2 -0
- package/dist/usage-DG1oeCca.js +693 -0
- package/dist/validation-error-CnjZ4t92.js +33 -0
- package/dist/validation-error-CtF23SrC.d.ts +26 -0
- package/dist/validity-uOp8UpYn.js +245 -0
- package/dist/verifier-BxBo6I44.js +466 -0
- package/dist/version-BvacVTZR.js +17 -0
- package/dist/views-Soe7bGSC.js +95 -0
- package/dist/vocabulary-DA8a8zif.d.ts +56 -0
- package/dist/vue/index.d.ts +79 -0
- package/dist/vue/index.js +196 -0
- package/dist/watch-Etoa_Mvr.js +2 -0
- package/dist/watch-UihESpsJ.js +128 -0
- package/dist/webmcp/index.d.ts +75 -0
- package/dist/webmcp/index.js +307 -0
- package/package.json +450 -5
- package/rulesets/permdock.yaml +29 -0
- package/schemas/approval-request-v1.json +175 -0
- package/schemas/catalog-v1.json +535 -0
- package/schemas/openapi/oas-3.1.json +1298 -0
- package/schemas/openapi/oas-3.2.json +1516 -0
- package/schemas/openapi/overlay-1.1.json +79 -0
- package/schemas/supabase-claims-v1.json +144 -0
- package/schemas/supabase-manifest-v1.json +361 -0
- package/skills/permdock/SKILL.md +66 -0
- package/skills/permdock-agents/SKILL.md +77 -0
- package/skills/permdock-agents/references/runtimes.md +213 -0
- package/skills/permdock-approvals/SKILL.md +80 -0
- package/skills/permdock-approvals/references/stores-and-resume.md +94 -0
- package/skills/permdock-audit/SKILL.md +67 -0
- package/skills/permdock-credentials/SKILL.md +55 -0
- package/skills/permdock-credentials/references/tokens-keys-links.md +132 -0
- package/skills/permdock-data/SKILL.md +57 -0
- package/skills/permdock-data/references/queries-and-rls.md +62 -0
- package/skills/permdock-data/references/relationships.md +67 -0
- package/skills/permdock-tenancy/SKILL.md +80 -0
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +89 -0
- package/skills/permdock-wire/SKILL.md +116 -0
- package/skills/permdock-wire/references/adapters.md +492 -0
- package/skills/permdock-wire/references/policy-options.md +45 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { C as Policy, D as PolicyVocabulary, Nr as Principal, ln as PermDock } from "../policy-CFZAr_Al.js";
|
|
2
|
+
import { f as Permission } from "../permissions-DttnqqxC.js";
|
|
3
|
+
import { n as RevocationFeed } from "../revocations-Cy06JNx2.js";
|
|
4
|
+
import { A as ConnectionOptions, O as Connection, n as OpenApiHooks } from "../create-BWyx3jua.js";
|
|
5
|
+
import { t as ServerAdapterOptions } from "../bind-CVy3Espv.js";
|
|
6
|
+
import { t as StreamProtectOptions } from "../stream-DlvG2hs-.js";
|
|
7
|
+
import { Middleware } from "@orpc/server";
|
|
8
|
+
//#region src/orpc/create.d.ts
|
|
9
|
+
type OrpcMiddlewareOpts<TCtx extends object = object, TInput = unknown> = {
|
|
10
|
+
readonly context: TCtx;
|
|
11
|
+
readonly input?: TInput;
|
|
12
|
+
readonly path?: readonly string[];
|
|
13
|
+
readonly next: (opts?: {
|
|
14
|
+
readonly context: TCtx;
|
|
15
|
+
}) => Promise<unknown>;
|
|
16
|
+
};
|
|
17
|
+
type OrpcMiddleware<TCtx extends object = object, TInput = unknown, V extends PolicyVocabulary = PolicyVocabulary> = Middleware<TCtx, TCtx & {
|
|
18
|
+
readonly permdock: PermDock<V>;
|
|
19
|
+
readonly permdockData?: unknown;
|
|
20
|
+
}, TInput, any, Record<never, never>>;
|
|
21
|
+
type OrpcPermDockOptions<TCtx extends object = object, TUser = unknown> = ServerAdapterOptions<OrpcMiddlewareOpts<TCtx>, TUser> & {
|
|
22
|
+
/** The Web `Request` behind a context; defaults to `context.request` or `context.req`. */
|
|
23
|
+
readonly request?: (context: TCtx) => Request | null | undefined;
|
|
24
|
+
/** Ends or revalidates open event iterators. */
|
|
25
|
+
readonly revocations?: RevocationFeed;
|
|
26
|
+
};
|
|
27
|
+
type OrpcOpenApiHooks<TCtx extends object = object, V extends PolicyVocabulary = PolicyVocabulary> = {
|
|
28
|
+
readonly protect: (permission: Permission | null, loadData?: (opts: OrpcMiddlewareOpts<TCtx>) => unknown, protectOptions?: StreamProtectOptions) => OrpcMiddleware<TCtx, unknown, V>;
|
|
29
|
+
readonly security: (permission: Permission) => {
|
|
30
|
+
readonly security: readonly Record<string, readonly string[]>[];
|
|
31
|
+
readonly "x-permdock-permissions": readonly string[];
|
|
32
|
+
};
|
|
33
|
+
readonly securitySchemes: OpenApiHooks["securitySchemes"];
|
|
34
|
+
};
|
|
35
|
+
type OrpcPermDock<TCtx extends object = object, V extends PolicyVocabulary = PolicyVocabulary> = {
|
|
36
|
+
readonly permdock: () => OrpcMiddleware<TCtx, unknown, V>;
|
|
37
|
+
readonly protect: (permission: Permission | null, loadData?: (opts: OrpcMiddlewareOpts<TCtx>) => unknown, protectOptions?: StreamProtectOptions) => OrpcMiddleware<TCtx, unknown, V>;
|
|
38
|
+
/** A long-lived connection for the request behind `context`. */
|
|
39
|
+
readonly connection: (opts: OrpcMiddlewareOpts<TCtx>, connectionOptions?: ConnectionOptions) => Promise<Connection>;
|
|
40
|
+
readonly permdockHandler: (request: Request) => Promise<Response>;
|
|
41
|
+
readonly openapi: OrpcOpenApiHooks<TCtx, V>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* The permission the procedure's first `protect` decides, or `undefined`
|
|
45
|
+
* when no `protect` is attached. Reads the procedure definition only and
|
|
46
|
+
* never decides.
|
|
47
|
+
*/
|
|
48
|
+
export declare function permissionOf(procedure: unknown): Permission | undefined;
|
|
49
|
+
export declare function createPermDock<TCtx extends object = object, TUser = unknown, TPrincipal extends Principal = Principal, V extends PolicyVocabulary = PolicyVocabulary>(policy: Policy<TUser, TPrincipal, V>, options: OrpcPermDockOptions<TCtx, TUser>): OrpcPermDock<TCtx, V>;
|
|
50
|
+
//#endregion
|
|
51
|
+
export type { OrpcMiddleware, OrpcMiddlewareOpts, OrpcOpenApiHooks, OrpcPermDock, OrpcPermDockOptions };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { t as compact } from "../compact-y6vfu2_f.js";
|
|
2
|
+
import { p as isPermission } from "../permissions-DVoF6dMt.js";
|
|
3
|
+
import { a as problemMessage } from "../http-SO7qGttf.js";
|
|
4
|
+
import { t as problemFromError } from "../map-error-pgUWNNtG.js";
|
|
5
|
+
import { n as attached } from "../bind-VnYn2HKq.js";
|
|
6
|
+
import { a as reloadAfter, r as isAsyncIterable } from "../stream-DDpvynSB.js";
|
|
7
|
+
import { i as rpcCode, n as guardStream, r as problemBody, t as bindRpcKernel } from "../rpc-DOK54_CS.js";
|
|
8
|
+
import { ORPCError } from "@orpc/server";
|
|
9
|
+
//#region src/orpc/create.ts
|
|
10
|
+
function toOpts(mw, input, next) {
|
|
11
|
+
return compact({
|
|
12
|
+
context: mw.context,
|
|
13
|
+
input,
|
|
14
|
+
path: mw.path,
|
|
15
|
+
next
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function isErrorConstructor(value) {
|
|
19
|
+
return typeof value === "function";
|
|
20
|
+
}
|
|
21
|
+
/** Uses the procedure's own constructor when it declares the code, so the declared status and `defined` apply. */
|
|
22
|
+
function orpcError(code, message, data, errors) {
|
|
23
|
+
const declared = errors !== void 0 && Object.hasOwn(errors, code) ? errors[code] : void 0;
|
|
24
|
+
return isErrorConstructor(declared) ? declared({
|
|
25
|
+
message,
|
|
26
|
+
data
|
|
27
|
+
}) : new ORPCError(code, {
|
|
28
|
+
message,
|
|
29
|
+
data
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function orpcErrorFrom(error, errors) {
|
|
33
|
+
const problem = error.toProblemDetails();
|
|
34
|
+
return orpcError(rpcCode(problem.status), error.code, problem, errors);
|
|
35
|
+
}
|
|
36
|
+
async function throwOrpcError(response, errors) {
|
|
37
|
+
const data = await problemBody(response);
|
|
38
|
+
const code = rpcCode(response.status);
|
|
39
|
+
throw orpcError(code, problemMessage(data, code), data, errors);
|
|
40
|
+
}
|
|
41
|
+
/** A PermDock error thrown further down (an `assert` in a handler) becomes the ORPCError `protect` throws. */
|
|
42
|
+
function mapDownstream(run, errors) {
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
resolve(run());
|
|
45
|
+
}).catch((error) => {
|
|
46
|
+
const mapped = problemFromError(error);
|
|
47
|
+
if (mapped === void 0) throw error;
|
|
48
|
+
return throwOrpcError(mapped, errors);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** Registered, so a second copy of `permdock` in the bundle reads the same tag. */
|
|
52
|
+
const PERMISSION = Symbol.for("permdock.orpc.permission");
|
|
53
|
+
function tagged(permission, middleware) {
|
|
54
|
+
if (permission !== null) Object.defineProperty(middleware, PERMISSION, { value: permission });
|
|
55
|
+
return middleware;
|
|
56
|
+
}
|
|
57
|
+
function readOwn(value, key) {
|
|
58
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && Object.hasOwn(value, key) ? Reflect.get(value, key) : void 0;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The permission the procedure's first `protect` decides, or `undefined`
|
|
62
|
+
* when no `protect` is attached. Reads the procedure definition only and
|
|
63
|
+
* never decides.
|
|
64
|
+
*/
|
|
65
|
+
function permissionOf(procedure) {
|
|
66
|
+
const ordered = readOwn(readOwn(procedure, "~orpc"), "orderedMiddlewares");
|
|
67
|
+
if (!Array.isArray(ordered)) return;
|
|
68
|
+
for (const entry of ordered) {
|
|
69
|
+
const permission = readOwn(readOwn(entry, "middleware"), PERMISSION);
|
|
70
|
+
if (isPermission(permission)) return permission;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function createPermDock(policy, options) {
|
|
74
|
+
const { kernel, bind, attach, scopeOf, connection, evaluate } = bindRpcKernel(policy, options, "orpc", (opts) => opts.context, (opts) => opts.path?.join(".") ?? "orpc");
|
|
75
|
+
/** Instances this factory built, with the tenant each was built for. */
|
|
76
|
+
const issued = /* @__PURE__ */ new WeakMap();
|
|
77
|
+
const issue = (instance, scope) => {
|
|
78
|
+
issued.set(instance, scope.tenant);
|
|
79
|
+
return instance;
|
|
80
|
+
};
|
|
81
|
+
const boundFor = (context, scope) => {
|
|
82
|
+
const bound = Reflect.get(context, "permdock");
|
|
83
|
+
if (typeof bound !== "object" || bound === null || !issued.has(bound) || issued.get(bound) !== scope.tenant) return;
|
|
84
|
+
return bound;
|
|
85
|
+
};
|
|
86
|
+
const permdock = () => ((mwOptions, input) => {
|
|
87
|
+
const opts = toOpts(mwOptions, input, mwOptions.next);
|
|
88
|
+
const request = bind(opts);
|
|
89
|
+
return scopeOf(opts).then((scope) => attached(async () => boundFor(opts.context, scope) ?? issue(await kernel.permdock(request, scope), scope))).then((instance) => {
|
|
90
|
+
if (!instance.ok) return throwOrpcError(instance.response, mwOptions.errors);
|
|
91
|
+
const nextCtx = {
|
|
92
|
+
...opts.context,
|
|
93
|
+
permdock: instance.permdock
|
|
94
|
+
};
|
|
95
|
+
attach(nextCtx, request);
|
|
96
|
+
return mapDownstream(() => mwOptions.next({ context: nextCtx }), mwOptions.errors);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
/** Wraps an event iterator so revocation ends it and unreadable items drop. */
|
|
100
|
+
const guardOutput = async (result, opts, permission, loadData, protectOptions, errors) => {
|
|
101
|
+
const output = result !== null && typeof result === "object" && "output" in result ? result.output : void 0;
|
|
102
|
+
if (!isAsyncIterable(output)) return result;
|
|
103
|
+
return {
|
|
104
|
+
...result,
|
|
105
|
+
output: await guardStream(output, (connectionOptions) => connection(opts, connectionOptions), permission, loadData, protectOptions, { onRevoked: (error) => orpcErrorFrom(error, errors) })
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
const protect = (permission, loadData, protectOptions) => tagged(permission, (async (mwOptions, input) => {
|
|
109
|
+
const opts = toOpts(mwOptions, input, mwOptions.next);
|
|
110
|
+
const request = bind(opts);
|
|
111
|
+
const scope = await scopeOf(opts);
|
|
112
|
+
const guard = await kernel.protect(permission, loadData === void 0 ? void 0 : () => loadData(opts), protectOptions)(request, scope);
|
|
113
|
+
if (guard.ok) {
|
|
114
|
+
const nextCtx = {
|
|
115
|
+
...opts.context,
|
|
116
|
+
permdock: issue(guard.permdock, scope),
|
|
117
|
+
permdockData: guard.data
|
|
118
|
+
};
|
|
119
|
+
attach(nextCtx, request);
|
|
120
|
+
return guardOutput(await mapDownstream(() => mwOptions.next({ context: nextCtx }), mwOptions.errors), opts, permission, loadData === void 0 ? void 0 : reloadAfter(guard.data, () => loadData(opts)), protectOptions, mwOptions.errors);
|
|
121
|
+
}
|
|
122
|
+
return throwOrpcError(guard.response, mwOptions.errors);
|
|
123
|
+
}));
|
|
124
|
+
const permdockHandler = (request) => {
|
|
125
|
+
return evaluate(request, {
|
|
126
|
+
context: { req: request },
|
|
127
|
+
path: ["permdock"],
|
|
128
|
+
next: (nextOpts) => Promise.resolve(nextOpts ?? { context: { req: request } })
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const kernelOpenApi = kernel.openapi;
|
|
132
|
+
return {
|
|
133
|
+
permdock,
|
|
134
|
+
protect,
|
|
135
|
+
connection,
|
|
136
|
+
permdockHandler,
|
|
137
|
+
openapi: {
|
|
138
|
+
protect,
|
|
139
|
+
security: kernelOpenApi.security,
|
|
140
|
+
securitySchemes: kernelOpenApi.securitySchemes
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
export { createPermDock, permissionOf };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { D as PolicyVocabulary, ln as PermDock } from "../policy-CFZAr_Al.js";
|
|
2
|
+
import { a as OtelOptions, i as OtelApi, n as GEN_AI_TOOL_CALL_ID, o as OtelWrap, r as GEN_AI_TOOL_NAME, s as StructuralLogger, t as GENAI_SEMCONV_PIN } from "../types-vNSDF7Dq.js";
|
|
3
|
+
//#region src/otel/instrument.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Listens on one instance. Spans carry no duration and no histogram is
|
|
6
|
+
* recorded, because a listener only sees a decision after it is made; use
|
|
7
|
+
* `withOtel` for timings and for `tenant()` / `team()` derived instances.
|
|
8
|
+
*/
|
|
9
|
+
export declare function instrument(permdock: PermDock, options?: OtelOptions): () => void;
|
|
10
|
+
/** Returns an instrumented instance: timed spans and histogram, derived instances included. */
|
|
11
|
+
export declare function withOtel<V extends PolicyVocabulary = PolicyVocabulary>(permdock: PermDock<V>, options?: OtelOptions): PermDock<V>;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { GENAI_SEMCONV_PIN, GEN_AI_TOOL_CALL_ID, GEN_AI_TOOL_NAME, type OtelApi, type OtelOptions, type OtelWrap, type StructuralLogger };
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { t as compact } from "../compact-y6vfu2_f.js";
|
|
2
|
+
//#region src/otel/types.ts
|
|
3
|
+
const GENAI_SEMCONV_PIN = "1.37.0";
|
|
4
|
+
const GEN_AI_TOOL_NAME = "gen_ai.tool.name";
|
|
5
|
+
const GEN_AI_TOOL_CALL_ID = "gen_ai.tool.call.id";
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/otel/instrument.ts
|
|
8
|
+
const FORBIDDEN = /* @__PURE__ */ new Set([
|
|
9
|
+
"__proto__",
|
|
10
|
+
"constructor",
|
|
11
|
+
"prototype"
|
|
12
|
+
]);
|
|
13
|
+
const SPAN_STATUS_ERROR = 2;
|
|
14
|
+
const OTEL_REGISTRY = Symbol.for("opentelemetry.js.api.1");
|
|
15
|
+
const OTEL_SPAN_KEY = Symbol.for("OpenTelemetry Context Key SPAN");
|
|
16
|
+
function registry() {
|
|
17
|
+
const value = globalThis[OTEL_REGISTRY];
|
|
18
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
19
|
+
}
|
|
20
|
+
const NOOP_TRACER = { startSpan: () => ({}) };
|
|
21
|
+
const registryApi = {
|
|
22
|
+
trace: {
|
|
23
|
+
getTracer: (name) => registry()?.trace?.getTracer?.(name) ?? NOOP_TRACER,
|
|
24
|
+
getActiveSpan: () => registry()?.context?.active?.()?.getValue?.(OTEL_SPAN_KEY)
|
|
25
|
+
},
|
|
26
|
+
metrics: { getMeter: (name) => registry()?.metrics?.getMeter?.(name) ?? {
|
|
27
|
+
createCounter: () => ({ add: () => void 0 }),
|
|
28
|
+
createHistogram: () => ({ record: () => void 0 })
|
|
29
|
+
} }
|
|
30
|
+
};
|
|
31
|
+
function resolveApi(injected) {
|
|
32
|
+
if (injected !== void 0) return injected;
|
|
33
|
+
return registry() === void 0 ? void 0 : registryApi;
|
|
34
|
+
}
|
|
35
|
+
function safeCall(fn, logger) {
|
|
36
|
+
try {
|
|
37
|
+
fn();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (logger?.error !== void 0) try {
|
|
40
|
+
logger.error("permdock.otel", { cause: String(error) });
|
|
41
|
+
} catch {}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function omitPath(attributes, path) {
|
|
45
|
+
if (Object.hasOwn(attributes, path)) {
|
|
46
|
+
const next = {};
|
|
47
|
+
for (const key of Object.keys(attributes)) if (key !== path) next[key] = attributes[key];
|
|
48
|
+
return {
|
|
49
|
+
attributes: next,
|
|
50
|
+
matched: true
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const parts = path.split(".");
|
|
54
|
+
if (parts.some((part) => FORBIDDEN.has(part))) return {
|
|
55
|
+
attributes,
|
|
56
|
+
matched: false
|
|
57
|
+
};
|
|
58
|
+
const [head, ...rest] = parts;
|
|
59
|
+
if (head === void 0 || rest.length === 0 || !Object.hasOwn(attributes, head)) return {
|
|
60
|
+
attributes,
|
|
61
|
+
matched: false
|
|
62
|
+
};
|
|
63
|
+
const nested = attributes[head];
|
|
64
|
+
if (nested === null || typeof nested !== "object") return {
|
|
65
|
+
attributes,
|
|
66
|
+
matched: false
|
|
67
|
+
};
|
|
68
|
+
const child = omitPath(nested, rest.join("."));
|
|
69
|
+
if (!child.matched) return {
|
|
70
|
+
attributes,
|
|
71
|
+
matched: false
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
attributes: {
|
|
75
|
+
...attributes,
|
|
76
|
+
[head]: child.attributes
|
|
77
|
+
},
|
|
78
|
+
matched: true
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function attributesOf(event, options, parent) {
|
|
82
|
+
const extra = options.attributes === void 0 ? {} : options.attributes(event);
|
|
83
|
+
let redacted = compact({
|
|
84
|
+
"permdock.outcome": event.outcome,
|
|
85
|
+
"permdock.permission": event.permission,
|
|
86
|
+
"permdock.scope": event.scope,
|
|
87
|
+
"permdock.resource.type": event.resource.type,
|
|
88
|
+
"permdock.resource.id": event.resource.id,
|
|
89
|
+
"permdock.subject.id": event.subject.principal?.id,
|
|
90
|
+
"permdock.actor.id": event.subject.actor?.id,
|
|
91
|
+
"permdock.actor.kind": event.subject.actor?.kind,
|
|
92
|
+
"permdock.delegation.scopes": event.subject.delegation?.scopes?.join(","),
|
|
93
|
+
"permdock.matched.role": event.matched?.role,
|
|
94
|
+
"permdock.denials.count": event.denials?.length,
|
|
95
|
+
"permdock.token": event.token,
|
|
96
|
+
"permdock.validate": event.trusted ? "trusted" : "boundary",
|
|
97
|
+
"permdock.adapter": event.adapter,
|
|
98
|
+
"permdock.filter.total": event.counts === void 0 ? void 0 : event.counts.granted + event.counts.denied + event.counts.approvalRequired,
|
|
99
|
+
"permdock.filter.kept": event.counts?.granted,
|
|
100
|
+
[GEN_AI_TOOL_NAME]: parent?.attributes?.[GEN_AI_TOOL_NAME],
|
|
101
|
+
[GEN_AI_TOOL_CALL_ID]: parent?.attributes?.[GEN_AI_TOOL_CALL_ID],
|
|
102
|
+
...extra
|
|
103
|
+
});
|
|
104
|
+
const unmatched = [];
|
|
105
|
+
for (const path of options.redact ?? []) {
|
|
106
|
+
const result = omitPath(redacted, path);
|
|
107
|
+
redacted = result.attributes;
|
|
108
|
+
if (!result.matched) unmatched.push(path);
|
|
109
|
+
}
|
|
110
|
+
if (unmatched.length > 0) safeCall(() => {
|
|
111
|
+
options.logger?.warn(`permdock.otel unmatched redact: ${unmatched.join(", ")}`);
|
|
112
|
+
}, options.logger);
|
|
113
|
+
return redacted;
|
|
114
|
+
}
|
|
115
|
+
/** Epoch milliseconds with sub-millisecond precision, the OTel `TimeInput` form. */
|
|
116
|
+
function now() {
|
|
117
|
+
return performance.timeOrigin + performance.now();
|
|
118
|
+
}
|
|
119
|
+
function recordSignals(event, options, api, timing) {
|
|
120
|
+
const parent = api?.trace.getActiveSpan?.();
|
|
121
|
+
const attributes = attributesOf(event, options, parent);
|
|
122
|
+
if (options.logger !== void 0) safeCall(() => {
|
|
123
|
+
options.logger?.info("permdock.decision", attributes);
|
|
124
|
+
}, options.logger);
|
|
125
|
+
if (api === void 0) return;
|
|
126
|
+
const name = options.tracer ?? "permdock";
|
|
127
|
+
const span = api.trace.getTracer(name).startSpan("permdock.decide", timing === void 0 ? void 0 : { startTime: timing.start });
|
|
128
|
+
if (span.isRecording?.() === false) safeCall(() => {
|
|
129
|
+
options.logger?.warn("permdock.otel: @opentelemetry/api is present but no provider is registered");
|
|
130
|
+
}, options.logger);
|
|
131
|
+
span.setAttributes?.(attributes);
|
|
132
|
+
if (event.outcome === "denied") {
|
|
133
|
+
span.addEvent?.("permdock.denied", compact({
|
|
134
|
+
role: event.denials?.map((denial) => denial.role).join(","),
|
|
135
|
+
reason: event.denials?.map((denial) => denial.reason).join(","),
|
|
136
|
+
alternatives: event.alternatives?.join(",")
|
|
137
|
+
}));
|
|
138
|
+
if (event.denials?.some((denial) => denial.reason === "validation") === true) span.recordException?.(/* @__PURE__ */ new Error("validation"));
|
|
139
|
+
if (options.errorOnDeny === true) span.setStatus?.({ code: SPAN_STATUS_ERROR });
|
|
140
|
+
}
|
|
141
|
+
span.end?.(timing?.end);
|
|
142
|
+
const meter = api.metrics?.getMeter(name);
|
|
143
|
+
const counterAttrs = compact({
|
|
144
|
+
"permdock.outcome": event.outcome,
|
|
145
|
+
"permdock.permission": event.permission,
|
|
146
|
+
"permdock.adapter": event.adapter
|
|
147
|
+
});
|
|
148
|
+
meter?.createCounter("permdock.decisions").add(1, counterAttrs);
|
|
149
|
+
if (timing !== void 0) meter?.createHistogram("permdock.decide.duration", { unit: "s" }).record((timing.end - timing.start) / 1e3, counterAttrs);
|
|
150
|
+
}
|
|
151
|
+
function listen(permdock, options, api, startedAt) {
|
|
152
|
+
return permdock.on("decision", (payload) => {
|
|
153
|
+
const end = now();
|
|
154
|
+
const start = startedAt();
|
|
155
|
+
const event = payload;
|
|
156
|
+
safeCall(() => {
|
|
157
|
+
recordSignals(event, options, api, start === void 0 ? void 0 : {
|
|
158
|
+
start,
|
|
159
|
+
end
|
|
160
|
+
});
|
|
161
|
+
}, options.logger);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Listens on one instance. Spans carry no duration and no histogram is
|
|
166
|
+
* recorded, because a listener only sees a decision after it is made; use
|
|
167
|
+
* `withOtel` for timings and for `tenant()` / `team()` derived instances.
|
|
168
|
+
*/
|
|
169
|
+
function instrument(permdock, options = {}) {
|
|
170
|
+
return listen(permdock, options, resolveApi(options.api), () => void 0);
|
|
171
|
+
}
|
|
172
|
+
function instrumented(permdock, options, api) {
|
|
173
|
+
let started;
|
|
174
|
+
listen(permdock, options, api, () => started);
|
|
175
|
+
const timed = (fn) => (...args) => {
|
|
176
|
+
const outer = started === void 0;
|
|
177
|
+
if (outer) started = now();
|
|
178
|
+
try {
|
|
179
|
+
return fn(...args);
|
|
180
|
+
} finally {
|
|
181
|
+
if (outer) started = void 0;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
return Object.freeze({
|
|
185
|
+
...permdock,
|
|
186
|
+
can: timed(permdock.can),
|
|
187
|
+
decide: timed(permdock.decide),
|
|
188
|
+
assert: timed(permdock.assert),
|
|
189
|
+
explain: timed(permdock.explain),
|
|
190
|
+
filter: timed(permdock.filter),
|
|
191
|
+
pick: timed(permdock.pick),
|
|
192
|
+
actions: timed(permdock.actions),
|
|
193
|
+
tenant: (id) => instrumented(permdock.tenant(id), options, api),
|
|
194
|
+
team: (id) => instrumented(permdock.team(id), options, api)
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/** Returns an instrumented instance: timed spans and histogram, derived instances included. */
|
|
198
|
+
function withOtel(permdock, options = {}) {
|
|
199
|
+
return instrumented(permdock, options, resolveApi(options.api));
|
|
200
|
+
}
|
|
201
|
+
//#endregion
|
|
202
|
+
export { GENAI_SEMCONV_PIN, GEN_AI_TOOL_CALL_ID, GEN_AI_TOOL_NAME, instrument, withOtel };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
//#region src/cli/package-root.ts
|
|
5
|
+
let cached;
|
|
6
|
+
/**
|
|
7
|
+
* The `permdock` package directory. The bundler may place this module in
|
|
8
|
+
* `dist/cli/` or in a shared chunk at `dist/`, so walk up instead of
|
|
9
|
+
* assuming a depth.
|
|
10
|
+
*/
|
|
11
|
+
function packageRoot() {
|
|
12
|
+
cached ??= findPackageRoot(dirname(fileURLToPath(import.meta.url)));
|
|
13
|
+
return cached;
|
|
14
|
+
}
|
|
15
|
+
/** The nearest directory at or above `start` whose `package.json` is named `permdock`. */
|
|
16
|
+
function findPackageRoot(start) {
|
|
17
|
+
let dir = start;
|
|
18
|
+
for (;;) {
|
|
19
|
+
const manifest = join(dir, "package.json");
|
|
20
|
+
if (existsSync(manifest)) {
|
|
21
|
+
const { name } = JSON.parse(readFileSync(manifest, "utf8"));
|
|
22
|
+
if (name === "permdock") return dir;
|
|
23
|
+
}
|
|
24
|
+
const parent = dirname(dir);
|
|
25
|
+
if (parent === dir) throw new Error("PermDock CLI: cannot find the permdock package root");
|
|
26
|
+
dir = parent;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { packageRoot as t };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { n as freezeDeep } from "./freeze-CrU8nQeX.js";
|
|
2
|
+
import { n as PermDockValidationError } from "./validation-error-CnjZ4t92.js";
|
|
3
|
+
import { t as catalogSchema } from "./schema-D3MnDMxa.js";
|
|
4
|
+
import { n as copyJson, t as checkSchema } from "./json-schema-BsAflUGW.js";
|
|
5
|
+
//#region src/catalog/parse.ts
|
|
6
|
+
function invalid(issues) {
|
|
7
|
+
const [first] = issues;
|
|
8
|
+
const where = first?.path === void 0 || first.path.length === 0 ? "" : ` at ${first.path.map(String).join(".")}`;
|
|
9
|
+
const more = issues.length > 1 ? ` (and ${String(issues.length - 1)} more)` : "";
|
|
10
|
+
throw new PermDockValidationError({
|
|
11
|
+
code: "invalid-data",
|
|
12
|
+
permission: "",
|
|
13
|
+
resource: "",
|
|
14
|
+
boundary: "catalog",
|
|
15
|
+
issues,
|
|
16
|
+
message: `PermDock: invalid catalog${where}: ${first?.message ?? "unknown"}${more}`
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Reads a `permissions.catalog.json` document (parsed, or the JSON text) and
|
|
21
|
+
* validates it against `schemas/catalog-v1.json`. Returns a deep-frozen copy
|
|
22
|
+
* built from own keys; throws `PermDockValidationError` with every issue.
|
|
23
|
+
*/
|
|
24
|
+
function parseCatalog(json) {
|
|
25
|
+
const issues = [];
|
|
26
|
+
let input = json;
|
|
27
|
+
if (typeof json === "string") try {
|
|
28
|
+
input = JSON.parse(json);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
invalid([{
|
|
31
|
+
message: `Expected JSON text: ${error instanceof Error ? error.message : String(error)}`,
|
|
32
|
+
path: []
|
|
33
|
+
}]);
|
|
34
|
+
}
|
|
35
|
+
let copy;
|
|
36
|
+
try {
|
|
37
|
+
copy = copyJson(input, [], issues, /* @__PURE__ */ new Set());
|
|
38
|
+
} catch (error) {
|
|
39
|
+
invalid([{
|
|
40
|
+
message: `Could not read the input: ${error instanceof Error ? error.message : String(error)}`,
|
|
41
|
+
path: []
|
|
42
|
+
}]);
|
|
43
|
+
}
|
|
44
|
+
if (issues.length === 0) checkSchema(catalogSchema, copy, [], issues);
|
|
45
|
+
if (issues.length > 0) invalid(issues);
|
|
46
|
+
return freezeDeep(copy);
|
|
47
|
+
}
|
|
48
|
+
/** Keys of the permissions the catalog marks `rowConditions: true`: the SQL helpers alone cannot enforce them. */
|
|
49
|
+
function rowConditionKeys(catalog) {
|
|
50
|
+
return new Set(catalog.permissions.filter((permission) => permission.rowConditions === true).map((permission) => permission.key));
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { rowConditionKeys as n, parseCatalog as t };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { pt as LocalSnapshotManifest } from "./policy-CFZAr_Al.js";
|
|
2
|
+
//#region src/core/parse-local-manifest.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Whether `value` has the shape `localSnapshotManifest(policy)` writes, with
|
|
5
|
+
* no prototype keys. A JSON import widens `v: 1` to `number`; this narrows it
|
|
6
|
+
* back without a cast.
|
|
7
|
+
*/
|
|
8
|
+
declare function parseLocalSnapshotManifest(value: unknown): value is LocalSnapshotManifest;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { parseLocalSnapshotManifest as t };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { T as isForbiddenKey } from "./permissions-DVoF6dMt.js";
|
|
2
|
+
//#region src/core/local-role.ts
|
|
3
|
+
/** The role name custom-role tables in a local snapshot manifest hold their grants under; no declared or tenant role can take it. */
|
|
4
|
+
const LOCAL_CUSTOM_ROLE = "\0custom";
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/core/parse-local-manifest.ts
|
|
7
|
+
function isRecord(value) {
|
|
8
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
function isStrings(value) {
|
|
11
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
12
|
+
}
|
|
13
|
+
function safeKeys(value) {
|
|
14
|
+
if (Array.isArray(value)) return value.every(safeKeys);
|
|
15
|
+
if (!isRecord(value)) return true;
|
|
16
|
+
return Object.entries(value).every(([key, item]) => !isForbiddenKey(key) && safeKeys(item));
|
|
17
|
+
}
|
|
18
|
+
function isGrants(value) {
|
|
19
|
+
return Array.isArray(value) && value.every((grant) => isRecord(grant) && typeof grant["permission"] === "string" && (grant["effect"] === "allow" || grant["effect"] === "deny") && (grant["role"] === null || typeof grant["role"] === "string") && (isRecord(grant["to"]) || Array.isArray(grant["to"])));
|
|
20
|
+
}
|
|
21
|
+
function isGrantTable(value) {
|
|
22
|
+
return isRecord(value) && Object.values(value).every(isGrants);
|
|
23
|
+
}
|
|
24
|
+
function isCustomTable(value) {
|
|
25
|
+
return isRecord(value) && isRecord(value["permissions"]) && Object.values(value["permissions"]).every((row) => isRecord(row) && isGrants(row["all"]) && (row["levels"] === void 0 || isGrantTable(row["levels"]))) && isGrantTable(value["includes"]);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether `value` has the shape `localSnapshotManifest(policy)` writes, with
|
|
29
|
+
* no prototype keys. A JSON import widens `v: 1` to `number`; this narrows it
|
|
30
|
+
* back without a cast.
|
|
31
|
+
*/
|
|
32
|
+
function parseLocalSnapshotManifest(value) {
|
|
33
|
+
return isRecord(value) && value["v"] === 1 && isStrings(value["roles"]) && (value["rank"] === void 0 || isStrings(value["rank"])) && (value["scopes"] === void 0 || Array.isArray(value["scopes"]) && value["scopes"].every(isRecord)) && (value["vocabulary"] === void 0 || isRecord(value["vocabulary"])) && isGrants(value["grants"]) && isRecord(value["custom"]) && Object.values(value["custom"]).every(isCustomTable) && safeKeys(value);
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { LOCAL_CUSTOM_ROLE as n, parseLocalSnapshotManifest as t };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { C as Policy, D as PolicyVocabulary, Nr as Principal, it as DecisionProvider, un as PermDockOptions } from "../policy-CFZAr_Al.js";
|
|
2
|
+
import { a as RelationMap, c as RemotePdpEndpoints, d as SpiceDbCheck, f as SpiceDbOptions, i as PdpPermDock, l as RemotePdpMapping, n as OpenFgaTuple, o as RemotePdpAuth, r as PdpFactory, s as RemotePdpCache, t as OpenFgaOptions, u as RemotePdpOptions } from "../types-BVyImy5I.js";
|
|
3
|
+
//#region src/pdp/create.d.ts
|
|
4
|
+
export declare function createPermDock<TUser, TPrincipal extends Principal = Principal, V extends PolicyVocabulary = PolicyVocabulary>(policy: Policy<TUser, TPrincipal, V>, user: TUser | null, options?: PermDockOptions): Promise<PdpPermDock<V>>;
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/pdp/relations.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* An OpenFGA store as a decision provider: `check` decides one row and
|
|
9
|
+
* `list-objects` lists the ids `filter` and `where` use.
|
|
10
|
+
*/
|
|
11
|
+
export declare function openfga(options: OpenFgaOptions): DecisionProvider;
|
|
12
|
+
/**
|
|
13
|
+
* A SpiceDB HTTP gateway as a decision provider: `CheckPermission` decides
|
|
14
|
+
* one row and `LookupResources` lists the ids `filter` and `where` use. A
|
|
15
|
+
* conditional permissionship (a caveat missing context) is a denial.
|
|
16
|
+
*/
|
|
17
|
+
export declare function spicedb(options: SpiceDbOptions): DecisionProvider;
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/pdp/remote.d.ts
|
|
20
|
+
export declare function remotePdp(options: RemotePdpOptions): DecisionProvider;
|
|
21
|
+
//#endregion
|
|
22
|
+
export type { OpenFgaOptions, OpenFgaTuple, PdpFactory, PdpPermDock, RelationMap, RemotePdpAuth, RemotePdpCache, RemotePdpEndpoints, RemotePdpMapping, RemotePdpOptions, SpiceDbCheck, SpiceDbOptions };
|