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,261 @@
|
|
|
1
|
+
import { t as compact } from "../compact-y6vfu2_f.js";
|
|
2
|
+
import { n as PermDockValidationError } from "../validation-error-CnjZ4t92.js";
|
|
3
|
+
import { n as PermDockDeniedError, r as PermDockRevokedError, t as PermDockApprovalRequiredError } from "../errors-Cz5zn0mW.js";
|
|
4
|
+
import { i as discoverViaSignatureAgent, r as InvalidSignatureError, s as verifyWebBotAuth } from "../evaluations-tz6D9A2G.js";
|
|
5
|
+
import { t as problemFromError } from "../map-error-pgUWNNtG.js";
|
|
6
|
+
import { a as socketConnection, r as bindKernel } from "../bind-VnYn2HKq.js";
|
|
7
|
+
import { i as onRevoked, t as POLICY_VIOLATION } from "../stream-DDpvynSB.js";
|
|
8
|
+
import { i as toRequest$1, n as isServerResponse, r as sendResponse } from "../http-BIhmLfCc.js";
|
|
9
|
+
import { Catch, Controller, Get, Inject, Injectable, Module, Post, Req, Res, createParamDecorator } from "@nestjs/common";
|
|
10
|
+
import { APP_FILTER, APP_GUARD, Reflector } from "@nestjs/core";
|
|
11
|
+
//#region src/nest/decorate.ts
|
|
12
|
+
/**
|
|
13
|
+
* Applies method decorators to `cls.prototype[key]` without decorator syntax,
|
|
14
|
+
* for projects limited to erasable TypeScript. Decorators apply in the order
|
|
15
|
+
* given; each sees the descriptor the previous one left.
|
|
16
|
+
*/
|
|
17
|
+
function decorateMethod(cls, key, ...decorators) {
|
|
18
|
+
for (const decorator of decorators) {
|
|
19
|
+
const descriptor = Object.getOwnPropertyDescriptor(cls.prototype, key);
|
|
20
|
+
if (descriptor === void 0) throw new TypeError(`decorateMethod: ${key} is not a method of the class`);
|
|
21
|
+
const next = decorator(cls.prototype, key, descriptor);
|
|
22
|
+
if (next !== void 0) Object.defineProperty(cls.prototype, key, next);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/nest/http.ts
|
|
27
|
+
function isReadable(value) {
|
|
28
|
+
return typeof value === "object" && value !== null && typeof value.read === "function";
|
|
29
|
+
}
|
|
30
|
+
function isFastifyReply(value) {
|
|
31
|
+
if (typeof value !== "object" || value === null) return false;
|
|
32
|
+
const reply = value;
|
|
33
|
+
return typeof reply["code"] === "function" && typeof reply["header"] === "function" && typeof reply["send"] === "function";
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* `@nestjs/platform-express` hands the guard an `IncomingMessage`;
|
|
37
|
+
* `@nestjs/platform-fastify` hands it a `FastifyRequest` whose stream is `raw`.
|
|
38
|
+
*/
|
|
39
|
+
function toRequest(req) {
|
|
40
|
+
if (isReadable(req)) return toRequest$1(req);
|
|
41
|
+
const raw = req.raw;
|
|
42
|
+
return toRequest$1(req, isReadable(raw) ? raw : null);
|
|
43
|
+
}
|
|
44
|
+
async function sendNestResponse(res, response) {
|
|
45
|
+
if (isServerResponse(res)) {
|
|
46
|
+
await sendResponse(res, response);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (isFastifyReply(res)) {
|
|
50
|
+
res.code(response.status);
|
|
51
|
+
for (const [key, value] of response.headers.entries()) res.header(key, value);
|
|
52
|
+
await res.send(await response.text());
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
throw new TypeError("permdock/nest supports @nestjs/platform-express and @nestjs/platform-fastify responses");
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/nest/create.ts
|
|
59
|
+
const PROTECT_KEY = "permdock:protect";
|
|
60
|
+
var PermDockHttpError = class extends Error {
|
|
61
|
+
name = "PermDockHttpError";
|
|
62
|
+
response;
|
|
63
|
+
constructor(response) {
|
|
64
|
+
super("permdock denied");
|
|
65
|
+
this.response = response;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
function reflectMeta() {
|
|
69
|
+
const ref = Reflect;
|
|
70
|
+
if (typeof ref.getMetadata !== "function" || typeof ref.defineMetadata !== "function") throw new TypeError("reflect-metadata is required for permdock/nest");
|
|
71
|
+
return ref;
|
|
72
|
+
}
|
|
73
|
+
function applyParameter(cls, key, index, decorator) {
|
|
74
|
+
decorator(cls.prototype, key, index);
|
|
75
|
+
}
|
|
76
|
+
function hasEmit(value) {
|
|
77
|
+
return typeof value === "object" && value !== null && typeof value.emit === "function";
|
|
78
|
+
}
|
|
79
|
+
/** One call per loader for a request, so class and method rules naming the same loader share its row. */
|
|
80
|
+
function loadsFor(req) {
|
|
81
|
+
const loaded = /* @__PURE__ */ new Map();
|
|
82
|
+
return (loader) => {
|
|
83
|
+
if (loader === void 0) return;
|
|
84
|
+
return () => {
|
|
85
|
+
if (req === void 0) return Promise.resolve(void 0);
|
|
86
|
+
let hit = loaded.get(loader);
|
|
87
|
+
if (hit === void 0) {
|
|
88
|
+
hit = Promise.resolve(loader(req));
|
|
89
|
+
loaded.set(loader, hit);
|
|
90
|
+
}
|
|
91
|
+
return hit;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function rulesOf(target) {
|
|
96
|
+
const found = reflectMeta().getMetadata(PROTECT_KEY, target);
|
|
97
|
+
if (!Array.isArray(found)) return [];
|
|
98
|
+
return found;
|
|
99
|
+
}
|
|
100
|
+
const Protect = (permission, loadData, protectOptions) => {
|
|
101
|
+
const rule = compact({
|
|
102
|
+
permission,
|
|
103
|
+
loadData,
|
|
104
|
+
options: protectOptions
|
|
105
|
+
});
|
|
106
|
+
return ((target, _propertyKey, descriptor) => {
|
|
107
|
+
const store = descriptor === void 0 ? target : descriptor.value;
|
|
108
|
+
if (typeof store !== "function" && (typeof store !== "object" || store === null)) throw new TypeError("Protect requires a class or method");
|
|
109
|
+
const existing = rulesOf(store);
|
|
110
|
+
reflectMeta().defineMetadata(PROTECT_KEY, [...existing, rule], store);
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
function createPermDock(policy, options) {
|
|
114
|
+
const { kernel, bind, rebind, scopeOf, handlerScope } = bindKernel(policy, options, "nest", toRequest);
|
|
115
|
+
const applyProtect = async (remaining, req, request, scope, load) => {
|
|
116
|
+
const [rule, ...rest] = remaining;
|
|
117
|
+
if (rule === void 0) return;
|
|
118
|
+
const guard = await kernel.protect(rule.permission, load(rule.loadData), rule.options)(request, scope);
|
|
119
|
+
if (!guard.ok) throw new PermDockHttpError(guard.response);
|
|
120
|
+
req.permdock = guard.permdock;
|
|
121
|
+
req.permdockData = guard.data;
|
|
122
|
+
await applyProtect(rest, req, request, scope, load);
|
|
123
|
+
};
|
|
124
|
+
const sockets = /* @__PURE__ */ new WeakMap();
|
|
125
|
+
const connection = (client, req, connectionOptions) => socketConnection(sockets, client, async () => {
|
|
126
|
+
const conn = await kernel.connection(bind(req), connectionOptions, await scopeOf(req));
|
|
127
|
+
onRevoked(conn, (problem) => {
|
|
128
|
+
client.emit?.("permdock:error", problem);
|
|
129
|
+
if (typeof client.disconnect === "function") client.disconnect(true);
|
|
130
|
+
else client.close?.(POLICY_VIOLATION, problem.type);
|
|
131
|
+
});
|
|
132
|
+
return conn;
|
|
133
|
+
});
|
|
134
|
+
/** Decides each rule for a gateway message against the client's connection, as `protect` does for HTTP. */
|
|
135
|
+
const checkMessage = async (rules, conn, req) => {
|
|
136
|
+
const request = req === void 0 ? void 0 : bind(req);
|
|
137
|
+
const load = loadsFor(req);
|
|
138
|
+
for (const rule of rules) {
|
|
139
|
+
if (conn.signal.aborted) throw conn.signal.reason instanceof PermDockRevokedError ? conn.signal.reason : new PermDockRevokedError({ code: "denied" });
|
|
140
|
+
const guard = await kernel.protectOn(conn.permdock, rule.permission, load(rule.loadData), rule.options, request);
|
|
141
|
+
if (!guard.ok) throw new PermDockHttpError(guard.response);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
class PermDockGuard {
|
|
145
|
+
reflector;
|
|
146
|
+
constructor(reflector) {
|
|
147
|
+
this.reflector = reflector;
|
|
148
|
+
}
|
|
149
|
+
async canActivate(context) {
|
|
150
|
+
const rules = this.rulesFor(context);
|
|
151
|
+
if (context.getType() === "ws" && rules.length > 0) {
|
|
152
|
+
const opened = sockets.get(context.switchToWs().getClient());
|
|
153
|
+
if (opened !== void 0) {
|
|
154
|
+
await checkMessage(rules, await opened, options.request?.(context));
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const req = context.getType() === "http" ? context.switchToHttp().getRequest() : rules.length === 0 ? void 0 : options.request?.(context);
|
|
159
|
+
if (req === void 0) return rules.length === 0;
|
|
160
|
+
const request = bind(req);
|
|
161
|
+
const scope = await scopeOf(req);
|
|
162
|
+
req.permdock = await kernel.permdock(request, scope);
|
|
163
|
+
await applyProtect(rules, req, request, scope, loadsFor(req));
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
rulesFor(context) {
|
|
167
|
+
const fromClass = this.reflector.get(PROTECT_KEY, context.getClass());
|
|
168
|
+
const fromHandler = this.reflector.get(PROTECT_KEY, context.getHandler());
|
|
169
|
+
return [...Array.isArray(fromClass) ? fromClass : rulesOf(context.getClass()), ...Array.isArray(fromHandler) ? fromHandler : rulesOf(context.getHandler())];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
Inject(Reflector)(PermDockGuard, void 0, 0);
|
|
173
|
+
Injectable()(PermDockGuard);
|
|
174
|
+
class PermDockExceptionFilter {
|
|
175
|
+
send = sendNestResponse;
|
|
176
|
+
async catch(exception, host) {
|
|
177
|
+
const problem = exception instanceof PermDockHttpError ? exception.response : problemFromError(exception, { credentials: host.getType() === "http" && host.switchToHttp().getRequest().headers.authorization !== void 0 });
|
|
178
|
+
if (problem === void 0) throw new TypeError("unhandled permdock exception");
|
|
179
|
+
if (host.getType() === "http") {
|
|
180
|
+
await this.send(host.switchToHttp().getResponse(), problem);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const client = host.getType() === "ws" ? host.switchToWs().getClient() : null;
|
|
184
|
+
if (!hasEmit(client)) throw exception;
|
|
185
|
+
const body = await problem.json();
|
|
186
|
+
client.emit("exception", {
|
|
187
|
+
status: "error",
|
|
188
|
+
message: typeof body.title === "string" ? body.title : "Forbidden",
|
|
189
|
+
problem: body
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
Catch(PermDockHttpError, InvalidSignatureError, PermDockDeniedError, PermDockApprovalRequiredError, PermDockRevokedError, PermDockValidationError)(PermDockExceptionFilter);
|
|
194
|
+
Injectable()(PermDockExceptionFilter);
|
|
195
|
+
class PermDockRoot {
|
|
196
|
+
static forRoot(moduleOptions = {}) {
|
|
197
|
+
return {
|
|
198
|
+
module: PermDockRoot,
|
|
199
|
+
providers: moduleOptions.guard === "global" ? [{
|
|
200
|
+
provide: APP_GUARD,
|
|
201
|
+
useExisting: PermDockGuard
|
|
202
|
+
}] : []
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
Module({
|
|
207
|
+
providers: [
|
|
208
|
+
{
|
|
209
|
+
provide: PermDockGuard,
|
|
210
|
+
useFactory: (reflector) => new PermDockGuard(reflector),
|
|
211
|
+
inject: [Reflector]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
provide: PermDockExceptionFilter,
|
|
215
|
+
useFactory: () => new PermDockExceptionFilter()
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
provide: APP_FILTER,
|
|
219
|
+
useExisting: PermDockExceptionFilter
|
|
220
|
+
}
|
|
221
|
+
],
|
|
222
|
+
exports: [PermDockGuard, PermDockExceptionFilter]
|
|
223
|
+
})(PermDockRoot);
|
|
224
|
+
const injectPermDock = createParamDecorator((_data, ctx) => {
|
|
225
|
+
if (ctx.getType() !== "http") return;
|
|
226
|
+
return ctx.switchToHttp().getRequest().permdock;
|
|
227
|
+
});
|
|
228
|
+
const InjectPermDock = () => injectPermDock();
|
|
229
|
+
const permdockHandler = (handlerOptions = {}) => {
|
|
230
|
+
const { POST, GET } = kernel.permdockHandler(handlerScope);
|
|
231
|
+
class EvaluationsController {
|
|
232
|
+
send = sendNestResponse;
|
|
233
|
+
async post(req, res) {
|
|
234
|
+
await this.send(res, await POST(rebind(req)));
|
|
235
|
+
}
|
|
236
|
+
async get(req, res) {
|
|
237
|
+
await this.send(res, await GET(bind(req)));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
Controller(handlerOptions.path ?? "api/permdock")(EvaluationsController);
|
|
241
|
+
decorateMethod(EvaluationsController, "post", Post());
|
|
242
|
+
decorateMethod(EvaluationsController, "get", Get());
|
|
243
|
+
applyParameter(EvaluationsController, "post", 0, Req());
|
|
244
|
+
applyParameter(EvaluationsController, "post", 1, Res({ passthrough: false }));
|
|
245
|
+
applyParameter(EvaluationsController, "get", 0, Req());
|
|
246
|
+
applyParameter(EvaluationsController, "get", 1, Res({ passthrough: false }));
|
|
247
|
+
return EvaluationsController;
|
|
248
|
+
};
|
|
249
|
+
return {
|
|
250
|
+
PermDockModule: PermDockRoot,
|
|
251
|
+
PermDockGuard,
|
|
252
|
+
Protect,
|
|
253
|
+
InjectPermDock,
|
|
254
|
+
PermDockExceptionFilter,
|
|
255
|
+
permdockHandler,
|
|
256
|
+
connection,
|
|
257
|
+
openapi: kernel.openapi
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
//#endregion
|
|
261
|
+
export { InvalidSignatureError, createPermDock, decorateMethod, discoverViaSignatureAgent, sendResponse, toRequest, verifyWebBotAuth };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { t as PermissionBoundaryState } from "../boundary-BmHxVH1J.js";
|
|
2
|
+
import { ComponentType, ReactNode } from "react";
|
|
3
|
+
//#region src/next/client.d.ts
|
|
4
|
+
/** A fallback node, or a function of what was refused. */
|
|
5
|
+
export type PermissionBoundaryFallback = ReactNode | ((state: PermissionBoundaryState) => ReactNode);
|
|
6
|
+
export type PermissionBoundaryProps = {
|
|
7
|
+
/** Rendered in place of the children when one throws `PermDockDeniedError`. */
|
|
8
|
+
readonly denied?: PermissionBoundaryFallback;
|
|
9
|
+
/** Rendered when a child throws `PermDockApprovalRequiredError`; defaults to `denied`. */
|
|
10
|
+
readonly approval?: PermissionBoundaryFallback;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* A component-level boundary for PermDock errors thrown below it, in a Server
|
|
14
|
+
* Component or a Client Component. Other errors, `forbidden()`, `notFound()`
|
|
15
|
+
* and `redirect()` pass through.
|
|
16
|
+
*/
|
|
17
|
+
export declare const PermissionBoundary: ComponentType<PermissionBoundaryProps & {
|
|
18
|
+
readonly children?: ReactNode;
|
|
19
|
+
}>;
|
|
20
|
+
/** Inside a `PermissionBoundary` fallback: what was refused, and `retry()`. */
|
|
21
|
+
export declare function usePermissionBoundary(): PermissionBoundaryState | null;
|
|
22
|
+
//#endregion
|
|
23
|
+
export type { PermissionBoundaryState };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { n as boundaryFallback, t as boundaryDigest } from "../boundary-BM8a_P6E.js";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import * as nextError from "next/error.js";
|
|
6
|
+
//#region src/next/client.tsx
|
|
7
|
+
const catchError = nextError.catchError ?? nextError.default.catchError;
|
|
8
|
+
const BoundaryContext = createContext(null);
|
|
9
|
+
function PermissionFallback(props, info) {
|
|
10
|
+
const parsed = boundaryDigest(info.error);
|
|
11
|
+
if (parsed === null) throw info.error;
|
|
12
|
+
const fallback = boundaryFallback(parsed, props);
|
|
13
|
+
const state = {
|
|
14
|
+
...parsed,
|
|
15
|
+
retry: info.retry
|
|
16
|
+
};
|
|
17
|
+
return /* @__PURE__ */ jsx(BoundaryContext.Provider, {
|
|
18
|
+
value: state,
|
|
19
|
+
children: typeof fallback === "function" ? fallback(state) : fallback ?? null
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A component-level boundary for PermDock errors thrown below it, in a Server
|
|
24
|
+
* Component or a Client Component. Other errors, `forbidden()`, `notFound()`
|
|
25
|
+
* and `redirect()` pass through.
|
|
26
|
+
*/
|
|
27
|
+
const PermissionBoundary = catchError(PermissionFallback);
|
|
28
|
+
/** Inside a `PermissionBoundary` fallback: what was refused, and `retry()`. */
|
|
29
|
+
function usePermissionBoundary() {
|
|
30
|
+
return useContext(BoundaryContext);
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { PermissionBoundary, usePermissionBoundary };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { C as Policy, D as PolicyVocabulary, Nr as Principal, Tt as Snapshot, Yn as Decision, ln as PermDock } from "../policy-CFZAr_Al.js";
|
|
2
|
+
import { f as Permission } from "../permissions-DttnqqxC.js";
|
|
3
|
+
import { f as ApprovalStore } from "../types-vKyAMtcX.js";
|
|
4
|
+
import { t as InstanceOptions } from "../instance-options-BK_rNOSC.js";
|
|
5
|
+
import { o as OtelWrap } from "../types-vNSDF7Dq.js";
|
|
6
|
+
import { a as snapshotHeaders, i as cacheLifeFor, n as SnapshotHeaders, o as snapshotTag, r as SnapshotHeadersOptions, t as CacheLifeForOptions } from "../snapshot-cache-DwQH8ufx.js";
|
|
7
|
+
import { ReactElement, ReactNode } from "react";
|
|
8
|
+
//#region src/next/types.d.ts
|
|
9
|
+
type NextSubjectInput = unknown;
|
|
10
|
+
type NextPermDockOptions<TUser = NextSubjectInput> = InstanceOptions & {
|
|
11
|
+
readonly subject: () => TUser | Promise<TUser>;
|
|
12
|
+
readonly tenant?: string | (() => string | undefined | Promise<string | undefined>);
|
|
13
|
+
readonly onDenied?: (decision: Decision) => never | void;
|
|
14
|
+
readonly store?: ApprovalStore;
|
|
15
|
+
/** `(permdock) => withOtel(permdock, options)` from `permdock/otel`. */
|
|
16
|
+
readonly otel?: OtelWrap;
|
|
17
|
+
/**
|
|
18
|
+
* Where `PermDockProvider` sends checks the snapshot cannot answer; default `/api/permdock`.
|
|
19
|
+
* `false` is snapshot-only: no `permdockHandler` route, and those checks are denied with
|
|
20
|
+
* reason `server-only`.
|
|
21
|
+
*/
|
|
22
|
+
readonly endpoint?: string | false;
|
|
23
|
+
};
|
|
24
|
+
type GetPermDockQuery = {
|
|
25
|
+
readonly tenant?: string;
|
|
26
|
+
};
|
|
27
|
+
type GetSnapshotQuery = GetPermDockQuery & {
|
|
28
|
+
readonly include?: readonly (Permission | {
|
|
29
|
+
readonly [key: string]: unknown;
|
|
30
|
+
})[];
|
|
31
|
+
readonly tenants?: "all";
|
|
32
|
+
/** Tags added next to `snapshotTag(sub)`, such as the app's own organisation tag. */
|
|
33
|
+
readonly tags?: readonly string[];
|
|
34
|
+
};
|
|
35
|
+
type RequireAccessInput = {
|
|
36
|
+
readonly permission: Permission;
|
|
37
|
+
/** The row for an instance permission; omit it for a collection permission. */
|
|
38
|
+
readonly data?: unknown;
|
|
39
|
+
/** The active tenant, as for `getPermDock({ tenant })`; defaults to the factory's `tenant`. */
|
|
40
|
+
readonly tenant?: string;
|
|
41
|
+
};
|
|
42
|
+
type ServerPermissionState = {
|
|
43
|
+
readonly allowed: boolean;
|
|
44
|
+
readonly status: "ready";
|
|
45
|
+
readonly decision: Decision;
|
|
46
|
+
};
|
|
47
|
+
type ServerPermDockProviderProps = {
|
|
48
|
+
readonly children: ReactNode;
|
|
49
|
+
readonly tenant?: string;
|
|
50
|
+
readonly include?: readonly (Permission | {
|
|
51
|
+
readonly [key: string]: unknown;
|
|
52
|
+
})[];
|
|
53
|
+
readonly tenants?: "all";
|
|
54
|
+
/** Overrides the factory's `endpoint`; `false` is snapshot-only. */
|
|
55
|
+
readonly endpoint?: string | false;
|
|
56
|
+
/** Suspends permission readers until the snapshot streams in, instead of answering `pending`. */
|
|
57
|
+
readonly suspend?: boolean;
|
|
58
|
+
};
|
|
59
|
+
type PermDockHandler = {
|
|
60
|
+
readonly POST: (request: Request) => Promise<Response>;
|
|
61
|
+
readonly GET: (request: Request) => Promise<Response>;
|
|
62
|
+
};
|
|
63
|
+
type NextPermDock<V extends PolicyVocabulary = PolicyVocabulary> = {
|
|
64
|
+
readonly getPermDock: (query?: GetPermDockQuery) => Promise<PermDock<V>>;
|
|
65
|
+
/**
|
|
66
|
+
* `{ allowed, status: 'ready', decision }`. Any failure to build the
|
|
67
|
+
* instance denies; Next.js interrupts (`redirect()`, `notFound()`,
|
|
68
|
+
* request-time bailouts) from `subject` or `tenant` pass through.
|
|
69
|
+
*/
|
|
70
|
+
readonly getPermission: (permission: Permission, data?: unknown, query?: GetPermDockQuery) => Promise<ServerPermissionState>;
|
|
71
|
+
/**
|
|
72
|
+
* The session's snapshot for a `'use cache: private'` function the app owns:
|
|
73
|
+
* calls `cacheLife(cacheLifeFor(snapshot))` and `cacheTag(snapshotTag(sub), ...tags)`
|
|
74
|
+
* in that scope, and throws outside one.
|
|
75
|
+
*/
|
|
76
|
+
readonly getSnapshot: (query?: GetSnapshotQuery) => Promise<Snapshot>;
|
|
77
|
+
/**
|
|
78
|
+
* Resolves to the granted `Decision`. A denial calls `unauthorized()` for an
|
|
79
|
+
* anonymous subject and `forbidden()` otherwise (`experimental.authInterrupts`);
|
|
80
|
+
* approval-required and boundary validation throw as from `assert`.
|
|
81
|
+
*/
|
|
82
|
+
readonly requireAccess: (input: RequireAccessInput) => Promise<Extract<Decision, {
|
|
83
|
+
readonly outcome: "granted";
|
|
84
|
+
}>>;
|
|
85
|
+
/** Never awaits: passes an unawaited snapshot to the client provider, whose hooks suspend. */
|
|
86
|
+
readonly PermDockProvider: (props: ServerPermDockProviderProps) => ReactElement;
|
|
87
|
+
readonly permdockHandler: () => PermDockHandler;
|
|
88
|
+
};
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region src/next/create.d.ts
|
|
91
|
+
export declare function createPermDock<TUser = NextSubjectInput, TPrincipal extends Principal = Principal, V extends PolicyVocabulary = PolicyVocabulary>(policy: Policy<TUser, TPrincipal, V>, options: NextPermDockOptions<TUser>): NextPermDock<V>;
|
|
92
|
+
//#endregion
|
|
93
|
+
export { type CacheLifeForOptions, type GetPermDockQuery, type GetSnapshotQuery, type NextPermDock, type NextPermDockOptions, type PermDockHandler, type RequireAccessInput, type ServerPermDockProviderProps, type ServerPermissionState, type SnapshotHeaders, type SnapshotHeadersOptions, cacheLifeFor, snapshotHeaders, snapshotTag };
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { t as compact } from "../compact-y6vfu2_f.js";
|
|
2
|
+
import { t as createPermDock$1 } from "../permdock-CzqXjCpU.js";
|
|
3
|
+
import { n as snapshotHeaders, r as snapshotTag, t as cacheLifeFor } from "../snapshot-cache-D6jLelln.js";
|
|
4
|
+
import { c as NO_GRANT, n as createEvaluationsHandler } from "../evaluations-tz6D9A2G.js";
|
|
5
|
+
import { t as instanceOptions } from "../instance-options-Dhhcnm3y.js";
|
|
6
|
+
import { cache } from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
import { forbidden, unauthorized, unstable_rethrow } from "#next/navigation";
|
|
9
|
+
import { cacheLife, cacheTag, io } from "next/cache.js";
|
|
10
|
+
import { after } from "next/server.js";
|
|
11
|
+
import { PermDockProvider } from "../react/provider-client.js";
|
|
12
|
+
//#region src/next/provider.tsx
|
|
13
|
+
function renderClientProvider(options) {
|
|
14
|
+
return /* @__PURE__ */ jsx(PermDockProvider, {
|
|
15
|
+
...compact({
|
|
16
|
+
snapshotPromise: options.snapshotPromise,
|
|
17
|
+
endpoint: options.endpoint,
|
|
18
|
+
tenant: options.tenant,
|
|
19
|
+
suspend: options.suspend
|
|
20
|
+
}),
|
|
21
|
+
children: options.children
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/next/create.ts
|
|
26
|
+
function assertServerOnly() {
|
|
27
|
+
if (globalThis.document !== void 0) throw new TypeError("permdock/next is server-only. Import hooks and Protected from permdock/react.");
|
|
28
|
+
}
|
|
29
|
+
async function readTenant(tenant) {
|
|
30
|
+
if (tenant === void 0 || typeof tenant === "string") return tenant;
|
|
31
|
+
try {
|
|
32
|
+
return await tenant();
|
|
33
|
+
} catch (error) {
|
|
34
|
+
unstable_rethrow(error);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** False outside a request or prerender scope, where `after()` throws. */
|
|
39
|
+
function defer(task) {
|
|
40
|
+
try {
|
|
41
|
+
after(task);
|
|
42
|
+
return true;
|
|
43
|
+
} catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function ignore() {}
|
|
48
|
+
/**
|
|
49
|
+
* Keeps the function alive until the sink has written and flushed: every
|
|
50
|
+
* pending write and one `flush()` per render run in `after()`, so serverless
|
|
51
|
+
* runtimes do not freeze with events still buffered.
|
|
52
|
+
*/
|
|
53
|
+
function afterResponse(sink) {
|
|
54
|
+
const flush = sink.flush?.bind(sink);
|
|
55
|
+
const scheduleFlush = cache(() => flush === void 0 ? false : defer(flush));
|
|
56
|
+
return {
|
|
57
|
+
write(events) {
|
|
58
|
+
const written = sink.write(events);
|
|
59
|
+
if (written !== void 0) defer(Promise.resolve(written).then(ignore, ignore));
|
|
60
|
+
scheduleFlush();
|
|
61
|
+
return written;
|
|
62
|
+
},
|
|
63
|
+
...flush === void 0 ? {} : { flush }
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function wrapInstance(permdock, onDenied) {
|
|
67
|
+
if (onDenied === void 0) return permdock;
|
|
68
|
+
const wrap = (next) => wrapInstance(next, onDenied);
|
|
69
|
+
const assert = ((permission, data, options) => permdock.assert(permission, data, compact({
|
|
70
|
+
...options,
|
|
71
|
+
onDenied: options?.onDenied ?? onDenied
|
|
72
|
+
})));
|
|
73
|
+
return Object.freeze({
|
|
74
|
+
...permdock,
|
|
75
|
+
assert,
|
|
76
|
+
tenant: (id) => wrap(permdock.tenant(id)),
|
|
77
|
+
team: (id) => wrap(permdock.team(id)),
|
|
78
|
+
derive: (options) => {
|
|
79
|
+
const derived = permdock.derive(options);
|
|
80
|
+
return derived instanceof Promise ? derived.then(wrap) : wrap(derived);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function createPermDock(policy, options) {
|
|
85
|
+
assertServerOnly();
|
|
86
|
+
const sink = options.sink === void 0 ? void 0 : afterResponse(options.sink);
|
|
87
|
+
const resolveSubject = cache(async () => {
|
|
88
|
+
try {
|
|
89
|
+
return await options.subject();
|
|
90
|
+
} catch (error) {
|
|
91
|
+
unstable_rethrow(error);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const resolveFallbackTenant = cache(() => readTenant(options.tenant));
|
|
96
|
+
const instantiate = cache(async (tenantKey) => {
|
|
97
|
+
const tenant = tenantKey === "" ? void 0 : tenantKey;
|
|
98
|
+
const user = await resolveSubject();
|
|
99
|
+
await io();
|
|
100
|
+
const built = await createPermDock$1(policy, user, compact({
|
|
101
|
+
tenant,
|
|
102
|
+
...instanceOptions(options),
|
|
103
|
+
sink
|
|
104
|
+
}));
|
|
105
|
+
return wrapInstance(options.otel === void 0 ? built : options.otel(built), options.onDenied);
|
|
106
|
+
});
|
|
107
|
+
const getPermDock = async (query) => {
|
|
108
|
+
const tenant = query?.tenant ?? await resolveFallbackTenant();
|
|
109
|
+
return instantiate(tenant ?? "");
|
|
110
|
+
};
|
|
111
|
+
const getPermission = async (permission, data, query) => {
|
|
112
|
+
try {
|
|
113
|
+
const decision = (await getPermDock(query)).decide(permission, data);
|
|
114
|
+
return {
|
|
115
|
+
allowed: decision.outcome === "granted",
|
|
116
|
+
status: "ready",
|
|
117
|
+
decision
|
|
118
|
+
};
|
|
119
|
+
} catch (error) {
|
|
120
|
+
unstable_rethrow(error);
|
|
121
|
+
return {
|
|
122
|
+
allowed: false,
|
|
123
|
+
status: "ready",
|
|
124
|
+
decision: NO_GRANT
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const getSnapshot = async (query = {}) => {
|
|
129
|
+
const permdock = await getPermDock(compact({ tenant: query.tenant }));
|
|
130
|
+
const snapshot = permdock.snapshot(compact({
|
|
131
|
+
include: query.include,
|
|
132
|
+
tenants: query.tenants
|
|
133
|
+
}));
|
|
134
|
+
try {
|
|
135
|
+
cacheLife(cacheLifeFor(snapshot));
|
|
136
|
+
cacheTag(snapshotTag(permdock.subject.principal?.id), ...query.tags ?? []);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
unstable_rethrow(error);
|
|
139
|
+
throw new Error("PermDock: getSnapshot() sets cacheLife() and cacheTag(), so call it inside a 'use cache: private' function with cacheComponents enabled.", { cause: error });
|
|
140
|
+
}
|
|
141
|
+
return snapshot;
|
|
142
|
+
};
|
|
143
|
+
const requireAccess = async (input) => {
|
|
144
|
+
const permdock = await getPermDock(input.tenant === void 0 ? void 0 : { tenant: input.tenant });
|
|
145
|
+
const assert = permdock.assert;
|
|
146
|
+
return assert(input.permission, input.data, { onDenied: (decision) => {
|
|
147
|
+
if (decision.outcome !== "denied" || decision.denials.some((denial) => denial.reason === "validation")) return;
|
|
148
|
+
if (permdock.subject.principal === null) unauthorized();
|
|
149
|
+
forbidden();
|
|
150
|
+
} });
|
|
151
|
+
};
|
|
152
|
+
const PermDockProvider = (props) => {
|
|
153
|
+
const snapshotPromise = getPermDock(props.tenant === void 0 ? void 0 : { tenant: props.tenant }).then((permdock) => permdock.snapshot(compact({
|
|
154
|
+
include: props.include,
|
|
155
|
+
tenants: props.tenants
|
|
156
|
+
})));
|
|
157
|
+
return renderClientProvider(compact({
|
|
158
|
+
snapshotPromise,
|
|
159
|
+
endpoint: props.endpoint ?? options.endpoint ?? "/api/permdock",
|
|
160
|
+
tenant: props.tenant,
|
|
161
|
+
suspend: props.suspend,
|
|
162
|
+
children: props.children
|
|
163
|
+
}));
|
|
164
|
+
};
|
|
165
|
+
const permdockHandler = () => createEvaluationsHandler(compact({
|
|
166
|
+
policy,
|
|
167
|
+
getPermDock,
|
|
168
|
+
store: options.store
|
|
169
|
+
}));
|
|
170
|
+
return {
|
|
171
|
+
getPermDock,
|
|
172
|
+
getPermission,
|
|
173
|
+
getSnapshot,
|
|
174
|
+
requireAccess,
|
|
175
|
+
PermDockProvider,
|
|
176
|
+
permdockHandler
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
180
|
+
export { cacheLifeFor, createPermDock, snapshotHeaders, snapshotTag };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { a as PermDockPluginOptions } from "../types-BPxgszlT.js";
|
|
2
|
+
//#region src/cli/plugin.d.ts
|
|
3
|
+
/** Any object: Next's `NextConfig` is an interface, so no index signature. */
|
|
4
|
+
type NextConfigLike = object;
|
|
5
|
+
/** What `next.config` may export: an object, or a function of the phase. */
|
|
6
|
+
type NextConfigInput<T extends NextConfigLike> = T | ((phase: string, context: NextConfigContext) => T | Promise<T>);
|
|
7
|
+
type NextConfigContext = {
|
|
8
|
+
readonly defaultConfig?: unknown;
|
|
9
|
+
};
|
|
10
|
+
/** Next's config function: Next calls it with the phase constant. */
|
|
11
|
+
type NextConfigFunction<T extends NextConfigLike> = (phase: string, context: NextConfigContext) => Promise<T>;
|
|
12
|
+
export declare function createPermDockPlugin(options?: PermDockPluginOptions): <T extends NextConfigLike>(nextConfig: NextConfigInput<T>) => NextConfigFunction<T>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export type { NextConfigContext, NextConfigFunction, NextConfigInput, NextConfigLike, PermDockPluginOptions };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { i as describeError } from "../errors-CWfoNg9N.js";
|
|
2
|
+
import { n as createCollectScheduler, r as report, t as collectOnce } from "../watch-UihESpsJ.js";
|
|
3
|
+
//#region src/cli/plugin.ts
|
|
4
|
+
const PHASE_BUILD = "phase-production-build";
|
|
5
|
+
const PHASE_DEV = "phase-development-server";
|
|
6
|
+
function createPermDockPlugin(options) {
|
|
7
|
+
const schedulers = /* @__PURE__ */ new Map();
|
|
8
|
+
return function permdockPlugin(nextConfig) {
|
|
9
|
+
return async (phase, context) => {
|
|
10
|
+
const resolved = typeof nextConfig === "function" ? await nextConfig(phase, context) : nextConfig;
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
if (phase === PHASE_BUILD) {
|
|
13
|
+
const check = process.env["PERMDOCK_COLLECT"] !== "write";
|
|
14
|
+
report(await runPluginCollect(cwd, options, check));
|
|
15
|
+
} else if (phase === PHASE_DEV) {
|
|
16
|
+
const scheduler = schedulers.get(cwd) ?? createCollectScheduler(cwd, options);
|
|
17
|
+
schedulers.set(cwd, scheduler);
|
|
18
|
+
try {
|
|
19
|
+
report(await scheduler.run(false));
|
|
20
|
+
} catch (error) {
|
|
21
|
+
report(describeError(error));
|
|
22
|
+
}
|
|
23
|
+
scheduler.watch();
|
|
24
|
+
}
|
|
25
|
+
return resolved;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async function runPluginCollect(cwd, options, check) {
|
|
30
|
+
return (await collectOnce(cwd, options, check, false)).message;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { createPermDockPlugin };
|
|
@@ -0,0 +1,24 @@
|
|
|
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 { a as ScopeGuard, h as InvalidSignatureError, i as ProtectOptions, n as OpenApiHooks, t as Guard, w as verifyWebBotAuth, x as discoverViaSignatureAgent } from "../create-BWyx3jua.js";
|
|
4
|
+
import { t as ServerAdapterOptions } from "../bind-CVy3Espv.js";
|
|
5
|
+
import { a as toRequest, i as sendResponse, n as fromResponse, r as isServerResponse, t as NodeRequest } from "../http-DPuDaChb.js";
|
|
6
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
7
|
+
//#region src/node/create.d.ts
|
|
8
|
+
type NodePermDockOptions<TUser = unknown> = ServerAdapterOptions<NodeRequest, TUser>;
|
|
9
|
+
type NodeProtect = {
|
|
10
|
+
(permission: Permission, loadData?: (req: NodeRequest) => unknown, protectOptions?: ProtectOptions): (req: IncomingMessage) => Promise<Guard>;
|
|
11
|
+
(permission: null, loadData?: (req: NodeRequest) => unknown, protectOptions?: ProtectOptions): (req: IncomingMessage) => Promise<ScopeGuard>;
|
|
12
|
+
};
|
|
13
|
+
type NodePermDock<V extends PolicyVocabulary = PolicyVocabulary> = {
|
|
14
|
+
readonly permdock: (req: IncomingMessage) => Promise<PermDock<V>>;
|
|
15
|
+
readonly protect: NodeProtect;
|
|
16
|
+
readonly send: typeof sendResponse;
|
|
17
|
+
readonly permdockHandler: () => (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
18
|
+
readonly toRequest: typeof toRequest;
|
|
19
|
+
readonly fromResponse: typeof fromResponse;
|
|
20
|
+
readonly openapi: OpenApiHooks;
|
|
21
|
+
};
|
|
22
|
+
export declare function createPermDock<TUser, TPrincipal extends Principal = Principal, V extends PolicyVocabulary = PolicyVocabulary>(policy: Policy<TUser, TPrincipal, V>, options: NodePermDockOptions<TUser>): NodePermDock<V>;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { InvalidSignatureError, type NodePermDock, type NodePermDockOptions, type NodeRequest, discoverViaSignatureAgent, fromResponse, isServerResponse, sendResponse, toRequest, verifyWebBotAuth };
|