@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
@@ -0,0 +1,85 @@
1
+ //#region src/constants.ts
2
+ /**
3
+ * Arc Framework Constants — Single Source of Truth
4
+ *
5
+ * Every default value, magic string, and framework constant lives here.
6
+ * Import from this module instead of hard-coding values inline.
7
+ *
8
+ * All exported values are deeply frozen (Object.freeze) to prevent
9
+ * accidental mutation at runtime — inspired by Go's const blocks
10
+ * and Rust's immutable-by-default philosophy.
11
+ */
12
+ /** Standard CRUD operation names */
13
+ const CRUD_OPERATIONS = Object.freeze([
14
+ "list",
15
+ "get",
16
+ "create",
17
+ "update",
18
+ "delete"
19
+ ]);
20
+ /** Mutation operations that emit events */
21
+ const MUTATION_OPERATIONS = Object.freeze([
22
+ "create",
23
+ "update",
24
+ "delete"
25
+ ]);
26
+ /** Lifecycle hook phases */
27
+ const HOOK_PHASES = Object.freeze([
28
+ "before",
29
+ "around",
30
+ "after"
31
+ ]);
32
+ /** Hook operations (superset of CRUD — includes 'read' alias for 'get') */
33
+ const HOOK_OPERATIONS = Object.freeze([
34
+ "create",
35
+ "update",
36
+ "delete",
37
+ "read",
38
+ "list"
39
+ ]);
40
+ /** Default items per page */
41
+ const DEFAULT_LIMIT = 20;
42
+ /** Maximum items per page (framework-wide ceiling) */
43
+ const DEFAULT_MAX_LIMIT = 1e3;
44
+ /** Default sort field (descending creation date) */
45
+ const DEFAULT_SORT = "-createdAt";
46
+ /** Default primary key field name */
47
+ const DEFAULT_ID_FIELD = "_id";
48
+ /** Default multi-tenant scoping field */
49
+ const DEFAULT_TENANT_FIELD = "organizationId";
50
+ /** Default HTTP method for update routes */
51
+ const DEFAULT_UPDATE_METHOD = "PATCH";
52
+ /** System-managed fields that cannot be set via request body */
53
+ const SYSTEM_FIELDS = Object.freeze([
54
+ "_id",
55
+ "__v",
56
+ "createdAt",
57
+ "updatedAt",
58
+ "deletedAt"
59
+ ]);
60
+ /** Maximum regex pattern length (ReDoS mitigation) */
61
+ const MAX_REGEX_LENGTH = 200;
62
+ /** Maximum search query length */
63
+ const MAX_SEARCH_LENGTH = 200;
64
+ /** Maximum filter nesting depth (prevents filter bombs) */
65
+ const MAX_FILTER_DEPTH = 10;
66
+ /**
67
+ * Query parameters consumed by the framework — never treated as filters.
68
+ * Shared by all query parsers (Arc built-in, Prisma, custom).
69
+ */
70
+ const RESERVED_QUERY_PARAMS = Object.freeze(new Set([
71
+ "page",
72
+ "limit",
73
+ "sort",
74
+ "populate",
75
+ "search",
76
+ "select",
77
+ "after",
78
+ "cursor",
79
+ "lean",
80
+ "_policyFilters"
81
+ ]));
82
+
83
+ //#endregion
84
+ export { DEFAULT_SORT as a, HOOK_OPERATIONS as c, MAX_REGEX_LENGTH as d, MAX_SEARCH_LENGTH as f, SYSTEM_FIELDS as h, DEFAULT_MAX_LIMIT as i, HOOK_PHASES as l, RESERVED_QUERY_PARAMS as m, DEFAULT_ID_FIELD as n, DEFAULT_TENANT_FIELD as o, MUTATION_OPERATIONS as p, DEFAULT_LIMIT as r, DEFAULT_UPDATE_METHOD as s, CRUD_OPERATIONS as t, MAX_FILTER_DEPTH as u };
85
+ //# sourceMappingURL=constants-DdXFXQtN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants-DdXFXQtN.mjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Arc Framework Constants — Single Source of Truth\n *\n * Every default value, magic string, and framework constant lives here.\n * Import from this module instead of hard-coding values inline.\n *\n * All exported values are deeply frozen (Object.freeze) to prevent\n * accidental mutation at runtime — inspired by Go's const blocks\n * and Rust's immutable-by-default philosophy.\n */\n\n// ============================================================================\n// CRUD Operations\n// ============================================================================\n\n/** Standard CRUD operation names */\nexport const CRUD_OPERATIONS = Object.freeze(\n ['list', 'get', 'create', 'update', 'delete'] as const,\n);\nexport type CrudOperation = (typeof CRUD_OPERATIONS)[number];\n\n/** Mutation operations that emit events */\nexport const MUTATION_OPERATIONS = Object.freeze(\n ['create', 'update', 'delete'] as const,\n);\nexport type MutationOperation = (typeof MUTATION_OPERATIONS)[number];\n\n// ============================================================================\n// Hook Phases\n// ============================================================================\n\n/** Lifecycle hook phases */\nexport const HOOK_PHASES = Object.freeze(\n ['before', 'around', 'after'] as const,\n);\nexport type HookPhase = (typeof HOOK_PHASES)[number];\n\n/** Hook operations (superset of CRUD — includes 'read' alias for 'get') */\nexport const HOOK_OPERATIONS = Object.freeze(\n ['create', 'update', 'delete', 'read', 'list'] as const,\n);\nexport type HookOperation = (typeof HOOK_OPERATIONS)[number];\n\n// ============================================================================\n// Pagination & Query Defaults\n// ============================================================================\n\n/** Default items per page */\nexport const DEFAULT_LIMIT = 20 as const;\n\n/** Maximum items per page (framework-wide ceiling) */\nexport const DEFAULT_MAX_LIMIT = 1000 as const;\n\n/** Default sort field (descending creation date) */\nexport const DEFAULT_SORT = '-createdAt' as const;\n\n// ============================================================================\n// Field & Schema Defaults\n// ============================================================================\n\n/** Default primary key field name */\nexport const DEFAULT_ID_FIELD = '_id' as const;\n\n/** Default multi-tenant scoping field */\nexport const DEFAULT_TENANT_FIELD = 'organizationId' as const;\n\n/** Default HTTP method for update routes */\nexport const DEFAULT_UPDATE_METHOD = 'PATCH' as const;\n\n/** System-managed fields that cannot be set via request body */\nexport const SYSTEM_FIELDS = Object.freeze(\n ['_id', '__v', 'createdAt', 'updatedAt', 'deletedAt'] as const,\n);\n\n// ============================================================================\n// Security Limits\n// ============================================================================\n\n/** Maximum regex pattern length (ReDoS mitigation) */\nexport const MAX_REGEX_LENGTH = 200 as const;\n\n/** Maximum search query length */\nexport const MAX_SEARCH_LENGTH = 200 as const;\n\n/** Maximum filter nesting depth (prevents filter bombs) */\nexport const MAX_FILTER_DEPTH = 10 as const;\n\n// ============================================================================\n// Reserved Query Parameters\n// ============================================================================\n\n/**\n * Query parameters consumed by the framework — never treated as filters.\n * Shared by all query parsers (Arc built-in, Prisma, custom).\n */\nexport const RESERVED_QUERY_PARAMS = Object.freeze(\n new Set([\n 'page',\n 'limit',\n 'sort',\n 'populate',\n 'search',\n 'select',\n 'after',\n 'cursor',\n 'lean',\n '_policyFilters',\n ]),\n);\n"],"mappings":";;;;;;;;;;;;AAgBA,MAAa,kBAAkB,OAAO,OACpC;CAAC;CAAQ;CAAO;CAAU;CAAU;CAAS,CAC9C;;AAID,MAAa,sBAAsB,OAAO,OACxC;CAAC;CAAU;CAAU;CAAS,CAC/B;;AAQD,MAAa,cAAc,OAAO,OAChC;CAAC;CAAU;CAAU;CAAQ,CAC9B;;AAID,MAAa,kBAAkB,OAAO,OACpC;CAAC;CAAU;CAAU;CAAU;CAAQ;CAAO,CAC/C;;AAQD,MAAa,gBAAgB;;AAG7B,MAAa,oBAAoB;;AAGjC,MAAa,eAAe;;AAO5B,MAAa,mBAAmB;;AAGhC,MAAa,uBAAuB;;AAGpC,MAAa,wBAAwB;;AAGrC,MAAa,gBAAgB,OAAO,OAClC;CAAC;CAAO;CAAO;CAAa;CAAa;CAAY,CACtD;;AAOD,MAAa,mBAAmB;;AAGhC,MAAa,oBAAoB;;AAGjC,MAAa,mBAAmB;;;;;AAUhC,MAAa,wBAAwB,OAAO,OAC1C,IAAI,IAAI;CACN;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC,CACH"}
@@ -0,0 +1,5 @@
1
+ import "../elevation-B_2dRLVP.mjs";
2
+ import { E as defineResource, T as ResourceDefinition, c as BaseController, d as QueryResolverConfig, f as BodySanitizer, h as AccessControlConfig, l as BaseControllerOptions, m as AccessControl, p as BodySanitizerConfig, u as QueryResolver } from "../interface-Ch8HU9uM.mjs";
3
+ import "../types-aYB4V7uN.mjs";
4
+ import { A as createCrudRouter, C as MutationOperation, D as ActionRouterConfig, E as ActionHandler, O as IdempotencyService, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, i as getControllerContext, j as createPermissionMiddleware, k as createActionRouter, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, n as createFastifyHandler, o as sendControllerResponse, p as DEFAULT_TENANT_FIELD, r as createRequestContext, s as CRUD_OPERATIONS, t as createCrudHandlers, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "../fastifyAdapter-BkrGrlFi.mjs";
5
+ export { AccessControl, type AccessControlConfig, type ActionHandler, type ActionRouterConfig, BaseController, type BaseControllerOptions, BodySanitizer, type BodySanitizerConfig, CRUD_OPERATIONS, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, type IdempotencyService, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, type QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, createActionRouter, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, getControllerContext, getControllerScope, sendControllerResponse };
@@ -0,0 +1,4 @@
1
+ import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "../constants-DdXFXQtN.mjs";
2
+ import { _ as QueryResolver, c as createPermissionMiddleware, d as createFastifyHandler, f as createRequestContext, g as BaseController, h as sendControllerResponse, m as getControllerScope, n as defineResource, o as createActionRouter, p as getControllerContext, s as createCrudRouter, t as ResourceDefinition, u as createCrudHandlers, v as BodySanitizer, y as AccessControl } from "../defineResource-k0_BDn8v.mjs";
3
+
4
+ export { AccessControl, BaseController, BodySanitizer, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, QueryResolver, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, createActionRouter, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, getControllerContext, getControllerScope, sendControllerResponse };
@@ -0,0 +1,560 @@
1
+ import { t as __exportAll } from "./chunk-C7Uep-_p.mjs";
2
+ import { n as PUBLIC_SCOPE } from "./types-Beqn1Un7.mjs";
3
+ import Fastify from "fastify";
4
+ import qs from "qs";
5
+
6
+ //#region src/factory/presets.ts
7
+ /**
8
+ * Production preset - strict security, performance optimized
9
+ */
10
+ const productionPreset = {
11
+ logger: {
12
+ level: "info",
13
+ redact: {
14
+ paths: [
15
+ "req.headers.authorization",
16
+ "req.headers.cookie",
17
+ "req.headers[\"set-cookie\"]",
18
+ "*.password",
19
+ "*.secret",
20
+ "*.token",
21
+ "*.accessToken",
22
+ "*.refreshToken",
23
+ "*.creditCard"
24
+ ],
25
+ censor: "[REDACTED]"
26
+ }
27
+ },
28
+ trustProxy: true,
29
+ helmet: { contentSecurityPolicy: { directives: {
30
+ defaultSrc: ["'self'"],
31
+ styleSrc: ["'self'", "'unsafe-inline'"],
32
+ scriptSrc: ["'self'"],
33
+ imgSrc: [
34
+ "'self'",
35
+ "data:",
36
+ "https:"
37
+ ]
38
+ } } },
39
+ cors: {
40
+ origin: false,
41
+ credentials: true,
42
+ methods: [
43
+ "GET",
44
+ "POST",
45
+ "PUT",
46
+ "DELETE",
47
+ "PATCH",
48
+ "OPTIONS"
49
+ ],
50
+ allowedHeaders: [
51
+ "Content-Type",
52
+ "Authorization",
53
+ "Accept"
54
+ ]
55
+ },
56
+ rateLimit: {
57
+ max: 100,
58
+ timeWindow: "1 minute"
59
+ },
60
+ underPressure: {
61
+ exposeStatusRoute: true,
62
+ maxEventLoopDelay: 1e3,
63
+ maxHeapUsedBytes: 1024 * 1024 * 1024,
64
+ maxRssBytes: 1024 * 1024 * 1024
65
+ }
66
+ };
67
+ /**
68
+ * Development preset - relaxed security, verbose logging
69
+ */
70
+ const developmentPreset = {
71
+ logger: {
72
+ level: "debug",
73
+ transport: {
74
+ target: "pino-pretty",
75
+ options: {
76
+ colorize: true,
77
+ translateTime: "SYS:HH:MM:ss",
78
+ ignore: "pid,hostname"
79
+ }
80
+ }
81
+ },
82
+ trustProxy: true,
83
+ helmet: { contentSecurityPolicy: false },
84
+ cors: {
85
+ origin: true,
86
+ credentials: true,
87
+ methods: [
88
+ "GET",
89
+ "POST",
90
+ "PUT",
91
+ "DELETE",
92
+ "PATCH",
93
+ "OPTIONS"
94
+ ],
95
+ allowedHeaders: [
96
+ "Content-Type",
97
+ "Authorization",
98
+ "Accept"
99
+ ]
100
+ },
101
+ rateLimit: {
102
+ max: 1e3,
103
+ timeWindow: "1 minute"
104
+ },
105
+ underPressure: {
106
+ exposeStatusRoute: true,
107
+ maxEventLoopDelay: 5e3
108
+ }
109
+ };
110
+ /**
111
+ * Testing preset - minimal setup, fast startup
112
+ */
113
+ const testingPreset = {
114
+ logger: false,
115
+ trustProxy: false,
116
+ helmet: false,
117
+ cors: false,
118
+ rateLimit: false,
119
+ underPressure: false,
120
+ sensible: true,
121
+ multipart: { limits: {
122
+ fileSize: 1024 * 1024,
123
+ files: 5
124
+ } }
125
+ };
126
+ /**
127
+ * Edge/Serverless preset - minimal cold-start overhead
128
+ *
129
+ * Optimized for AWS Lambda, Vercel, Cloudflare Workers, and similar environments.
130
+ * Disables all heavy plugins that add cold-start latency:
131
+ * - Security headers (handled by API Gateway / CDN)
132
+ * - Rate limiting (handled by API Gateway / CDN)
133
+ * - Health monitoring (Lambda has its own health checks)
134
+ * - File uploads (use pre-signed URLs instead)
135
+ * - Raw body parsing (register per-route if needed)
136
+ *
137
+ * Arc core plugins (requestId, health, gracefulShutdown) are also disabled
138
+ * since the serverless runtime manages request lifecycle.
139
+ */
140
+ const edgePreset = {
141
+ logger: { level: "warn" },
142
+ trustProxy: true,
143
+ helmet: false,
144
+ cors: false,
145
+ rateLimit: false,
146
+ underPressure: false,
147
+ sensible: true,
148
+ multipart: false,
149
+ rawBody: false,
150
+ arcPlugins: {
151
+ requestId: false,
152
+ health: false,
153
+ gracefulShutdown: false,
154
+ emitEvents: true
155
+ }
156
+ };
157
+ /**
158
+ * Get preset by name
159
+ */
160
+ function getPreset(name) {
161
+ switch (name) {
162
+ case "production": return productionPreset;
163
+ case "development": return developmentPreset;
164
+ case "testing": return testingPreset;
165
+ case "edge": return edgePreset;
166
+ default: throw new Error(`Unknown preset: ${name}`);
167
+ }
168
+ }
169
+
170
+ //#endregion
171
+ //#region src/factory/createApp.ts
172
+ /**
173
+ * ArcFactory - Production-ready Fastify application factory
174
+ *
175
+ * Enforces security best practices by making plugins opt-out instead of opt-in.
176
+ * A developer must explicitly disable security features rather than forget to enable them.
177
+ *
178
+ * Note: Arc is database-agnostic. Connect your database separately and provide
179
+ * adapters when defining resources. This allows multiple databases, custom
180
+ * connection pooling, and full control over your data layer.
181
+ *
182
+ * @example
183
+ * // 1. Connect your database(s) separately
184
+ * import mongoose from 'mongoose';
185
+ * await mongoose.connect(process.env.MONGO_URI);
186
+ *
187
+ * // 2. Create Arc app (no database config needed)
188
+ * const app = await createApp({
189
+ * preset: 'production',
190
+ * auth: { type: 'jwt', jwt: { secret: process.env.JWT_SECRET } },
191
+ * cors: { origin: ['https://example.com'] },
192
+ * });
193
+ *
194
+ * // 3. Register resources with your adapters
195
+ * await app.register(productResource.toPlugin());
196
+ *
197
+ * @example
198
+ * // Multiple databases example
199
+ * const primaryDb = await mongoose.connect(process.env.PRIMARY_DB);
200
+ * const analyticsDb = mongoose.createConnection(process.env.ANALYTICS_DB);
201
+ *
202
+ * const orderResource = defineResource({
203
+ * adapter: createMongooseAdapter({ model: OrderModel, repository: orderRepo }),
204
+ * });
205
+ *
206
+ * const analyticsResource = defineResource({
207
+ * adapter: createMongooseAdapter({ model: AnalyticsModel, repository: analyticsRepo }),
208
+ * });
209
+ */
210
+ var createApp_exports = /* @__PURE__ */ __exportAll({
211
+ ArcFactory: () => ArcFactory,
212
+ createApp: () => createApp
213
+ });
214
+ const PLUGIN_REGISTRY = {
215
+ cors: {
216
+ package: "@fastify/cors",
217
+ loader: () => import("@fastify/cors").then((m) => m.default)
218
+ },
219
+ helmet: {
220
+ package: "@fastify/helmet",
221
+ loader: () => import("@fastify/helmet").then((m) => m.default)
222
+ },
223
+ rateLimit: {
224
+ package: "@fastify/rate-limit",
225
+ loader: () => import("@fastify/rate-limit").then((m) => m.default)
226
+ },
227
+ underPressure: {
228
+ package: "@fastify/under-pressure",
229
+ loader: () => import("@fastify/under-pressure").then((m) => m.default)
230
+ },
231
+ sensible: {
232
+ package: "@fastify/sensible",
233
+ loader: () => import("@fastify/sensible").then((m) => m.default)
234
+ },
235
+ multipart: {
236
+ package: "@fastify/multipart",
237
+ loader: () => import("@fastify/multipart").then((m) => m.default),
238
+ optional: true
239
+ },
240
+ rawBody: {
241
+ package: "fastify-raw-body",
242
+ loader: () => import("fastify-raw-body").then((m) => m.default),
243
+ optional: true
244
+ }
245
+ };
246
+ async function loadPlugin(name, logger) {
247
+ const entry = PLUGIN_REGISTRY[name];
248
+ if (!entry) throw new Error(`Unknown plugin: ${name}`);
249
+ try {
250
+ return await entry.loader();
251
+ } catch (error) {
252
+ const err = error;
253
+ const isModuleNotFound = err.message.includes("Cannot find module") || err.message.includes("Cannot find package") || err.message.includes("MODULE_NOT_FOUND") || err.message.includes("Could not resolve");
254
+ if (isModuleNotFound && entry.optional) {
255
+ logger?.warn(`Optional plugin '${name}' skipped (${entry.package} not installed)`);
256
+ return null;
257
+ }
258
+ if (isModuleNotFound) throw new Error(`Plugin '${name}' requires package '${entry.package}' which is not installed.\nInstall it with: npm install ${entry.package}\nOr disable this plugin by setting ${name}: false in createApp options.`);
259
+ throw new Error(`Failed to load plugin '${name}': ${err.message}`);
260
+ }
261
+ }
262
+ /**
263
+ * Create a production-ready Fastify application with Arc framework
264
+ *
265
+ * Security plugins are enabled by default (opt-out):
266
+ * - helmet (security headers)
267
+ * - cors (cross-origin requests)
268
+ * - rateLimit (DDoS protection)
269
+ * - underPressure (health monitoring)
270
+ *
271
+ * Note: Compression is not included due to known Fastify 5 issues.
272
+ * Use a reverse proxy (Nginx, Caddy) or CDN for compression.
273
+ *
274
+ * @param options - Application configuration
275
+ * @returns Configured Fastify instance
276
+ */
277
+ async function createApp(options) {
278
+ if (options.debug !== void 0 && options.debug !== false) {
279
+ const { configureArcLogger } = await import("./logger-Df2O2WsW.mjs").then((n) => n.r);
280
+ configureArcLogger({ debug: options.debug });
281
+ }
282
+ const authConfig = options.auth;
283
+ const isAuthDisabled = authConfig === false;
284
+ if (!isAuthDisabled && authConfig && authConfig.type === "jwt") {
285
+ if (!authConfig.jwt?.secret && !authConfig.authenticate) throw new Error("createApp: JWT secret required when Arc auth is enabled.\nProvide auth.jwt.secret, auth.authenticate, or set auth: false to disable.\nExample: auth: { type: 'jwt', jwt: { secret: process.env.JWT_SECRET } }");
286
+ }
287
+ if (options.runtime === "distributed") {
288
+ const MEMORY_NAMES = new Set(["memory", "memory-cache"]);
289
+ const missing = [];
290
+ const eventsTransport = options.stores?.events;
291
+ if (!eventsTransport || MEMORY_NAMES.has(eventsTransport.name)) missing.push("events transport");
292
+ const cacheStore = options.stores?.cache;
293
+ if (!cacheStore || MEMORY_NAMES.has(cacheStore.name)) missing.push("cache store");
294
+ const idempotencyStore = options.stores?.idempotency;
295
+ if (!idempotencyStore || MEMORY_NAMES.has(idempotencyStore.name)) missing.push("idempotency store");
296
+ if (options.arcPlugins?.queryCache) {
297
+ const qcStore = options.stores?.queryCache;
298
+ if (!qcStore || MEMORY_NAMES.has(qcStore.name)) missing.push("queryCache store");
299
+ }
300
+ if (missing.length > 0) throw new Error(`[Arc] runtime: 'distributed' requires Redis/durable adapters.\nMissing: ${missing.join(", ")}.\nProvide Redis-backed stores or use runtime: 'memory' for development.`);
301
+ }
302
+ const config = {
303
+ ...options.preset ? getPreset(options.preset) : {},
304
+ ...options
305
+ };
306
+ let fastify = Fastify({
307
+ logger: config.logger ?? true,
308
+ trustProxy: config.trustProxy ?? false,
309
+ routerOptions: { querystringParser: (str) => qs.parse(str) },
310
+ ajv: { customOptions: {
311
+ coerceTypes: true,
312
+ useDefaults: true,
313
+ removeAdditional: false,
314
+ keywords: ["example"]
315
+ } }
316
+ });
317
+ if (config.typeProvider === "typebox") try {
318
+ const { TypeBoxValidatorCompiler } = await import("@fastify/type-provider-typebox");
319
+ fastify.setValidatorCompiler(TypeBoxValidatorCompiler);
320
+ fastify.log.debug("TypeBox type provider enabled");
321
+ } catch {
322
+ fastify.log.warn("typeProvider: \"typebox\" requested but @fastify/type-provider-typebox is not installed. Install it with: npm install @sinclair/typebox @fastify/type-provider-typebox");
323
+ }
324
+ fastify.removeContentTypeParser("application/json");
325
+ fastify.addContentTypeParser("application/json", { parseAs: "string" }, (_req, body, done) => {
326
+ if (!body || body.length === 0) return done(null, void 0);
327
+ try {
328
+ done(null, JSON.parse(body));
329
+ } catch (err) {
330
+ done(err);
331
+ }
332
+ });
333
+ if (config.helmet !== false) {
334
+ const helmet = await loadPlugin("helmet");
335
+ await fastify.register(helmet, config.helmet ?? {});
336
+ fastify.log.debug("Helmet (security headers) enabled");
337
+ } else fastify.log.warn("Helmet disabled - security headers not applied");
338
+ if (config.cors !== false) {
339
+ const cors = await loadPlugin("cors");
340
+ const corsOptions = config.cors ?? {};
341
+ if (config.preset === "production" && (!corsOptions || !("origin" in corsOptions))) throw new Error("CORS origin must be explicitly configured in production.\nSet cors.origin to allowed domains or set cors: false to disable.\nExample: cors: { origin: ['https://yourdomain.com'] }\nDocs: https://github.com/classytic/arc#security");
342
+ await fastify.register(cors, corsOptions);
343
+ fastify.log.debug("CORS enabled");
344
+ } else fastify.log.warn("CORS disabled");
345
+ if (config.rateLimit !== false) {
346
+ const rateLimit = await loadPlugin("rateLimit");
347
+ const rateLimitOpts = config.rateLimit ?? {
348
+ max: 100,
349
+ timeWindow: "1 minute"
350
+ };
351
+ await fastify.register(rateLimit, rateLimitOpts);
352
+ if (config.preset === "production") {
353
+ if (!(typeof rateLimitOpts === "object" && "store" in rateLimitOpts)) fastify.log.warn("Rate limiting is using in-memory store. In multi-instance deployments, each instance tracks limits independently. Configure a Redis store for distributed rate limiting: rateLimit: { store: new RedisStore({ ... }) }");
354
+ }
355
+ fastify.log.debug("Rate limiting enabled");
356
+ } else fastify.log.warn("Rate limiting disabled");
357
+ if (config.preset === "production") fastify.log.warn("Response compression is not enabled (Fastify 5 stream issues). Use a reverse proxy (Nginx, Caddy, Cloudflare) for gzip/brotli in production.");
358
+ if (config.underPressure !== false) {
359
+ const underPressure = await loadPlugin("underPressure");
360
+ await fastify.register(underPressure, config.underPressure ?? { exposeStatusRoute: true });
361
+ fastify.log.debug("Health monitoring (under-pressure) enabled");
362
+ } else fastify.log.debug("Health monitoring disabled");
363
+ if (config.sensible !== false) {
364
+ const sensible = await loadPlugin("sensible");
365
+ await fastify.register(sensible);
366
+ fastify.log.debug("Sensible (HTTP helpers) enabled");
367
+ }
368
+ if (config.multipart !== false) {
369
+ const multipart = await loadPlugin("multipart", fastify.log);
370
+ if (multipart) {
371
+ await fastify.register(multipart, {
372
+ limits: {
373
+ fileSize: 10 * 1024 * 1024,
374
+ files: 10
375
+ },
376
+ throwFileSizeLimit: true,
377
+ ...config.multipart
378
+ });
379
+ fastify.log.debug("Multipart (file uploads) enabled");
380
+ }
381
+ }
382
+ if (config.rawBody !== false) {
383
+ const rawBody = await loadPlugin("rawBody", fastify.log);
384
+ if (rawBody) {
385
+ await fastify.register(rawBody, {
386
+ field: "rawBody",
387
+ global: false,
388
+ encoding: "utf8",
389
+ runFirst: true,
390
+ ...config.rawBody
391
+ });
392
+ fastify.log.debug("Raw body parsing enabled");
393
+ }
394
+ }
395
+ const { arcCorePlugin, requestIdPlugin, healthPlugin, gracefulShutdownPlugin } = await import("./plugins/index.mjs");
396
+ await fastify.register(arcCorePlugin, { emitEvents: config.arcPlugins?.emitEvents !== false });
397
+ /** Track a plugin in the Arc plugin registry */
398
+ const trackPlugin = (name, opts) => {
399
+ fastify.arc.plugins.set(name, {
400
+ name,
401
+ options: opts,
402
+ registeredAt: (/* @__PURE__ */ new Date()).toISOString()
403
+ });
404
+ };
405
+ trackPlugin("arc-core");
406
+ if (config.arcPlugins?.events !== false) {
407
+ const { default: eventPlugin } = await import("./eventPlugin-DGR_B2on.mjs").then((n) => n.n);
408
+ const eventOpts = typeof config.arcPlugins?.events === "object" ? config.arcPlugins.events : {};
409
+ await fastify.register(eventPlugin, {
410
+ ...eventOpts,
411
+ transport: options.stores?.events
412
+ });
413
+ trackPlugin("arc-events", eventOpts);
414
+ fastify.log.debug(`Arc events plugin enabled (transport: ${fastify.events.transportName})`);
415
+ }
416
+ if (config.arcPlugins?.requestId !== false) {
417
+ await fastify.register(requestIdPlugin);
418
+ trackPlugin("arc-request-id");
419
+ fastify.log.debug("Arc requestId plugin enabled");
420
+ }
421
+ if (config.arcPlugins?.health !== false) {
422
+ await fastify.register(healthPlugin);
423
+ trackPlugin("arc-health");
424
+ fastify.log.debug("Arc health plugin enabled");
425
+ }
426
+ if (config.arcPlugins?.gracefulShutdown !== false) {
427
+ await fastify.register(gracefulShutdownPlugin);
428
+ trackPlugin("arc-graceful-shutdown");
429
+ fastify.log.debug("Arc gracefulShutdown plugin enabled");
430
+ }
431
+ if (config.arcPlugins?.caching) {
432
+ const { default: cachingPlugin } = await import("./caching-Bl28lYsR.mjs").then((n) => n.r);
433
+ const cachingOpts = config.arcPlugins.caching === true ? {} : config.arcPlugins.caching;
434
+ await fastify.register(cachingPlugin, cachingOpts);
435
+ trackPlugin("arc-caching", cachingOpts);
436
+ fastify.log.debug("Arc caching plugin enabled");
437
+ }
438
+ if (config.arcPlugins?.queryCache) {
439
+ const { queryCachePlugin } = await import("./queryCachePlugin-DMBnp2Q0.mjs").then((n) => n.n);
440
+ const qcOpts = config.arcPlugins.queryCache === true ? {} : config.arcPlugins.queryCache;
441
+ const store = options.stores?.queryCache ?? new (await (import("./memory-cQgelFOj.mjs").then((n) => n.n))).MemoryCacheStore();
442
+ await fastify.register(queryCachePlugin, {
443
+ store,
444
+ ...qcOpts
445
+ });
446
+ trackPlugin("arc-query-cache", qcOpts);
447
+ fastify.log.debug("Arc queryCache plugin enabled");
448
+ }
449
+ if (config.arcPlugins?.sse) if (config.arcPlugins?.events === false) fastify.log.warn("SSE plugin requires events plugin (arcPlugins.events). SSE disabled.");
450
+ else {
451
+ const { default: ssePlugin } = await import("./sse-B3c3_yZp.mjs").then((n) => n.r);
452
+ const sseOpts = config.arcPlugins.sse === true ? {} : config.arcPlugins.sse;
453
+ await fastify.register(ssePlugin, sseOpts);
454
+ trackPlugin("arc-sse", sseOpts);
455
+ fastify.log.debug("Arc SSE plugin enabled");
456
+ }
457
+ fastify.decorateRequest("scope", null);
458
+ fastify.addHook("onRequest", async (request) => {
459
+ if (!request.scope) request.scope = PUBLIC_SCOPE;
460
+ });
461
+ if (isAuthDisabled) fastify.log.debug("Authentication disabled");
462
+ else if (authConfig) switch (authConfig.type) {
463
+ case "betterAuth": {
464
+ const { plugin, openapi } = authConfig.betterAuth;
465
+ await fastify.register(plugin);
466
+ trackPlugin("auth-better-auth");
467
+ if (openapi && !fastify.arc.externalOpenApiPaths.includes(openapi)) fastify.arc.externalOpenApiPaths.push(openapi);
468
+ fastify.log.debug("Better Auth authentication enabled");
469
+ break;
470
+ }
471
+ case "custom":
472
+ await fastify.register(authConfig.plugin);
473
+ trackPlugin("auth-custom");
474
+ fastify.log.debug("Custom authentication plugin enabled");
475
+ break;
476
+ case "authenticator": {
477
+ const { authenticate } = authConfig;
478
+ fastify.decorate("authenticate", async function(request, reply) {
479
+ await authenticate(request, reply);
480
+ });
481
+ trackPlugin("auth-authenticator");
482
+ fastify.log.debug("Custom authenticator enabled");
483
+ break;
484
+ }
485
+ case "jwt": {
486
+ const { authPlugin } = await import("./auth/index.mjs");
487
+ const { type: _, ...arcAuthOpts } = authConfig;
488
+ await fastify.register(authPlugin, arcAuthOpts);
489
+ trackPlugin("auth-jwt");
490
+ fastify.log.debug("Arc authentication plugin enabled");
491
+ break;
492
+ }
493
+ }
494
+ if (config.elevation) {
495
+ const { elevationPlugin } = await import("./elevation-BRy3yFWT.mjs").then((n) => n.r);
496
+ await fastify.register(elevationPlugin, config.elevation);
497
+ trackPlugin("arc-elevation", config.elevation);
498
+ fastify.log.debug("Elevation plugin enabled");
499
+ }
500
+ if (config.errorHandler !== false) {
501
+ const { errorHandlerPlugin } = await import("./errorHandler-C1okiriz.mjs").then((n) => n.n);
502
+ const errorOpts = typeof config.errorHandler === "object" ? config.errorHandler : { includeStack: config.preset !== "production" };
503
+ await fastify.register(errorHandlerPlugin, errorOpts);
504
+ trackPlugin("arc-error-handler", errorOpts);
505
+ fastify.log.debug("Arc error handler enabled");
506
+ }
507
+ if (config.plugins) {
508
+ await config.plugins(fastify);
509
+ fastify.log.debug("Custom plugins registered");
510
+ }
511
+ if (config.onReady) {
512
+ const onReady = config.onReady;
513
+ fastify.addHook("onReady", async () => {
514
+ await onReady(fastify);
515
+ });
516
+ }
517
+ if (config.onClose) {
518
+ const onClose = config.onClose;
519
+ fastify.addHook("onClose", async () => {
520
+ await onClose(fastify);
521
+ });
522
+ }
523
+ const authMode = isAuthDisabled ? "none" : authConfig ? authConfig.type : "none";
524
+ fastify.log.info({
525
+ preset: config.preset ?? "custom",
526
+ runtime: config.runtime ?? "memory",
527
+ auth: authMode,
528
+ helmet: config.helmet !== false,
529
+ cors: config.cors !== false,
530
+ rateLimit: config.rateLimit !== false
531
+ }, "Arc application created");
532
+ return fastify;
533
+ }
534
+ /**
535
+ * Quick factory for common scenarios
536
+ */
537
+ const ArcFactory = {
538
+ async production(options) {
539
+ return createApp({
540
+ ...options,
541
+ preset: "production"
542
+ });
543
+ },
544
+ async development(options) {
545
+ return createApp({
546
+ ...options,
547
+ preset: "development"
548
+ });
549
+ },
550
+ async testing(options) {
551
+ return createApp({
552
+ ...options,
553
+ preset: "testing"
554
+ });
555
+ }
556
+ };
557
+
558
+ //#endregion
559
+ export { getPreset as a, developmentPreset as i, createApp as n, productionPreset as o, createApp_exports as r, testingPreset as s, ArcFactory as t };
560
+ //# sourceMappingURL=createApp-CUgNqegw.mjs.map