@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,319 +0,0 @@
1
- import fp from 'fastify-plugin';
2
-
3
- // src/audit/auditPlugin.ts
4
-
5
- // src/audit/stores/interface.ts
6
- function createAuditEntry(resource, documentId, action, context, data) {
7
- const changes = data?.before && data?.after ? detectChanges(data.before, data.after) : void 0;
8
- return {
9
- id: generateAuditId(),
10
- resource,
11
- documentId,
12
- action,
13
- userId: context.user?._id?.toString() ?? context.user?.id,
14
- organizationId: context.organizationId,
15
- before: data?.before,
16
- after: data?.after,
17
- changes,
18
- requestId: context.requestId,
19
- ipAddress: context.ipAddress,
20
- userAgent: context.userAgent,
21
- metadata: data?.metadata,
22
- timestamp: /* @__PURE__ */ new Date()
23
- };
24
- }
25
- function detectChanges(before, after) {
26
- const changes = [];
27
- const allKeys = /* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)]);
28
- for (const key of allKeys) {
29
- if (key.startsWith("_") || key === "updatedAt") continue;
30
- const oldVal = JSON.stringify(before[key]);
31
- const newVal = JSON.stringify(after[key]);
32
- if (oldVal !== newVal) {
33
- changes.push(key);
34
- }
35
- }
36
- return changes;
37
- }
38
- function generateAuditId() {
39
- const timestamp = Date.now().toString(36);
40
- const random = Math.random().toString(36).substring(2, 10);
41
- return `aud_${timestamp}${random}`;
42
- }
43
-
44
- // src/audit/stores/memory.ts
45
- var MemoryAuditStore = class {
46
- name = "memory";
47
- entries = [];
48
- maxEntries;
49
- constructor(options = {}) {
50
- this.maxEntries = options.maxEntries ?? 1e3;
51
- }
52
- async log(entry) {
53
- this.entries.unshift(entry);
54
- if (this.entries.length > this.maxEntries) {
55
- this.entries = this.entries.slice(0, this.maxEntries);
56
- }
57
- }
58
- async query(options = {}) {
59
- let results = [...this.entries];
60
- if (options.resource) {
61
- results = results.filter((e) => e.resource === options.resource);
62
- }
63
- if (options.documentId) {
64
- results = results.filter((e) => e.documentId === options.documentId);
65
- }
66
- if (options.userId) {
67
- results = results.filter((e) => e.userId === options.userId);
68
- }
69
- if (options.organizationId) {
70
- results = results.filter((e) => e.organizationId === options.organizationId);
71
- }
72
- if (options.action) {
73
- const actions = Array.isArray(options.action) ? options.action : [options.action];
74
- results = results.filter((e) => actions.includes(e.action));
75
- }
76
- if (options.from) {
77
- results = results.filter((e) => e.timestamp >= options.from);
78
- }
79
- if (options.to) {
80
- results = results.filter((e) => e.timestamp <= options.to);
81
- }
82
- const offset = options.offset ?? 0;
83
- const limit = options.limit ?? 100;
84
- results = results.slice(offset, offset + limit);
85
- return results;
86
- }
87
- async close() {
88
- this.entries = [];
89
- }
90
- /** Get all entries (for testing) */
91
- getAll() {
92
- return [...this.entries];
93
- }
94
- /** Clear all entries (for testing) */
95
- clear() {
96
- this.entries = [];
97
- }
98
- };
99
-
100
- // src/audit/stores/mongodb.ts
101
- var MongoAuditStore = class {
102
- constructor(options) {
103
- this.options = options;
104
- const collectionName = options.collection ?? "audit_logs";
105
- this.collection = options.connection.collection(collectionName);
106
- this.ttlDays = options.ttlDays ?? 90;
107
- }
108
- name = "mongodb";
109
- collection;
110
- initialized = false;
111
- ttlDays;
112
- async ensureIndexes() {
113
- if (this.initialized) return;
114
- try {
115
- await this.collection.createIndex({
116
- resource: 1,
117
- documentId: 1,
118
- timestamp: -1
119
- });
120
- await this.collection.createIndex({ userId: 1, timestamp: -1 });
121
- await this.collection.createIndex({ organizationId: 1, timestamp: -1 });
122
- if (this.ttlDays > 0) {
123
- await this.collection.createIndex(
124
- { timestamp: 1 },
125
- { expireAfterSeconds: this.ttlDays * 24 * 60 * 60 }
126
- );
127
- }
128
- this.initialized = true;
129
- } catch {
130
- this.initialized = true;
131
- }
132
- }
133
- async log(entry) {
134
- await this.ensureIndexes();
135
- await this.collection.insertOne({
136
- _id: entry.id,
137
- resource: entry.resource,
138
- documentId: entry.documentId,
139
- action: entry.action,
140
- userId: entry.userId,
141
- organizationId: entry.organizationId,
142
- before: entry.before,
143
- after: entry.after,
144
- changes: entry.changes,
145
- requestId: entry.requestId,
146
- ipAddress: entry.ipAddress,
147
- userAgent: entry.userAgent,
148
- metadata: entry.metadata,
149
- timestamp: entry.timestamp
150
- });
151
- }
152
- async query(options = {}) {
153
- await this.ensureIndexes();
154
- const query = {};
155
- if (options.resource) {
156
- query.resource = options.resource;
157
- }
158
- if (options.documentId) {
159
- query.documentId = options.documentId;
160
- }
161
- if (options.userId) {
162
- query.userId = options.userId;
163
- }
164
- if (options.organizationId) {
165
- query.organizationId = options.organizationId;
166
- }
167
- if (options.action) {
168
- const actions = Array.isArray(options.action) ? options.action : [options.action];
169
- query.action = actions.length === 1 ? actions[0] : { $in: actions };
170
- }
171
- if (options.from || options.to) {
172
- query.timestamp = {};
173
- if (options.from) {
174
- query.timestamp.$gte = options.from;
175
- }
176
- if (options.to) {
177
- query.timestamp.$lte = options.to;
178
- }
179
- }
180
- const offset = options.offset ?? 0;
181
- const limit = options.limit ?? 100;
182
- const docs = await this.collection.find(query).sort({ timestamp: -1 }).skip(offset).limit(limit).toArray();
183
- return docs.map((doc) => ({
184
- id: String(doc._id),
185
- resource: doc.resource,
186
- documentId: doc.documentId,
187
- action: doc.action,
188
- userId: doc.userId,
189
- organizationId: doc.organizationId,
190
- before: doc.before,
191
- after: doc.after,
192
- changes: doc.changes,
193
- requestId: doc.requestId,
194
- ipAddress: doc.ipAddress,
195
- userAgent: doc.userAgent,
196
- metadata: doc.metadata,
197
- timestamp: doc.timestamp
198
- }));
199
- }
200
- };
201
-
202
- // src/audit/auditPlugin.ts
203
- var auditPlugin = async (fastify, opts = {}) => {
204
- const {
205
- enabled = false,
206
- stores: storeTypes = ["memory"],
207
- mongoConnection,
208
- mongoCollection = "audit_logs",
209
- ttlDays = 90,
210
- customStores = []
211
- } = opts;
212
- if (!enabled) {
213
- fastify.decorate("audit", createNoopLogger());
214
- fastify.decorateRequest("auditContext", void 0);
215
- fastify.log?.debug?.("Audit plugin disabled");
216
- return;
217
- }
218
- const stores = [...customStores];
219
- for (const type of storeTypes) {
220
- switch (type) {
221
- case "memory":
222
- stores.push(new MemoryAuditStore());
223
- break;
224
- case "mongodb":
225
- if (!mongoConnection) {
226
- throw new Error("Audit: mongoConnection required for mongodb store");
227
- }
228
- stores.push(new MongoAuditStore({
229
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
230
- connection: mongoConnection,
231
- collection: mongoCollection,
232
- ttlDays
233
- }));
234
- break;
235
- }
236
- }
237
- if (stores.length === 0) {
238
- throw new Error("Audit: at least one store must be configured");
239
- }
240
- async function logToStores(entry) {
241
- await Promise.all(stores.map((store) => store.log(entry)));
242
- }
243
- const audit = {
244
- async create(resource, documentId, data, context) {
245
- const entry = createAuditEntry(resource, documentId, "create", context ?? {}, {
246
- after: data
247
- });
248
- await logToStores(entry);
249
- },
250
- async update(resource, documentId, before, after, context) {
251
- const entry = createAuditEntry(resource, documentId, "update", context ?? {}, {
252
- before,
253
- after
254
- });
255
- await logToStores(entry);
256
- },
257
- async delete(resource, documentId, data, context) {
258
- const entry = createAuditEntry(resource, documentId, "delete", context ?? {}, {
259
- before: data
260
- });
261
- await logToStores(entry);
262
- },
263
- async restore(resource, documentId, data, context) {
264
- const entry = createAuditEntry(resource, documentId, "restore", context ?? {}, {
265
- after: data
266
- });
267
- await logToStores(entry);
268
- },
269
- async custom(resource, documentId, action, data, context) {
270
- const entry = createAuditEntry(resource, documentId, "custom", context ?? {}, {
271
- metadata: { customAction: action, ...data }
272
- });
273
- await logToStores(entry);
274
- },
275
- async query(options) {
276
- for (const store of stores) {
277
- if (store.query) {
278
- return store.query(options);
279
- }
280
- }
281
- return [];
282
- }
283
- };
284
- fastify.decorate("audit", audit);
285
- fastify.decorateRequest("auditContext", void 0);
286
- fastify.addHook("onRequest", async (request) => {
287
- const user = request.user;
288
- const context = request.context;
289
- request.auditContext = {
290
- user,
291
- organizationId: context?.organizationId ?? void 0,
292
- requestId: request.id,
293
- ipAddress: request.ip,
294
- userAgent: request.headers["user-agent"]
295
- };
296
- });
297
- fastify.addHook("onClose", async () => {
298
- await Promise.all(stores.map((store) => store.close?.()));
299
- });
300
- fastify.log?.info?.({ stores: storeTypes }, "Audit plugin enabled");
301
- };
302
- function createNoopLogger() {
303
- const noop = async () => {
304
- };
305
- return {
306
- create: noop,
307
- update: noop,
308
- delete: noop,
309
- restore: noop,
310
- custom: noop,
311
- query: async () => []
312
- };
313
- }
314
- var auditPlugin_default = fp(auditPlugin, {
315
- name: "arc-audit",
316
- fastify: "5.x"
317
- });
318
-
319
- export { MemoryAuditStore, MongoAuditStore, auditPlugin_default as auditPlugin, auditPlugin as auditPluginFn, createAuditEntry };
@@ -1,47 +0,0 @@
1
- import { FastifyPluginAsync } from 'fastify';
2
- import { g as AuthHelpers, h as AuthPluginOptions } from '../index-B4t03KQ0.js';
3
- import 'mongoose';
4
- import '../types-B99TBmFV.js';
5
-
6
- /**
7
- * Auth Plugin - Flexible, Database-Agnostic Authentication
8
- *
9
- * Arc provides JWT infrastructure and calls your authenticator.
10
- * You control ALL authentication logic.
11
- *
12
- * Design principles:
13
- * - Arc handles plumbing (JWT sign/verify utilities)
14
- * - App handles business logic (how to authenticate, where users live)
15
- * - Works with any database (Prisma, MongoDB, Postgres, none)
16
- * - Supports multiple auth strategies (JWT, API keys, sessions, etc.)
17
- *
18
- * @example
19
- * ```typescript
20
- * // In createApp
21
- * auth: {
22
- * jwt: { secret: process.env.JWT_SECRET },
23
- * authenticate: async (request, { jwt }) => {
24
- * // Your auth logic - Arc never touches your database
25
- * const token = request.headers.authorization?.split(' ')[1];
26
- * if (!token) return null;
27
- * const decoded = jwt.verify(token);
28
- * return userRepo.findById(decoded.id);
29
- * },
30
- * }
31
- * ```
32
- */
33
-
34
- declare module 'fastify' {
35
- interface FastifyInstance {
36
- /** Authenticate middleware - use in preHandler for protected routes */
37
- authenticate: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
38
- /** Authorize middleware factory - checks if user has required roles */
39
- authorize: (...roles: string[]) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
40
- /** Auth helpers - issueTokens, jwt utilities */
41
- auth: AuthHelpers;
42
- }
43
- }
44
- declare const authPlugin: FastifyPluginAsync<AuthPluginOptions>;
45
- declare const _default: FastifyPluginAsync<AuthPluginOptions>;
46
-
47
- export { AuthPluginOptions, _default as authPlugin, authPlugin as authPluginFn };
@@ -1,174 +0,0 @@
1
- import fp from 'fastify-plugin';
2
-
3
- // src/auth/authPlugin.ts
4
- function parseExpiresIn(input, defaultValue) {
5
- if (!input) return defaultValue;
6
- if (/^\d+$/.test(input)) return parseInt(input, 10);
7
- const match = /^(\d+)\s*([smhd])$/i.exec(input);
8
- if (!match) return defaultValue;
9
- const value = parseInt(match[1], 10);
10
- const unit = match[2].toLowerCase();
11
- const multipliers = { s: 1, m: 60, h: 3600, d: 86400 };
12
- return value * (multipliers[unit] ?? 1);
13
- }
14
- function extractBearerToken(request) {
15
- const auth = request.headers.authorization;
16
- if (!auth?.startsWith("Bearer ")) return null;
17
- return auth.slice(7);
18
- }
19
- var authPlugin = async (fastify, opts = {}) => {
20
- const { jwt: jwtConfig, authenticate: appAuthenticator, onFailure, userProperty = "user" } = opts;
21
- let jwtContext = null;
22
- if (jwtConfig?.secret) {
23
- if (jwtConfig.secret.length < 32) {
24
- throw new Error(
25
- `JWT secret must be at least 32 characters (current: ${jwtConfig.secret.length}).
26
- Use a strong random secret for production.`
27
- );
28
- }
29
- const jwtPlugin = await import('@fastify/jwt');
30
- await fastify.register(jwtPlugin.default ?? jwtPlugin, {
31
- secret: jwtConfig.secret,
32
- sign: {
33
- expiresIn: jwtConfig.expiresIn ?? "15m",
34
- ...jwtConfig.sign ?? {}
35
- },
36
- verify: { ...jwtConfig.verify ?? {} }
37
- });
38
- const fastifyWithJwt = fastify;
39
- jwtContext = {
40
- verify: (token) => {
41
- return fastifyWithJwt.jwt.verify(token);
42
- },
43
- sign: (payload, options) => {
44
- return fastifyWithJwt.jwt.sign(payload, options);
45
- },
46
- decode: (token) => {
47
- try {
48
- return fastifyWithJwt.jwt.decode(token);
49
- } catch {
50
- return null;
51
- }
52
- }
53
- };
54
- fastify.log.info("Auth: JWT infrastructure enabled");
55
- }
56
- const authContext = {
57
- jwt: jwtContext,
58
- fastify
59
- };
60
- const authenticate = async (request, reply) => {
61
- try {
62
- let user = null;
63
- if (appAuthenticator) {
64
- user = await appAuthenticator(request, authContext);
65
- } else if (jwtContext) {
66
- const token = extractBearerToken(request);
67
- if (token) {
68
- const decoded = jwtContext.verify(token);
69
- user = decoded;
70
- }
71
- } else {
72
- throw new Error(
73
- "No authenticator configured. Provide auth.authenticate function or auth.jwt.secret."
74
- );
75
- }
76
- if (!user) {
77
- throw new Error("Authentication required");
78
- }
79
- request[userProperty] = user;
80
- } catch (err) {
81
- const error = err instanceof Error ? err : new Error(String(err));
82
- if (onFailure) {
83
- await onFailure(request, reply, error);
84
- return;
85
- }
86
- const message = process.env.NODE_ENV === "production" ? "Authentication required" : error.message;
87
- reply.code(401).send({
88
- success: false,
89
- error: "Unauthorized",
90
- message
91
- });
92
- }
93
- };
94
- const refreshSecret = jwtConfig?.refreshSecret ?? jwtConfig?.secret;
95
- const accessExpiresIn = jwtConfig?.expiresIn ?? "15m";
96
- const refreshExpiresIn = jwtConfig?.refreshExpiresIn ?? "7d";
97
- const issueTokens = (payload, options) => {
98
- if (!jwtContext) {
99
- throw new Error("JWT not configured. Provide auth.jwt.secret to use issueTokens.");
100
- }
101
- const accessTtl = options?.expiresIn ?? accessExpiresIn;
102
- const refreshTtl = options?.refreshExpiresIn ?? refreshExpiresIn;
103
- const accessToken = jwtContext.sign(payload, { expiresIn: accessTtl });
104
- const refreshPayload = payload.id ? { id: payload.id, type: "refresh" } : payload._id ? { id: payload._id, type: "refresh" } : { ...payload, type: "refresh" };
105
- let refreshToken;
106
- if (refreshSecret) {
107
- const fastifyWithJwt = fastify;
108
- refreshToken = fastifyWithJwt.jwt.sign(refreshPayload, {
109
- expiresIn: refreshTtl,
110
- // Use refresh secret if different from main secret
111
- ...refreshSecret !== jwtConfig?.secret ? { secret: refreshSecret } : {}
112
- });
113
- }
114
- return {
115
- accessToken,
116
- refreshToken,
117
- expiresIn: parseExpiresIn(accessTtl, 900),
118
- refreshExpiresIn: refreshToken ? parseExpiresIn(refreshTtl, 604800) : void 0,
119
- tokenType: "Bearer"
120
- };
121
- };
122
- const verifyRefreshToken = (token) => {
123
- if (!jwtContext) {
124
- throw new Error("JWT not configured. Provide auth.jwt.secret to use verifyRefreshToken.");
125
- }
126
- const fastifyWithJwt = fastify;
127
- return fastifyWithJwt.jwt.verify(token, {
128
- ...refreshSecret !== jwtConfig?.secret ? { secret: refreshSecret } : {}
129
- });
130
- };
131
- const authorize = (...allowedRoles) => {
132
- return async (request, reply) => {
133
- const user = request[userProperty];
134
- if (!user) {
135
- reply.code(401).send({
136
- success: false,
137
- error: "Unauthorized",
138
- message: "No user context"
139
- });
140
- return;
141
- }
142
- const userRoles = user.roles ?? [];
143
- if (allowedRoles.length === 1 && allowedRoles[0] === "*") {
144
- return;
145
- }
146
- const hasRole = allowedRoles.some((role) => userRoles.includes(role));
147
- if (!hasRole) {
148
- reply.code(403).send({
149
- success: false,
150
- error: "Forbidden",
151
- message: `Requires one of: ${allowedRoles.join(", ")}`
152
- });
153
- return;
154
- }
155
- };
156
- };
157
- const authHelpers = {
158
- jwt: jwtContext,
159
- issueTokens,
160
- verifyRefreshToken
161
- };
162
- fastify.decorate("authenticate", authenticate);
163
- fastify.decorate("authorize", authorize);
164
- fastify.decorate("auth", authHelpers);
165
- fastify.log.info(
166
- `Auth: Plugin registered (jwt=${!!jwtContext}, customAuth=${!!appAuthenticator})`
167
- );
168
- };
169
- var authPlugin_default = fp(authPlugin, {
170
- name: "arc-auth",
171
- fastify: "5.x"
172
- });
173
-
174
- export { authPlugin_default as authPlugin, authPlugin as authPluginFn };
@@ -1,11 +0,0 @@
1
- /**
2
- * Arc CLI - Docs Command
3
- *
4
- * Export OpenAPI specification from registered resources
5
- */
6
- declare function exportDocs(args: string[]): Promise<void>;
7
- declare const _default: {
8
- exportDocs: typeof exportDocs;
9
- };
10
-
11
- export { _default as default, exportDocs };