permdock 0.1.0 → 0.3.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 +106 -47
- package/dist/a2a/index.d.ts +7 -16
- package/dist/a2a/index.js +59 -98
- package/dist/adapter-context-mlWsVGGg.js +23 -0
- package/dist/ai-sdk/index.d.ts +37 -16
- package/dist/ai-sdk/index.js +30 -13
- package/dist/approvals/index.d.ts +3 -3
- package/dist/approvals/index.js +5 -4
- package/dist/{approvals-DaxY-Bdg.js → approvals-DbYAuNkG.js} +17 -11
- package/dist/approvers-DT4AVyIg.js +52 -0
- package/dist/{arazzo-CTeVuXr5.js → arazzo-BAgw9ap6.js} +2 -2
- package/dist/{arazzo-aoTkqYsJ.js → arazzo-CKwwqFWz.js} +2 -2
- package/dist/authzen/index.d.ts +4 -13
- package/dist/authzen/index.js +16 -50
- package/dist/better-auth/index.d.ts +20 -3
- package/dist/better-auth/index.js +27 -7
- package/dist/better-supabase/index.d.ts +223 -0
- package/dist/better-supabase/index.js +648 -0
- package/dist/bind-C_ob3LKa.d.ts +25 -0
- package/dist/bind-CuzGytRf.js +97 -0
- package/dist/boundary-BM8a_P6E.js +13 -0
- package/dist/boundary-BmHxVH1J.d.ts +15 -0
- package/dist/canonical-json-DemiK4Vp.js +26 -0
- package/dist/{capability-BDG_nkxt.d.ts → capability-2kYTMWDv.d.ts} +2 -2
- package/dist/{capability-B68OFnZx.js → capability-4qPdO9gk.js} +7 -5
- package/dist/catalog/index.d.ts +1 -1
- package/dist/catalog/index.js +1 -1
- package/dist/catalog-CRW5Mx_B.js +2 -0
- package/dist/{catalog-H-vFGwWK.js → catalog-DWF5cYqB.js} +4 -4
- package/dist/{catalog-B0E6bggc.js → catalog-dFZdWCGN.js} +2 -2
- package/dist/{catalog-doc-BSo_Q_-6.js → catalog-doc-DdGm82XT.js} +20 -32
- package/dist/claude-agent/index.d.ts +5 -14
- package/dist/claude-agent/index.js +4 -10
- package/dist/clerk/index.d.ts +12 -3
- package/dist/clerk/index.js +26 -5
- package/dist/cli/bin.js +1 -1
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +2 -2
- package/dist/clients-C7zLFuWT.d.ts +12 -0
- package/dist/clients-DjU5ABMy.js +23 -0
- package/dist/cloud/index.d.ts +4 -5
- package/dist/cloud/index.js +20 -6
- package/dist/{cloud-BNQTrmrr.js → cloud-CB_ELYuX.js} +2 -2
- package/dist/{cloud-Cuxr6Czw.js → cloud-DWLXO2af.js} +7 -6
- package/dist/collect-DClJsheJ.js +83 -0
- package/dist/{collect-O-tOtbnk.js → collect-DSTE3ml9.js} +194 -42
- package/dist/collect-DSWOk19R.js +2 -0
- package/dist/{commands-BMh_Etm2.js → commands-DSxCqG9A.js} +16 -12
- package/dist/compile/index.d.ts +3 -0
- package/dist/compile/index.js +2 -0
- package/dist/{compile-D22iwvuV.js → compile-Ba4blROR.js} +85 -30
- package/dist/compile-BkRyBDBw.d.ts +94 -0
- package/dist/config-BJiM-xAm.js +157 -0
- package/dist/config-Dnszbv-6.js +36 -0
- package/dist/config-report-DMvWKUxL.js +44 -0
- package/dist/{connection-JvqwHODC.js → connection-CU8MQxRi.js} +1 -1
- package/dist/{context-CKEAabd7.js → context-Bcy85rGi.js} +36 -27
- package/dist/convex/index.d.ts +9 -4
- package/dist/convex/index.js +14 -4
- package/dist/create-B1d519XK.d.ts +245 -0
- package/dist/create-CMwIl-w2.js +253 -0
- package/dist/{credential-B_rkUNlY.js → credential-8P81ff4u.js} +26 -46
- package/dist/delegation-D8pUEuce.js +103 -0
- package/dist/{describe-Bt1YD5uS.js → describe-B_gVZEVi.js} +10 -15
- package/dist/{describe-DernyItf.d.ts → describe-DMYiCjJV.d.ts} +9 -10
- package/dist/{diff-x5Il8LVa.js → diff-2VaeChzX.js} +44 -11
- package/dist/{diff-BUzf5Poi.js → diff-DBIhz_f2.js} +2 -2
- package/dist/{doctor-Bqo6FwUa.js → doctor-BwCAMLx_.js} +2 -2
- package/dist/doctor-collect-CHk6XWOA.js +665 -0
- package/dist/doctor-igIiM_Hl.js +1194 -0
- package/dist/drizzle/index.d.ts +4 -3
- package/dist/drizzle/index.js +3 -3
- package/dist/elysia/index.d.ts +6 -28
- package/dist/elysia/index.js +16 -60
- package/dist/{errors-DSMnAVNa.js → errors-CWfoNg9N.js} +8 -4
- package/dist/{errors-Iy71s7Oj.js → errors-Cz5zn0mW.js} +17 -71
- package/dist/{errors-DbZ1YOnb.d.ts → errors-DPdqI50v.d.ts} +8 -21
- package/dist/{errors-m3u9TmDu.js → errors-DRnGZHzF.js} +4 -1
- package/dist/evaluation-items-CfCCejQd.js +40 -0
- package/dist/{evaluations-DsAU9ppl.js → evaluations-tz6D9A2G.js} +28 -46
- package/dist/eve/index.d.ts +6 -15
- package/dist/eve/index.js +7 -12
- package/dist/expiry-BoBJ8Tvc.js +7 -0
- package/dist/express/index.d.ts +6 -29
- package/dist/express/index.js +28 -58
- package/dist/fastify/index.d.ts +6 -29
- package/dist/fastify/index.js +16 -65
- package/dist/fields-BMl1RxoX.js +26 -0
- package/dist/{files-B_wAGYmt.js → files-DWUN9PzI.js} +5 -1
- package/dist/{fixtures-Cvaw0gDG.js → fixtures-ht28Cplr.js} +5 -2
- package/dist/{freeze-y1_jQL4v.js → freeze-CrU8nQeX.js} +31 -2
- package/dist/{from-snapshot-BMGnhmgv.js → from-snapshot-CTLijvdm.js} +66 -48
- package/dist/{grantee-Bv04_Vzf.js → grantee-Cv5Sogfv.js} +88 -7
- package/dist/graph-sql-B-dsAT6j.d.ts +29 -0
- package/dist/{headers-B5RRv3Xm.js → headers-BZSDieNT.js} +1 -1
- package/dist/{headers-C8SHQccD.d.ts → headers-Cf-zWvsO.d.ts} +1 -1
- package/dist/helpers-H_KARDVC.js +421 -0
- package/dist/hono/index.d.ts +6 -28
- package/dist/hono/index.js +11 -43
- package/dist/{hosted-BwKQ1BTA.js → hosted-DJQw46hn.js} +6 -5
- package/dist/{http-GgVApX1k.js → http-BIhmLfCc.js} +4 -20
- package/dist/http-SO7qGttf.js +44 -0
- package/dist/ids-DC4V4CFu.js +18 -0
- package/dist/index-0nNqHspG.d.ts +6 -0
- package/dist/{index-xIxJLwOQ.d.ts → index-BNc7Wer_.d.ts} +75 -7
- package/dist/{index-CltcQ4Bf.d.ts → index-C7Tw7MaW.d.ts} +68 -5
- package/dist/{index-LF_hS-yn.d.ts → index-C8z4RjQV.d.ts} +1 -1
- package/dist/index.d.ts +14 -9
- package/dist/index.js +22 -17
- package/dist/instance-options-Dhhcnm3y.js +22 -0
- package/dist/instance-options-jARdwfPN.d.ts +11 -0
- package/dist/{parse-DPfIvFMU.js → json-schema-BsAflUGW.js} +28 -57
- package/dist/jwt/index.d.ts +10 -6
- package/dist/jwt/index.js +32 -13
- package/dist/kernel-_RRHmnMY.js +208 -0
- package/dist/kysely/index.d.ts +4 -3
- package/dist/kysely/index.js +3 -3
- package/dist/live-options-H2eG8dfJ.js +60 -0
- package/dist/{load-BZ24CpZP.js → load-DhWEB9P1.js} +16 -10
- package/dist/load-DwJUafYN.js +2 -0
- package/dist/manifest-iaoBXHKc.js +783 -0
- package/dist/manifest-uDS9y5de.d.ts +206 -0
- package/dist/{map-DowSO96j.js → map-AcxK9o_D.js} +4 -15
- package/dist/{map-claims-B_6I1Rn-.js → map-claims-Z4QZOiFF.js} +13 -4
- package/dist/map-error-pgUWNNtG.js +23 -0
- package/dist/may-use-DndQ5tQ-.js +77 -0
- package/dist/mcp/index.d.ts +54 -22
- package/dist/mcp/index.js +218 -178
- package/dist/nest/index.d.ts +26 -31
- package/dist/nest/index.js +75 -84
- package/dist/next/client.d.ts +7 -8
- package/dist/next/client.js +11 -9
- package/dist/next/index.d.ts +30 -47
- package/dist/next/index.js +45 -60
- package/dist/next/plugin.d.ts +1 -1
- package/dist/next/plugin.js +32 -1
- package/dist/node/index.d.ts +9 -28
- package/dist/node/index.js +11 -43
- package/dist/openai/index.d.ts +6 -15
- package/dist/openai/index.js +7 -20
- package/dist/openapi/index.d.ts +87 -4
- package/dist/openapi/index.js +3 -3
- package/dist/{openapi-DcqM8nU7.js → openapi-BqRBvAng.js} +237 -5
- package/dist/{openapi-DWD0Uc_4.js → openapi-CqqEbHsL.js} +5 -5
- package/dist/{openapi-import-BWRUNNeW.js → openapi-import-cmwetbzw.js} +1 -1
- package/dist/{openapi-CwePaF7C.js → openapi-l0xYHkcv.js} +3 -3
- package/dist/{openapi-schema-D8j_T9tO.js → openapi-schema--ARjyfQr.js} +2 -2
- package/dist/orpc/index.d.ts +15 -28
- package/dist/orpc/index.js +74 -117
- package/dist/otel/index.d.ts +2 -2
- package/dist/parse-BuyjxhZV.js +53 -0
- package/dist/parse-local-manifest-BrMozJCo.js +36 -0
- package/dist/parse-local-manifest-JLnaBH0S.d.ts +10 -0
- package/dist/pdp/index.d.ts +2 -2
- package/dist/pdp/index.js +14 -127
- package/dist/{permdock-yoZ7EjxX.js → permdock-CbgvLnuo.js} +672 -149
- package/dist/{permissions-B8vCg_bI.d.ts → permissions-CDgvKG5L.d.ts} +2 -2
- package/dist/{permissions-DC7GROPA.js → permissions-DVoF6dMt.js} +77 -15
- package/dist/{permissions-B4apnahQ.d.ts → permissions-DttnqqxC.d.ts} +34 -5
- package/dist/{permissions-CofRqesP.js → permissions-RJrovw98.js} +3 -3
- package/dist/{pins-CqE1jZuF.js → pins-8ILTftC9.js} +2 -2
- package/dist/{policy-Cq2fB8Q5.d.ts → policy-D2W7uv19.d.ts} +2 -2
- package/dist/{policy-CInmNGkM.d.ts → policy-IB6yxpC3.d.ts} +351 -42
- package/dist/{policy-ANp36PnI.js → policy-xyWg7QdR.js} +173 -22
- package/dist/powersync-BylawD_U.js +540 -0
- package/dist/powersync-DliZK_-y.js +62 -0
- package/dist/powersync-e_AZrKbg.js +2 -0
- package/dist/prisma/index.d.ts +3 -2
- package/dist/prisma/index.js +45 -20
- package/dist/{problem-Cgp9-KZA.js → problem-B43ztKIm.js} +74 -109
- package/dist/problem-details-DX075l9V.d.ts +7 -0
- package/dist/problem-details-_AMOYz-w.js +144 -0
- package/dist/{protected-BuPAycJT.d.ts → protected-BdnIEFkY.d.ts} +5 -4
- package/dist/protected-utU-SLuy.js +100 -0
- package/dist/protected-xAr24FEC.d.ts +40 -0
- package/dist/provider-CSQd7m92.js +52 -0
- package/dist/{provider-wTAUda2v.d.ts → provider-DZY281jO.d.ts} +1 -1
- package/dist/provider-store-Cfbvo4DE.js +43 -0
- package/dist/react/index.d.ts +7 -5
- package/dist/react/index.js +5 -4
- package/dist/react/provider-client.d.ts +1 -1
- package/dist/react/provider-client.js +1 -1
- package/dist/react-native/index.d.ts +166 -10
- package/dist/react-native/index.js +607 -85
- package/dist/{refs-ChLSxbST.js → refs-KYb4ntaz.js} +4 -3
- package/dist/{relations-r4soIFZB.js → relations-cjOL01hZ.js} +110 -31
- package/dist/replay-BsOyTrdV.js +28 -0
- package/dist/replay-CYyiLiwO.d.ts +5 -0
- package/dist/resource-ref-CaS9yVPi.js +20 -0
- package/dist/revocations-Bhr0aMIC.js +27 -0
- package/dist/{rls-BOFU3chG.js → rls-B4ur8nKQ.js} +8 -3
- package/dist/rls-DQtdgTHB.js +2521 -0
- package/dist/rls-fields-74oZPXWL.js +3582 -0
- package/dist/{rls-graph-DxQ39PJj.js → rls-graph-CHwx0V8q.js} +100 -36
- package/dist/{rls-import-CXV6LBlS.js → rls-import-BTFVk3jH.js} +7 -6
- package/dist/{rls-migrate-DrFPbf8p.js → rls-migrate-CN4TlJTO.js} +6 -5
- package/dist/rls-ownership-RuFqaqGz.js +843 -0
- package/dist/rls-shared-Cewd_-zI.js +495 -0
- package/dist/rls-verify-CVQTHTh5.js +746 -0
- package/dist/{row-check-BajTgQZ-.d.ts → row-check-Dt35czLy.d.ts} +12 -15
- package/dist/row-conditions-h2HythXQ.js +27 -0
- package/dist/rpc-DL9Sqvb1.js +89 -0
- package/dist/{run-CJ6UvS3a.js → run-DKDbM4Du.js} +31 -12
- package/dist/runtime-CB8gQFvS.js +11 -0
- package/dist/{saas-BRrZzJkM.js → saas-DhpJjnBA.js} +17 -7
- package/dist/{schema-P8yoma__.js → schema-D3MnDMxa.js} +8 -4
- package/dist/scim/index.d.ts +1 -1
- package/dist/scim/index.js +1 -1
- package/dist/{scim-9NFa0XVZ.js → scim-BFGBBAqR.js} +1 -1
- package/dist/{scopes-cKVp_WTw.js → scopes-CVdPrWN-.js} +35 -8
- package/dist/server/index.d.ts +22 -11
- package/dist/server/index.js +11 -8
- package/dist/{credentials-BgRX3WEg.js → server-DlZ28Oz5.js} +1 -1
- package/dist/shared-DRu8VFVM.js +123 -0
- package/dist/{sink-Cfr9-7YC.d.ts → sink-B1fZzIMf.d.ts} +1 -1
- package/dist/skills-Biq5uup3.js +192 -0
- package/dist/{skills-C_lpV4Jx.js → skills-Bx-U0irG.js} +10 -4
- package/dist/{snapshot-DE8dE_hz.js → snapshot-Enxd0n-s.js} +138 -214
- package/dist/snapshot-cache-B-LxUahj.d.ts +45 -0
- package/dist/snapshot-cache-D6jLelln.js +44 -0
- package/dist/solid/index.d.ts +39 -9
- package/dist/solid/index.js +76 -85
- package/dist/sources-4p0-4xQm.js +545 -0
- package/dist/sources-BdOYLw9j.d.ts +192 -0
- package/dist/{sql-Bll1d7y0.js → sql-xdg5f4Fi.js} +6 -1
- package/dist/{src-CTNT-PBW.js → src-BDwEZWrZ.js} +149 -11
- package/dist/ssf/index.d.ts +3 -2
- package/dist/ssf/index.js +3 -29
- package/dist/store-DMAWwAJV.js +371 -0
- package/dist/{store-Bq90395i.d.ts → store-jOBYpiXC.d.ts} +13 -4
- package/dist/store-options-ByhZq1jV.js +716 -0
- package/dist/{stores-CkG2HrSg.js → stores-BT2pSCub.js} +10 -63
- package/dist/{stores-CvOnu_2T.d.ts → stores-C0IMQrGI.d.ts} +20 -9
- package/dist/{stream-BhMfZOwr.d.ts → stream-D1RXubw2.d.ts} +2 -2
- package/dist/{stream-Q_xlB6Ko.js → stream-DDpvynSB.js} +16 -2
- package/dist/subject-settings-BwBmCdTR.js +128 -0
- package/dist/supabase/index.d.ts +133 -6
- package/dist/supabase/index.js +4 -3
- package/dist/supabase/middleware.d.ts +32 -27
- package/dist/supabase/middleware.js +56 -22
- package/dist/{supabase-D8UlBA7Z.js → supabase-Boqb9a_Y.js} +3 -3
- package/dist/{supabase-DTxGtYdi.js → supabase-C0qESOa-.js} +347 -367
- package/dist/supabase-config-BpPXt3x1.js +472 -0
- package/dist/supabase-hook-6sYLXg_u.js +2 -0
- package/dist/{supabase-hook-D_OqGb_V.js → supabase-hook-CSLQ4zJ3.js} +1037 -705
- package/dist/supautils-Cn4R4cJ4.js +91 -0
- package/dist/svelte/PermissionBoundary.svelte +37 -0
- package/dist/svelte/Protected.svelte +8 -2
- package/dist/svelte/index.d.ts +9 -6
- package/dist/svelte/index.js +61 -7
- package/dist/svelte/runtime.d.ts +4 -3
- package/dist/svelte/runtime.js +4 -3
- package/dist/svelte/source.d.ts +9 -6
- package/dist/svelte/source.js +7 -4
- package/dist/terminal/index.d.ts +6 -14
- package/dist/terminal/index.js +44 -32
- package/dist/testing/index.d.ts +105 -16
- package/dist/testing/index.js +504 -40
- package/dist/testing/saas/index.d.ts +4 -4
- package/dist/testing/saas/index.js +2 -2
- package/dist/testing/saas/permissions.d.ts +1 -1
- package/dist/testing/saas/permissions.js +1 -1
- package/dist/token-CIWxJOCh.js +50 -0
- package/dist/trpc/index.d.ts +7 -26
- package/dist/trpc/index.js +17 -100
- package/dist/types-BnIEz1sU.d.ts +48 -0
- package/dist/{types-CxquUByI.d.ts → types-Bvc4oWT6.d.ts} +1 -1
- package/dist/{sources-DOpW5Ila.d.ts → types-C97IskBw.d.ts} +86 -127
- package/dist/types-CKNSyIf_.d.ts +52 -0
- package/dist/types-Cq_H8N_X.d.ts +197 -0
- package/dist/{types-D6Z6-rKJ.d.ts → types-DbjRN55U.d.ts} +273 -22
- package/dist/{types-BBK-exvJ.d.ts → types-Dnemwd77.d.ts} +7 -1
- package/dist/{types-BvBk1wgn.d.ts → types-DxiCGmmd.d.ts} +5 -3
- package/dist/{types-B9dmiiab.d.ts → types-QCuYJh4q.d.ts} +1 -1
- package/dist/{types-B8w5PFtS.d.ts → types-aqOHTHcp.d.ts} +17 -1
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +10 -9
- package/dist/usage-DorAJiU_.js +2 -0
- package/dist/{usage-1ozMubLY.js → usage-GTixvDDU.js} +2 -2
- package/dist/{usage-CUnK6Ou9.js → usage-ItS7nLcl.js} +225 -62
- package/dist/validation-error-Ba264OaJ.d.ts +26 -0
- package/dist/validation-error-CnjZ4t92.js +33 -0
- package/dist/{validity-D0uRmJKJ.js → validity-uOp8UpYn.js} +57 -36
- package/dist/{verifier-B90agnhl.js → verifier-BxBo6I44.js} +10 -5
- package/dist/version-BvacVTZR.js +17 -0
- package/dist/views-Soe7bGSC.js +95 -0
- package/dist/{vocabulary-Dk0fs-Jk.d.ts → vocabulary-DA8a8zif.d.ts} +1 -1
- package/dist/vue/index.d.ts +35 -13
- package/dist/vue/index.js +86 -93
- package/dist/watch-BwxLTYMZ.js +2 -0
- package/dist/watch-DVBJ9cBq.js +128 -0
- package/dist/webmcp/index.d.ts +2 -2
- package/dist/webmcp/index.js +7 -13
- package/package.json +62 -36
- package/schemas/approval-request-v1.json +175 -0
- package/schemas/catalog-v1.json +29 -1
- package/schemas/supabase-claims-v1.json +6 -1
- package/schemas/supabase-manifest-v1.json +150 -6
- package/skills/permdock/SKILL.md +7 -7
- package/skills/permdock-agents/SKILL.md +5 -5
- package/skills/permdock-agents/references/runtimes.md +12 -10
- package/skills/permdock-approvals/SKILL.md +4 -4
- package/skills/permdock-approvals/references/stores-and-resume.md +15 -4
- package/skills/permdock-audit/SKILL.md +3 -3
- package/skills/permdock-credentials/SKILL.md +4 -4
- package/skills/permdock-credentials/references/tokens-keys-links.md +7 -2
- package/skills/permdock-data/SKILL.md +4 -4
- package/skills/permdock-data/references/queries-and-rls.md +14 -6
- package/skills/permdock-data/references/relationships.md +5 -3
- package/skills/permdock-tenancy/SKILL.md +9 -6
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +14 -8
- package/skills/permdock-wire/SKILL.md +4 -4
- package/skills/permdock-wire/references/adapters.md +42 -30
- package/skills/permdock-wire/references/policy-options.md +5 -3
- package/dist/approvers-aH0PJkmf.js +0 -20
- package/dist/catalog-idsHc0vo.js +0 -2
- package/dist/collect-B7_TIfmg.js +0 -49
- package/dist/collect-fRPAQIWb.js +0 -2
- package/dist/compile-CQbvyIBr.d.ts +0 -30
- package/dist/config-BPYmjTOp.js +0 -26
- package/dist/context-gtAwAILx.js +0 -6
- package/dist/create-BKF3dgFk.d.ts +0 -162
- package/dist/create-CSkhDU9T.js +0 -222
- package/dist/doctor-BGle8Gqi.js +0 -1314
- package/dist/helpers-DnSOrhB9.js +0 -682
- package/dist/index-fG6NSXlc.d.ts +0 -9
- package/dist/kernel-YOGCWNLf.js +0 -211
- package/dist/load-QOOm1z70.js +0 -2
- package/dist/manifest-DDQbC6K0.d.ts +0 -118
- package/dist/map-error-RJ3ZsUyA.js +0 -16
- package/dist/may-use-CnFEjVEp.js +0 -37
- package/dist/pg-4GJWDUxG.js +0 -953
- package/dist/plugin-4gr7IxFJ.js +0 -65
- package/dist/protected-B4K3BKoX.js +0 -138
- package/dist/protected-wY7nXhY9.d.ts +0 -23
- package/dist/provider-_wx46HpB.js +0 -48
- package/dist/rls-CJVja9Ww.js +0 -2119
- package/dist/rls-helpers-BxRuif0l.js +0 -1346
- package/dist/runtime-DP9ttFh1.js +0 -27
- package/dist/skills-Dx3QLnMY.js +0 -110
- package/dist/source-DoBBYJi2.js +0 -6
- package/dist/sources-DVHM3Mwq.js +0 -284
- package/dist/store-C6hFW6ta.js +0 -508
- package/dist/subject-settings-xt7V845g.js +0 -82
- package/dist/supabase-hook-DW-xP4hU.js +0 -2
- package/dist/types-DbWdEfcm.d.ts +0 -87
- package/dist/types-bva3i4Gf.d.ts +0 -98
- package/dist/types-i4BAOvdb.d.ts +0 -97
- package/dist/usage-PyEor6GA.js +0 -2
- package/dist/version-CnSh33Fj.js +0 -16
package/dist/store-C6hFW6ta.js
DELETED
|
@@ -1,508 +0,0 @@
|
|
|
1
|
-
import { t as compact } from "./compact-y6vfu2_f.js";
|
|
2
|
-
import { n as parseSnapshot } from "./snapshot-DE8dE_hz.js";
|
|
3
|
-
import { s as nowSeconds } from "./validity-D0uRmJKJ.js";
|
|
4
|
-
import { n as fromSnapshot, t as emptySnapshot } from "./from-snapshot-BMGnhmgv.js";
|
|
5
|
-
import { t as timeoutSignal } from "./timeout-D51niuQP.js";
|
|
6
|
-
//#region src/react/store.ts
|
|
7
|
-
/** Milliseconds a decision, refresh or approval request may take; a slower one is an error like a failed request. */
|
|
8
|
-
const STORE_TIMEOUT_MS = 1e4;
|
|
9
|
-
function cacheKey(permission, data) {
|
|
10
|
-
if (data === null || typeof data !== "object") return `${permission.key}:*`;
|
|
11
|
-
const id = data["id"];
|
|
12
|
-
return `${permission.key}:${typeof id === "string" || typeof id === "number" ? String(id) : "*"}`;
|
|
13
|
-
}
|
|
14
|
-
function withTenant(source, tenant) {
|
|
15
|
-
if (tenant === void 0) return source;
|
|
16
|
-
const hashAt = source.indexOf("#");
|
|
17
|
-
const hash = hashAt === -1 ? "" : source.slice(hashAt);
|
|
18
|
-
const rest = hashAt === -1 ? source : source.slice(0, hashAt);
|
|
19
|
-
const queryAt = rest.indexOf("?");
|
|
20
|
-
const path = queryAt === -1 ? rest : rest.slice(0, queryAt);
|
|
21
|
-
const params = new URLSearchParams(queryAt === -1 ? "" : rest.slice(queryAt + 1));
|
|
22
|
-
params.set("tenant", tenant);
|
|
23
|
-
return `${path}?${params.toString()}${hash}`;
|
|
24
|
-
}
|
|
25
|
-
function refKey(ref) {
|
|
26
|
-
if ("key" in ref && typeof ref.key === "string") return ref.key;
|
|
27
|
-
return "";
|
|
28
|
-
}
|
|
29
|
-
function isJws(value) {
|
|
30
|
-
const parts = value.split(".");
|
|
31
|
-
return parts.length === 3 && parts.every((part) => part.length > 0);
|
|
32
|
-
}
|
|
33
|
-
const CURRENT = Symbol.for("permdock.current");
|
|
34
|
-
const SERVER_ONLY = {
|
|
35
|
-
outcome: "denied",
|
|
36
|
-
denials: [{
|
|
37
|
-
role: null,
|
|
38
|
-
reason: "opaque-condition"
|
|
39
|
-
}],
|
|
40
|
-
alternatives: []
|
|
41
|
-
};
|
|
42
|
-
/** The client has no endpoint to ask (`endpoint: false`, or none given). */
|
|
43
|
-
const NO_ENDPOINT = {
|
|
44
|
-
outcome: "denied",
|
|
45
|
-
denials: [{
|
|
46
|
-
role: null,
|
|
47
|
-
reason: "server-only"
|
|
48
|
-
}],
|
|
49
|
-
alternatives: []
|
|
50
|
-
};
|
|
51
|
-
function needsEndpoint(decision) {
|
|
52
|
-
return decision.outcome === "denied" && decision.denials.some((denial) => denial.reason === "opaque-condition");
|
|
53
|
-
}
|
|
54
|
-
function createClientStore(options) {
|
|
55
|
-
const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
56
|
-
const server = options.server ?? globalThis.window === void 0;
|
|
57
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
58
|
-
const answers = /* @__PURE__ */ new Map();
|
|
59
|
-
let queued = [];
|
|
60
|
-
let flushScheduled = false;
|
|
61
|
-
let emitScheduled = false;
|
|
62
|
-
let snapshot = emptySnapshot();
|
|
63
|
-
let tenant = options.tenant;
|
|
64
|
-
let base = "server-only";
|
|
65
|
-
let instance = fromSnapshot(snapshot, compact({ tenant }));
|
|
66
|
-
let cached;
|
|
67
|
-
let verifying = false;
|
|
68
|
-
let refreshing = 0;
|
|
69
|
-
let following = 0;
|
|
70
|
-
let refreshSeq = 0;
|
|
71
|
-
let silent = false;
|
|
72
|
-
let adopted;
|
|
73
|
-
let generation = 0;
|
|
74
|
-
const emit = () => {
|
|
75
|
-
cached = wrap(instance);
|
|
76
|
-
if (silent) return;
|
|
77
|
-
for (const listener of listeners) listener();
|
|
78
|
-
};
|
|
79
|
-
const emitSoon = () => {
|
|
80
|
-
if (emitScheduled) return;
|
|
81
|
-
emitScheduled = true;
|
|
82
|
-
queueMicrotask(() => {
|
|
83
|
-
emitScheduled = false;
|
|
84
|
-
emit();
|
|
85
|
-
});
|
|
86
|
-
};
|
|
87
|
-
const reset = () => {
|
|
88
|
-
generation += 1;
|
|
89
|
-
answers.clear();
|
|
90
|
-
queued = [];
|
|
91
|
-
};
|
|
92
|
-
const hydrate = (next) => {
|
|
93
|
-
reset();
|
|
94
|
-
snapshot = next;
|
|
95
|
-
instance = fromSnapshot(snapshot, compact({ tenant }));
|
|
96
|
-
base = "ready";
|
|
97
|
-
options.onSnapshot?.(next, tenant);
|
|
98
|
-
emit();
|
|
99
|
-
};
|
|
100
|
-
const storeStatus = () => {
|
|
101
|
-
if (verifying || refreshing > 0 || following > 0) return "pending";
|
|
102
|
-
if (base === "server-only") return "server-only";
|
|
103
|
-
if (base === "stale" || isStale()) return "stale";
|
|
104
|
-
for (const entry of answers.values()) if (entry.status === "pending") return "pending";
|
|
105
|
-
return "ready";
|
|
106
|
-
};
|
|
107
|
-
const isStale = () => {
|
|
108
|
-
const maxAge = snapshot.issuedAt > 0 ? options.maxAge : void 0;
|
|
109
|
-
if (snapshot.expiresAt === void 0 && maxAge === void 0) return false;
|
|
110
|
-
const now = nowSeconds();
|
|
111
|
-
if (snapshot.expiresAt !== void 0 && snapshot.expiresAt <= now) return true;
|
|
112
|
-
return maxAge !== void 0 && now - snapshot.issuedAt > maxAge;
|
|
113
|
-
};
|
|
114
|
-
const serverOnly = () => {
|
|
115
|
-
hydrate(emptySnapshot());
|
|
116
|
-
base = "server-only";
|
|
117
|
-
emit();
|
|
118
|
-
};
|
|
119
|
-
const applyParsed = (value) => {
|
|
120
|
-
try {
|
|
121
|
-
hydrate(parseSnapshot(value));
|
|
122
|
-
} catch {
|
|
123
|
-
serverOnly();
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
const verifyJws = async (raw) => {
|
|
127
|
-
if (options.verifier === void 0) return;
|
|
128
|
-
try {
|
|
129
|
-
const verified = await options.verifier.verify(raw, { typ: "permdock-snapshot+jwt" });
|
|
130
|
-
return verified.ok ? verified.claims["snapshot"] : void 0;
|
|
131
|
-
} catch {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
const bootJws = async (raw) => {
|
|
136
|
-
if (options.verifier === void 0) {
|
|
137
|
-
serverOnly();
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
const started = generation;
|
|
141
|
-
verifying = true;
|
|
142
|
-
emit();
|
|
143
|
-
const claim = await verifyJws(raw);
|
|
144
|
-
verifying = false;
|
|
145
|
-
if (started !== generation) {
|
|
146
|
-
emit();
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
if (claim === void 0) {
|
|
150
|
-
serverOnly();
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
applyParsed(claim);
|
|
154
|
-
};
|
|
155
|
-
const scheduleFlush = () => {
|
|
156
|
-
if (flushScheduled || options.endpoint === void 0) return;
|
|
157
|
-
flushScheduled = true;
|
|
158
|
-
queueMicrotask(() => {
|
|
159
|
-
flushScheduled = false;
|
|
160
|
-
flush();
|
|
161
|
-
});
|
|
162
|
-
};
|
|
163
|
-
const flush = async () => {
|
|
164
|
-
const batch = queued;
|
|
165
|
-
queued = [];
|
|
166
|
-
if (batch.length === 0 || options.endpoint === void 0) return;
|
|
167
|
-
const started = generation;
|
|
168
|
-
if (snapshot.simulated === true) {
|
|
169
|
-
for (const item of batch) answers.set(item.key, {
|
|
170
|
-
decision: SERVER_ONLY,
|
|
171
|
-
status: "server-only"
|
|
172
|
-
});
|
|
173
|
-
emit();
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
const response = await fetchImpl(options.endpoint, {
|
|
178
|
-
method: "POST",
|
|
179
|
-
credentials: "include",
|
|
180
|
-
signal: timeoutSignal(STORE_TIMEOUT_MS),
|
|
181
|
-
headers: {
|
|
182
|
-
accept: "application/json",
|
|
183
|
-
"content-type": "application/json",
|
|
184
|
-
...options.headers
|
|
185
|
-
},
|
|
186
|
-
body: JSON.stringify({ evaluations: batch.map((item) => ({
|
|
187
|
-
subject: {
|
|
188
|
-
type: instance.subject.principal?.kind ?? "user",
|
|
189
|
-
id: instance.subject.principal?.id ?? ""
|
|
190
|
-
},
|
|
191
|
-
action: { name: item.permission.action },
|
|
192
|
-
resource: {
|
|
193
|
-
type: item.permission.resource,
|
|
194
|
-
id: item.data !== null && typeof item.data === "object" && "id" in item.data ? String(item.data.id ?? "") : void 0,
|
|
195
|
-
properties: item.data
|
|
196
|
-
}
|
|
197
|
-
})) })
|
|
198
|
-
});
|
|
199
|
-
if (!response.ok) throw new Error("evaluations failed");
|
|
200
|
-
const body = await response.json();
|
|
201
|
-
if (started !== generation) return;
|
|
202
|
-
for (const [index, item] of batch.entries()) {
|
|
203
|
-
const decision = (body.evaluations?.[index])?.context?.permdock ?? SERVER_ONLY;
|
|
204
|
-
answers.set(item.key, {
|
|
205
|
-
decision,
|
|
206
|
-
status: "ready"
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
} catch {
|
|
210
|
-
if (started !== generation) return;
|
|
211
|
-
for (const item of batch) answers.set(item.key, {
|
|
212
|
-
decision: SERVER_ONLY,
|
|
213
|
-
status: "server-only"
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
emit();
|
|
217
|
-
};
|
|
218
|
-
const enqueue = (key, permission, data) => {
|
|
219
|
-
if (answers.has(key)) return;
|
|
220
|
-
if (options.endpoint === void 0) {
|
|
221
|
-
answers.set(key, {
|
|
222
|
-
decision: NO_ENDPOINT,
|
|
223
|
-
status: "server-only"
|
|
224
|
-
});
|
|
225
|
-
options.onServerOnly?.(permission);
|
|
226
|
-
emitSoon();
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
answers.set(key, {
|
|
230
|
-
decision: SERVER_ONLY,
|
|
231
|
-
status: "pending"
|
|
232
|
-
});
|
|
233
|
-
queued.push({
|
|
234
|
-
permission,
|
|
235
|
-
data,
|
|
236
|
-
key
|
|
237
|
-
});
|
|
238
|
-
emitSoon();
|
|
239
|
-
scheduleFlush();
|
|
240
|
-
};
|
|
241
|
-
const permissionState = (permission, data) => {
|
|
242
|
-
const key = `${tenant ?? ""}|${cacheKey(permission, data)}`;
|
|
243
|
-
const hit = answers.get(key);
|
|
244
|
-
if (hit !== void 0) return {
|
|
245
|
-
allowed: hit.decision.outcome === "granted",
|
|
246
|
-
status: hit.status,
|
|
247
|
-
decision: hit.decision
|
|
248
|
-
};
|
|
249
|
-
const decision = instance.decide(permission, data);
|
|
250
|
-
if (needsEndpoint(decision)) {
|
|
251
|
-
if (server && options.endpoint !== void 0) return {
|
|
252
|
-
allowed: false,
|
|
253
|
-
status: "pending",
|
|
254
|
-
decision: SERVER_ONLY
|
|
255
|
-
};
|
|
256
|
-
enqueue(key, permission, data);
|
|
257
|
-
const next = answers.get(key);
|
|
258
|
-
if (next !== void 0) return {
|
|
259
|
-
allowed: false,
|
|
260
|
-
status: next.status,
|
|
261
|
-
decision: next.decision
|
|
262
|
-
};
|
|
263
|
-
return {
|
|
264
|
-
allowed: false,
|
|
265
|
-
status: "server-only",
|
|
266
|
-
decision: NO_ENDPOINT
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
return {
|
|
270
|
-
allowed: decision.outcome === "granted",
|
|
271
|
-
status: verifying || following > 0 ? "pending" : isStale() ? "stale" : "ready",
|
|
272
|
-
decision
|
|
273
|
-
};
|
|
274
|
-
};
|
|
275
|
-
const approvalInterval = options.approvalInterval ?? 2e3;
|
|
276
|
-
const approvals = /* @__PURE__ */ new Map();
|
|
277
|
-
const polls = /* @__PURE__ */ new Map();
|
|
278
|
-
let approvalEpoch = 0;
|
|
279
|
-
const TERMINAL = /* @__PURE__ */ new Set([
|
|
280
|
-
"approved",
|
|
281
|
-
"rejected",
|
|
282
|
-
"expired"
|
|
283
|
-
]);
|
|
284
|
-
const stopPolls = () => {
|
|
285
|
-
for (const timer of polls.values()) clearTimeout(timer);
|
|
286
|
-
polls.clear();
|
|
287
|
-
};
|
|
288
|
-
const schedulePoll = (token) => {
|
|
289
|
-
if (server || options.approvals === void 0 || polls.has(token) || listeners.size === 0) return;
|
|
290
|
-
const epoch = approvalEpoch;
|
|
291
|
-
const href = `${options.approvals.replace(/\/+$/u, "")}/${encodeURIComponent(token)}`;
|
|
292
|
-
polls.set(token, setTimeout(() => {
|
|
293
|
-
(async () => {
|
|
294
|
-
let next;
|
|
295
|
-
try {
|
|
296
|
-
const response = await fetchImpl(href, {
|
|
297
|
-
method: "GET",
|
|
298
|
-
credentials: "include",
|
|
299
|
-
signal: timeoutSignal(STORE_TIMEOUT_MS),
|
|
300
|
-
headers: {
|
|
301
|
-
accept: "application/json",
|
|
302
|
-
...options.headers
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
if (response.status === 404) next = "expired";
|
|
306
|
-
else if (response.ok) {
|
|
307
|
-
const body = await response.json();
|
|
308
|
-
next = body.status === "pending" || body.status === "approved" || body.status === "rejected" || body.status === "expired" ? body.status : void 0;
|
|
309
|
-
}
|
|
310
|
-
} catch {
|
|
311
|
-
next = void 0;
|
|
312
|
-
}
|
|
313
|
-
if (epoch !== approvalEpoch) return;
|
|
314
|
-
polls.delete(token);
|
|
315
|
-
if (next !== void 0 && approvals.get(token) !== next) {
|
|
316
|
-
approvals.set(token, next);
|
|
317
|
-
emit();
|
|
318
|
-
}
|
|
319
|
-
if (!TERMINAL.has(approvals.get(token) ?? "required")) schedulePoll(token);
|
|
320
|
-
})();
|
|
321
|
-
}, approvalInterval));
|
|
322
|
-
};
|
|
323
|
-
const approvalState = (decision) => {
|
|
324
|
-
if (decision.outcome !== "approval-required") return "not-needed";
|
|
325
|
-
const current = approvals.get(decision.token) ?? "required";
|
|
326
|
-
if (!TERMINAL.has(current)) schedulePoll(decision.token);
|
|
327
|
-
return current;
|
|
328
|
-
};
|
|
329
|
-
const subscribe = (listener) => {
|
|
330
|
-
listeners.add(listener);
|
|
331
|
-
return () => {
|
|
332
|
-
listeners.delete(listener);
|
|
333
|
-
if (listeners.size === 0) stopPolls();
|
|
334
|
-
};
|
|
335
|
-
};
|
|
336
|
-
const wrap = (permdock) => {
|
|
337
|
-
const client = {
|
|
338
|
-
...permdock,
|
|
339
|
-
status(permission, data) {
|
|
340
|
-
if (permission === void 0) return storeStatus();
|
|
341
|
-
return permissionState(permission, data).status;
|
|
342
|
-
},
|
|
343
|
-
invalidate(ref) {
|
|
344
|
-
const prefix = refKey(ref);
|
|
345
|
-
for (const key of answers.keys()) {
|
|
346
|
-
const unscoped = key.slice(key.indexOf("|") + 1);
|
|
347
|
-
if (prefix === "" || unscoped === prefix || unscoped.startsWith(`${prefix}:`) || unscoped.startsWith(`${prefix}.`)) answers.delete(key);
|
|
348
|
-
}
|
|
349
|
-
base = "stale";
|
|
350
|
-
emit();
|
|
351
|
-
},
|
|
352
|
-
async refresh(query) {
|
|
353
|
-
const requested = query?.tenant;
|
|
354
|
-
const source = options.snapshotUrl ?? options.endpoint;
|
|
355
|
-
if (requested !== void 0 && (snapshot.tenants.includes(requested) || source === void 0)) {
|
|
356
|
-
tenant = requested;
|
|
357
|
-
hydrate(snapshot);
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
if (source === void 0) return;
|
|
361
|
-
const started = generation;
|
|
362
|
-
refreshSeq += 1;
|
|
363
|
-
const seq = refreshSeq;
|
|
364
|
-
refreshing += 1;
|
|
365
|
-
emit();
|
|
366
|
-
let body;
|
|
367
|
-
let ok = false;
|
|
368
|
-
try {
|
|
369
|
-
const response = await fetchImpl(withTenant(source, requested), {
|
|
370
|
-
method: "GET",
|
|
371
|
-
credentials: "include",
|
|
372
|
-
signal: timeoutSignal(STORE_TIMEOUT_MS),
|
|
373
|
-
headers: {
|
|
374
|
-
accept: "application/json",
|
|
375
|
-
...options.headers
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
if (response.ok) {
|
|
379
|
-
body = await response.json();
|
|
380
|
-
ok = true;
|
|
381
|
-
}
|
|
382
|
-
} catch {
|
|
383
|
-
ok = false;
|
|
384
|
-
}
|
|
385
|
-
if (ok && typeof body === "string" && isJws(body)) {
|
|
386
|
-
body = await verifyJws(body);
|
|
387
|
-
ok = body !== void 0;
|
|
388
|
-
}
|
|
389
|
-
refreshing -= 1;
|
|
390
|
-
if (started !== generation || seq !== refreshSeq) {
|
|
391
|
-
emit();
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
let next;
|
|
395
|
-
try {
|
|
396
|
-
next = ok ? parseSnapshot(body) : void 0;
|
|
397
|
-
} catch {
|
|
398
|
-
next = void 0;
|
|
399
|
-
}
|
|
400
|
-
if (next === void 0) {
|
|
401
|
-
base = "stale";
|
|
402
|
-
emit();
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
if (requested !== void 0) tenant = requested;
|
|
406
|
-
hydrate(next);
|
|
407
|
-
},
|
|
408
|
-
clear() {
|
|
409
|
-
reset();
|
|
410
|
-
tenant = options.tenant;
|
|
411
|
-
snapshot = emptySnapshot();
|
|
412
|
-
instance = fromSnapshot(snapshot, compact({ tenant }));
|
|
413
|
-
base = "server-only";
|
|
414
|
-
approvalEpoch += 1;
|
|
415
|
-
stopPolls();
|
|
416
|
-
approvals.clear();
|
|
417
|
-
options.onClear?.();
|
|
418
|
-
emit();
|
|
419
|
-
},
|
|
420
|
-
subscribe
|
|
421
|
-
};
|
|
422
|
-
Object.defineProperty(client, CURRENT, { value: () => cached });
|
|
423
|
-
return client;
|
|
424
|
-
};
|
|
425
|
-
const boot = (value) => {
|
|
426
|
-
if (typeof value === "string" && isJws(value)) {
|
|
427
|
-
cached = wrap(instance);
|
|
428
|
-
bootJws(value);
|
|
429
|
-
} else {
|
|
430
|
-
applyParsed(value);
|
|
431
|
-
cached = wrap(instance);
|
|
432
|
-
}
|
|
433
|
-
};
|
|
434
|
-
boot(options.snapshot);
|
|
435
|
-
return {
|
|
436
|
-
get() {
|
|
437
|
-
return cached;
|
|
438
|
-
},
|
|
439
|
-
subscribe,
|
|
440
|
-
permissionState,
|
|
441
|
-
approvalState,
|
|
442
|
-
replace(value) {
|
|
443
|
-
if (typeof value === "string" && isJws(value)) {
|
|
444
|
-
bootJws(value);
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
447
|
-
applyParsed(value);
|
|
448
|
-
},
|
|
449
|
-
follow(value) {
|
|
450
|
-
const started = generation;
|
|
451
|
-
following += 1;
|
|
452
|
-
emit();
|
|
453
|
-
const settle = (next) => {
|
|
454
|
-
following -= 1;
|
|
455
|
-
if (started !== generation) {
|
|
456
|
-
emit();
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
|
-
if (next === void 0) serverOnly();
|
|
460
|
-
else if (typeof next === "string" && isJws(next)) bootJws(next);
|
|
461
|
-
else applyParsed(next);
|
|
462
|
-
};
|
|
463
|
-
Promise.resolve(value).then(settle, () => {
|
|
464
|
-
settle(void 0);
|
|
465
|
-
});
|
|
466
|
-
},
|
|
467
|
-
adopt(value, source) {
|
|
468
|
-
if (adopted === source) return;
|
|
469
|
-
adopted = source;
|
|
470
|
-
reset();
|
|
471
|
-
silent = true;
|
|
472
|
-
try {
|
|
473
|
-
boot(value);
|
|
474
|
-
} finally {
|
|
475
|
-
silent = false;
|
|
476
|
-
}
|
|
477
|
-
queueMicrotask(emit);
|
|
478
|
-
},
|
|
479
|
-
snapshot() {
|
|
480
|
-
return snapshot;
|
|
481
|
-
},
|
|
482
|
-
async requestApproval(decision, note) {
|
|
483
|
-
if (decision.outcome !== "approval-required" || snapshot.simulated === true) return;
|
|
484
|
-
const href = options.approvals ?? options.endpoint;
|
|
485
|
-
if (href === void 0) return;
|
|
486
|
-
if ((await fetchImpl(href, {
|
|
487
|
-
method: "POST",
|
|
488
|
-
credentials: "include",
|
|
489
|
-
signal: timeoutSignal(STORE_TIMEOUT_MS),
|
|
490
|
-
headers: {
|
|
491
|
-
accept: "application/json",
|
|
492
|
-
"content-type": "application/json",
|
|
493
|
-
...options.headers
|
|
494
|
-
},
|
|
495
|
-
body: JSON.stringify({
|
|
496
|
-
permission: decision.grant.permission,
|
|
497
|
-
token: decision.token,
|
|
498
|
-
note
|
|
499
|
-
})
|
|
500
|
-
})).ok && !TERMINAL.has(approvals.get(decision.token) ?? "required")) {
|
|
501
|
-
approvals.set(decision.token, "pending");
|
|
502
|
-
emit();
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
//#endregion
|
|
508
|
-
export { createClientStore as t };
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
//#region src/conditions/row-check.ts
|
|
2
|
-
const MISSING = Object.freeze({ found: false });
|
|
3
|
-
const GRANTED = Object.freeze({
|
|
4
|
-
found: true,
|
|
5
|
-
granted: true
|
|
6
|
-
});
|
|
7
|
-
const DENIED = Object.freeze({
|
|
8
|
-
found: true,
|
|
9
|
-
granted: false
|
|
10
|
-
});
|
|
11
|
-
function rowCheckOf(found, granted) {
|
|
12
|
-
return found ? granted ? GRANTED : DENIED : MISSING;
|
|
13
|
-
}
|
|
14
|
-
/** Reads `select <filter> as granted ... where <key> limit 2`; only a boolean `true` or `1` grants. */
|
|
15
|
-
function rowCheckFrom(rows) {
|
|
16
|
-
if (rows.length > 1) throw new Error("PermDock: checkRow key matches more than one row");
|
|
17
|
-
const [row] = rows;
|
|
18
|
-
return rowCheckOf(row !== void 0, row?.granted === true || row?.granted === 1);
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region src/conditions/subject-settings.ts
|
|
22
|
-
const NAME = /^[a-z_][a-z0-9_]*$/u;
|
|
23
|
-
function settingName(name, what) {
|
|
24
|
-
if (!NAME.test(name)) throw new Error(`PermDock: unsafe ${what} '${name}'`);
|
|
25
|
-
return name;
|
|
26
|
-
}
|
|
27
|
-
function setConfig(name, value) {
|
|
28
|
-
return {
|
|
29
|
-
strings: [`select set_config('${name}', `, ", true)"],
|
|
30
|
-
values: [value]
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* The transaction preamble that makes Postgres see `permdock.subject`: the role, then the
|
|
35
|
-
* claims the generated policies read. Runs inside the caller's transaction, so every setting
|
|
36
|
-
* is local to it.
|
|
37
|
-
*/
|
|
38
|
-
function subjectStatements(permdock, options = {}) {
|
|
39
|
-
const principal = permdock.subject.principal;
|
|
40
|
-
const role = options.role ?? (principal === null ? "anon" : "authenticated");
|
|
41
|
-
if (role !== false && role !== "authenticated" && role !== "anon") throw new Error(`PermDock: withSubject sets role authenticated or anon, not '${String(role)}'`);
|
|
42
|
-
const tenantClaim = settingName(options.tenantClaim ?? "tenant_id", "tenant claim");
|
|
43
|
-
const claims = Object.fromEntries(Object.entries(options.claims ?? {}).filter(([name]) => name !== "sub" && name !== "role" && name !== tenantClaim));
|
|
44
|
-
if (principal !== null) {
|
|
45
|
-
claims["sub"] = principal.id;
|
|
46
|
-
if (principal.tenant !== void 0) claims[tenantClaim] = principal.tenant;
|
|
47
|
-
}
|
|
48
|
-
if (role !== false) claims["role"] = role;
|
|
49
|
-
const statements = role === false ? [] : [{
|
|
50
|
-
strings: [`set local role ${role}`],
|
|
51
|
-
values: []
|
|
52
|
-
}];
|
|
53
|
-
const dialect = options.dialect ?? "supabase";
|
|
54
|
-
switch (dialect) {
|
|
55
|
-
case "supabase":
|
|
56
|
-
case "neon":
|
|
57
|
-
statements.push(setConfig("request.jwt.claims", JSON.stringify(claims)), setConfig("request.jwt.claim.sub", principal?.id ?? ""));
|
|
58
|
-
return statements;
|
|
59
|
-
case "guc": {
|
|
60
|
-
const prefix = settingName(options.gucPrefix ?? "app", "setting prefix");
|
|
61
|
-
statements.push(setConfig(`${prefix}.user_id`, principal?.id ?? ""));
|
|
62
|
-
for (const [name, value] of Object.entries(claims)) {
|
|
63
|
-
if (name === "sub") continue;
|
|
64
|
-
statements.push(setConfig(`${prefix}.${settingName(name, "claim name")}`, typeof value === "string" ? value : JSON.stringify(value)));
|
|
65
|
-
}
|
|
66
|
-
return statements;
|
|
67
|
-
}
|
|
68
|
-
default: return dialect;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/** A statement as text with `$1`, `$2` placeholders, for raw executors. */
|
|
72
|
-
function statementText(statement) {
|
|
73
|
-
let text = "";
|
|
74
|
-
for (const [index, part] of statement.strings.entries()) text = index === 0 ? part : `${text}$${String(index)}${part}`;
|
|
75
|
-
return text;
|
|
76
|
-
}
|
|
77
|
-
/** A statement as a template-strings array, for `sql` tags. */
|
|
78
|
-
function statementTemplate(statement) {
|
|
79
|
-
return Object.assign([...statement.strings], { raw: [...statement.strings] });
|
|
80
|
-
}
|
|
81
|
-
//#endregion
|
|
82
|
-
export { rowCheckOf as a, rowCheckFrom as i, statementText as n, subjectStatements as r, statementTemplate as t };
|
package/dist/types-DbWdEfcm.d.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { E as PolicyVocabulary, Et as TokenVerifier, Mn as Decision, Zt as PermDock, gt as Snapshot, ir as Actor, mr as Principal, ur as Delegation } from "./policy-CInmNGkM.js";
|
|
2
|
-
import { d as Permission } from "./permissions-B4apnahQ.js";
|
|
3
|
-
import { ReactNode } from "react";
|
|
4
|
-
//#region src/react/types.d.ts
|
|
5
|
-
type ClientStatus = "ready" | "pending" | "stale" | "server-only";
|
|
6
|
-
type PermissionState = {
|
|
7
|
-
readonly allowed: boolean;
|
|
8
|
-
readonly status: ClientStatus;
|
|
9
|
-
readonly decision: Decision;
|
|
10
|
-
};
|
|
11
|
-
type PermissionSet = {
|
|
12
|
-
readonly granted: readonly Permission[];
|
|
13
|
-
get(permission: Permission): PermissionState | undefined;
|
|
14
|
-
};
|
|
15
|
-
type ClientPermDock<V extends PolicyVocabulary = PolicyVocabulary> = PermDock<V> & {
|
|
16
|
-
status(permission?: Permission, data?: unknown): ClientStatus;
|
|
17
|
-
invalidate(ref: Permission | {
|
|
18
|
-
readonly [key: string]: unknown;
|
|
19
|
-
}): void;
|
|
20
|
-
refresh(options?: {
|
|
21
|
-
readonly tenant?: string;
|
|
22
|
-
}): Promise<void>;
|
|
23
|
-
clear(): void;
|
|
24
|
-
subscribe(listener: () => void): () => void;
|
|
25
|
-
};
|
|
26
|
-
type ApprovalState = "not-needed" | "required" | "pending" | "approved" | "rejected" | "expired";
|
|
27
|
-
type ApprovalHandle = {
|
|
28
|
-
readonly state: ApprovalState;
|
|
29
|
-
readonly token: string | undefined;
|
|
30
|
-
readonly request: (note?: string) => Promise<void>;
|
|
31
|
-
};
|
|
32
|
-
type SubjectView = {
|
|
33
|
-
readonly principal: Principal | null;
|
|
34
|
-
readonly actor: Actor | undefined;
|
|
35
|
-
readonly delegation: Delegation | undefined;
|
|
36
|
-
readonly expiresAt: number | undefined;
|
|
37
|
-
readonly simulated: boolean;
|
|
38
|
-
};
|
|
39
|
-
type TenantView = {
|
|
40
|
-
readonly tenant: string | null;
|
|
41
|
-
readonly tenants: readonly string[];
|
|
42
|
-
readonly switchTo: (id: string) => Promise<void>;
|
|
43
|
-
readonly status: ClientStatus;
|
|
44
|
-
};
|
|
45
|
-
type FilterResult<T> = readonly T[] & {
|
|
46
|
-
readonly partial: boolean;
|
|
47
|
-
};
|
|
48
|
-
type PermDockProviderProps = ({
|
|
49
|
-
readonly snapshot: Snapshot | string;
|
|
50
|
-
readonly snapshotPromise?: never;
|
|
51
|
-
} | {
|
|
52
|
-
/**
|
|
53
|
-
* An unawaited snapshot from a Server Component. Hooks suspend until it resolves, so only
|
|
54
|
-
* the components that read permissions wait. A rejection reaches the nearest error boundary.
|
|
55
|
-
*/
|
|
56
|
-
readonly snapshotPromise: PromiseLike<Snapshot | string>;
|
|
57
|
-
readonly snapshot?: never;
|
|
58
|
-
}) & {
|
|
59
|
-
/**
|
|
60
|
-
* The AuthZEN evaluations endpoint for checks the snapshot cannot answer. `false` never
|
|
61
|
-
* fetches: those checks answer `denied` with reason `server-only`.
|
|
62
|
-
*/
|
|
63
|
-
readonly endpoint?: string | false;
|
|
64
|
-
readonly approvals?: string;
|
|
65
|
-
readonly tenant?: string;
|
|
66
|
-
readonly fetch?: typeof fetch;
|
|
67
|
-
readonly headers?: Readonly<Record<string, string>>;
|
|
68
|
-
readonly maxAge?: number;
|
|
69
|
-
readonly verifier?: TokenVerifier;
|
|
70
|
-
readonly children: ReactNode;
|
|
71
|
-
};
|
|
72
|
-
type UseRolesOptions = {
|
|
73
|
-
readonly tenant?: string;
|
|
74
|
-
readonly team?: string;
|
|
75
|
-
};
|
|
76
|
-
type ProtectedProps = {
|
|
77
|
-
readonly permission: Permission;
|
|
78
|
-
readonly data?: unknown;
|
|
79
|
-
readonly tenant?: string;
|
|
80
|
-
readonly pending?: ReactNode;
|
|
81
|
-
readonly fallback?: ReactNode | ((decision: Decision) => ReactNode);
|
|
82
|
-
readonly children: ReactNode | ((decision: Extract<Decision, {
|
|
83
|
-
readonly outcome: "granted";
|
|
84
|
-
}>) => ReactNode);
|
|
85
|
-
};
|
|
86
|
-
//#endregion
|
|
87
|
-
export { FilterResult as a, PermissionState as c, TenantView as d, UseRolesOptions as f, ClientStatus as i, ProtectedProps as l, ApprovalState as n, PermDockProviderProps as o, ClientPermDock as r, PermissionSet as s, ApprovalHandle as t, SubjectView as u };
|