@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,4 +0,0 @@
1
- export { ac as HookContext, ad as HookHandler, aI as HookOperation, aH as HookPhase, aJ as HookRegistration, H as HookSystem, aK as HookSystemOptions, aC as afterCreate, aG as afterDelete, aE as afterUpdate, aB as beforeCreate, aF as beforeDelete, aD as beforeUpdate, aA as createHookSystem, ab as hookSystem } from '../index-B4t03KQ0.js';
2
- import 'mongoose';
3
- import 'fastify';
4
- import '../types-B99TBmFV.js';
@@ -1,199 +0,0 @@
1
- // src/hooks/HookSystem.ts
2
- var HookSystem = class {
3
- hooks;
4
- logger;
5
- constructor(options) {
6
- this.hooks = /* @__PURE__ */ new Map();
7
- this.logger = options?.logger ?? { error: (...args) => console.error(...args) };
8
- }
9
- /**
10
- * Generate hook key
11
- */
12
- getKey(resource, operation, phase) {
13
- return `${resource}:${operation}:${phase}`;
14
- }
15
- /**
16
- * Register a hook
17
- * Supports both object parameter and positional arguments
18
- */
19
- register(resourceOrOptions, operation, phase, handler, priority = 10) {
20
- let resource;
21
- let finalOperation;
22
- let finalPhase;
23
- let finalHandler;
24
- let finalPriority;
25
- if (typeof resourceOrOptions === "object") {
26
- resource = resourceOrOptions.resource;
27
- finalOperation = resourceOrOptions.operation;
28
- finalPhase = resourceOrOptions.phase;
29
- finalHandler = resourceOrOptions.handler;
30
- finalPriority = resourceOrOptions.priority ?? 10;
31
- } else {
32
- resource = resourceOrOptions;
33
- finalOperation = operation;
34
- finalPhase = phase;
35
- finalHandler = handler;
36
- finalPriority = priority;
37
- }
38
- const key = this.getKey(resource, finalOperation, finalPhase);
39
- if (!this.hooks.has(key)) {
40
- this.hooks.set(key, []);
41
- }
42
- const registration = {
43
- resource,
44
- operation: finalOperation,
45
- phase: finalPhase,
46
- handler: finalHandler,
47
- priority: finalPriority
48
- };
49
- const hooks = this.hooks.get(key);
50
- hooks.push(registration);
51
- hooks.sort((a, b) => a.priority - b.priority);
52
- return () => {
53
- const idx = hooks.indexOf(registration);
54
- if (idx !== -1) {
55
- hooks.splice(idx, 1);
56
- }
57
- };
58
- }
59
- /**
60
- * Register before hook
61
- */
62
- before(resource, operation, handler, priority = 10) {
63
- return this.register(resource, operation, "before", handler, priority);
64
- }
65
- /**
66
- * Register after hook
67
- */
68
- after(resource, operation, handler, priority = 10) {
69
- return this.register(resource, operation, "after", handler, priority);
70
- }
71
- /**
72
- * Execute hooks for a given context
73
- */
74
- async execute(ctx) {
75
- const key = this.getKey(ctx.resource, ctx.operation, ctx.phase);
76
- const hooks = this.hooks.get(key) ?? [];
77
- const wildcardKey = this.getKey("*", ctx.operation, ctx.phase);
78
- const wildcardHooks = this.hooks.get(wildcardKey) ?? [];
79
- const allHooks = [...wildcardHooks, ...hooks];
80
- allHooks.sort((a, b) => a.priority - b.priority);
81
- let result = ctx.data;
82
- for (const hook of allHooks) {
83
- const handlerContext = {
84
- resource: ctx.resource,
85
- operation: ctx.operation,
86
- phase: ctx.phase,
87
- data: result,
88
- result: ctx.result,
89
- user: ctx.user,
90
- context: ctx.context,
91
- meta: ctx.meta
92
- };
93
- const hookResult = await hook.handler(handlerContext);
94
- if (hookResult !== void 0 && hookResult !== null) {
95
- result = hookResult;
96
- }
97
- }
98
- return result;
99
- }
100
- /**
101
- * Execute before hooks
102
- */
103
- async executeBefore(resource, operation, data, options) {
104
- const result = await this.execute({
105
- resource,
106
- operation,
107
- phase: "before",
108
- data,
109
- user: options?.user,
110
- context: options?.context,
111
- meta: options?.meta
112
- });
113
- return result ?? data;
114
- }
115
- /**
116
- * Execute after hooks
117
- * Errors in after hooks are logged but don't fail the request
118
- */
119
- async executeAfter(resource, operation, result, options) {
120
- try {
121
- await this.execute({
122
- resource,
123
- operation,
124
- phase: "after",
125
- result,
126
- user: options?.user,
127
- context: options?.context,
128
- meta: options?.meta
129
- });
130
- } catch (error) {
131
- this.logger.error(
132
- `[HookSystem] Error in after hook for ${resource}:${operation}:`,
133
- error
134
- );
135
- }
136
- }
137
- /**
138
- * Get all registered hooks
139
- */
140
- getAll() {
141
- const all = [];
142
- for (const hooks of this.hooks.values()) {
143
- all.push(...hooks);
144
- }
145
- return all;
146
- }
147
- /**
148
- * Get hooks for a specific resource
149
- */
150
- getForResource(resource) {
151
- const all = [];
152
- for (const [key, hooks] of this.hooks.entries()) {
153
- if (key.startsWith(`${resource}:`)) {
154
- all.push(...hooks);
155
- }
156
- }
157
- return all;
158
- }
159
- /**
160
- * Clear all hooks
161
- */
162
- clear() {
163
- this.hooks.clear();
164
- }
165
- /**
166
- * Clear hooks for a specific resource
167
- */
168
- clearResource(resource) {
169
- for (const key of this.hooks.keys()) {
170
- if (key.startsWith(`${resource}:`)) {
171
- this.hooks.delete(key);
172
- }
173
- }
174
- }
175
- };
176
- function createHookSystem(options) {
177
- return new HookSystem(options);
178
- }
179
- var hookSystem = new HookSystem();
180
- function beforeCreate(resource, handler, priority = 10) {
181
- return hookSystem.before(resource, "create", handler, priority);
182
- }
183
- function afterCreate(resource, handler, priority = 10) {
184
- return hookSystem.after(resource, "create", handler, priority);
185
- }
186
- function beforeUpdate(resource, handler, priority = 10) {
187
- return hookSystem.before(resource, "update", handler, priority);
188
- }
189
- function afterUpdate(resource, handler, priority = 10) {
190
- return hookSystem.after(resource, "update", handler, priority);
191
- }
192
- function beforeDelete(resource, handler, priority = 10) {
193
- return hookSystem.before(resource, "delete", handler, priority);
194
- }
195
- function afterDelete(resource, handler, priority = 10) {
196
- return hookSystem.after(resource, "delete", handler, priority);
197
- }
198
-
199
- export { HookSystem, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, hookSystem };
@@ -1,323 +0,0 @@
1
- import { FastifyPluginAsync } from 'fastify';
2
-
3
- /**
4
- * Idempotency Store Interface
5
- *
6
- * Defines the contract for idempotency key storage backends.
7
- * Implement this interface for custom stores (Redis, DynamoDB, etc.)
8
- */
9
- interface IdempotencyResult {
10
- /** The idempotency key */
11
- key: string;
12
- /** HTTP status code of the cached response */
13
- statusCode: number;
14
- /** Response headers to replay */
15
- headers: Record<string, string>;
16
- /** Response body */
17
- body: unknown;
18
- /** When this entry was created */
19
- createdAt: Date;
20
- /** When this entry expires */
21
- expiresAt: Date;
22
- }
23
- interface IdempotencyLock {
24
- /** The idempotency key being locked */
25
- key: string;
26
- /** Request ID that holds the lock */
27
- requestId: string;
28
- /** When the lock was acquired */
29
- lockedAt: Date;
30
- /** When the lock expires (auto-release) */
31
- expiresAt: Date;
32
- }
33
- interface IdempotencyStore {
34
- /** Store name for logging */
35
- readonly name: string;
36
- /**
37
- * Get a cached result for an idempotency key
38
- * Returns undefined if not found or expired
39
- */
40
- get(key: string): Promise<IdempotencyResult | undefined>;
41
- /**
42
- * Store a result for an idempotency key
43
- * TTL is handled by the store implementation
44
- */
45
- set(key: string, result: Omit<IdempotencyResult, 'key'>): Promise<void>;
46
- /**
47
- * Try to acquire a lock for processing a key
48
- * Returns true if lock acquired, false if already locked
49
- * Used to prevent concurrent processing of the same key
50
- */
51
- tryLock(key: string, requestId: string, ttlMs: number): Promise<boolean>;
52
- /**
53
- * Release a lock after processing complete
54
- */
55
- unlock(key: string, requestId: string): Promise<void>;
56
- /**
57
- * Check if a key is currently locked
58
- */
59
- isLocked(key: string): Promise<boolean>;
60
- /**
61
- * Delete a cached result (for manual invalidation)
62
- */
63
- delete(key: string): Promise<void>;
64
- /**
65
- * Close the store (cleanup connections)
66
- */
67
- close?(): Promise<void>;
68
- }
69
- /**
70
- * Helper to create a result object
71
- */
72
- declare function createIdempotencyResult(statusCode: number, body: unknown, headers: Record<string, string>, ttlMs: number): Omit<IdempotencyResult, 'key'>;
73
-
74
- /**
75
- * Idempotency Plugin
76
- *
77
- * Duplicate request protection for mutating operations.
78
- * Uses idempotency keys to ensure safe retries.
79
- *
80
- * @example
81
- * import { idempotencyPlugin } from '@classytic/arc/idempotency';
82
- *
83
- * await fastify.register(idempotencyPlugin, {
84
- * enabled: true,
85
- * headerName: 'idempotency-key',
86
- * ttlMs: 86400000, // 24 hours
87
- * });
88
- *
89
- * // Client sends:
90
- * // POST /api/orders
91
- * // Idempotency-Key: order-123-abc
92
- *
93
- * // If same key sent again within TTL, returns cached response
94
- */
95
-
96
- interface IdempotencyPluginOptions {
97
- /** Enable idempotency (default: false) */
98
- enabled?: boolean;
99
- /** Header name for idempotency key (default: 'idempotency-key') */
100
- headerName?: string;
101
- /** TTL for cached responses in ms (default: 86400000 = 24h) */
102
- ttlMs?: number;
103
- /** Lock timeout in ms (default: 30000 = 30s) */
104
- lockTimeoutMs?: number;
105
- /** HTTP methods to apply idempotency to (default: ['POST', 'PUT', 'PATCH']) */
106
- methods?: string[];
107
- /** URL patterns to include (regex). If set, only matching URLs use idempotency */
108
- include?: RegExp[];
109
- /** URL patterns to exclude (regex). Excluded patterns take precedence */
110
- exclude?: RegExp[];
111
- /** Custom store (default: MemoryIdempotencyStore) */
112
- store?: IdempotencyStore;
113
- /** Retry-After header value in seconds when request is in-flight (default: 1) */
114
- retryAfterSeconds?: number;
115
- }
116
- declare module 'fastify' {
117
- interface FastifyRequest {
118
- /** The idempotency key for this request (if present) */
119
- idempotencyKey?: string;
120
- /** Whether this response was replayed from cache */
121
- idempotencyReplayed?: boolean;
122
- }
123
- interface FastifyInstance {
124
- /** Idempotency utilities */
125
- idempotency: {
126
- /** Manually invalidate an idempotency key */
127
- invalidate: (key: string) => Promise<void>;
128
- /** Check if a key has a cached response */
129
- has: (key: string) => Promise<boolean>;
130
- };
131
- }
132
- }
133
- declare const idempotencyPlugin: FastifyPluginAsync<IdempotencyPluginOptions>;
134
- declare const _default: FastifyPluginAsync<IdempotencyPluginOptions>;
135
-
136
- /**
137
- * In-Memory Idempotency Store
138
- *
139
- * Default store for development and small deployments.
140
- * NOT suitable for multi-instance deployments - use Redis or similar.
141
- *
142
- * Features:
143
- * - Automatic TTL expiration
144
- * - Lock support for concurrent request handling
145
- * - Periodic cleanup of expired entries
146
- */
147
-
148
- interface MemoryIdempotencyStoreOptions {
149
- /** Default TTL in milliseconds (default: 86400000 = 24h) */
150
- ttlMs?: number;
151
- /** Cleanup interval in milliseconds (default: 60000 = 1 min) */
152
- cleanupIntervalMs?: number;
153
- /** Maximum entries before oldest are evicted (default: 10000) */
154
- maxEntries?: number;
155
- }
156
- declare class MemoryIdempotencyStore implements IdempotencyStore {
157
- readonly name = "memory";
158
- private results;
159
- private locks;
160
- private ttlMs;
161
- private maxEntries;
162
- private cleanupInterval;
163
- constructor(options?: MemoryIdempotencyStoreOptions);
164
- get(key: string): Promise<IdempotencyResult | undefined>;
165
- set(key: string, result: Omit<IdempotencyResult, 'key'>): Promise<void>;
166
- tryLock(key: string, requestId: string, ttlMs: number): Promise<boolean>;
167
- unlock(key: string, requestId: string): Promise<void>;
168
- isLocked(key: string): Promise<boolean>;
169
- delete(key: string): Promise<void>;
170
- close(): Promise<void>;
171
- /**
172
- * Get current stats (for debugging/monitoring)
173
- */
174
- getStats(): {
175
- results: number;
176
- locks: number;
177
- };
178
- /**
179
- * Remove expired entries
180
- */
181
- private cleanup;
182
- /**
183
- * Evict oldest entries when at capacity
184
- */
185
- private evictOldest;
186
- }
187
-
188
- /**
189
- * Redis Idempotency Store
190
- *
191
- * Durable idempotency store using Redis.
192
- * Suitable for multi-instance deployments.
193
- *
194
- * @example
195
- * import { createClient } from 'redis';
196
- * import { RedisIdempotencyStore } from '@classytic/arc/idempotency';
197
- *
198
- * const redis = createClient({ url: process.env.REDIS_URL });
199
- * await redis.connect();
200
- *
201
- * await fastify.register(idempotencyPlugin, {
202
- * store: new RedisIdempotencyStore({ client: redis }),
203
- * });
204
- */
205
-
206
- interface RedisClient {
207
- get(key: string): Promise<string | null>;
208
- set(key: string, value: string, options?: {
209
- EX?: number;
210
- NX?: boolean;
211
- }): Promise<string | null>;
212
- del(key: string | string[]): Promise<number>;
213
- exists(key: string | string[]): Promise<number>;
214
- quit?(): Promise<string>;
215
- disconnect?(): Promise<void>;
216
- }
217
- interface RedisIdempotencyStoreOptions {
218
- /** Redis client instance */
219
- client: RedisClient;
220
- /** Key prefix (default: 'idem:') */
221
- prefix?: string;
222
- /** Lock key prefix (default: 'idem:lock:') */
223
- lockPrefix?: string;
224
- /** Default TTL in ms (default: 86400000 = 24 hours) */
225
- ttlMs?: number;
226
- }
227
- declare class RedisIdempotencyStore implements IdempotencyStore {
228
- readonly name = "redis";
229
- private client;
230
- private prefix;
231
- private lockPrefix;
232
- private ttlMs;
233
- constructor(options: RedisIdempotencyStoreOptions);
234
- private resultKey;
235
- private lockKey;
236
- get(key: string): Promise<IdempotencyResult | undefined>;
237
- set(key: string, result: Omit<IdempotencyResult, 'key'>): Promise<void>;
238
- tryLock(key: string, requestId: string, ttlMs: number): Promise<boolean>;
239
- unlock(key: string, requestId: string): Promise<void>;
240
- isLocked(key: string): Promise<boolean>;
241
- delete(key: string): Promise<void>;
242
- close(): Promise<void>;
243
- }
244
-
245
- /**
246
- * MongoDB Idempotency Store
247
- *
248
- * Durable idempotency store using MongoDB.
249
- * Suitable for multi-instance deployments.
250
- *
251
- * @example
252
- * import mongoose from 'mongoose';
253
- * import { MongoIdempotencyStore } from '@classytic/arc/idempotency';
254
- *
255
- * await fastify.register(idempotencyPlugin, {
256
- * store: new MongoIdempotencyStore({
257
- * connection: mongoose.connection,
258
- * collection: 'idempotency_keys',
259
- * }),
260
- * });
261
- */
262
-
263
- interface MongoConnection {
264
- db: {
265
- collection(name: string): MongoCollection;
266
- };
267
- }
268
- interface MongoCollection {
269
- findOne(filter: object): Promise<IdempotencyDocument | null>;
270
- insertOne(doc: object): Promise<{
271
- acknowledged: boolean;
272
- }>;
273
- updateOne(filter: object, update: object, options?: object): Promise<{
274
- acknowledged: boolean;
275
- }>;
276
- deleteOne(filter: object): Promise<{
277
- deletedCount: number;
278
- }>;
279
- createIndex(spec: object, options?: object): Promise<string>;
280
- }
281
- interface IdempotencyDocument {
282
- _id: string;
283
- result?: {
284
- statusCode: number;
285
- headers: Record<string, string>;
286
- body: unknown;
287
- };
288
- lock?: {
289
- requestId: string;
290
- expiresAt: Date;
291
- };
292
- createdAt: Date;
293
- expiresAt: Date;
294
- }
295
- interface MongoIdempotencyStoreOptions {
296
- /** Mongoose connection or MongoDB connection object */
297
- connection: MongoConnection;
298
- /** Collection name (default: 'arc_idempotency') */
299
- collection?: string;
300
- /** Create TTL index on startup (default: true) */
301
- createIndex?: boolean;
302
- /** Default TTL in ms (default: 86400000 = 24 hours) */
303
- ttlMs?: number;
304
- }
305
- declare class MongoIdempotencyStore implements IdempotencyStore {
306
- readonly name = "mongodb";
307
- private connection;
308
- private collectionName;
309
- private ttlMs;
310
- private indexCreated;
311
- constructor(options: MongoIdempotencyStoreOptions);
312
- private get collection();
313
- private ensureIndex;
314
- get(key: string): Promise<IdempotencyResult | undefined>;
315
- set(key: string, result: Omit<IdempotencyResult, 'key'>): Promise<void>;
316
- tryLock(key: string, requestId: string, ttlMs: number): Promise<boolean>;
317
- unlock(key: string, requestId: string): Promise<void>;
318
- isLocked(key: string): Promise<boolean>;
319
- delete(key: string): Promise<void>;
320
- close(): Promise<void>;
321
- }
322
-
323
- export { type IdempotencyLock, type IdempotencyPluginOptions, type IdempotencyResult, type IdempotencyStore, MemoryIdempotencyStore, type MemoryIdempotencyStoreOptions, MongoIdempotencyStore, type MongoIdempotencyStoreOptions, type RedisClient, RedisIdempotencyStore, type RedisIdempotencyStoreOptions, createIdempotencyResult, _default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn };