@classytic/arc 1.1.0 → 2.1.3

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 (200) hide show
  1. package/README.md +247 -794
  2. package/bin/arc.js +91 -52
  3. package/dist/EventTransport-BkUDYZEb.d.mts +99 -0
  4. package/dist/HookSystem-BsGV-j2l.mjs +404 -0
  5. package/dist/ResourceRegistry-7Ic20ZMw.mjs +249 -0
  6. package/dist/adapters/index.d.mts +5 -0
  7. package/dist/adapters/index.mjs +3 -0
  8. package/dist/audit/index.d.mts +81 -0
  9. package/dist/audit/index.mjs +275 -0
  10. package/dist/audit/mongodb.d.mts +5 -0
  11. package/dist/audit/mongodb.mjs +3 -0
  12. package/dist/audited-CGdLiSlE.mjs +140 -0
  13. package/dist/auth/index.d.mts +188 -0
  14. package/dist/auth/index.mjs +1096 -0
  15. package/dist/auth/redis-session.d.mts +43 -0
  16. package/dist/auth/redis-session.mjs +75 -0
  17. package/dist/betterAuthOpenApi-DjWDddNc.mjs +249 -0
  18. package/dist/cache/index.d.mts +145 -0
  19. package/dist/cache/index.mjs +91 -0
  20. package/dist/caching-GSDJcA6-.mjs +93 -0
  21. package/dist/chunk-C7Uep-_p.mjs +20 -0
  22. package/dist/circuitBreaker-DYhWBW_D.mjs +1096 -0
  23. package/dist/cli/commands/describe.d.mts +18 -0
  24. package/dist/cli/commands/describe.mjs +238 -0
  25. package/dist/cli/commands/docs.d.mts +13 -0
  26. package/dist/cli/commands/docs.mjs +52 -0
  27. package/dist/cli/commands/{generate.d.ts → generate.d.mts} +3 -2
  28. package/dist/cli/commands/generate.mjs +357 -0
  29. package/dist/cli/commands/{init.d.ts → init.d.mts} +11 -8
  30. package/dist/cli/commands/{init.js → init.mjs} +807 -617
  31. package/dist/cli/commands/introspect.d.mts +10 -0
  32. package/dist/cli/commands/introspect.mjs +75 -0
  33. package/dist/cli/index.d.mts +16 -0
  34. package/dist/cli/index.mjs +156 -0
  35. package/dist/constants-DdXFXQtN.mjs +84 -0
  36. package/dist/core/index.d.mts +5 -0
  37. package/dist/core/index.mjs +4 -0
  38. package/dist/createApp-D2D5XXaV.mjs +559 -0
  39. package/dist/defineResource-PXzSJ15_.mjs +2197 -0
  40. package/dist/discovery/index.d.mts +46 -0
  41. package/dist/discovery/index.mjs +109 -0
  42. package/dist/docs/index.d.mts +162 -0
  43. package/dist/docs/index.mjs +74 -0
  44. package/dist/elevation-DGo5shaX.d.mts +87 -0
  45. package/dist/elevation-DSTbVvYj.mjs +113 -0
  46. package/dist/errorHandler-C3GY3_ow.mjs +108 -0
  47. package/dist/errorHandler-CW3OOeYq.d.mts +72 -0
  48. package/dist/errors-DAWRdiYP.d.mts +124 -0
  49. package/dist/errors-DBANPbGr.mjs +211 -0
  50. package/dist/eventPlugin-BEOvaDqo.mjs +229 -0
  51. package/dist/eventPlugin-H6wDDjGO.d.mts +124 -0
  52. package/dist/events/index.d.mts +53 -0
  53. package/dist/events/index.mjs +51 -0
  54. package/dist/events/transports/redis-stream-entry.d.mts +2 -0
  55. package/dist/events/transports/redis-stream-entry.mjs +177 -0
  56. package/dist/events/transports/redis.d.mts +76 -0
  57. package/dist/events/transports/redis.mjs +124 -0
  58. package/dist/externalPaths-SyPF2tgK.d.mts +50 -0
  59. package/dist/factory/index.d.mts +63 -0
  60. package/dist/factory/index.mjs +3 -0
  61. package/dist/fastifyAdapter-C8DlE0YH.d.mts +216 -0
  62. package/dist/fields-Bi_AVKSo.d.mts +109 -0
  63. package/dist/fields-CTd_CrKr.mjs +114 -0
  64. package/dist/hooks/index.d.mts +4 -0
  65. package/dist/hooks/index.mjs +3 -0
  66. package/dist/idempotency/index.d.mts +96 -0
  67. package/dist/idempotency/index.mjs +319 -0
  68. package/dist/idempotency/mongodb.d.mts +2 -0
  69. package/dist/idempotency/mongodb.mjs +114 -0
  70. package/dist/idempotency/redis.d.mts +2 -0
  71. package/dist/idempotency/redis.mjs +103 -0
  72. package/dist/index.d.mts +260 -0
  73. package/dist/index.mjs +104 -0
  74. package/dist/integrations/event-gateway.d.mts +46 -0
  75. package/dist/integrations/event-gateway.mjs +43 -0
  76. package/dist/integrations/index.d.mts +5 -0
  77. package/dist/integrations/index.mjs +1 -0
  78. package/dist/integrations/jobs.d.mts +103 -0
  79. package/dist/integrations/jobs.mjs +123 -0
  80. package/dist/integrations/streamline.d.mts +60 -0
  81. package/dist/integrations/streamline.mjs +125 -0
  82. package/dist/integrations/websocket.d.mts +82 -0
  83. package/dist/integrations/websocket.mjs +288 -0
  84. package/dist/interface-CSNjltAc.d.mts +77 -0
  85. package/dist/interface-DTbsvIWe.d.mts +54 -0
  86. package/dist/interface-e9XfSsUV.d.mts +1097 -0
  87. package/dist/introspectionPlugin-B3JkrjwU.mjs +53 -0
  88. package/dist/keys-DhqDRxv3.mjs +42 -0
  89. package/dist/logger-ByrvQWZO.mjs +78 -0
  90. package/dist/memory-B2v7KrCB.mjs +143 -0
  91. package/dist/migrations/index.d.mts +156 -0
  92. package/dist/migrations/index.mjs +260 -0
  93. package/dist/mongodb-ClykrfGo.d.mts +118 -0
  94. package/dist/mongodb-DNKEExbf.mjs +93 -0
  95. package/dist/mongodb-Dg8O_gvd.d.mts +71 -0
  96. package/dist/openapi-9nB_kiuR.mjs +525 -0
  97. package/dist/org/index.d.mts +68 -0
  98. package/dist/org/index.mjs +513 -0
  99. package/dist/org/types.d.mts +82 -0
  100. package/dist/org/types.mjs +1 -0
  101. package/dist/permissions/index.d.mts +278 -0
  102. package/dist/permissions/index.mjs +579 -0
  103. package/dist/plugins/index.d.mts +172 -0
  104. package/dist/plugins/index.mjs +522 -0
  105. package/dist/plugins/response-cache.d.mts +87 -0
  106. package/dist/plugins/response-cache.mjs +283 -0
  107. package/dist/plugins/tracing-entry.d.mts +2 -0
  108. package/dist/plugins/tracing-entry.mjs +185 -0
  109. package/dist/pluralize-CM-jZg7p.mjs +86 -0
  110. package/dist/policies/{index.d.ts → index.d.mts} +204 -170
  111. package/dist/policies/index.mjs +321 -0
  112. package/dist/presets/{index.d.ts → index.d.mts} +62 -131
  113. package/dist/presets/index.mjs +143 -0
  114. package/dist/presets/multiTenant.d.mts +24 -0
  115. package/dist/presets/multiTenant.mjs +113 -0
  116. package/dist/presets-BTeYbw7h.d.mts +57 -0
  117. package/dist/presets-CeFtfDR8.mjs +119 -0
  118. package/dist/prisma-C3iornoK.d.mts +274 -0
  119. package/dist/prisma-DJbMt3yf.mjs +627 -0
  120. package/dist/queryCachePlugin-B6R0d4av.mjs +138 -0
  121. package/dist/queryCachePlugin-Q6SYuHZ6.d.mts +71 -0
  122. package/dist/redis-UwjEp8Ea.d.mts +49 -0
  123. package/dist/redis-stream-CBg0upHI.d.mts +103 -0
  124. package/dist/registry/index.d.mts +11 -0
  125. package/dist/registry/index.mjs +4 -0
  126. package/dist/requestContext-xi6OKBL-.mjs +55 -0
  127. package/dist/schemaConverter-Dtg0Kt9T.mjs +98 -0
  128. package/dist/schemas/index.d.mts +63 -0
  129. package/dist/schemas/index.mjs +82 -0
  130. package/dist/scope/index.d.mts +21 -0
  131. package/dist/scope/index.mjs +65 -0
  132. package/dist/sessionManager-D_iEHjQl.d.mts +186 -0
  133. package/dist/sse-DkqQ1uxb.mjs +123 -0
  134. package/dist/testing/index.d.mts +907 -0
  135. package/dist/testing/index.mjs +1976 -0
  136. package/dist/tracing-8CEbhF0w.d.mts +70 -0
  137. package/dist/typeGuards-DwxA1t_L.mjs +9 -0
  138. package/dist/types/index.d.mts +946 -0
  139. package/dist/types/index.mjs +14 -0
  140. package/dist/types-B0dhNrnd.d.mts +445 -0
  141. package/dist/types-Beqn1Un7.mjs +38 -0
  142. package/dist/types-DelU6kln.mjs +25 -0
  143. package/dist/types-RLkFVgaw.d.mts +101 -0
  144. package/dist/utils/index.d.mts +747 -0
  145. package/dist/utils/index.mjs +6 -0
  146. package/package.json +194 -68
  147. package/dist/BaseController-DVAiHxEQ.d.ts +0 -233
  148. package/dist/adapters/index.d.ts +0 -237
  149. package/dist/adapters/index.js +0 -668
  150. package/dist/arcCorePlugin-CsShQdyP.d.ts +0 -273
  151. package/dist/audit/index.d.ts +0 -195
  152. package/dist/audit/index.js +0 -319
  153. package/dist/auth/index.d.ts +0 -47
  154. package/dist/auth/index.js +0 -174
  155. package/dist/cli/commands/docs.d.ts +0 -11
  156. package/dist/cli/commands/docs.js +0 -474
  157. package/dist/cli/commands/generate.js +0 -334
  158. package/dist/cli/commands/introspect.d.ts +0 -8
  159. package/dist/cli/commands/introspect.js +0 -338
  160. package/dist/cli/index.d.ts +0 -4
  161. package/dist/cli/index.js +0 -3269
  162. package/dist/core/index.d.ts +0 -220
  163. package/dist/core/index.js +0 -2786
  164. package/dist/createApp-Ce9wl8W9.d.ts +0 -77
  165. package/dist/docs/index.d.ts +0 -166
  166. package/dist/docs/index.js +0 -658
  167. package/dist/errors-8WIxGS_6.d.ts +0 -122
  168. package/dist/events/index.d.ts +0 -117
  169. package/dist/events/index.js +0 -89
  170. package/dist/factory/index.d.ts +0 -38
  171. package/dist/factory/index.js +0 -1652
  172. package/dist/hooks/index.d.ts +0 -4
  173. package/dist/hooks/index.js +0 -199
  174. package/dist/idempotency/index.d.ts +0 -323
  175. package/dist/idempotency/index.js +0 -500
  176. package/dist/index-B4t03KQ0.d.ts +0 -1366
  177. package/dist/index.d.ts +0 -135
  178. package/dist/index.js +0 -4756
  179. package/dist/migrations/index.d.ts +0 -185
  180. package/dist/migrations/index.js +0 -274
  181. package/dist/org/index.d.ts +0 -129
  182. package/dist/org/index.js +0 -220
  183. package/dist/permissions/index.d.ts +0 -144
  184. package/dist/permissions/index.js +0 -103
  185. package/dist/plugins/index.d.ts +0 -46
  186. package/dist/plugins/index.js +0 -1069
  187. package/dist/policies/index.js +0 -196
  188. package/dist/presets/index.js +0 -384
  189. package/dist/presets/multiTenant.d.ts +0 -39
  190. package/dist/presets/multiTenant.js +0 -112
  191. package/dist/registry/index.d.ts +0 -16
  192. package/dist/registry/index.js +0 -253
  193. package/dist/testing/index.d.ts +0 -618
  194. package/dist/testing/index.js +0 -48020
  195. package/dist/types/index.d.ts +0 -4
  196. package/dist/types/index.js +0 -8
  197. package/dist/types-B99TBmFV.d.ts +0 -76
  198. package/dist/types-BvckRbs2.d.ts +0 -143
  199. package/dist/utils/index.d.ts +0 -679
  200. package/dist/utils/index.js +0 -931
@@ -1,130 +1,91 @@
1
- import { FastifyRequest, FastifyReply } from 'fastify';
2
-
3
- /**
4
- * Policy Interface
5
- *
6
- * Pluggable authorization interface for Arc.
7
- * Apps implement this interface to define custom authorization strategies.
8
- *
9
- * @example RBAC Policy
10
- * ```typescript
11
- * class RBACPolicy implements PolicyEngine {
12
- * can(user, operation, context) {
13
- * return {
14
- * allowed: user.roles.includes('admin'),
15
- * reason: 'Admin role required',
16
- * };
17
- * }
18
- * toMiddleware(operation) {
19
- * return async (request, reply) => {
20
- * const result = await this.can(request.user, operation);
21
- * if (!result.allowed) {
22
- * reply.code(403).send({ error: result.reason });
23
- * }
24
- * };
25
- * }
26
- * }
27
- * ```
28
- *
29
- * @example ABAC (Attribute-Based) Policy
30
- * ```typescript
31
- * class ABACPolicy implements PolicyEngine {
32
- * can(user, operation, context) {
33
- * return {
34
- * allowed: this.evaluateAttributes(user, operation, context),
35
- * filters: { department: user.department },
36
- * fieldMask: { exclude: ['salary', 'ssn'] },
37
- * };
38
- * }
39
- * // ...
40
- * }
41
- * ```
42
- */
1
+ import { t as PermissionCheck } from "../types-RLkFVgaw.mjs";
2
+ import { FastifyReply, FastifyRequest } from "fastify";
43
3
 
4
+ //#region src/policies/PolicyInterface.d.ts
44
5
  /**
45
6
  * Policy result returned by can() method
46
7
  */
47
8
  interface PolicyResult {
48
- /**
49
- * Whether the operation is allowed
50
- */
51
- allowed: boolean;
52
- /**
53
- * Human-readable reason if denied
54
- * Returned in 403 error responses
55
- */
56
- reason?: string;
57
- /**
58
- * Query filters to apply (for list operations)
59
- *
60
- * @example
61
- * ```typescript
62
- * // Multi-tenant filter
63
- * { organizationId: user.organizationId }
64
- *
65
- * // Ownership filter
66
- * { userId: user.id }
67
- *
68
- * // Complex filter
69
- * { $or: [{ public: true }, { createdBy: user.id }] }
70
- * ```
71
- */
72
- filters?: Record<string, any>;
73
- /**
74
- * Fields to include/exclude in response
75
- *
76
- * @example
77
- * ```typescript
78
- * // Hide sensitive fields from non-admins
79
- * { exclude: ['password', 'ssn', 'salary'] }
80
- *
81
- * // Only show specific fields
82
- * { include: ['name', 'email', 'role'] }
83
- * ```
84
- */
85
- fieldMask?: {
86
- include?: string[];
87
- exclude?: string[];
88
- };
89
- /**
90
- * Additional context for downstream middleware
91
- *
92
- * @example
93
- * ```typescript
94
- * {
95
- * auditLog: { action: 'read', resource: 'patient', userId: user.id },
96
- * rateLimit: { tier: user.subscriptionTier },
97
- * }
98
- * ```
99
- */
100
- metadata?: Record<string, any>;
9
+ /**
10
+ * Whether the operation is allowed
11
+ */
12
+ allowed: boolean;
13
+ /**
14
+ * Human-readable reason if denied
15
+ * Returned in 403 error responses
16
+ */
17
+ reason?: string;
18
+ /**
19
+ * Query filters to apply (for list operations)
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // Multi-tenant filter
24
+ * { organizationId: user.organizationId }
25
+ *
26
+ * // Ownership filter
27
+ * { userId: user.id }
28
+ *
29
+ * // Complex filter
30
+ * { $or: [{ public: true }, { createdBy: user.id }] }
31
+ * ```
32
+ */
33
+ filters?: Record<string, any>;
34
+ /**
35
+ * Fields to include/exclude in response
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // Hide sensitive fields from non-admins
40
+ * { exclude: ['password', 'ssn', 'salary'] }
41
+ *
42
+ * // Only show specific fields
43
+ * { include: ['name', 'email', 'role'] }
44
+ * ```
45
+ */
46
+ fieldMask?: {
47
+ include?: string[];
48
+ exclude?: string[];
49
+ };
50
+ /**
51
+ * Additional context for downstream middleware
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * {
56
+ * auditLog: { action: 'read', resource: 'patient', userId: user.id },
57
+ * rateLimit: { tier: user.subscriptionTier },
58
+ * }
59
+ * ```
60
+ */
61
+ metadata?: Record<string, any>;
101
62
  }
102
63
  /**
103
64
  * Policy context provided to can() method
104
65
  */
105
66
  interface PolicyContext {
106
- /**
107
- * The document being accessed (for update/delete/get)
108
- * Populated by fetchDocument middleware
109
- */
110
- document?: any;
111
- /**
112
- * Request body (for create/update)
113
- */
114
- body?: any;
115
- /**
116
- * Request params (e.g., :id from route)
117
- */
118
- params?: any;
119
- /**
120
- * Request query parameters
121
- */
122
- query?: any;
123
- /**
124
- * Additional app-specific context
125
- * Can include anything your policy needs to make decisions
126
- */
127
- [key: string]: any;
67
+ /**
68
+ * The document being accessed (for update/delete/get)
69
+ * Populated by fetchDocument middleware
70
+ */
71
+ document?: any;
72
+ /**
73
+ * Request body (for create/update)
74
+ */
75
+ body?: any;
76
+ /**
77
+ * Request params (e.g., :id from route)
78
+ */
79
+ params?: any;
80
+ /**
81
+ * Request query parameters
82
+ */
83
+ query?: any;
84
+ /**
85
+ * Additional app-specific context
86
+ * Can include anything your policy needs to make decisions
87
+ */
88
+ [key: string]: any;
128
89
  }
129
90
  /**
130
91
  * Policy Engine Interface
@@ -145,7 +106,7 @@ interface PolicyContext {
145
106
  * can(user, operation, context) {
146
107
  * // Check RBAC
147
108
  * const allowedRoles = this.config.roles[operation] || [];
148
- * if (!user.roles.some(r => allowedRoles.includes(r))) {
109
+ * if (!getUserRoles(user).some(r => allowedRoles.includes(r))) {
149
110
  * return { allowed: false, reason: 'Insufficient permissions' };
150
111
  * }
151
112
  *
@@ -212,48 +173,48 @@ interface PolicyContext {
212
173
  * ```
213
174
  */
214
175
  interface PolicyEngine {
215
- /**
216
- * Check if user can perform operation
217
- *
218
- * @param user - User object from request (request.user)
219
- * @param operation - Operation name (list, get, create, update, delete, custom)
220
- * @param context - Additional context (document, body, params, query, etc.)
221
- * @returns Policy result with allowed/denied and optional filters/fieldMask
222
- *
223
- * @example
224
- * ```typescript
225
- * const result = await policy.can(request.user, 'update', {
226
- * document: existingDocument,
227
- * body: request.body,
228
- * });
229
- *
230
- * if (!result.allowed) {
231
- * throw new Error(result.reason);
232
- * }
233
- * ```
234
- */
235
- can(user: any, operation: string, context?: PolicyContext): PolicyResult | Promise<PolicyResult>;
236
- /**
237
- * Generate Fastify middleware for this policy
238
- *
239
- * Called during route registration to create preHandler middleware.
240
- * Middleware should:
241
- * 1. Call can() with request context
242
- * 2. Return 403 if denied
243
- * 3. Attach result to request for downstream use
244
- *
245
- * @param operation - Operation name (list, get, create, update, delete)
246
- * @returns Fastify preHandler middleware
247
- *
248
- * @example
249
- * ```typescript
250
- * const middleware = policy.toMiddleware('update');
251
- * fastify.put('/products/:id', {
252
- * preHandler: [authenticate, middleware],
253
- * }, handler);
254
- * ```
255
- */
256
- toMiddleware(operation: string): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
176
+ /**
177
+ * Check if user can perform operation
178
+ *
179
+ * @param user - User object from request (request.user)
180
+ * @param operation - Operation name (list, get, create, update, delete, custom)
181
+ * @param context - Additional context (document, body, params, query, etc.)
182
+ * @returns Policy result with allowed/denied and optional filters/fieldMask
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * const result = await policy.can(request.user, 'update', {
187
+ * document: existingDocument,
188
+ * body: request.body,
189
+ * });
190
+ *
191
+ * if (!result.allowed) {
192
+ * throw new Error(result.reason);
193
+ * }
194
+ * ```
195
+ */
196
+ can(user: any, operation: string, context?: PolicyContext): PolicyResult | Promise<PolicyResult>;
197
+ /**
198
+ * Generate Fastify middleware for this policy
199
+ *
200
+ * Called during route registration to create preHandler middleware.
201
+ * Middleware should:
202
+ * 1. Call can() with request context
203
+ * 2. Return 403 if denied
204
+ * 3. Attach result to request for downstream use
205
+ *
206
+ * @param operation - Operation name (list, get, create, update, delete)
207
+ * @returns Fastify preHandler middleware
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * const middleware = policy.toMiddleware('update');
212
+ * fastify.put('/products/:id', {
213
+ * preHandler: [authenticate, middleware],
214
+ * }, handler);
215
+ * ```
216
+ */
217
+ toMiddleware(operation: string): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
257
218
  }
258
219
  /**
259
220
  * Policy factory function signature
@@ -278,18 +239,91 @@ type PolicyFactory<TConfig = any> = (config: TConfig) => PolicyEngine;
278
239
  /**
279
240
  * Extended Fastify request with policy result
280
241
  */
281
- declare module 'fastify' {
282
- interface FastifyRequest {
283
- policyResult?: PolicyResult;
284
- }
242
+ /**
243
+ * Access control statement
244
+ *
245
+ * Maps to Better Auth's organization permission model
246
+ * where permissions are defined as resource + action pairs.
247
+ */
248
+ interface AccessControlStatement {
249
+ /** Resource name (e.g., 'product', 'order') */
250
+ resource: string;
251
+ /** Allowed actions on this resource */
252
+ action: string[];
285
253
  }
286
-
287
254
  /**
288
- * Policy Helper Utilities
255
+ * Options for createAccessControlPolicy
256
+ */
257
+ interface AccessControlPolicyOptions {
258
+ /** Permission statements defining resource-action pairs */
259
+ statements: AccessControlStatement[];
260
+ /**
261
+ * Optional async permission check against external source (e.g., org role permissions).
262
+ * Called when the static statements allow the action — use this for dynamic checks
263
+ * like verifying the user's org role actually grants the permission.
264
+ *
265
+ * @param userId - ID of the user
266
+ * @param resource - Resource being accessed
267
+ * @param action - Action being performed
268
+ * @returns Whether the user has the permission
269
+ */
270
+ checkPermission?: (userId: string, resource: string, action: string) => Promise<boolean>;
271
+ }
272
+ /**
273
+ * Create a PermissionCheck from access control statements.
274
+ *
275
+ * Maps Better Auth's statement-based access control model to Arc's
276
+ * PermissionCheck function, which can be used directly in resource permissions.
277
+ *
278
+ * The returned PermissionCheck:
279
+ * 1. Looks up the resource + action in the statements list
280
+ * 2. If no matching statement exists, denies access
281
+ * 3. If a matching statement exists and `checkPermission` is provided,
282
+ * calls it for dynamic verification (e.g., check org role)
283
+ * 4. If `checkPermission` is not provided, allows access based on static statements
284
+ *
285
+ * @example Static statements only
286
+ * ```typescript
287
+ * import { createAccessControlPolicy } from '@classytic/arc/policies';
289
288
  *
290
- * Common operations for working with PolicyEngine implementations.
289
+ * const editorPermissions = createAccessControlPolicy({
290
+ * statements: [
291
+ * { resource: 'product', action: ['create', 'update'] },
292
+ * { resource: 'order', action: ['read'] },
293
+ * ],
294
+ * });
295
+ *
296
+ * // Use in resource config
297
+ * defineResource({
298
+ * name: 'product',
299
+ * permissions: {
300
+ * create: editorPermissions,
301
+ * update: editorPermissions,
302
+ * },
303
+ * });
304
+ * ```
305
+ *
306
+ * @example With dynamic permission check (Better Auth org roles)
307
+ * ```typescript
308
+ * const policy = createAccessControlPolicy({
309
+ * statements: [
310
+ * { resource: 'product', action: ['create', 'update'] },
311
+ * { resource: 'order', action: ['read'] },
312
+ * ],
313
+ * checkPermission: async (userId, resource, action) => {
314
+ * return hasOrgPermission(userId, resource, action);
315
+ * },
316
+ * });
317
+ * ```
291
318
  */
292
-
319
+ declare function createAccessControlPolicy(options: AccessControlPolicyOptions): PermissionCheck;
320
+ declare module 'fastify' {
321
+ interface FastifyRequest {
322
+ policyResult?: PolicyResult;
323
+ }
324
+ }
325
+ //#endregion
326
+ //#region src/policies/helpers.d.ts
293
327
  /**
294
328
  * Helper to create Fastify middleware from any PolicyEngine implementation
295
329
  *
@@ -394,5 +428,5 @@ declare function allowAll(): PolicyEngine;
394
428
  * ```
395
429
  */
396
430
  declare function denyAll(reason?: string): PolicyEngine;
397
-
398
- export { type PolicyContext, type PolicyEngine, type PolicyFactory, type PolicyResult, allowAll, anyPolicy, combinePolicies, createPolicyMiddleware, denyAll };
431
+ //#endregion
432
+ export { type AccessControlPolicyOptions, type AccessControlStatement, type PolicyContext, type PolicyEngine, type PolicyFactory, type PolicyResult, allowAll, anyPolicy, combinePolicies, createAccessControlPolicy, createPolicyMiddleware, denyAll };