@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
package/dist/org/index.js DELETED
@@ -1,220 +0,0 @@
1
- import fp from 'fastify-plugin';
2
-
3
- // src/org/orgScopePlugin.ts
4
- function createOrgContext(orgId, options = {}) {
5
- return {
6
- organizationId: orgId,
7
- orgScope: options.orgScope ?? "explicit",
8
- orgRoles: options.orgRoles ?? [],
9
- ...options
10
- };
11
- }
12
- var orgScopePlugin = async (fastify, opts = {}) => {
13
- const {
14
- header = "x-organization-id",
15
- bypassRoles = ["superadmin"],
16
- userOrgsPath = "organizations",
17
- validateMembership
18
- } = opts;
19
- if (!fastify.hasRequestDecorator("context")) {
20
- fastify.decorateRequest("context", void 0);
21
- }
22
- if (!fastify.hasRequestDecorator("organizationId")) {
23
- fastify.decorateRequest("organizationId", void 0);
24
- }
25
- fastify.decorate("organizationScoped", function organizationScoped(options = {}) {
26
- const { required = true } = options;
27
- return async function organizationScopePreHandler(request, reply) {
28
- const user = request.user;
29
- const userWithRoles = user;
30
- const roles = Array.isArray(userWithRoles?.roles) ? userWithRoles.roles : userWithRoles?.roles ? [String(userWithRoles.roles)] : [];
31
- const orgIdFromHeader = request.headers[header]?.toString().trim();
32
- const isAuthenticated = !!user;
33
- const isSuperadmin = bypassRoles.some((role) => roles.includes(role));
34
- const req = request;
35
- req.context = req.context ?? {};
36
- if (!orgIdFromHeader) {
37
- if (isSuperadmin) {
38
- request.log?.debug?.({ msg: "Superadmin - no org filter required" });
39
- req.context.orgScope = "global";
40
- return;
41
- }
42
- if (required) {
43
- reply.code(403).send({
44
- success: false,
45
- error: "Organization context required",
46
- code: "ORG_HEADER_REQUIRED",
47
- message: "x-organization-id header required"
48
- });
49
- return;
50
- }
51
- request.log?.debug?.({ msg: "No org filter - showing all public data" });
52
- req.context.orgScope = "public";
53
- return;
54
- }
55
- if (!isAuthenticated) {
56
- request.log?.warn?.({
57
- msg: "Organization filtering requires authentication",
58
- headerOrgId: orgIdFromHeader
59
- });
60
- reply.code(401).send({
61
- success: false,
62
- error: "Authentication required to filter by organization",
63
- code: "AUTH_REQUIRED_FOR_ORG"
64
- });
65
- return;
66
- }
67
- if (isSuperadmin) {
68
- request.log?.debug?.({
69
- msg: "Superadmin accessing organization",
70
- orgId: orgIdFromHeader
71
- });
72
- req.organizationId = orgIdFromHeader;
73
- req.context.organizationId = orgIdFromHeader;
74
- req.context.orgScope = "bypass";
75
- req.context.bypassReason = "superadmin";
76
- return;
77
- }
78
- const userOrgs = user?.[userOrgsPath] ?? [];
79
- let hasAccess = false;
80
- if (validateMembership) {
81
- hasAccess = await validateMembership(user, orgIdFromHeader);
82
- } else {
83
- hasAccess = userOrgs.some((org) => {
84
- const memberOrgId = org.organizationId?.toString() ?? String(org);
85
- return memberOrgId === orgIdFromHeader;
86
- });
87
- }
88
- if (!hasAccess) {
89
- request.log?.warn?.({
90
- msg: "Access denied - user not member of organization",
91
- userId: user._id ?? user.id,
92
- requestedOrgId: orgIdFromHeader,
93
- userOrgIds: userOrgs.map((o) => o.organizationId?.toString() ?? String(o))
94
- });
95
- reply.code(403).send({
96
- success: false,
97
- error: "No access to this organization",
98
- code: "ORG_ACCESS_DENIED"
99
- });
100
- return;
101
- }
102
- req.organizationId = orgIdFromHeader;
103
- req.context.organizationId = orgIdFromHeader;
104
- req.context.orgScope = "member";
105
- const orgMembership = userOrgs.find((o) => {
106
- const memberOrgId = o.organizationId?.toString() ?? String(o);
107
- return memberOrgId === orgIdFromHeader;
108
- });
109
- req.context.orgRoles = orgMembership?.roles ?? [];
110
- request.log?.debug?.({
111
- msg: "Organization context set",
112
- orgId: orgIdFromHeader,
113
- userId: user._id ?? user.id,
114
- orgRoles: req.context.orgRoles
115
- });
116
- };
117
- });
118
- fastify.decorate("createOrgContext", createOrgContext);
119
- fastify.log?.info?.("Organization scope plugin registered");
120
- };
121
- var orgScopePlugin_default = fp(orgScopePlugin, {
122
- name: "arc-org-scope",
123
- fastify: "5.x"
124
- });
125
-
126
- // src/org/orgGuard.ts
127
- function orgGuard(options = {}) {
128
- const {
129
- requireOrgContext = true,
130
- roles = [],
131
- allowGlobal = false
132
- } = options;
133
- return async function orgGuardMiddleware(request, reply) {
134
- const context = request.context ?? {};
135
- const user = request.user;
136
- const userWithRoles = user;
137
- if (allowGlobal && userWithRoles?.roles?.includes("superadmin")) {
138
- return;
139
- }
140
- if (requireOrgContext && !context.organizationId) {
141
- reply.code(403).send({
142
- success: false,
143
- error: "Organization context required",
144
- code: "ORG_CONTEXT_REQUIRED",
145
- message: "This endpoint requires an organization context. Please specify organization via x-organization-id header."
146
- });
147
- return;
148
- }
149
- if (roles.length > 0 && context.organizationId) {
150
- const contextWithRoles = context;
151
- const userOrgRoles = contextWithRoles.orgRoles ?? [];
152
- const hasRequiredRole = roles.some((role) => userOrgRoles.includes(role));
153
- if (!hasRequiredRole && !userWithRoles?.roles?.includes("superadmin")) {
154
- reply.code(403).send({
155
- success: false,
156
- error: "Insufficient organization permissions",
157
- code: "ORG_ROLE_REQUIRED",
158
- message: `This action requires one of these organization roles: ${roles.join(", ")}`,
159
- required: roles,
160
- current: userOrgRoles
161
- });
162
- return;
163
- }
164
- }
165
- };
166
- }
167
- function requireOrg() {
168
- return orgGuard({ requireOrgContext: true });
169
- }
170
- function requireOrgRole(...roles) {
171
- return orgGuard({ requireOrgContext: true, roles });
172
- }
173
-
174
- // src/org/orgMembership.ts
175
- async function orgMembershipCheck(user, orgId, options = {}) {
176
- const {
177
- userOrgsPath = "organizations",
178
- bypassRoles = ["superadmin"],
179
- validateFromDb
180
- } = options;
181
- if (!user || !orgId) return false;
182
- const userWithRoles = user;
183
- const userRoles = userWithRoles.roles ?? [];
184
- if (bypassRoles.some((role) => userRoles.includes(role))) {
185
- return true;
186
- }
187
- const userOrgs = user[userOrgsPath] ?? [];
188
- const isMemberFromUser = userOrgs.some((o) => {
189
- const memberOrgId = o.organizationId?.toString() ?? String(o);
190
- return memberOrgId === orgId.toString();
191
- });
192
- if (isMemberFromUser) return true;
193
- if (validateFromDb) {
194
- const userId = (user._id ?? user.id)?.toString();
195
- if (userId) {
196
- return validateFromDb(userId, orgId);
197
- }
198
- }
199
- return false;
200
- }
201
- function getOrgRoles(user, orgId, options = {}) {
202
- const { userOrgsPath = "organizations" } = options;
203
- if (!user || !orgId) return [];
204
- const userOrgs = user[userOrgsPath] ?? [];
205
- const membership = userOrgs.find((o) => {
206
- const memberOrgId = o.organizationId?.toString() ?? String(o);
207
- return memberOrgId === orgId.toString();
208
- });
209
- const membershipRoles = membership;
210
- return membershipRoles?.roles ?? [];
211
- }
212
- function hasOrgRole(user, orgId, roles, options = {}) {
213
- const userOrgRoles = getOrgRoles(user, orgId, options);
214
- const requiredRoles = Array.isArray(roles) ? roles : [roles];
215
- const userWithRoles = user;
216
- if (userWithRoles?.roles?.includes("superadmin")) return true;
217
- return requiredRoles.some((role) => userOrgRoles.includes(role));
218
- }
219
-
220
- export { createOrgContext, getOrgRoles, hasOrgRole, orgGuard, orgMembershipCheck, orgScopePlugin_default as orgScopePlugin, orgScopePlugin as orgScopePluginFn, requireOrg, requireOrgRole };
@@ -1,144 +0,0 @@
1
- import { P as PermissionCheck, a as PermissionContext } from '../types-B99TBmFV.js';
2
- export { b as PermissionResult, U as UserBase } from '../types-B99TBmFV.js';
3
- import 'fastify';
4
-
5
- /**
6
- * Permission System
7
- *
8
- * Clean, function-based permission system.
9
- * PermissionCheck is THE ONLY way to define permissions.
10
- *
11
- * @example
12
- * ```typescript
13
- * import { allowPublic, requireAuth, requireRoles } from '@classytic/arc/permissions';
14
- *
15
- * defineResource({
16
- * permissions: {
17
- * list: allowPublic(),
18
- * get: allowPublic(),
19
- * create: requireAuth(),
20
- * update: requireRoles(['admin', 'editor']),
21
- * delete: requireRoles(['admin']),
22
- * }
23
- * });
24
- * ```
25
- */
26
-
27
- /**
28
- * Allow public access (no authentication required)
29
- *
30
- * @example
31
- * ```typescript
32
- * permissions: {
33
- * list: allowPublic(),
34
- * get: allowPublic(),
35
- * }
36
- * ```
37
- */
38
- declare function allowPublic(): PermissionCheck;
39
- /**
40
- * Require authentication (any authenticated user)
41
- *
42
- * @example
43
- * ```typescript
44
- * permissions: {
45
- * create: requireAuth(),
46
- * update: requireAuth(),
47
- * }
48
- * ```
49
- */
50
- declare function requireAuth(): PermissionCheck;
51
- /**
52
- * Require specific roles
53
- *
54
- * @param roles - Required roles (user needs at least one)
55
- * @param options - Optional bypass roles
56
- *
57
- * @example
58
- * ```typescript
59
- * permissions: {
60
- * create: requireRoles(['admin', 'editor']),
61
- * delete: requireRoles(['admin']),
62
- * }
63
- *
64
- * // With bypass roles
65
- * permissions: {
66
- * update: requireRoles(['owner'], { bypassRoles: ['admin', 'superadmin'] }),
67
- * }
68
- * ```
69
- */
70
- declare function requireRoles(roles: readonly string[], options?: {
71
- bypassRoles?: readonly string[];
72
- }): PermissionCheck;
73
- /**
74
- * Require resource ownership
75
- *
76
- * Returns filters to scope queries to user's owned resources.
77
- *
78
- * @param ownerField - Field containing owner ID (default: 'userId')
79
- * @param options - Optional bypass roles
80
- *
81
- * @example
82
- * ```typescript
83
- * permissions: {
84
- * update: requireOwnership('userId'),
85
- * delete: requireOwnership('createdBy', { bypassRoles: ['admin'] }),
86
- * }
87
- * ```
88
- */
89
- declare function requireOwnership(ownerField?: string, options?: {
90
- bypassRoles?: readonly string[];
91
- }): PermissionCheck;
92
- /**
93
- * Combine multiple checks - ALL must pass (AND logic)
94
- *
95
- * @example
96
- * ```typescript
97
- * permissions: {
98
- * update: allOf(
99
- * requireAuth(),
100
- * requireRoles(['editor']),
101
- * requireOwnership('createdBy')
102
- * ),
103
- * }
104
- * ```
105
- */
106
- declare function allOf(...checks: PermissionCheck[]): PermissionCheck;
107
- /**
108
- * Combine multiple checks - ANY must pass (OR logic)
109
- *
110
- * @example
111
- * ```typescript
112
- * permissions: {
113
- * update: anyOf(
114
- * requireRoles(['admin']),
115
- * requireOwnership('createdBy')
116
- * ),
117
- * }
118
- * ```
119
- */
120
- declare function anyOf(...checks: PermissionCheck[]): PermissionCheck;
121
- /**
122
- * Deny all access
123
- *
124
- * @example
125
- * ```typescript
126
- * permissions: {
127
- * delete: denyAll('Deletion not allowed'),
128
- * }
129
- * ```
130
- */
131
- declare function denyAll(reason?: string): PermissionCheck;
132
- /**
133
- * Dynamic permission based on context
134
- *
135
- * @example
136
- * ```typescript
137
- * permissions: {
138
- * update: when((ctx) => ctx.data?.status === 'draft'),
139
- * }
140
- * ```
141
- */
142
- declare function when(condition: (ctx: PermissionContext) => boolean | Promise<boolean>): PermissionCheck;
143
-
144
- export { PermissionCheck, PermissionContext, allOf, allowPublic, anyOf, denyAll, requireAuth, requireOwnership, requireRoles, when };
@@ -1,103 +0,0 @@
1
- // src/permissions/index.ts
2
- function allowPublic() {
3
- const check = () => true;
4
- check._isPublic = true;
5
- return check;
6
- }
7
- function requireAuth() {
8
- const check = (ctx) => {
9
- if (!ctx.user) {
10
- return { granted: false, reason: "Authentication required" };
11
- }
12
- return true;
13
- };
14
- return check;
15
- }
16
- function requireRoles(roles, options) {
17
- const check = (ctx) => {
18
- if (!ctx.user) {
19
- return { granted: false, reason: "Authentication required" };
20
- }
21
- const userRoles = ctx.user.roles ?? [];
22
- if (options?.bypassRoles?.some((r) => userRoles.includes(r))) {
23
- return true;
24
- }
25
- if (roles.some((r) => userRoles.includes(r))) {
26
- return true;
27
- }
28
- return {
29
- granted: false,
30
- reason: `Required roles: ${roles.join(", ")}`
31
- };
32
- };
33
- check._roles = roles;
34
- return check;
35
- }
36
- function requireOwnership(ownerField = "userId", options) {
37
- return (ctx) => {
38
- if (!ctx.user) {
39
- return { granted: false, reason: "Authentication required" };
40
- }
41
- const userRoles = ctx.user.roles ?? [];
42
- if (options?.bypassRoles?.some((r) => userRoles.includes(r))) {
43
- return true;
44
- }
45
- const userId = ctx.user.id ?? ctx.user._id;
46
- return {
47
- granted: true,
48
- filters: { [ownerField]: userId }
49
- };
50
- };
51
- }
52
- function allOf(...checks) {
53
- return async (ctx) => {
54
- let mergedFilters = {};
55
- for (const check of checks) {
56
- const result = await check(ctx);
57
- const normalized = typeof result === "boolean" ? { granted: result } : result;
58
- if (!normalized.granted) {
59
- return normalized;
60
- }
61
- if (normalized.filters) {
62
- mergedFilters = { ...mergedFilters, ...normalized.filters };
63
- }
64
- }
65
- return {
66
- granted: true,
67
- filters: Object.keys(mergedFilters).length > 0 ? mergedFilters : void 0
68
- };
69
- };
70
- }
71
- function anyOf(...checks) {
72
- return async (ctx) => {
73
- const reasons = [];
74
- for (const check of checks) {
75
- const result = await check(ctx);
76
- const normalized = typeof result === "boolean" ? { granted: result } : result;
77
- if (normalized.granted) {
78
- return normalized;
79
- }
80
- if (normalized.reason) {
81
- reasons.push(normalized.reason);
82
- }
83
- }
84
- return {
85
- granted: false,
86
- reason: reasons.join("; ")
87
- };
88
- };
89
- }
90
- function denyAll(reason = "Access denied") {
91
- return () => ({ granted: false, reason });
92
- }
93
- function when(condition) {
94
- return async (ctx) => {
95
- const result = await condition(ctx);
96
- return {
97
- granted: result,
98
- reason: result ? void 0 : "Condition not met"
99
- };
100
- };
101
- }
102
-
103
- export { allOf, allowPublic, anyOf, denyAll, requireAuth, requireOwnership, requireRoles, when };
@@ -1,46 +0,0 @@
1
- export { k as ArcCore, A as ArcCorePluginOptions, G as GracefulShutdownOptions, b as HealthCheck, H as HealthOptions, R as RequestIdOptions, T as TracingOptions, f as arcCorePlugin, j as arcCorePluginFn, d as createSpan, e as gracefulShutdownPlugin, g as gracefulShutdownPluginFn, a as healthPlugin, h as healthPluginFn, i as isTracingAvailable, _ as requestIdPlugin, r as requestIdPluginFn, t as traced, c as tracingPlugin } from '../arcCorePlugin-CsShQdyP.js';
2
- import { FastifyInstance, FastifyRequest } from 'fastify';
3
- import '../index-B4t03KQ0.js';
4
- import 'mongoose';
5
- import '../types-B99TBmFV.js';
6
-
7
- /**
8
- * Error Handler Plugin
9
- *
10
- * Global error handling for Arc applications.
11
- * Catches all errors and returns a consistent JSON response.
12
- *
13
- * @example
14
- * import { errorHandlerPlugin } from '@classytic/arc/plugins';
15
- *
16
- * await fastify.register(errorHandlerPlugin, {
17
- * includeStack: process.env.NODE_ENV !== 'production',
18
- * onError: (error, request) => {
19
- * // Log to external service (Sentry, etc.)
20
- * Sentry.captureException(error);
21
- * }
22
- * });
23
- */
24
-
25
- interface ErrorHandlerOptions {
26
- /**
27
- * Include stack trace in error responses (default: false in production)
28
- */
29
- includeStack?: boolean;
30
- /**
31
- * Custom error callback for logging to external services
32
- */
33
- onError?: (error: Error, request: FastifyRequest) => void | Promise<void>;
34
- /**
35
- * Map specific error types to custom responses
36
- */
37
- errorMap?: Record<string, {
38
- statusCode: number;
39
- code: string;
40
- message?: string;
41
- }>;
42
- }
43
- declare function errorHandlerPluginFn(fastify: FastifyInstance, options?: ErrorHandlerOptions): Promise<void>;
44
- declare const errorHandlerPlugin: typeof errorHandlerPluginFn;
45
-
46
- export { type ErrorHandlerOptions, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn };