permdock 0.0.0 → 0.1.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 +268 -1
- package/dist/a2a/index.d.ts +178 -0
- package/dist/a2a/index.js +271 -0
- package/dist/ai-sdk/index.d.ts +74 -0
- package/dist/ai-sdk/index.js +137 -0
- package/dist/approval-required-TzNB9oQA.js +6 -0
- package/dist/approvals/index.d.ts +3 -0
- package/dist/approvals/index.js +4 -0
- package/dist/approvals-DaxY-Bdg.js +218 -0
- package/dist/approvers-aH0PJkmf.js +20 -0
- package/dist/arazzo-CTeVuXr5.js +70 -0
- package/dist/arazzo-aoTkqYsJ.js +54 -0
- package/dist/authzen/index.d.ts +48 -0
- package/dist/authzen/index.js +336 -0
- package/dist/better-auth/index.d.ts +92 -0
- package/dist/better-auth/index.js +324 -0
- package/dist/budget-JqcRqyhK.d.ts +11 -0
- package/dist/budget-NbEtbJC_.js +11 -0
- package/dist/capability-B68OFnZx.js +171 -0
- package/dist/capability-BDG_nkxt.d.ts +99 -0
- package/dist/catalog/index.d.ts +12 -0
- package/dist/catalog/index.js +2 -0
- package/dist/catalog-B0E6bggc.js +48 -0
- package/dist/catalog-H-vFGwWK.js +55 -0
- package/dist/catalog-doc-BSo_Q_-6.js +298 -0
- package/dist/catalog-idsHc0vo.js +2 -0
- package/dist/catalog-path-CnI0XTFK.js +12 -0
- package/dist/claude-agent/index.d.ts +81 -0
- package/dist/claude-agent/index.js +83 -0
- package/dist/clerk/index.d.ts +56 -0
- package/dist/clerk/index.js +280 -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/cloud/index.d.ts +91 -0
- package/dist/cloud/index.js +390 -0
- package/dist/cloud-BNQTrmrr.js +50 -0
- package/dist/cloud-Cuxr6Czw.js +117 -0
- package/dist/collect-B7_TIfmg.js +49 -0
- package/dist/collect-O-tOtbnk.js +350 -0
- package/dist/collect-fRPAQIWb.js +2 -0
- package/dist/commands-BMh_Etm2.js +93 -0
- package/dist/compact-y6vfu2_f.js +19 -0
- package/dist/compare-pfyVnBjE.js +12 -0
- package/dist/compile-CQbvyIBr.d.ts +30 -0
- package/dist/compile-D22iwvuV.js +558 -0
- package/dist/config-BPYmjTOp.js +26 -0
- package/dist/connection-JvqwHODC.js +194 -0
- package/dist/context-CKEAabd7.js +73 -0
- package/dist/context-gtAwAILx.js +6 -0
- package/dist/convex/index.d.ts +40 -0
- package/dist/convex/index.js +55 -0
- package/dist/create-BKF3dgFk.d.ts +162 -0
- package/dist/create-CSkhDU9T.js +222 -0
- package/dist/credential-B_rkUNlY.js +326 -0
- package/dist/credentials-BgRX3WEg.js +268 -0
- package/dist/describe-Bt1YD5uS.js +99 -0
- package/dist/describe-DernyItf.d.ts +37 -0
- package/dist/diff-BUzf5Poi.js +48 -0
- package/dist/diff-x5Il8LVa.js +418 -0
- package/dist/digest-B3kc_PgQ.d.ts +19 -0
- package/dist/digest-BI-6aa6d.js +27 -0
- package/dist/doctor-BGle8Gqi.js +1314 -0
- package/dist/doctor-Bqo6FwUa.js +53 -0
- package/dist/drizzle/index.d.ts +72 -0
- package/dist/drizzle/index.js +160 -0
- package/dist/duration-xK2jGFVc.js +25 -0
- package/dist/elysia/index.d.ts +71 -0
- package/dist/elysia/index.js +103 -0
- package/dist/errors-DSMnAVNa.js +43 -0
- package/dist/errors-DbZ1YOnb.d.ts +138 -0
- package/dist/errors-Iy71s7Oj.js +177 -0
- package/dist/errors-m3u9TmDu.js +27 -0
- package/dist/evaluations-DsAU9ppl.js +479 -0
- package/dist/eve/index.d.ts +95 -0
- package/dist/eve/index.js +181 -0
- package/dist/express/index.d.ts +46 -0
- package/dist/express/index.js +108 -0
- package/dist/fastify/index.d.ts +56 -0
- package/dist/fastify/index.js +141 -0
- package/dist/files-B_wAGYmt.js +121 -0
- package/dist/fixtures-Cvaw0gDG.js +64 -0
- package/dist/freeze-y1_jQL4v.js +31 -0
- package/dist/from-snapshot-BMGnhmgv.js +552 -0
- package/dist/generate-CH7ThJ14.js +173 -0
- package/dist/grantee-Bv04_Vzf.js +521 -0
- package/dist/headers-B5RRv3Xm.js +6 -0
- package/dist/headers-C8SHQccD.d.ts +6 -0
- package/dist/helpers-DnSOrhB9.js +682 -0
- package/dist/hono/index.d.ts +70 -0
- package/dist/hono/index.js +131 -0
- package/dist/hosted-BwKQ1BTA.js +265 -0
- package/dist/http-DPuDaChb.d.ts +13 -0
- package/dist/http-GgVApX1k.js +111 -0
- package/dist/index-CltcQ4Bf.d.ts +138 -0
- package/dist/index-LF_hS-yn.d.ts +177 -0
- package/dist/index-fG6NSXlc.d.ts +9 -0
- package/dist/index-xIxJLwOQ.d.ts +415 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +21 -0
- package/dist/jwt/index.d.ts +87 -0
- package/dist/jwt/index.js +571 -0
- package/dist/kernel-YOGCWNLf.js +211 -0
- package/dist/kysely/index.d.ts +77 -0
- package/dist/kysely/index.js +129 -0
- package/dist/load-BZ24CpZP.js +69 -0
- package/dist/load-QOOm1z70.js +2 -0
- package/dist/load-jose-BL6LH4bL.js +11 -0
- package/dist/lru-8q4WZjBV.js +28 -0
- package/dist/manifest-DDQbC6K0.d.ts +118 -0
- package/dist/map-DowSO96j.js +158 -0
- package/dist/map-claims-B_6I1Rn-.js +360 -0
- package/dist/map-error-RJ3ZsUyA.js +16 -0
- package/dist/markers-B0hYLvMD.js +60 -0
- package/dist/may-use-CnFEjVEp.js +37 -0
- package/dist/mcp/index.d.ts +127 -0
- package/dist/mcp/index.js +563 -0
- package/dist/nest/index.d.ts +80 -0
- package/dist/nest/index.js +270 -0
- package/dist/next/client.d.ts +24 -0
- package/dist/next/client.js +31 -0
- package/dist/next/index.d.ts +110 -0
- package/dist/next/index.js +195 -0
- package/dist/next/plugin.d.ts +14 -0
- package/dist/next/plugin.js +2 -0
- package/dist/node/index.d.ts +43 -0
- package/dist/node/index.js +66 -0
- package/dist/openai/index.d.ts +71 -0
- package/dist/openai/index.js +105 -0
- package/dist/openapi/index.d.ts +93 -0
- package/dist/openapi/index.js +3 -0
- package/dist/openapi-CwePaF7C.js +164 -0
- package/dist/openapi-DWD0Uc_4.js +250 -0
- package/dist/openapi-DcqM8nU7.js +306 -0
- package/dist/openapi-import-BWRUNNeW.js +5959 -0
- package/dist/openapi-schema-D8j_T9tO.js +6902 -0
- package/dist/orpc/index.d.ts +64 -0
- package/dist/orpc/index.js +188 -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-DPfIvFMU.js +135 -0
- package/dist/pdp/index.d.ts +22 -0
- package/dist/pdp/index.js +795 -0
- package/dist/peer-BOr_kJE1.js +31 -0
- package/dist/permdock-yoZ7EjxX.js +2956 -0
- package/dist/permissions-B4apnahQ.d.ts +185 -0
- package/dist/permissions-B8vCg_bI.d.ts +52 -0
- package/dist/permissions-CofRqesP.js +142 -0
- package/dist/permissions-DC7GROPA.js +600 -0
- package/dist/pg-4GJWDUxG.js +953 -0
- package/dist/pins-CqE1jZuF.js +12 -0
- package/dist/plugin-4gr7IxFJ.js +65 -0
- package/dist/policy-ANp36PnI.js +971 -0
- package/dist/policy-CInmNGkM.d.ts +1959 -0
- package/dist/policy-Cq2fB8Q5.d.ts +20 -0
- package/dist/prisma/index.d.ts +135 -0
- package/dist/prisma/index.js +430 -0
- package/dist/problem-Cgp9-KZA.js +226 -0
- package/dist/prompt-CXYhLfsS.js +32 -0
- package/dist/protected-B4K3BKoX.js +138 -0
- package/dist/protected-BuPAycJT.d.ts +26 -0
- package/dist/protected-wY7nXhY9.d.ts +23 -0
- package/dist/provider-_wx46HpB.js +48 -0
- package/dist/provider-wTAUda2v.d.ts +6 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.js +6 -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 +42 -0
- package/dist/react-native/index.js +174 -0
- package/dist/refs-ChLSxbST.js +90 -0
- package/dist/relations-r4soIFZB.js +426 -0
- package/dist/revocations-Cy06JNx2.d.ts +21 -0
- package/dist/rls-BOFU3chG.js +233 -0
- package/dist/rls-CJVja9Ww.js +2119 -0
- package/dist/rls-graph-DxQ39PJj.js +371 -0
- package/dist/rls-helpers-BxRuif0l.js +1346 -0
- package/dist/rls-import-CXV6LBlS.js +942 -0
- package/dist/rls-migrate-DrFPbf8p.js +366 -0
- package/dist/row-check-BajTgQZ-.d.ts +43 -0
- package/dist/run-CJ6UvS3a.js +155 -0
- package/dist/runtime-DP9ttFh1.js +27 -0
- package/dist/saas-BRrZzJkM.js +1193 -0
- package/dist/schema-P8yoma__.js +296 -0
- package/dist/scim/index.d.ts +2 -0
- package/dist/scim/index.js +2 -0
- package/dist/scim-9NFa0XVZ.js +1445 -0
- package/dist/scopes-cKVp_WTw.js +212 -0
- package/dist/server/index.d.ts +123 -0
- package/dist/server/index.js +8 -0
- package/dist/sha256-BO0swRXL.js +150 -0
- package/dist/sink-Bd9PSyfq.js +141 -0
- package/dist/sink-Cfr9-7YC.d.ts +104 -0
- package/dist/skills-C_lpV4Jx.js +50 -0
- package/dist/skills-Dx3QLnMY.js +110 -0
- package/dist/snapshot-DE8dE_hz.js +1051 -0
- package/dist/solid/index.d.ts +63 -0
- package/dist/solid/index.js +197 -0
- package/dist/source-DoBBYJi2.js +6 -0
- package/dist/sources-DOpW5Ila.d.ts +347 -0
- package/dist/sources-DVHM3Mwq.js +284 -0
- package/dist/sql-Bll1d7y0.js +22 -0
- package/dist/src-CTNT-PBW.js +430 -0
- package/dist/ssf/index.d.ts +3 -0
- package/dist/ssf/index.js +622 -0
- package/dist/store-Bq90395i.d.ts +27 -0
- package/dist/store-C6hFW6ta.js +508 -0
- package/dist/stores-CkG2HrSg.js +140 -0
- package/dist/stores-CvOnu_2T.d.ts +41 -0
- package/dist/stream-BhMfZOwr.d.ts +12 -0
- package/dist/stream-Q_xlB6Ko.js +52 -0
- package/dist/style-CTm1AXDT.js +22 -0
- package/dist/subject-C6dLxqHU.js +24 -0
- package/dist/subject-settings-xt7V845g.js +82 -0
- package/dist/supabase/index.d.ts +67 -0
- package/dist/supabase/index.js +4 -0
- package/dist/supabase/middleware.d.ts +77 -0
- package/dist/supabase/middleware.js +68 -0
- package/dist/supabase-D8UlBA7Z.js +83 -0
- package/dist/supabase-DTxGtYdi.js +796 -0
- package/dist/supabase-hook-DW-xP4hU.js +2 -0
- package/dist/supabase-hook-D_OqGb_V.js +1528 -0
- package/dist/svelte/Protected.svelte +34 -0
- package/dist/svelte/index.d.ts +10 -0
- package/dist/svelte/index.js +53 -0
- package/dist/svelte/runtime.d.ts +6 -0
- package/dist/svelte/runtime.js +3 -0
- package/dist/svelte/source.d.ts +10 -0
- package/dist/svelte/source.js +8 -0
- package/dist/terminal/index.d.ts +171 -0
- package/dist/terminal/index.js +821 -0
- package/dist/testing/index.d.ts +656 -0
- package/dist/testing/index.js +3208 -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/trpc/index.d.ts +80 -0
- package/dist/trpc/index.js +205 -0
- package/dist/types-B8w5PFtS.d.ts +141 -0
- package/dist/types-B9dmiiab.d.ts +66 -0
- package/dist/types-BBK-exvJ.d.ts +177 -0
- package/dist/types-BvBk1wgn.d.ts +118 -0
- package/dist/types-CxquUByI.d.ts +9 -0
- package/dist/types-D6Z6-rKJ.d.ts +312 -0
- package/dist/types-DbWdEfcm.d.ts +87 -0
- package/dist/types-bva3i4Gf.d.ts +98 -0
- package/dist/types-i4BAOvdb.d.ts +97 -0
- package/dist/unplugin/index.d.ts +7 -0
- package/dist/unplugin/index.js +30 -0
- package/dist/usage-1ozMubLY.js +42 -0
- package/dist/usage-CUnK6Ou9.js +530 -0
- package/dist/usage-PyEor6GA.js +2 -0
- package/dist/validity-D0uRmJKJ.js +224 -0
- package/dist/verifier-B90agnhl.js +461 -0
- package/dist/version-CnSh33Fj.js +16 -0
- package/dist/vocabulary-Dk0fs-Jk.d.ts +56 -0
- package/dist/vue/index.d.ts +57 -0
- package/dist/vue/index.js +203 -0
- package/dist/webmcp/index.d.ts +75 -0
- package/dist/webmcp/index.js +313 -0
- package/package.json +423 -4
- package/rulesets/permdock.yaml +29 -0
- package/schemas/catalog-v1.json +507 -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 +139 -0
- package/schemas/supabase-manifest-v1.json +217 -0
- package/skills/permdock/SKILL.md +66 -0
- package/skills/permdock-agents/SKILL.md +77 -0
- package/skills/permdock-agents/references/runtimes.md +211 -0
- package/skills/permdock-approvals/SKILL.md +80 -0
- package/skills/permdock-approvals/references/stores-and-resume.md +83 -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 +127 -0
- package/skills/permdock-data/SKILL.md +57 -0
- package/skills/permdock-data/references/queries-and-rls.md +54 -0
- package/skills/permdock-data/references/relationships.md +65 -0
- package/skills/permdock-tenancy/SKILL.md +77 -0
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +83 -0
- package/skills/permdock-wire/SKILL.md +116 -0
- package/skills/permdock-wire/references/adapters.md +480 -0
- package/skills/permdock-wire/references/policy-options.md +43 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Et as TokenVerifier, Mn as Decision, gt as Snapshot, pr as Membership } from "../policy-CInmNGkM.js";
|
|
2
|
+
import { d as Permission } from "../permissions-B4apnahQ.js";
|
|
3
|
+
import { r as Role } from "../vocabulary-Dk0fs-Jk.js";
|
|
4
|
+
import { a as requiredPlans, i as describe } from "../describe-DernyItf.js";
|
|
5
|
+
import { t as approvalHeaders } from "../headers-C8SHQccD.js";
|
|
6
|
+
import { a as FilterResult, c as PermissionState, d as TenantView, f as UseRolesOptions, i as ClientStatus, n as ApprovalState, r as ClientPermDock, s as PermissionSet, t as ApprovalHandle, u as SubjectView } from "../types-DbWdEfcm.js";
|
|
7
|
+
import { Accessor, Accessor as Accessor$1, JSX } from "solid-js";
|
|
8
|
+
//#region src/solid/types.d.ts
|
|
9
|
+
/** Structural `JSX.Element`: text, a DOM node or a list of children. */
|
|
10
|
+
type SolidChild = string | number | boolean | null | undefined | {
|
|
11
|
+
readonly nodeType: number;
|
|
12
|
+
} | readonly SolidChild[];
|
|
13
|
+
type PermDockProviderProps = {
|
|
14
|
+
/**
|
|
15
|
+
* An accessor re-hydrates the store when it changes and keeps it `pending`
|
|
16
|
+
* while it returns `undefined` (a loading `createResource`); a promise keeps
|
|
17
|
+
* the store `pending` until it settles.
|
|
18
|
+
*/
|
|
19
|
+
readonly snapshot: Snapshot | string | Accessor$1<Snapshot | string | undefined> | PromiseLike<Snapshot | string>;
|
|
20
|
+
readonly endpoint?: string;
|
|
21
|
+
readonly approvals?: string;
|
|
22
|
+
readonly tenant?: string;
|
|
23
|
+
readonly fetch?: typeof fetch;
|
|
24
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
25
|
+
readonly maxAge?: number;
|
|
26
|
+
readonly verifier?: TokenVerifier;
|
|
27
|
+
readonly children: unknown;
|
|
28
|
+
};
|
|
29
|
+
type ProtectedProps = {
|
|
30
|
+
readonly permission: Permission;
|
|
31
|
+
readonly data?: unknown;
|
|
32
|
+
readonly tenant?: string;
|
|
33
|
+
readonly pending?: SolidChild;
|
|
34
|
+
readonly fallback?: SolidChild | ((decision: Decision) => SolidChild);
|
|
35
|
+
readonly children: SolidChild | ((decision: Extract<Decision, {
|
|
36
|
+
readonly outcome: "granted";
|
|
37
|
+
}>) => SolidChild);
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/solid/hooks.d.ts
|
|
41
|
+
export declare function usePermDock(): ClientPermDock;
|
|
42
|
+
export declare function usePermission(permission: Permission | Accessor<Permission>, data?: Accessor<unknown>): Accessor<PermissionState>;
|
|
43
|
+
export declare function usePermissions(permissions: Accessor<readonly Permission[]>, data?: Accessor<unknown>): Accessor<PermissionSet>;
|
|
44
|
+
export declare function useFilter<T>(permission: Permission<string, T, "instance">, rows: Accessor<readonly T[]>): Accessor<FilterResult<T>>;
|
|
45
|
+
export declare function useTenant(): Accessor<TenantView>;
|
|
46
|
+
export declare function useMemberships(): Accessor<readonly Membership[]>;
|
|
47
|
+
export declare function useRoles(options?: Accessor<UseRolesOptions>): Accessor<{
|
|
48
|
+
readonly roles: readonly Role[];
|
|
49
|
+
}>;
|
|
50
|
+
export declare function useAssignableRoles(): Accessor<readonly Role[]>;
|
|
51
|
+
export declare function useAssignablePermissions(options?: {
|
|
52
|
+
readonly tenant?: string;
|
|
53
|
+
}): Accessor<readonly Permission[]>;
|
|
54
|
+
export declare function useSubject(): Accessor<SubjectView>;
|
|
55
|
+
export declare function useApproval(decision: Accessor<Decision>): Accessor<ApprovalHandle>;
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/solid/protected.d.ts
|
|
58
|
+
export declare function Protected(props: ProtectedProps): JSX.Element;
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/solid/provider.d.ts
|
|
61
|
+
export declare function PermDockProvider(props: PermDockProviderProps): JSX.Element;
|
|
62
|
+
//#endregion
|
|
63
|
+
export { type ApprovalHandle, type ApprovalState, type ClientPermDock, type ClientStatus, type FilterResult, type PermDockProviderProps, type PermissionSet, type PermissionState, type ProtectedProps, type SolidChild, type SubjectView, type TenantView, type UseRolesOptions, approvalHeaders, describe, requiredPlans };
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { t as compact } from "../compact-y6vfu2_f.js";
|
|
2
|
+
import { n as requiredPlans, t as describe } from "../describe-Bt1YD5uS.js";
|
|
3
|
+
import { t as emptySnapshot } from "../from-snapshot-BMGnhmgv.js";
|
|
4
|
+
import { t as approvalHeaders } from "../headers-B5RRv3Xm.js";
|
|
5
|
+
import { t as createClientStore } from "../store-C6hFW6ta.js";
|
|
6
|
+
import { t as isPromiseLike } from "../source-DoBBYJi2.js";
|
|
7
|
+
import { createComponent, createComputed, createContext, createMemo, createSignal, on, onCleanup, useContext } from "solid-js";
|
|
8
|
+
//#region src/solid/context.ts
|
|
9
|
+
const PermDockContext = createContext(void 0);
|
|
10
|
+
function useStore() {
|
|
11
|
+
const store = useContext(PermDockContext);
|
|
12
|
+
if (store === void 0) throw new Error("PermDock: hooks require <PermDockProvider>.");
|
|
13
|
+
return store;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/solid/hooks.ts
|
|
17
|
+
function useVersion(store) {
|
|
18
|
+
const [tick, setTick] = createSignal(0);
|
|
19
|
+
onCleanup(store.subscribe(() => {
|
|
20
|
+
setTick((current) => current + 1);
|
|
21
|
+
}));
|
|
22
|
+
return tick;
|
|
23
|
+
}
|
|
24
|
+
function usePermDock() {
|
|
25
|
+
const store = useStore();
|
|
26
|
+
const version = useVersion(store);
|
|
27
|
+
return new Proxy({}, { get(_target, prop, _receiver) {
|
|
28
|
+
version();
|
|
29
|
+
return Reflect.get(store.get(), prop);
|
|
30
|
+
} });
|
|
31
|
+
}
|
|
32
|
+
function usePermission(permission, data) {
|
|
33
|
+
const store = useStore();
|
|
34
|
+
const version = useVersion(store);
|
|
35
|
+
return createMemo(() => {
|
|
36
|
+
version();
|
|
37
|
+
const current = typeof permission === "function" ? permission() : permission;
|
|
38
|
+
return store.permissionState(current, data?.());
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function usePermissions(permissions, data) {
|
|
42
|
+
const store = useStore();
|
|
43
|
+
const version = useVersion(store);
|
|
44
|
+
return createMemo(() => {
|
|
45
|
+
version();
|
|
46
|
+
const granted = [];
|
|
47
|
+
const byKey = {};
|
|
48
|
+
for (const permission of permissions()) {
|
|
49
|
+
const next = store.permissionState(permission, data?.());
|
|
50
|
+
byKey[permission.key] = next;
|
|
51
|
+
if (next.allowed) granted.push(permission);
|
|
52
|
+
}
|
|
53
|
+
return new Proxy({
|
|
54
|
+
granted,
|
|
55
|
+
get(permission) {
|
|
56
|
+
return byKey[permission.key];
|
|
57
|
+
}
|
|
58
|
+
}, { get(target, prop, receiver) {
|
|
59
|
+
if (typeof prop === "string" && Object.hasOwn(byKey, prop)) return byKey[prop];
|
|
60
|
+
return Reflect.get(target, prop, receiver);
|
|
61
|
+
} });
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function useFilter(permission, rows) {
|
|
65
|
+
const permdock = usePermDock();
|
|
66
|
+
return createMemo(() => {
|
|
67
|
+
const next = permdock.filter(permission, rows());
|
|
68
|
+
next.partial = permdock.where(permission).partial;
|
|
69
|
+
return next;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function useTenant() {
|
|
73
|
+
const permdock = usePermDock();
|
|
74
|
+
return createMemo(() => ({
|
|
75
|
+
tenant: permdock.subject.principal?.tenant ?? null,
|
|
76
|
+
tenants: permdock.tenants(),
|
|
77
|
+
switchTo: (id) => permdock.refresh({ tenant: id }),
|
|
78
|
+
status: permdock.status()
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
function useMemberships() {
|
|
82
|
+
const permdock = usePermDock();
|
|
83
|
+
return createMemo(() => permdock.memberships());
|
|
84
|
+
}
|
|
85
|
+
function useRoles(options = () => ({})) {
|
|
86
|
+
const permdock = usePermDock();
|
|
87
|
+
return createMemo(() => {
|
|
88
|
+
const next = options();
|
|
89
|
+
return { roles: (next.team === void 0 ? permdock : permdock.team(next.team)).heldRoles(next.tenant === void 0 ? void 0 : { tenant: next.tenant }) };
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function useAssignableRoles() {
|
|
93
|
+
const permdock = usePermDock();
|
|
94
|
+
return createMemo(() => permdock.assignableRoles());
|
|
95
|
+
}
|
|
96
|
+
function useAssignablePermissions(options = {}) {
|
|
97
|
+
const permdock = usePermDock();
|
|
98
|
+
return createMemo(() => permdock.assignablePermissions(options));
|
|
99
|
+
}
|
|
100
|
+
function useSubject() {
|
|
101
|
+
const permdock = usePermDock();
|
|
102
|
+
return createMemo(() => {
|
|
103
|
+
const snapshot = permdock.snapshot();
|
|
104
|
+
const simulated = typeof snapshot === "object" && snapshot !== null && "simulated" in snapshot && snapshot.simulated === true;
|
|
105
|
+
return {
|
|
106
|
+
principal: permdock.subject.principal,
|
|
107
|
+
actor: permdock.subject.actor,
|
|
108
|
+
delegation: permdock.subject.delegation,
|
|
109
|
+
expiresAt: permdock.subject.expiresAt,
|
|
110
|
+
simulated
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function useApproval(decision) {
|
|
115
|
+
const store = useStore();
|
|
116
|
+
const version = useVersion(store);
|
|
117
|
+
return createMemo(() => {
|
|
118
|
+
version();
|
|
119
|
+
const next = decision();
|
|
120
|
+
return {
|
|
121
|
+
state: store.approvalState(next),
|
|
122
|
+
token: next.outcome === "approval-required" ? next.token : void 0,
|
|
123
|
+
request: (note) => store.requestApproval(next, note)
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/solid/protected.ts
|
|
129
|
+
function Protected(props) {
|
|
130
|
+
const root = usePermDock();
|
|
131
|
+
const local = usePermission(() => props.permission, () => props.data);
|
|
132
|
+
const view = createMemo(() => {
|
|
133
|
+
if (props.tenant === void 0) return local();
|
|
134
|
+
return tenantView(root.tenant(props.tenant), props.permission, props.data);
|
|
135
|
+
});
|
|
136
|
+
const render = () => {
|
|
137
|
+
const scoped = view();
|
|
138
|
+
if (scoped.status === "pending") return props.pending ?? null;
|
|
139
|
+
if (!scoped.allowed || scoped.decision.outcome !== "granted") {
|
|
140
|
+
if (typeof props.fallback === "function") return props.fallback(scoped.decision);
|
|
141
|
+
return props.fallback ?? null;
|
|
142
|
+
}
|
|
143
|
+
if (typeof props.children === "function") return props.children(scoped.decision);
|
|
144
|
+
return props.children;
|
|
145
|
+
};
|
|
146
|
+
return render;
|
|
147
|
+
}
|
|
148
|
+
function tenantView(permdock, permission, data) {
|
|
149
|
+
const decision = permdock.decide(permission, data);
|
|
150
|
+
return {
|
|
151
|
+
allowed: decision.outcome === "granted",
|
|
152
|
+
status: "ready",
|
|
153
|
+
decision
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/solid/provider.ts
|
|
158
|
+
function PermDockProvider(props) {
|
|
159
|
+
const source = props.snapshot;
|
|
160
|
+
const promised = isPromiseLike(source);
|
|
161
|
+
const read = typeof source === "function" ? source : void 0;
|
|
162
|
+
const initial = promised ? void 0 : read === void 0 ? source : read();
|
|
163
|
+
const store = createClientStore(compact({
|
|
164
|
+
snapshot: initial ?? emptySnapshot(),
|
|
165
|
+
endpoint: props.endpoint,
|
|
166
|
+
approvals: props.approvals,
|
|
167
|
+
tenant: props.tenant,
|
|
168
|
+
fetch: props.fetch,
|
|
169
|
+
headers: props.headers,
|
|
170
|
+
maxAge: props.maxAge,
|
|
171
|
+
verifier: props.verifier
|
|
172
|
+
}));
|
|
173
|
+
if (promised) store.follow(source);
|
|
174
|
+
else if (read !== void 0) {
|
|
175
|
+
let arrive;
|
|
176
|
+
if (initial === void 0) store.follow(new Promise((resolve) => {
|
|
177
|
+
arrive = resolve;
|
|
178
|
+
}));
|
|
179
|
+
createComputed(on(read, (next) => {
|
|
180
|
+
if (next === void 0) return;
|
|
181
|
+
if (arrive === void 0) {
|
|
182
|
+
store.replace(next);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
arrive(next);
|
|
186
|
+
arrive = void 0;
|
|
187
|
+
}, { defer: initial !== void 0 }));
|
|
188
|
+
}
|
|
189
|
+
return createComponent(PermDockContext.Provider, {
|
|
190
|
+
value: store,
|
|
191
|
+
get children() {
|
|
192
|
+
return props.children;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
//#endregion
|
|
197
|
+
export { PermDockProvider, Protected, approvalHeaders, describe, requiredPlans, useApproval, useAssignablePermissions, useAssignableRoles, useFilter, useMemberships, usePermDock, usePermission, usePermissions, useRoles, useSubject, useTenant };
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { J as AuthEvent, ct as MembershipSource, mr as Principal } from "./policy-CInmNGkM.js";
|
|
2
|
+
import { a as SupabaseManifestMembership } from "./manifest-DDQbC6K0.js";
|
|
3
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
//#region src/supabase/claims.d.ts
|
|
5
|
+
/** One entry of the `memberships` claim, as `schemas/supabase-claims-v1.json` defines it. */
|
|
6
|
+
type SupabaseMembershipClaim = {
|
|
7
|
+
readonly scope?: string;
|
|
8
|
+
/** Canonical text of the scope instance id, compared exactly. */
|
|
9
|
+
readonly id?: string;
|
|
10
|
+
/** The id of every ancestor scope instance, by scope name. */
|
|
11
|
+
readonly within?: Readonly<Record<string, string>>;
|
|
12
|
+
readonly on?: {
|
|
13
|
+
readonly resource: string;
|
|
14
|
+
readonly id: string;
|
|
15
|
+
};
|
|
16
|
+
readonly tenant?: string;
|
|
17
|
+
readonly team?: string;
|
|
18
|
+
readonly roles: readonly string[];
|
|
19
|
+
readonly via?: string;
|
|
20
|
+
/** Seconds since the epoch. */
|
|
21
|
+
readonly expiresAt?: number;
|
|
22
|
+
readonly grantedBy?: string;
|
|
23
|
+
readonly reason?: string;
|
|
24
|
+
/** The subgroup a membership source's `group` fills: a fixed name or a column. */
|
|
25
|
+
readonly member?: {
|
|
26
|
+
readonly group: string;
|
|
27
|
+
};
|
|
28
|
+
readonly managedBy?: "idp";
|
|
29
|
+
readonly entitlements?: readonly string[];
|
|
30
|
+
/** Custom roles in compact form, read by the RLS helpers in `jwt` mode. */
|
|
31
|
+
readonly grants?: Readonly<Record<string, unknown>>;
|
|
32
|
+
};
|
|
33
|
+
/** An RFC 8693 `act` claim: the acting party, optionally acting for another. */
|
|
34
|
+
type SupabaseActClaim = {
|
|
35
|
+
readonly sub?: string;
|
|
36
|
+
readonly act?: SupabaseActClaim;
|
|
37
|
+
readonly [claim: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
/** The claims the hook writes; each may also sit under `app_metadata`. */
|
|
40
|
+
type SupabasePermDockClaims<TenantClaim extends string = "tenant_id"> = {
|
|
41
|
+
/** Global roles: one name, a list, or `null` for none. */
|
|
42
|
+
readonly user_role?: string | readonly string[] | null;
|
|
43
|
+
readonly roles?: readonly string[];
|
|
44
|
+
readonly memberships?: readonly SupabaseMembershipClaim[];
|
|
45
|
+
/** `true` when the size budget cut `memberships` or `attrs`. */
|
|
46
|
+
readonly memberships_truncated?: boolean;
|
|
47
|
+
/** Allow-listed server-owned attributes, read as `principal.claims.attrs.<key>`. */
|
|
48
|
+
readonly attrs?: Readonly<Record<string, unknown>>;
|
|
49
|
+
/** The principal's authorization version. */
|
|
50
|
+
readonly authz_ver?: number;
|
|
51
|
+
} & { readonly [K in TenantClaim]?: string; };
|
|
52
|
+
/**
|
|
53
|
+
* A Supabase access token in PermDock's claim contract
|
|
54
|
+
* (`schemas/supabase-claims-v1.json`). Claims it does not name pass through.
|
|
55
|
+
*/
|
|
56
|
+
type SupabaseClaims<TenantClaim extends string = "tenant_id"> = SupabasePermDockClaims<TenantClaim> & {
|
|
57
|
+
/** The OAuth client of a third-party app (Supabase OAuth server). */
|
|
58
|
+
readonly client_id?: string;
|
|
59
|
+
/** OAuth scopes, space-separated or as a list. */
|
|
60
|
+
readonly scope?: string | readonly string[];
|
|
61
|
+
readonly act?: SupabaseActClaim;
|
|
62
|
+
readonly app_metadata?: SupabasePermDockClaims<TenantClaim> & {
|
|
63
|
+
readonly [claim: string]: unknown;
|
|
64
|
+
};
|
|
65
|
+
readonly [claim: string]: unknown;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* A Standard Schema v1 over {@link SupabaseClaims}. `extend(app)` adds an
|
|
69
|
+
* application's own claim schema: both validate the same claims, their issues
|
|
70
|
+
* are combined, and the app's output is merged over the base.
|
|
71
|
+
*/
|
|
72
|
+
type SupabaseClaimsSchema<TenantClaim extends string = "tenant_id", Extra = unknown> = StandardSchemaV1<unknown, SupabaseClaims<TenantClaim> & Extra> & {
|
|
73
|
+
extend<App extends StandardSchemaV1>(app: App): SupabaseClaimsSchema<TenantClaim, Extra & StandardSchemaV1.InferOutput<App>>;
|
|
74
|
+
};
|
|
75
|
+
type SupabaseClaimsOptions<TenantClaim extends string = "tenant_id"> = {
|
|
76
|
+
/** The claim holding the active tenant; `rls.tenantClaim`, default `tenant_id`. */
|
|
77
|
+
readonly tenantClaim?: TenantClaim;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* A Standard Schema v1 for PermDock's Supabase claims. Unknown claims pass
|
|
81
|
+
* through unchanged; a known claim with the wrong shape is an issue, so the
|
|
82
|
+
* whole token is rejected as `schemas/supabase-claims-v1.json` rejects it.
|
|
83
|
+
* Needs no validation library.
|
|
84
|
+
*
|
|
85
|
+
* ```ts
|
|
86
|
+
* sb.claims(supabaseClaims().extend(z.object({ datetime_preferences: Prefs })))
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare function supabaseClaims<TenantClaim extends string = "tenant_id">(options?: SupabaseClaimsOptions<TenantClaim>): SupabaseClaimsSchema<TenantClaim>;
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/supabase/types.d.ts
|
|
92
|
+
type SupabasePrincipal = Principal & {
|
|
93
|
+
readonly claims?: Readonly<Record<string, unknown>>;
|
|
94
|
+
readonly email?: string;
|
|
95
|
+
readonly phone?: string;
|
|
96
|
+
readonly is_anonymous?: boolean;
|
|
97
|
+
};
|
|
98
|
+
type SupabaseInclude = "email" | "phone" | "is_anonymous";
|
|
99
|
+
type SupabaseMembershipTable = {
|
|
100
|
+
readonly table: string;
|
|
101
|
+
readonly user: string;
|
|
102
|
+
readonly role: string;
|
|
103
|
+
/** Per scope name, the column holding that scope's id: the table's own scope and its ancestors. */
|
|
104
|
+
readonly columns?: Readonly<Record<string, string>>;
|
|
105
|
+
readonly tenant?: string;
|
|
106
|
+
readonly team?: string;
|
|
107
|
+
readonly id?: string;
|
|
108
|
+
readonly expiresAt?: string;
|
|
109
|
+
};
|
|
110
|
+
/** A table whose row says whether a user or a scope instance is active. A missing row counts as suspended. */
|
|
111
|
+
type SupabaseActiveRow = {
|
|
112
|
+
readonly table: string;
|
|
113
|
+
/** Column holding the user id or the scope instance id. */
|
|
114
|
+
readonly id: string;
|
|
115
|
+
/** Nullable timestamp column; a row with a value is suspended. */
|
|
116
|
+
readonly disabledAt?: string;
|
|
117
|
+
/** Status column; only a row whose value is in `active` counts as active. */
|
|
118
|
+
readonly status?: string;
|
|
119
|
+
readonly active?: readonly string[];
|
|
120
|
+
};
|
|
121
|
+
type SupabaseSuspension = {
|
|
122
|
+
/** A suspended user holds no role and no membership. */
|
|
123
|
+
readonly users?: SupabaseActiveRow;
|
|
124
|
+
/** Per scope name: a suspended instance voids its memberships and every membership nested under it. */
|
|
125
|
+
readonly scopes?: Readonly<Record<string, SupabaseActiveRow>>;
|
|
126
|
+
};
|
|
127
|
+
type SupabaseMemberships = {
|
|
128
|
+
/** The membership table of each named scope. */
|
|
129
|
+
readonly scopes?: Readonly<Record<string, SupabaseMembershipTable>>;
|
|
130
|
+
readonly tenant?: SupabaseMembershipTable;
|
|
131
|
+
readonly team?: SupabaseMembershipTable;
|
|
132
|
+
readonly resource?: Readonly<Record<string, SupabaseMembershipTable>>;
|
|
133
|
+
};
|
|
134
|
+
type AuthorizeSqlOptions = {
|
|
135
|
+
/** Postgres schema of `authorize`, `user_roles`, `role_permissions` and `app_permission`. Default `permdock`. */
|
|
136
|
+
readonly schema?: string;
|
|
137
|
+
/** `database` (default) reads the tables on every call; `jwt` reads the hook-injected claims. */
|
|
138
|
+
readonly authorize?: "database" | "jwt";
|
|
139
|
+
/** The policy's first scope, which `requested_tenant` is an instance of. Default `tenant`. */
|
|
140
|
+
readonly scope?: string;
|
|
141
|
+
/** Membership table for tenant requests in `database` mode; without one they deny. */
|
|
142
|
+
readonly tenant?: boolean | SupabaseMembershipTable;
|
|
143
|
+
/**
|
|
144
|
+
* Tenant requests also answer from custom roles, through the `permdock_custom_keys` function
|
|
145
|
+
* `permdock rls generate --custom-roles` emits: the `custom_role_*` tables in `database` mode,
|
|
146
|
+
* the `memberships[].grants` claim in `jwt` mode. `declared` role names never resolve as custom.
|
|
147
|
+
*/
|
|
148
|
+
readonly customRoles?: {
|
|
149
|
+
readonly declared: readonly string[];
|
|
150
|
+
};
|
|
151
|
+
/** A suspended user, or a suspended instance of `scope` for a tenant request, answers `false`. */
|
|
152
|
+
readonly suspension?: SupabaseSuspension;
|
|
153
|
+
};
|
|
154
|
+
type SupabaseRlsOptions = {
|
|
155
|
+
readonly roleClaim?: string;
|
|
156
|
+
readonly tenantClaim?: string;
|
|
157
|
+
/** Postgres type of tenant columns; the tenant claim is cast to it. `rls generate` defaults to `uuid`. */
|
|
158
|
+
readonly tenantType?: string;
|
|
159
|
+
readonly memberships?: SupabaseMembershipTable | SupabaseMemberships;
|
|
160
|
+
readonly suspension?: SupabaseSuspension;
|
|
161
|
+
};
|
|
162
|
+
type SupabaseRlsConfig = {
|
|
163
|
+
readonly dialect: "supabase";
|
|
164
|
+
readonly roleClaim: string;
|
|
165
|
+
readonly tenantClaim: string;
|
|
166
|
+
readonly tenantType?: string;
|
|
167
|
+
readonly memberships?: SupabaseMemberships;
|
|
168
|
+
readonly suspension?: SupabaseSuspension;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* The structural shape `subjectFromSupabaseSession` reads: a discriminant and the verified JWT claims.
|
|
172
|
+
* Matches better-supabase's `AuthSession` and similar session objects without importing them.
|
|
173
|
+
*/
|
|
174
|
+
type SupabaseSessionLike = {
|
|
175
|
+
readonly kind: string;
|
|
176
|
+
readonly claims?: unknown;
|
|
177
|
+
};
|
|
178
|
+
type SupabaseSubjectOptions = {
|
|
179
|
+
readonly roles?: string;
|
|
180
|
+
readonly tenant?: string;
|
|
181
|
+
readonly memberships?: string;
|
|
182
|
+
readonly schema?: StandardSchemaV1;
|
|
183
|
+
readonly include?: readonly SupabaseInclude[];
|
|
184
|
+
readonly declared?: readonly string[];
|
|
185
|
+
/** Claim holding plan names per tenant id; the active tenant's entry becomes `principal.plans`. */
|
|
186
|
+
readonly plans?: string;
|
|
187
|
+
/** `'deny'` maps a token with `is_anonymous: true` (`signInAnonymously()`) to the anonymous subject, as `rls.anonymousSignIns: 'deny'` does in RLS. */
|
|
188
|
+
readonly anonymousSignIns?: "deny";
|
|
189
|
+
/** Audit hook: `membership-dropped` for a `memberships` entry that could not be read, `invalid-chain` for a malformed `act`. */
|
|
190
|
+
readonly onAuth?: (event: AuthEvent) => void;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Who acts for the user. `oauth-client`: a third-party app or an agent chain (`client_id`, or an
|
|
194
|
+
* `act` without `kind`). `support`: a support session (`act.kind: "support"` with `session_id`).
|
|
195
|
+
* `impersonation`: an admin acting as the user (`act.kind: "impersonation"`). `chain` is a copy of
|
|
196
|
+
* the token's `act` claim when it has one.
|
|
197
|
+
*/
|
|
198
|
+
type SupabaseActor = {
|
|
199
|
+
readonly id: string;
|
|
200
|
+
readonly kind: "oauth-client";
|
|
201
|
+
readonly chain?: SupabaseActClaim;
|
|
202
|
+
} | {
|
|
203
|
+
readonly id: string;
|
|
204
|
+
readonly kind: "support";
|
|
205
|
+
readonly sessionId: string;
|
|
206
|
+
readonly readOnly: boolean;
|
|
207
|
+
readonly reason?: string;
|
|
208
|
+
readonly chain: SupabaseActClaim;
|
|
209
|
+
} | {
|
|
210
|
+
readonly id: string;
|
|
211
|
+
readonly kind: "impersonation";
|
|
212
|
+
readonly reason?: string;
|
|
213
|
+
readonly chain: SupabaseActClaim;
|
|
214
|
+
};
|
|
215
|
+
/** `actorOf` output: `{ ok: false }` must deny. */
|
|
216
|
+
type SupabaseActorResult = {
|
|
217
|
+
readonly ok: true;
|
|
218
|
+
readonly actor?: SupabaseActor;
|
|
219
|
+
} | {
|
|
220
|
+
readonly ok: false;
|
|
221
|
+
readonly reason: "invalid-chain";
|
|
222
|
+
};
|
|
223
|
+
type SupabaseDelegation = {
|
|
224
|
+
readonly scopes: readonly string[];
|
|
225
|
+
};
|
|
226
|
+
//#endregion
|
|
227
|
+
//#region src/supabase/sources.d.ts
|
|
228
|
+
/**
|
|
229
|
+
* Runs one parameterised statement: `pg`'s `client.query` (which resolves
|
|
230
|
+
* `{ rows }`) and `postgres`'s `sql.unsafe` (which resolves the rows) both fit.
|
|
231
|
+
*/
|
|
232
|
+
type SqlQuery = (text: string, values: readonly unknown[]) => Promise<readonly Record<string, unknown>[] | {
|
|
233
|
+
readonly rows: readonly Record<string, unknown>[];
|
|
234
|
+
}>;
|
|
235
|
+
type Common = {
|
|
236
|
+
readonly table: string;
|
|
237
|
+
/** Runs the lookups; without it the source only describes SQL (for `permdock supabase hook generate`). */
|
|
238
|
+
readonly query?: SqlQuery;
|
|
239
|
+
/** Drop suspended users and memberships under suspended instances, like `rls.suspension`. */
|
|
240
|
+
readonly suspension?: SupabaseSuspension;
|
|
241
|
+
};
|
|
242
|
+
type MembershipTableOptions = Common & {
|
|
243
|
+
/** Column names; `user`, `scope`, `id` and `role` default to `user_id`, `scope`, `scope_id`, `role`. */
|
|
244
|
+
readonly columns?: {
|
|
245
|
+
readonly user?: string;
|
|
246
|
+
readonly scope?: string;
|
|
247
|
+
readonly id?: string;
|
|
248
|
+
/** A `jsonb` column of ancestor ids keyed by scope name. */
|
|
249
|
+
readonly within?: string;
|
|
250
|
+
readonly role?: string;
|
|
251
|
+
readonly via?: string;
|
|
252
|
+
readonly expiresAt?: string;
|
|
253
|
+
/** The principal id that wrote the membership (`grantedBy`). */
|
|
254
|
+
readonly grantedBy?: string;
|
|
255
|
+
/** Free-text justification recorded on the membership (`reason`). */
|
|
256
|
+
readonly reason?: string;
|
|
257
|
+
/** A subgroup column filling `member.group`. */
|
|
258
|
+
readonly group?: string;
|
|
259
|
+
/** A text column; the value `idp` marks the row as owned by the identity provider. */
|
|
260
|
+
readonly managedBy?: string;
|
|
261
|
+
/** A `text[]` column of seats. */
|
|
262
|
+
readonly seats?: string;
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
type MembershipJunctionOptions = Common & {
|
|
266
|
+
/** The declared scope every row is a membership of. */
|
|
267
|
+
readonly scope: string;
|
|
268
|
+
/** Default `user_id`. */
|
|
269
|
+
readonly user?: string;
|
|
270
|
+
/** The column holding the scope instance id. Default `<scope>_id`. */
|
|
271
|
+
readonly id?: string;
|
|
272
|
+
/** Ancestor id columns keyed by scope name. */
|
|
273
|
+
readonly within?: Readonly<Record<string, string>>;
|
|
274
|
+
/** A role column, or fixed roles every row holds (a contact table with no role column). */
|
|
275
|
+
readonly roles: string | readonly string[];
|
|
276
|
+
/** The membership kind every row has (`contact`, `staff`, `partner`). */
|
|
277
|
+
readonly via?: string;
|
|
278
|
+
readonly expiresAt?: string;
|
|
279
|
+
/** The principal id that wrote the membership (`grantedBy`). */
|
|
280
|
+
readonly grantedBy?: string;
|
|
281
|
+
/** Free-text justification recorded on the membership (`reason`). */
|
|
282
|
+
readonly reason?: string;
|
|
283
|
+
/** A subgroup filling `member.group`: a fixed name every row has, or a column. */
|
|
284
|
+
readonly group?: string | {
|
|
285
|
+
readonly column: string;
|
|
286
|
+
};
|
|
287
|
+
/** `idp` when the identity provider owns every row, or a text column holding `idp` per row. */
|
|
288
|
+
readonly managedBy?: "idp" | {
|
|
289
|
+
readonly column: string;
|
|
290
|
+
};
|
|
291
|
+
/** A `text[]` column of seats. */
|
|
292
|
+
readonly seats?: string;
|
|
293
|
+
};
|
|
294
|
+
/** What `permdock supabase hook generate` compiles; the same SQL the source runs. */
|
|
295
|
+
type MembershipSql = {
|
|
296
|
+
readonly table: string;
|
|
297
|
+
/** Columns of the table that decide a membership; triggers bump the authorization version on them. */
|
|
298
|
+
readonly user: string;
|
|
299
|
+
/** `<table>.<user>%type`: the PL/pgSQL type of the user column, for a variable `select` compares with. */
|
|
300
|
+
readonly userType: string;
|
|
301
|
+
/**
|
|
302
|
+
* The `select` of claim rows for one user, with every filter applied.
|
|
303
|
+
* `user` must have the column's type (a `userType` variable, or an untyped
|
|
304
|
+
* `$1` Postgres infers): the column is compared uncast so its index applies.
|
|
305
|
+
*/
|
|
306
|
+
select(user: string): string;
|
|
307
|
+
/** The `select` of member rows for one scope instance (`$1` scope, `$2` id). */
|
|
308
|
+
list(): string;
|
|
309
|
+
/** A text column holding `idp` for rows the identity provider owns; `''` when every row is owned. */
|
|
310
|
+
readonly managed?: string;
|
|
311
|
+
/** Other tables the `select` reads (suspension tables). */
|
|
312
|
+
readonly reads: readonly string[];
|
|
313
|
+
/** Every column that decides who holds which membership: user, scope, id, `within`, role, `via` and expiry. */
|
|
314
|
+
readonly columns: readonly string[];
|
|
315
|
+
/** For a single-scope source: its scope and the scopes whose ids each row carries. */
|
|
316
|
+
readonly scope?: string;
|
|
317
|
+
readonly holds?: readonly string[];
|
|
318
|
+
/** The source's entry in the hook manifest's `memberships`. */
|
|
319
|
+
readonly manifest: SupabaseManifestMembership;
|
|
320
|
+
};
|
|
321
|
+
type SqlMembershipSource = MembershipSource & {
|
|
322
|
+
readonly sql: MembershipSql;
|
|
323
|
+
};
|
|
324
|
+
/**
|
|
325
|
+
* Memberships from one table holding every scope: a row per user, scope,
|
|
326
|
+
* instance and role (`user_id, scope, scope_id, role`), with optional
|
|
327
|
+
* `within`, `via`, expiry, owner and seat columns. Rows of the same instance
|
|
328
|
+
* merge into one membership.
|
|
329
|
+
*/
|
|
330
|
+
declare function fromTable(options: MembershipTableOptions): SqlMembershipSource;
|
|
331
|
+
/**
|
|
332
|
+
* Memberships from a table of one scope (`customer_contacts`): every row is a
|
|
333
|
+
* membership of `scope`, with roles from a column or fixed (`['contact']`), a
|
|
334
|
+
* fixed `via`, and ancestor ids from `within` columns.
|
|
335
|
+
*/
|
|
336
|
+
declare function fromJunction(options: MembershipJunctionOptions): SqlMembershipSource;
|
|
337
|
+
declare const AUTHZ_VERSION_TABLE = "permdock_authz_version";
|
|
338
|
+
/**
|
|
339
|
+
* Reads the authorization version `permdock supabase hook generate` keeps in
|
|
340
|
+
* `<schema>.permdock_authz_version`: pass it to `claimsFirst(sources, { version })`.
|
|
341
|
+
*/
|
|
342
|
+
declare function authzVersion(options: {
|
|
343
|
+
readonly query: SqlQuery;
|
|
344
|
+
readonly schema?: string;
|
|
345
|
+
}): NonNullable<MembershipSource["version"]>;
|
|
346
|
+
//#endregion
|
|
347
|
+
export { SupabaseActClaim as C, SupabaseMembershipClaim as D, SupabaseClaimsSchema as E, SupabasePermDockClaims as O, SupabaseSuspension as S, SupabaseClaimsOptions as T, SupabasePrincipal as _, SqlMembershipSource as a, SupabaseSessionLike as b, fromJunction as c, SupabaseActiveRow as d, SupabaseActor as f, SupabaseMembershipTable as g, SupabaseInclude as h, MembershipTableOptions as i, supabaseClaims as k, fromTable as l, SupabaseDelegation as m, MembershipJunctionOptions as n, SqlQuery as o, SupabaseActorResult as p, MembershipSql as r, authzVersion as s, AUTHZ_VERSION_TABLE as t, AuthorizeSqlOptions as u, SupabaseRlsConfig as v, SupabaseClaims as w, SupabaseSubjectOptions as x, SupabaseRlsOptions as y };
|