@vllnt/convex-permissions 0.1.0-canary.a432481

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.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +114 -0
  3. package/dist/client/index.d.ts +125 -0
  4. package/dist/client/index.d.ts.map +1 -0
  5. package/dist/client/index.js +76 -0
  6. package/dist/client/index.js.map +1 -0
  7. package/dist/client/types.d.ts +11 -0
  8. package/dist/client/types.d.ts.map +1 -0
  9. package/dist/client/types.js +3 -0
  10. package/dist/client/types.js.map +1 -0
  11. package/dist/component/_generated/api.d.ts +38 -0
  12. package/dist/component/_generated/api.d.ts.map +1 -0
  13. package/dist/component/_generated/api.js +31 -0
  14. package/dist/component/_generated/api.js.map +1 -0
  15. package/dist/component/_generated/component.d.ts +66 -0
  16. package/dist/component/_generated/component.d.ts.map +1 -0
  17. package/dist/component/_generated/component.js +11 -0
  18. package/dist/component/_generated/component.js.map +1 -0
  19. package/dist/component/_generated/dataModel.d.ts +46 -0
  20. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  21. package/dist/component/_generated/dataModel.js +11 -0
  22. package/dist/component/_generated/dataModel.js.map +1 -0
  23. package/dist/component/_generated/server.d.ts +121 -0
  24. package/dist/component/_generated/server.d.ts.map +1 -0
  25. package/dist/component/_generated/server.js +78 -0
  26. package/dist/component/_generated/server.js.map +1 -0
  27. package/dist/component/convex.config.d.ts +3 -0
  28. package/dist/component/convex.config.d.ts.map +1 -0
  29. package/dist/component/convex.config.js +7 -0
  30. package/dist/component/convex.config.js.map +1 -0
  31. package/dist/component/mutations.d.ts +23 -0
  32. package/dist/component/mutations.d.ts.map +1 -0
  33. package/dist/component/mutations.js +104 -0
  34. package/dist/component/mutations.js.map +1 -0
  35. package/dist/component/queries.d.ts +26 -0
  36. package/dist/component/queries.d.ts.map +1 -0
  37. package/dist/component/queries.js +78 -0
  38. package/dist/component/queries.js.map +1 -0
  39. package/dist/component/schema.d.ts +37 -0
  40. package/dist/component/schema.d.ts.map +1 -0
  41. package/dist/component/schema.js +28 -0
  42. package/dist/component/schema.js.map +1 -0
  43. package/dist/component/validators.d.ts +17 -0
  44. package/dist/component/validators.d.ts.map +1 -0
  45. package/dist/component/validators.js +11 -0
  46. package/dist/component/validators.js.map +1 -0
  47. package/dist/shared.d.ts +25 -0
  48. package/dist/shared.d.ts.map +1 -0
  49. package/dist/shared.js +43 -0
  50. package/dist/shared.js.map +1 -0
  51. package/package.json +96 -0
  52. package/src/client/index.ts +191 -0
  53. package/src/client/types.ts +11 -0
  54. package/src/component/_generated/api.ts +54 -0
  55. package/src/component/_generated/component.ts +93 -0
  56. package/src/component/_generated/dataModel.ts +60 -0
  57. package/src/component/_generated/server.ts +156 -0
  58. package/src/component/convex.config.ts +9 -0
  59. package/src/component/mutations.ts +111 -0
  60. package/src/component/queries.ts +90 -0
  61. package/src/component/schema.ts +29 -0
  62. package/src/component/validators.ts +11 -0
  63. package/src/shared.ts +51 -0
  64. package/src/test.ts +13 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 bntvllnt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,114 @@
1
+ <!-- Badges -->
2
+ [![Convex Component](https://img.shields.io/badge/convex-component-EE342F.svg)](https://www.convex.dev/components)
3
+ [![npm version](https://img.shields.io/npm/v/@vllnt/convex-permissions.svg)](https://www.npmjs.com/package/@vllnt/convex-permissions)
4
+ [![CI](https://github.com/vllnt/convex-permissions/actions/workflows/ci.yml/badge.svg)](https://github.com/vllnt/convex-permissions/actions/workflows/ci.yml)
5
+ [![License](https://img.shields.io/npm/l/@vllnt/convex-permissions.svg)](./LICENSE)
6
+
7
+ # @vllnt/convex-permissions
8
+
9
+ Role-based access control as a Convex component — typed, sandboxed,
10
+ runtime-editable roles and grants keyed by opaque refs.
11
+
12
+ ```ts
13
+ // Define a role, assign it, enforce it — all from host functions.
14
+ await permissions.defineRole(ctx, { name: "editor", grants: ["doc.read", "doc.edit"] });
15
+ await permissions.assign(ctx, { subjectRef: userId, role: "editor" });
16
+ await permissions.require(ctx, { subjectRef: userId, action: "doc.edit" }); // throws on deny
17
+ ```
18
+
19
+ ## Features
20
+
21
+ - **Stored, runtime-editable RBAC** — roles, grants, and assignments live in sandboxed tables; change them with a mutation, no redeploy.
22
+ - **Typed end to end** — `Permissions<TRole, TAction>` is generic over your role and action unions.
23
+ - **Wildcard grants** — `"doc.*"` grants every `doc.` action; `"*"` grants everything.
24
+ - **Scoped / multi-tenant** — assign within an opaque `scopeRef`; unscoped assignments apply globally.
25
+ - **Agnostic by construction** — opaque `subjectRef` / `scopeRef`, no auth library, no domain model, no vendor.
26
+ - **`require` throws** — `ConvexError<PermissionDenied>` the host maps to a 403.
27
+ - **Default-deny** — unknown subjects and unmatched actions are denied.
28
+ - **Runs anywhere** — identical on Convex Cloud and self-hosted `convex-backend`.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ npm install @vllnt/convex-permissions
34
+ ```
35
+
36
+ Peer dependency: `convex@^1.36.1`.
37
+
38
+ ## Usage
39
+
40
+ ```ts
41
+ // convex/convex.config.ts
42
+ import { defineApp } from "convex/server";
43
+ import permissions from "@vllnt/convex-permissions/convex.config";
44
+
45
+ const app = defineApp();
46
+ app.use(permissions);
47
+ export default app;
48
+ ```
49
+
50
+ ```ts
51
+ // convex/permissions.ts — instantiate the typed client, then define / assign / check.
52
+ import { components } from "./_generated/api";
53
+ import { Permissions } from "@vllnt/convex-permissions";
54
+
55
+ type Role = "admin" | "editor" | "viewer";
56
+ type Action = "doc.read" | "doc.edit" | "doc.delete";
57
+
58
+ export const permissions = new Permissions<Role, Action>(components.permissions);
59
+
60
+ // from any host mutation/query (gate management behind your own admin auth):
61
+ await permissions.defineRole(ctx, { name: "editor", grants: ["doc.read", "doc.edit"] });
62
+ await permissions.assign(ctx, { subjectRef: userId, role: "editor", scopeRef: orgId });
63
+ const allowed = await permissions.check(ctx, { subjectRef: userId, action: "doc.edit" });
64
+ await permissions.require(ctx, { subjectRef: userId, action: "doc.edit" }); // throws on deny
65
+ ```
66
+
67
+ ## API Reference
68
+
69
+ | Method | Kind | Result |
70
+ |--------|------|--------|
71
+ | `defineRole(ctx, { name, grants, description? })` | mutation | Upsert a role (runtime-editable) |
72
+ | `removeRole(ctx, name)` | mutation | Delete a role by name |
73
+ | `assign(ctx, { subjectRef, role, scopeRef? })` | mutation | Grant a role to a subject |
74
+ | `revoke(ctx, { subjectRef, role, scopeRef? })` | mutation | Remove a role from a subject |
75
+ | `check(ctx, { subjectRef, action, scopeRef? })` | query | Boolean permission check (default-deny) |
76
+ | `require(ctx, { subjectRef, action, scopeRef? })` | query | Enforce access — throws on deny |
77
+ | `rolesFor(ctx, { subjectRef, scopeRef? })` | query | List role names for a subject |
78
+ | `permissionsFor(ctx, { subjectRef, scopeRef? })` | query | List distinct grants for a subject |
79
+ | `listRoles(ctx)` | query | All role definitions |
80
+
81
+ Full reference: [docs/API.md](docs/API.md).
82
+
83
+ ## Security
84
+
85
+ - **Host owns auth** — it authenticates the caller, resolves identity to an opaque `subjectRef`, and gates the management methods behind its own admin authorization.
86
+ - **Opaque refs only** — `subjectRef`, `scopeRef`, and action keys are arbitrary strings; tables are sandboxed (reached only via the client).
87
+ - **Default-deny** — no matching grant ⇒ denied; boundary validation rejects refs not matching `^[A-Za-z0-9_.:-]{1,128}$`.
88
+
89
+ See [docs/API.md](docs/API.md).
90
+
91
+ ## Testing
92
+
93
+ ```bash
94
+ pnpm test # single run
95
+ pnpm test:coverage # enforced 100% on covered files
96
+ ```
97
+
98
+ Tests run against the real component runtime via `convex-test` (`@edge-runtime/vm`), not mocks.
99
+
100
+ ## Contributing
101
+
102
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
103
+
104
+ ## Author
105
+
106
+ Built by [bntvllnt](https://github.com/bntvllnt) · [bntvllnt.com](https://bntvllnt.com) · [X @bntvllnt](https://x.com/bntvllnt)
107
+
108
+ Part of the [@vllnt](https://github.com/vllnt) Convex component fleet — [vllnt.com](https://vllnt.com)
109
+
110
+ If this is useful, [sponsor the work](https://github.com/sponsors/bntvllnt).
111
+
112
+ ## License
113
+
114
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,125 @@
1
+ import type { FunctionArgs, FunctionReference, FunctionReturnType } from "convex/server";
2
+ import type { RoleDoc } from "./types.js";
3
+ /**
4
+ * The component's function references, as exposed on the host via
5
+ * `components.permissions`. Hand-written so the client typechecks without the
6
+ * component's generated code — the host supplies the mounted ref.
7
+ */
8
+ export interface PermissionsComponent {
9
+ mutations: {
10
+ defineRole: FunctionReference<"mutation", "internal", {
11
+ name: string;
12
+ grants: string[];
13
+ description?: string;
14
+ }, null>;
15
+ removeRole: FunctionReference<"mutation", "internal", {
16
+ name: string;
17
+ }, boolean>;
18
+ assign: FunctionReference<"mutation", "internal", {
19
+ subjectRef: string;
20
+ role: string;
21
+ scopeRef?: string;
22
+ }, boolean>;
23
+ revoke: FunctionReference<"mutation", "internal", {
24
+ subjectRef: string;
25
+ role: string;
26
+ scopeRef?: string;
27
+ }, boolean>;
28
+ };
29
+ queries: {
30
+ check: FunctionReference<"query", "internal", {
31
+ subjectRef: string;
32
+ action: string;
33
+ scopeRef?: string;
34
+ }, boolean>;
35
+ rolesFor: FunctionReference<"query", "internal", {
36
+ subjectRef: string;
37
+ scopeRef?: string;
38
+ }, string[]>;
39
+ permissionsFor: FunctionReference<"query", "internal", {
40
+ subjectRef: string;
41
+ scopeRef?: string;
42
+ }, string[]>;
43
+ listRoles: FunctionReference<"query", "internal", Record<string, never>, RoleDoc[]>;
44
+ };
45
+ }
46
+ interface RunQueryCtx {
47
+ runQuery<Q extends FunctionReference<"query", "internal">>(reference: Q, args: FunctionArgs<Q>): Promise<FunctionReturnType<Q>>;
48
+ }
49
+ interface RunMutationCtx {
50
+ runMutation<M extends FunctionReference<"mutation", "internal">>(reference: M, args: FunctionArgs<M>): Promise<FunctionReturnType<M>>;
51
+ }
52
+ /** Structured payload thrown by `Permissions.require` on an authorization failure. */
53
+ export interface PermissionDenied {
54
+ code: "FORBIDDEN";
55
+ subjectRef: string;
56
+ action: string;
57
+ scopeRef?: string;
58
+ }
59
+ /**
60
+ * Consumer-facing client for the permissions component. Construct with the
61
+ * mounted component ref, then call from host queries / mutations. The host owns
62
+ * auth — it resolves identity and passes an opaque `subjectRef` in. Generic over
63
+ * the host's role + action unions so checks are typed end to end.
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * type Role = "admin" | "editor" | "viewer";
68
+ * type Action = "doc.read" | "doc.edit" | "doc.delete";
69
+ * const permissions = new Permissions<Role, Action>(components.permissions);
70
+ * await permissions.require(ctx, { subjectRef: userId, action: "doc.edit" });
71
+ * ```
72
+ */
73
+ export declare class Permissions<TRole extends string = string, TAction extends string = string> {
74
+ private readonly component;
75
+ constructor(component: PermissionsComponent);
76
+ /** Create or update a role definition (upsert by name). */
77
+ defineRole(ctx: RunMutationCtx, role: {
78
+ name: TRole;
79
+ grants: readonly (TAction | string)[];
80
+ description?: string;
81
+ }): Promise<null>;
82
+ /** Delete a role definition. Resolves true if a role was removed. */
83
+ removeRole(ctx: RunMutationCtx, name: TRole): Promise<boolean>;
84
+ /** Assign a role to a subject. Resolves true if newly created. */
85
+ assign(ctx: RunMutationCtx, args: {
86
+ subjectRef: string;
87
+ role: TRole;
88
+ scopeRef?: string;
89
+ }): Promise<boolean>;
90
+ /** Remove a role assignment. Resolves true if an assignment was removed. */
91
+ revoke(ctx: RunMutationCtx, args: {
92
+ subjectRef: string;
93
+ role: TRole;
94
+ scopeRef?: string;
95
+ }): Promise<boolean>;
96
+ /** Is the subject authorized to perform the action? */
97
+ check(ctx: RunQueryCtx, args: {
98
+ subjectRef: string;
99
+ action: TAction;
100
+ scopeRef?: string;
101
+ }): Promise<boolean>;
102
+ /**
103
+ * Enforce an action. Throws `ConvexError<PermissionDenied>` when the subject is
104
+ * not authorized — the host can map this to a 403.
105
+ */
106
+ require(ctx: RunQueryCtx, args: {
107
+ subjectRef: string;
108
+ action: TAction;
109
+ scopeRef?: string;
110
+ }): Promise<void>;
111
+ /** Role names the subject holds in the optional scope (sorted). */
112
+ rolesFor(ctx: RunQueryCtx, args: {
113
+ subjectRef: string;
114
+ scopeRef?: string;
115
+ }): Promise<string[]>;
116
+ /** Distinct grants the subject has in the optional scope (sorted). */
117
+ permissionsFor(ctx: RunQueryCtx, args: {
118
+ subjectRef: string;
119
+ scopeRef?: string;
120
+ }): Promise<string[]>;
121
+ /** All role definitions. */
122
+ listRoles(ctx: RunQueryCtx): Promise<RoleDoc[]>;
123
+ }
124
+ export type { RoleDoc };
125
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { ConvexError } from "convex/values";
2
+ /**
3
+ * Consumer-facing client for the permissions component. Construct with the
4
+ * mounted component ref, then call from host queries / mutations. The host owns
5
+ * auth — it resolves identity and passes an opaque `subjectRef` in. Generic over
6
+ * the host's role + action unions so checks are typed end to end.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * type Role = "admin" | "editor" | "viewer";
11
+ * type Action = "doc.read" | "doc.edit" | "doc.delete";
12
+ * const permissions = new Permissions<Role, Action>(components.permissions);
13
+ * await permissions.require(ctx, { subjectRef: userId, action: "doc.edit" });
14
+ * ```
15
+ */
16
+ export class Permissions {
17
+ component;
18
+ constructor(component) {
19
+ this.component = component;
20
+ }
21
+ /** Create or update a role definition (upsert by name). */
22
+ defineRole(ctx, role) {
23
+ return ctx.runMutation(this.component.mutations.defineRole, {
24
+ name: role.name,
25
+ grants: [...role.grants],
26
+ description: role.description,
27
+ });
28
+ }
29
+ /** Delete a role definition. Resolves true if a role was removed. */
30
+ removeRole(ctx, name) {
31
+ return ctx.runMutation(this.component.mutations.removeRole, { name });
32
+ }
33
+ /** Assign a role to a subject. Resolves true if newly created. */
34
+ assign(ctx, args) {
35
+ return ctx.runMutation(this.component.mutations.assign, args);
36
+ }
37
+ /** Remove a role assignment. Resolves true if an assignment was removed. */
38
+ revoke(ctx, args) {
39
+ return ctx.runMutation(this.component.mutations.revoke, args);
40
+ }
41
+ /** Is the subject authorized to perform the action? */
42
+ check(ctx, args) {
43
+ return ctx.runQuery(this.component.queries.check, args);
44
+ }
45
+ /**
46
+ * Enforce an action. Throws `ConvexError<PermissionDenied>` when the subject is
47
+ * not authorized — the host can map this to a 403.
48
+ */
49
+ async require(ctx, args) {
50
+ const allowed = await this.check(ctx, args);
51
+ if (!allowed) {
52
+ // `ConvexError` data must be a Convex `Value`; an inline object literal
53
+ // satisfies that (a named interface would not, lacking an index signature).
54
+ // The shape matches `PermissionDenied`, which consumers use to type catches.
55
+ throw new ConvexError({
56
+ code: "FORBIDDEN",
57
+ subjectRef: args.subjectRef,
58
+ action: args.action,
59
+ scopeRef: args.scopeRef,
60
+ });
61
+ }
62
+ }
63
+ /** Role names the subject holds in the optional scope (sorted). */
64
+ rolesFor(ctx, args) {
65
+ return ctx.runQuery(this.component.queries.rolesFor, args);
66
+ }
67
+ /** Distinct grants the subject has in the optional scope (sorted). */
68
+ permissionsFor(ctx, args) {
69
+ return ctx.runQuery(this.component.queries.permissionsFor, args);
70
+ }
71
+ /** All role definitions. */
72
+ listRoles(ctx) {
73
+ return ctx.runQuery(this.component.queries.listRoles, {});
74
+ }
75
+ }
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAqF5C;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,WAAW;IAIO;IAA7B,YAA6B,SAA+B;QAA/B,cAAS,GAAT,SAAS,CAAsB;IAAG,CAAC;IAEhE,2DAA2D;IAC3D,UAAU,CACR,GAAmB,EACnB,IAAkF;QAElF,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE;YAC1D,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;YACxB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,qEAAqE;IACrE,UAAU,CAAC,GAAmB,EAAE,IAAW;QACzC,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,kEAAkE;IAClE,MAAM,CACJ,GAAmB,EACnB,IAA4D;QAE5D,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChE,CAAC;IAED,4EAA4E;IAC5E,MAAM,CACJ,GAAmB,EACnB,IAA4D;QAE5D,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChE,CAAC;IAED,uDAAuD;IACvD,KAAK,CACH,GAAgB,EAChB,IAAgE;QAEhE,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,CACX,GAAgB,EAChB,IAAgE;QAEhE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,wEAAwE;YACxE,4EAA4E;YAC5E,6EAA6E;YAC7E,MAAM,IAAI,WAAW,CAAC;gBACpB,IAAI,EAAE,WAAW;gBACjB,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,QAAQ,CACN,GAAgB,EAChB,IAA+C;QAE/C,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7D,CAAC;IAED,sEAAsE;IACtE,cAAc,CACZ,GAAgB,EAChB,IAA+C;QAE/C,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,4BAA4B;IAC5B,SAAS,CAAC,GAAgB;QACxB,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ /** Public TypeScript surface for `@vllnt/convex-permissions`. */
2
+ /** A stored role definition, as returned by `Permissions.listRoles`. */
3
+ export interface RoleDoc {
4
+ _id: string;
5
+ _creationTime: number;
6
+ name: string;
7
+ grants: string[];
8
+ description?: string;
9
+ updatedAt: number;
10
+ }
11
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,wEAAwE;AACxE,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,3 @@
1
+ /** Public TypeScript surface for `@vllnt/convex-permissions`. */
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA,iEAAiE"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Generated `api` utility.
3
+ *
4
+ * THIS CODE IS AUTOMATICALLY GENERATED.
5
+ *
6
+ * To regenerate, run `npx convex dev`.
7
+ * @module
8
+ */
9
+ import type * as mutations from "../mutations.js";
10
+ import type * as queries from "../queries.js";
11
+ import type * as validators from "../validators.js";
12
+ import type { ApiFromModules, FilterApi, FunctionReference } from "convex/server";
13
+ declare const fullApi: ApiFromModules<{
14
+ mutations: typeof mutations;
15
+ queries: typeof queries;
16
+ validators: typeof validators;
17
+ }>;
18
+ /**
19
+ * A utility for referencing Convex functions in your app's public API.
20
+ *
21
+ * Usage:
22
+ * ```js
23
+ * const myFunctionReference = api.myModule.myFunction;
24
+ * ```
25
+ */
26
+ export declare const api: FilterApi<typeof fullApi, FunctionReference<any, "public">>;
27
+ /**
28
+ * A utility for referencing Convex functions in your app's internal API.
29
+ *
30
+ * Usage:
31
+ * ```js
32
+ * const myFunctionReference = internal.myModule.myFunction;
33
+ * ```
34
+ */
35
+ export declare const internal: FilterApi<typeof fullApi, FunctionReference<any, "internal">>;
36
+ export declare const components: {};
37
+ export {};
38
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,OAAO,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAGvB,QAAA,MAAM,OAAO,EAAE,cAAc,CAAC;IAC5B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,UAAU,EAAE,OAAO,UAAU,CAAC;CAC/B,CAAiB,CAAC;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,EAAE,SAAS,CACzB,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CACjB,CAAC;AAElB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,CAC9B,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CACnB,CAAC;AAElB,eAAO,MAAM,UAAU,EAAqC,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * Generated `api` utility.
4
+ *
5
+ * THIS CODE IS AUTOMATICALLY GENERATED.
6
+ *
7
+ * To regenerate, run `npx convex dev`.
8
+ * @module
9
+ */
10
+ import { anyApi, componentsGeneric } from "convex/server";
11
+ const fullApi = anyApi;
12
+ /**
13
+ * A utility for referencing Convex functions in your app's public API.
14
+ *
15
+ * Usage:
16
+ * ```js
17
+ * const myFunctionReference = api.myModule.myFunction;
18
+ * ```
19
+ */
20
+ export const api = anyApi;
21
+ /**
22
+ * A utility for referencing Convex functions in your app's internal API.
23
+ *
24
+ * Usage:
25
+ * ```js
26
+ * const myFunctionReference = internal.myModule.myFunction;
27
+ * ```
28
+ */
29
+ export const internal = anyApi;
30
+ export const components = componentsGeneric();
31
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AAWH,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,OAAO,GAIR,MAAa,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAGZ,MAAa,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAGjB,MAAa,CAAC;AAElB,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,EAAmB,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Generated `ComponentApi` utility.
3
+ *
4
+ * THIS CODE IS AUTOMATICALLY GENERATED.
5
+ *
6
+ * To regenerate, run `npx convex dev`.
7
+ * @module
8
+ */
9
+ import type { FunctionReference } from "convex/server";
10
+ /**
11
+ * A utility for referencing a Convex component's exposed API.
12
+ *
13
+ * Useful when expecting a parameter like `components.myComponent`.
14
+ * Usage:
15
+ * ```ts
16
+ * async function myFunction(ctx: QueryCtx, component: ComponentApi) {
17
+ * return ctx.runQuery(component.someFile.someQuery, { ...args });
18
+ * }
19
+ * ```
20
+ */
21
+ export type ComponentApi<Name extends string | undefined = string | undefined> = {
22
+ mutations: {
23
+ assign: FunctionReference<"mutation", "internal", {
24
+ role: string;
25
+ scopeRef?: string;
26
+ subjectRef: string;
27
+ }, boolean, Name>;
28
+ defineRole: FunctionReference<"mutation", "internal", {
29
+ description?: string;
30
+ grants: Array<string>;
31
+ name: string;
32
+ }, null, Name>;
33
+ removeRole: FunctionReference<"mutation", "internal", {
34
+ name: string;
35
+ }, boolean, Name>;
36
+ revoke: FunctionReference<"mutation", "internal", {
37
+ role: string;
38
+ scopeRef?: string;
39
+ subjectRef: string;
40
+ }, boolean, Name>;
41
+ };
42
+ queries: {
43
+ check: FunctionReference<"query", "internal", {
44
+ action: string;
45
+ scopeRef?: string;
46
+ subjectRef: string;
47
+ }, boolean, Name>;
48
+ listRoles: FunctionReference<"query", "internal", {}, Array<{
49
+ _creationTime: number;
50
+ _id: string;
51
+ description?: string;
52
+ grants: Array<string>;
53
+ name: string;
54
+ updatedAt: number;
55
+ }>, Name>;
56
+ permissionsFor: FunctionReference<"query", "internal", {
57
+ scopeRef?: string;
58
+ subjectRef: string;
59
+ }, Array<string>, Name>;
60
+ rolesFor: FunctionReference<"query", "internal", {
61
+ scopeRef?: string;
62
+ subjectRef: string;
63
+ }, Array<string>, Name>;
64
+ };
65
+ };
66
+ //# sourceMappingURL=component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/component.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,CAAC,IAAI,SAAS,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,IAC3E;IACE,SAAS,EAAE;QACT,MAAM,EAAE,iBAAiB,CACvB,UAAU,EACV,UAAU,EACV;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,EACvD,OAAO,EACP,IAAI,CACL,CAAC;QACF,UAAU,EAAE,iBAAiB,CAC3B,UAAU,EACV,UAAU,EACV;YAAE,WAAW,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAC7D,IAAI,EACJ,IAAI,CACL,CAAC;QACF,UAAU,EAAE,iBAAiB,CAC3B,UAAU,EACV,UAAU,EACV;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,EAChB,OAAO,EACP,IAAI,CACL,CAAC;QACF,MAAM,EAAE,iBAAiB,CACvB,UAAU,EACV,UAAU,EACV;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,EACvD,OAAO,EACP,IAAI,CACL,CAAC;KACH,CAAC;IACF,OAAO,EAAE;QACP,KAAK,EAAE,iBAAiB,CACtB,OAAO,EACP,UAAU,EACV;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,EACzD,OAAO,EACP,IAAI,CACL,CAAC;QACF,SAAS,EAAE,iBAAiB,CAC1B,OAAO,EACP,UAAU,EACV,EAAE,EACF,KAAK,CAAC;YACJ,aAAa,EAAE,MAAM,CAAC;YACtB,GAAG,EAAE,MAAM,CAAC;YACZ,WAAW,CAAC,EAAE,MAAM,CAAC;YACrB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YACtB,IAAI,EAAE,MAAM,CAAC;YACb,SAAS,EAAE,MAAM,CAAC;SACnB,CAAC,EACF,IAAI,CACL,CAAC;QACF,cAAc,EAAE,iBAAiB,CAC/B,OAAO,EACP,UAAU,EACV;YAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,EACzC,KAAK,CAAC,MAAM,CAAC,EACb,IAAI,CACL,CAAC;QACF,QAAQ,EAAE,iBAAiB,CACzB,OAAO,EACP,UAAU,EACV;YAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,EACzC,KAAK,CAAC,MAAM,CAAC,EACb,IAAI,CACL,CAAC;KACH,CAAC;CACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * Generated `ComponentApi` utility.
4
+ *
5
+ * THIS CODE IS AUTOMATICALLY GENERATED.
6
+ *
7
+ * To regenerate, run `npx convex dev`.
8
+ * @module
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/component/_generated/component.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Generated data model types.
3
+ *
4
+ * THIS CODE IS AUTOMATICALLY GENERATED.
5
+ *
6
+ * To regenerate, run `npx convex dev`.
7
+ * @module
8
+ */
9
+ import type { DataModelFromSchemaDefinition, DocumentByName, TableNamesInDataModel, SystemTableNames } from "convex/server";
10
+ import type { GenericId } from "convex/values";
11
+ import schema from "../schema.js";
12
+ /**
13
+ * The names of all of your Convex tables.
14
+ */
15
+ export type TableNames = TableNamesInDataModel<DataModel>;
16
+ /**
17
+ * The type of a document stored in Convex.
18
+ *
19
+ * @typeParam TableName - A string literal type of the table name (like "users").
20
+ */
21
+ export type Doc<TableName extends TableNames> = DocumentByName<DataModel, TableName>;
22
+ /**
23
+ * An identifier for a document in Convex.
24
+ *
25
+ * Convex documents are uniquely identified by their `Id`, which is accessible
26
+ * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids).
27
+ *
28
+ * Documents can be loaded using `db.get(tableName, id)` in query and mutation functions.
29
+ *
30
+ * IDs are just strings at runtime, but this type can be used to distinguish them from other
31
+ * strings when type checking.
32
+ *
33
+ * @typeParam TableName - A string literal type of the table name (like "users").
34
+ */
35
+ export type Id<TableName extends TableNames | SystemTableNames> = GenericId<TableName>;
36
+ /**
37
+ * A type describing your Convex data model.
38
+ *
39
+ * This type includes information about what tables you have, the type of
40
+ * documents stored in those tables, and the indexes defined on them.
41
+ *
42
+ * This type is used to parameterize methods like `queryGeneric` and
43
+ * `mutationGeneric` to make them type-safe.
44
+ */
45
+ export type DataModel = DataModelFromSchemaDefinition<typeof schema>;
46
+ //# sourceMappingURL=dataModel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataModel.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/dataModel.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,6BAA6B,EAC7B,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,MAAM,MAAM,cAAc,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;AAE1D;;;;GAIG;AACH,MAAM,MAAM,GAAG,CAAC,SAAS,SAAS,UAAU,IAAI,cAAc,CAC5D,SAAS,EACT,SAAS,CACV,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,EAAE,CAAC,SAAS,SAAS,UAAU,GAAG,gBAAgB,IAC5D,SAAS,CAAC,SAAS,CAAC,CAAC;AAEvB;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG,6BAA6B,CAAC,OAAO,MAAM,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * Generated data model types.
4
+ *
5
+ * THIS CODE IS AUTOMATICALLY GENERATED.
6
+ *
7
+ * To regenerate, run `npx convex dev`.
8
+ * @module
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=dataModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataModel.js","sourceRoot":"","sources":["../../../src/component/_generated/dataModel.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG"}