@classytic/arc 1.1.0 → 2.1.2

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 (322) hide show
  1. package/README.md +247 -794
  2. package/bin/arc.js +91 -52
  3. package/dist/EventTransport-BD2U0BTc.d.mts +100 -0
  4. package/dist/EventTransport-BD2U0BTc.d.mts.map +1 -0
  5. package/dist/HookSystem-BsGV-j2l.mjs +405 -0
  6. package/dist/HookSystem-BsGV-j2l.mjs.map +1 -0
  7. package/dist/ResourceRegistry-DsN4KJjV.mjs +250 -0
  8. package/dist/ResourceRegistry-DsN4KJjV.mjs.map +1 -0
  9. package/dist/adapters/index.d.mts +5 -0
  10. package/dist/adapters/index.mjs +3 -0
  11. package/dist/audit/index.d.mts +82 -0
  12. package/dist/audit/index.d.mts.map +1 -0
  13. package/dist/audit/index.mjs +276 -0
  14. package/dist/audit/index.mjs.map +1 -0
  15. package/dist/audit/mongodb.d.mts +5 -0
  16. package/dist/audit/mongodb.mjs +3 -0
  17. package/dist/audited-C3T5DTUx.mjs +141 -0
  18. package/dist/audited-C3T5DTUx.mjs.map +1 -0
  19. package/dist/auth/index.d.mts +189 -0
  20. package/dist/auth/index.d.mts.map +1 -0
  21. package/dist/auth/index.mjs +1102 -0
  22. package/dist/auth/index.mjs.map +1 -0
  23. package/dist/auth/redis-session.d.mts +44 -0
  24. package/dist/auth/redis-session.d.mts.map +1 -0
  25. package/dist/auth/redis-session.mjs +76 -0
  26. package/dist/auth/redis-session.mjs.map +1 -0
  27. package/dist/betterAuthOpenApi-BrHKeSAx.mjs +250 -0
  28. package/dist/betterAuthOpenApi-BrHKeSAx.mjs.map +1 -0
  29. package/dist/cache/index.d.mts +146 -0
  30. package/dist/cache/index.d.mts.map +1 -0
  31. package/dist/cache/index.mjs +92 -0
  32. package/dist/cache/index.mjs.map +1 -0
  33. package/dist/caching-Bl28lYsR.mjs +94 -0
  34. package/dist/caching-Bl28lYsR.mjs.map +1 -0
  35. package/dist/chunk-C7Uep-_p.mjs +20 -0
  36. package/dist/circuitBreaker-DeY4FCjs.mjs +1097 -0
  37. package/dist/circuitBreaker-DeY4FCjs.mjs.map +1 -0
  38. package/dist/cli/commands/describe.d.mts +19 -0
  39. package/dist/cli/commands/describe.d.mts.map +1 -0
  40. package/dist/cli/commands/describe.mjs +239 -0
  41. package/dist/cli/commands/describe.mjs.map +1 -0
  42. package/dist/cli/commands/docs.d.mts +14 -0
  43. package/dist/cli/commands/docs.d.mts.map +1 -0
  44. package/dist/cli/commands/docs.mjs +53 -0
  45. package/dist/cli/commands/docs.mjs.map +1 -0
  46. package/dist/cli/commands/{generate.d.ts → generate.d.mts} +3 -1
  47. package/dist/cli/commands/generate.d.mts.map +1 -0
  48. package/dist/cli/commands/generate.mjs +358 -0
  49. package/dist/cli/commands/generate.mjs.map +1 -0
  50. package/dist/cli/commands/{init.d.ts → init.d.mts} +12 -8
  51. package/dist/cli/commands/init.d.mts.map +1 -0
  52. package/dist/cli/commands/{init.js → init.mjs} +807 -616
  53. package/dist/cli/commands/init.mjs.map +1 -0
  54. package/dist/cli/commands/introspect.d.mts +11 -0
  55. package/dist/cli/commands/introspect.d.mts.map +1 -0
  56. package/dist/cli/commands/introspect.mjs +76 -0
  57. package/dist/cli/commands/introspect.mjs.map +1 -0
  58. package/dist/cli/index.d.mts +17 -0
  59. package/dist/cli/index.d.mts.map +1 -0
  60. package/dist/cli/index.mjs +157 -0
  61. package/dist/cli/index.mjs.map +1 -0
  62. package/dist/constants-DdXFXQtN.mjs +85 -0
  63. package/dist/constants-DdXFXQtN.mjs.map +1 -0
  64. package/dist/core/index.d.mts +5 -0
  65. package/dist/core/index.mjs +4 -0
  66. package/dist/createApp-CUgNqegw.mjs +560 -0
  67. package/dist/createApp-CUgNqegw.mjs.map +1 -0
  68. package/dist/defineResource-k0_BDn8v.mjs +2197 -0
  69. package/dist/defineResource-k0_BDn8v.mjs.map +1 -0
  70. package/dist/discovery/index.d.mts +47 -0
  71. package/dist/discovery/index.d.mts.map +1 -0
  72. package/dist/discovery/index.mjs +110 -0
  73. package/dist/discovery/index.mjs.map +1 -0
  74. package/dist/docs/index.d.mts +163 -0
  75. package/dist/docs/index.d.mts.map +1 -0
  76. package/dist/docs/index.mjs +73 -0
  77. package/dist/docs/index.mjs.map +1 -0
  78. package/dist/elevation-BRy3yFWT.mjs +113 -0
  79. package/dist/elevation-BRy3yFWT.mjs.map +1 -0
  80. package/dist/elevation-B_2dRLVP.d.mts +88 -0
  81. package/dist/elevation-B_2dRLVP.d.mts.map +1 -0
  82. package/dist/errorHandler-BbcgBmIH.d.mts +73 -0
  83. package/dist/errorHandler-BbcgBmIH.d.mts.map +1 -0
  84. package/dist/errorHandler-C1okiriz.mjs +109 -0
  85. package/dist/errorHandler-C1okiriz.mjs.map +1 -0
  86. package/dist/errors-B9bZok84.mjs +212 -0
  87. package/dist/errors-B9bZok84.mjs.map +1 -0
  88. package/dist/errors-ChKiFz62.d.mts +125 -0
  89. package/dist/errors-ChKiFz62.d.mts.map +1 -0
  90. package/dist/eventPlugin-CTrLH3mt.d.mts +125 -0
  91. package/dist/eventPlugin-CTrLH3mt.d.mts.map +1 -0
  92. package/dist/eventPlugin-DGR_B2on.mjs +230 -0
  93. package/dist/eventPlugin-DGR_B2on.mjs.map +1 -0
  94. package/dist/events/index.d.mts +54 -0
  95. package/dist/events/index.d.mts.map +1 -0
  96. package/dist/events/index.mjs +52 -0
  97. package/dist/events/index.mjs.map +1 -0
  98. package/dist/events/transports/redis-stream-entry.d.mts +2 -0
  99. package/dist/events/transports/redis-stream-entry.mjs +178 -0
  100. package/dist/events/transports/redis-stream-entry.mjs.map +1 -0
  101. package/dist/events/transports/redis.d.mts +77 -0
  102. package/dist/events/transports/redis.d.mts.map +1 -0
  103. package/dist/events/transports/redis.mjs +125 -0
  104. package/dist/events/transports/redis.mjs.map +1 -0
  105. package/dist/externalPaths-DlINfKbP.d.mts +51 -0
  106. package/dist/externalPaths-DlINfKbP.d.mts.map +1 -0
  107. package/dist/factory/index.d.mts +64 -0
  108. package/dist/factory/index.d.mts.map +1 -0
  109. package/dist/factory/index.mjs +3 -0
  110. package/dist/fastifyAdapter-BkrGrlFi.d.mts +217 -0
  111. package/dist/fastifyAdapter-BkrGrlFi.d.mts.map +1 -0
  112. package/dist/fields-DyaDVX4J.d.mts +110 -0
  113. package/dist/fields-DyaDVX4J.d.mts.map +1 -0
  114. package/dist/fields-iagOozy0.mjs +115 -0
  115. package/dist/fields-iagOozy0.mjs.map +1 -0
  116. package/dist/hooks/index.d.mts +4 -0
  117. package/dist/hooks/index.mjs +3 -0
  118. package/dist/idempotency/index.d.mts +97 -0
  119. package/dist/idempotency/index.d.mts.map +1 -0
  120. package/dist/idempotency/index.mjs +320 -0
  121. package/dist/idempotency/index.mjs.map +1 -0
  122. package/dist/idempotency/mongodb.d.mts +2 -0
  123. package/dist/idempotency/mongodb.mjs +115 -0
  124. package/dist/idempotency/mongodb.mjs.map +1 -0
  125. package/dist/idempotency/redis.d.mts +2 -0
  126. package/dist/idempotency/redis.mjs +104 -0
  127. package/dist/idempotency/redis.mjs.map +1 -0
  128. package/dist/index.d.mts +261 -0
  129. package/dist/index.d.mts.map +1 -0
  130. package/dist/index.mjs +105 -0
  131. package/dist/index.mjs.map +1 -0
  132. package/dist/integrations/event-gateway.d.mts +47 -0
  133. package/dist/integrations/event-gateway.d.mts.map +1 -0
  134. package/dist/integrations/event-gateway.mjs +44 -0
  135. package/dist/integrations/event-gateway.mjs.map +1 -0
  136. package/dist/integrations/index.d.mts +5 -0
  137. package/dist/integrations/index.mjs +1 -0
  138. package/dist/integrations/jobs.d.mts +104 -0
  139. package/dist/integrations/jobs.d.mts.map +1 -0
  140. package/dist/integrations/jobs.mjs +124 -0
  141. package/dist/integrations/jobs.mjs.map +1 -0
  142. package/dist/integrations/streamline.d.mts +61 -0
  143. package/dist/integrations/streamline.d.mts.map +1 -0
  144. package/dist/integrations/streamline.mjs +126 -0
  145. package/dist/integrations/streamline.mjs.map +1 -0
  146. package/dist/integrations/websocket.d.mts +83 -0
  147. package/dist/integrations/websocket.d.mts.map +1 -0
  148. package/dist/integrations/websocket.mjs +289 -0
  149. package/dist/integrations/websocket.mjs.map +1 -0
  150. package/dist/interface-B01JvPVc.d.mts +78 -0
  151. package/dist/interface-B01JvPVc.d.mts.map +1 -0
  152. package/dist/interface-CZe8IkMf.d.mts +55 -0
  153. package/dist/interface-CZe8IkMf.d.mts.map +1 -0
  154. package/dist/interface-Ch8HU9uM.d.mts +1098 -0
  155. package/dist/interface-Ch8HU9uM.d.mts.map +1 -0
  156. package/dist/introspectionPlugin-rFdO8ZUa.mjs +54 -0
  157. package/dist/introspectionPlugin-rFdO8ZUa.mjs.map +1 -0
  158. package/dist/keys-BqNejWup.mjs +43 -0
  159. package/dist/keys-BqNejWup.mjs.map +1 -0
  160. package/dist/logger-Df2O2WsW.mjs +79 -0
  161. package/dist/logger-Df2O2WsW.mjs.map +1 -0
  162. package/dist/memory-cQgelFOj.mjs +144 -0
  163. package/dist/memory-cQgelFOj.mjs.map +1 -0
  164. package/dist/migrations/index.d.mts +157 -0
  165. package/dist/migrations/index.d.mts.map +1 -0
  166. package/dist/migrations/index.mjs +261 -0
  167. package/dist/migrations/index.mjs.map +1 -0
  168. package/dist/mongodb-BfJVlUJH.mjs +94 -0
  169. package/dist/mongodb-BfJVlUJH.mjs.map +1 -0
  170. package/dist/mongodb-CGzRbfAK.d.mts +119 -0
  171. package/dist/mongodb-CGzRbfAK.d.mts.map +1 -0
  172. package/dist/mongodb-JN-9JA7K.d.mts +72 -0
  173. package/dist/mongodb-JN-9JA7K.d.mts.map +1 -0
  174. package/dist/openapi-G3Cw7XuM.mjs +524 -0
  175. package/dist/openapi-G3Cw7XuM.mjs.map +1 -0
  176. package/dist/org/index.d.mts +69 -0
  177. package/dist/org/index.d.mts.map +1 -0
  178. package/dist/org/index.mjs +514 -0
  179. package/dist/org/index.mjs.map +1 -0
  180. package/dist/org/types.d.mts +83 -0
  181. package/dist/org/types.d.mts.map +1 -0
  182. package/dist/org/types.mjs +1 -0
  183. package/dist/permissions/index.d.mts +279 -0
  184. package/dist/permissions/index.d.mts.map +1 -0
  185. package/dist/permissions/index.mjs +579 -0
  186. package/dist/permissions/index.mjs.map +1 -0
  187. package/dist/plugins/index.d.mts +173 -0
  188. package/dist/plugins/index.d.mts.map +1 -0
  189. package/dist/plugins/index.mjs +523 -0
  190. package/dist/plugins/index.mjs.map +1 -0
  191. package/dist/plugins/response-cache.d.mts +88 -0
  192. package/dist/plugins/response-cache.d.mts.map +1 -0
  193. package/dist/plugins/response-cache.mjs +284 -0
  194. package/dist/plugins/response-cache.mjs.map +1 -0
  195. package/dist/plugins/tracing-entry.d.mts +2 -0
  196. package/dist/plugins/tracing-entry.mjs +186 -0
  197. package/dist/plugins/tracing-entry.mjs.map +1 -0
  198. package/dist/pluralize-CEweyOEm.mjs +87 -0
  199. package/dist/pluralize-CEweyOEm.mjs.map +1 -0
  200. package/dist/policies/{index.d.ts → index.d.mts} +204 -169
  201. package/dist/policies/index.d.mts.map +1 -0
  202. package/dist/policies/index.mjs +322 -0
  203. package/dist/policies/index.mjs.map +1 -0
  204. package/dist/presets/{index.d.ts → index.d.mts} +63 -131
  205. package/dist/presets/index.d.mts.map +1 -0
  206. package/dist/presets/index.mjs +144 -0
  207. package/dist/presets/index.mjs.map +1 -0
  208. package/dist/presets/multiTenant.d.mts +25 -0
  209. package/dist/presets/multiTenant.d.mts.map +1 -0
  210. package/dist/presets/multiTenant.mjs +114 -0
  211. package/dist/presets/multiTenant.mjs.map +1 -0
  212. package/dist/presets-BITljm96.mjs +120 -0
  213. package/dist/presets-BITljm96.mjs.map +1 -0
  214. package/dist/presets-DzSMwlKj.d.mts +58 -0
  215. package/dist/presets-DzSMwlKj.d.mts.map +1 -0
  216. package/dist/prisma-DJbMt3yf.mjs +628 -0
  217. package/dist/prisma-DJbMt3yf.mjs.map +1 -0
  218. package/dist/prisma-Dg9GoVdj.d.mts +275 -0
  219. package/dist/prisma-Dg9GoVdj.d.mts.map +1 -0
  220. package/dist/queryCachePlugin-7THaI5mt.d.mts +72 -0
  221. package/dist/queryCachePlugin-7THaI5mt.d.mts.map +1 -0
  222. package/dist/queryCachePlugin-DMBnp2Q0.mjs +139 -0
  223. package/dist/queryCachePlugin-DMBnp2Q0.mjs.map +1 -0
  224. package/dist/redis-D-JAeLtm.d.mts +50 -0
  225. package/dist/redis-D-JAeLtm.d.mts.map +1 -0
  226. package/dist/redis-stream-Bdh_vUU8.d.mts +104 -0
  227. package/dist/redis-stream-Bdh_vUU8.d.mts.map +1 -0
  228. package/dist/registry/index.d.mts +12 -0
  229. package/dist/registry/index.d.mts.map +1 -0
  230. package/dist/registry/index.mjs +4 -0
  231. package/dist/requestContext-QQD6ROJc.mjs +56 -0
  232. package/dist/requestContext-QQD6ROJc.mjs.map +1 -0
  233. package/dist/schemaConverter-BwrmWroW.mjs +99 -0
  234. package/dist/schemaConverter-BwrmWroW.mjs.map +1 -0
  235. package/dist/schemas/index.d.mts +64 -0
  236. package/dist/schemas/index.d.mts.map +1 -0
  237. package/dist/schemas/index.mjs +83 -0
  238. package/dist/schemas/index.mjs.map +1 -0
  239. package/dist/scope/index.d.mts +22 -0
  240. package/dist/scope/index.d.mts.map +1 -0
  241. package/dist/scope/index.mjs +66 -0
  242. package/dist/scope/index.mjs.map +1 -0
  243. package/dist/sessionManager-jPKLbHE0.d.mts +187 -0
  244. package/dist/sessionManager-jPKLbHE0.d.mts.map +1 -0
  245. package/dist/sse-B3c3_yZp.mjs +124 -0
  246. package/dist/sse-B3c3_yZp.mjs.map +1 -0
  247. package/dist/testing/index.d.mts +908 -0
  248. package/dist/testing/index.d.mts.map +1 -0
  249. package/dist/testing/index.mjs +1977 -0
  250. package/dist/testing/index.mjs.map +1 -0
  251. package/dist/tracing-Cc7vVQPp.d.mts +71 -0
  252. package/dist/tracing-Cc7vVQPp.d.mts.map +1 -0
  253. package/dist/typeGuards-DhMNLuvU.mjs +10 -0
  254. package/dist/typeGuards-DhMNLuvU.mjs.map +1 -0
  255. package/dist/types/index.d.mts +947 -0
  256. package/dist/types/index.d.mts.map +1 -0
  257. package/dist/types/index.mjs +15 -0
  258. package/dist/types/index.mjs.map +1 -0
  259. package/dist/types-Beqn1Un7.mjs +39 -0
  260. package/dist/types-Beqn1Un7.mjs.map +1 -0
  261. package/dist/types-CIgB7UUl.d.mts +446 -0
  262. package/dist/types-CIgB7UUl.d.mts.map +1 -0
  263. package/dist/types-aYB4V7uN.d.mts +87 -0
  264. package/dist/types-aYB4V7uN.d.mts.map +1 -0
  265. package/dist/utils/index.d.mts +748 -0
  266. package/dist/utils/index.d.mts.map +1 -0
  267. package/dist/utils/index.mjs +6 -0
  268. package/package.json +194 -68
  269. package/dist/BaseController-DVAiHxEQ.d.ts +0 -233
  270. package/dist/adapters/index.d.ts +0 -237
  271. package/dist/adapters/index.js +0 -668
  272. package/dist/arcCorePlugin-CsShQdyP.d.ts +0 -273
  273. package/dist/audit/index.d.ts +0 -195
  274. package/dist/audit/index.js +0 -319
  275. package/dist/auth/index.d.ts +0 -47
  276. package/dist/auth/index.js +0 -174
  277. package/dist/cli/commands/docs.d.ts +0 -11
  278. package/dist/cli/commands/docs.js +0 -474
  279. package/dist/cli/commands/generate.js +0 -334
  280. package/dist/cli/commands/introspect.d.ts +0 -8
  281. package/dist/cli/commands/introspect.js +0 -338
  282. package/dist/cli/index.d.ts +0 -4
  283. package/dist/cli/index.js +0 -3269
  284. package/dist/core/index.d.ts +0 -220
  285. package/dist/core/index.js +0 -2786
  286. package/dist/createApp-Ce9wl8W9.d.ts +0 -77
  287. package/dist/docs/index.d.ts +0 -166
  288. package/dist/docs/index.js +0 -658
  289. package/dist/errors-8WIxGS_6.d.ts +0 -122
  290. package/dist/events/index.d.ts +0 -117
  291. package/dist/events/index.js +0 -89
  292. package/dist/factory/index.d.ts +0 -38
  293. package/dist/factory/index.js +0 -1652
  294. package/dist/hooks/index.d.ts +0 -4
  295. package/dist/hooks/index.js +0 -199
  296. package/dist/idempotency/index.d.ts +0 -323
  297. package/dist/idempotency/index.js +0 -500
  298. package/dist/index-B4t03KQ0.d.ts +0 -1366
  299. package/dist/index.d.ts +0 -135
  300. package/dist/index.js +0 -4756
  301. package/dist/migrations/index.d.ts +0 -185
  302. package/dist/migrations/index.js +0 -274
  303. package/dist/org/index.d.ts +0 -129
  304. package/dist/org/index.js +0 -220
  305. package/dist/permissions/index.d.ts +0 -144
  306. package/dist/permissions/index.js +0 -103
  307. package/dist/plugins/index.d.ts +0 -46
  308. package/dist/plugins/index.js +0 -1069
  309. package/dist/policies/index.js +0 -196
  310. package/dist/presets/index.js +0 -384
  311. package/dist/presets/multiTenant.d.ts +0 -39
  312. package/dist/presets/multiTenant.js +0 -112
  313. package/dist/registry/index.d.ts +0 -16
  314. package/dist/registry/index.js +0 -253
  315. package/dist/testing/index.d.ts +0 -618
  316. package/dist/testing/index.js +0 -48020
  317. package/dist/types/index.d.ts +0 -4
  318. package/dist/types/index.js +0 -8
  319. package/dist/types-B99TBmFV.d.ts +0 -76
  320. package/dist/types-BvckRbs2.d.ts +0 -143
  321. package/dist/utils/index.d.ts +0 -679
  322. 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-aYB4V7uN.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
@@ -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.
289
274
  *
290
- * Common operations for working with PolicyEngine implementations.
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';
288
+ *
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
+ } //# sourceMappingURL=PolicyInterface.d.ts.map
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,6 @@ 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 };
433
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/policies/PolicyInterface.ts","../../src/policies/helpers.ts"],"mappings":";;;;;;;UA+CiB,YAAA;EAyMb;;;EArMF,OAAA;EA4NA;;;;EAtNA,MAAA;EAwN6B;;;;AAsB/B;;;;;;;;;;AAWA;EAxOE,OAAA,GAAU,MAAA;;;;AAkPZ;;;;;;;;;EApOE,SAAA;IACE,OAAA;IACA,OAAA;EAAA;EAiSY;;;;;;;;;AAmDf;;EAtUC,QAAA,GAAW,MAAA;AAAA;;;;UAMI,aAAA;EAoUc;;;;EA/T7B,QAAA;ECnFc;;;EDwFd,IAAA;ECrFW;;;ED0FX,MAAA;EC1F0D;;;ED+F1D,KAAA;EC/FW;;;;EAAA,CDqGV,GAAA;AAAA;;AC5BH;;;;;;;;;AA4HA;;;;;;;;;AA2FA;;;;;AA6BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UDhIiB,YAAA;;;;;;;;;;;;;;;;;;;;;EAqBf,GAAA,CACE,IAAA,OACA,SAAA,UACA,OAAA,GAAU,aAAA,GACT,YAAA,GAAe,OAAA,CAAQ,YAAA;;;;;;;;;;;;;;;;;;;;;EAsB1B,YAAA,CACE,SAAA,YACE,OAAA,EAAS,cAAA,EAAgB,KAAA,EAAO,YAAA,KAAiB,OAAA;AAAA;;;;;;;;;;;;;;;;;;;;KAsB3C,aAAA,mBAAgC,MAAA,EAAQ,OAAA,KAAY,YAAA;;;;;;;;;;UAW/C,sBAAA;;EAEf,QAAA;;EAEA,MAAA;AAAA;;;;UAMe,0BAAA;;EAEf,UAAA,EAAY,sBAAA;;;;;;;;;;;EAWZ,eAAA,IAAmB,MAAA,UAAgB,QAAA,UAAkB,MAAA,aAAmB,OAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkD1D,yBAAA,CACd,OAAA,EAAS,0BAAA,GACR,eAAA;AAAA;EAAA,UAoDS,cAAA;IACR,YAAA,GAAe,YAAA;EAAA;AAAA;;;;;;;;;;;;;;;AApUnB;;;;;;;;;;;iBC9EgB,sBAAA,CACd,MAAA,EAAQ,YAAA,EACR,SAAA,YACE,OAAA,EAAS,cAAA,EAAgB,KAAA,EAAO,YAAA,KAAiB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ADoQrD;iBC3LgB,eAAA,CAAA,GAAmB,QAAA,EAAU,YAAA,KAAiB,YAAA;;;;;;;;;ADsM9D;;;;;AAUA;;;;;;;iBCpFgB,SAAA,CAAA,GAAa,QAAA,EAAU,YAAA,KAAiB,YAAA;;;;;;ADmJxD;;;;;;;iBCxDgB,QAAA,CAAA,GAAY,YAAA;;AD2G3B;;;;;;;;;;;;;AC9YD;iBAgUgB,OAAA,CAAQ,MAAA,YAAmC,YAAA"}