@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,618 +0,0 @@
1
- import { q as ResourceDefinition, A as AnyRecord, y as CrudRepository } from '../index-B4t03KQ0.js';
2
- import Fastify, { FastifyInstance } from 'fastify';
3
- import { C as CreateAppOptions } from '../types-BvckRbs2.js';
4
- import { Mock } from 'vitest';
5
- import { Connection } from 'mongoose';
6
- import '../types-B99TBmFV.js';
7
- import '@fastify/cors';
8
- import '@fastify/helmet';
9
- import '@fastify/rate-limit';
10
-
11
- /**
12
- * Resource Test Harness
13
- *
14
- * Generates baseline tests for Arc resources automatically.
15
- * Tests CRUD operations + preset routes with minimal configuration.
16
- *
17
- * @example
18
- * import { createTestHarness } from '@classytic/arc/testing';
19
- * import productResource from './product.resource.js';
20
- *
21
- * const harness = createTestHarness(productResource, {
22
- * fixtures: {
23
- * valid: { name: 'Test Product', price: 100 },
24
- * update: { name: 'Updated Product' },
25
- * },
26
- * });
27
- *
28
- * // Run all baseline tests (50+ auto-generated)
29
- * harness.runAll();
30
- *
31
- * // Or run specific test suites
32
- * harness.runCrud();
33
- * harness.runPresets();
34
- */
35
-
36
- /**
37
- * Test fixtures for a resource
38
- */
39
- interface TestFixtures$1<T = any> {
40
- /** Valid create payload */
41
- valid: Partial<T>;
42
- /** Update payload (optional, defaults to valid) */
43
- update?: Partial<T>;
44
- /** Invalid payload for validation tests (optional) */
45
- invalid?: Partial<T>;
46
- }
47
- /**
48
- * Test harness options
49
- */
50
- interface TestHarnessOptions<T = any> {
51
- /** Test data fixtures */
52
- fixtures: TestFixtures$1<T>;
53
- /** Custom setup function (runs before all tests) */
54
- setupFn?: () => Promise<void> | void;
55
- /** Custom teardown function (runs after all tests) */
56
- teardownFn?: () => Promise<void> | void;
57
- /** MongoDB connection URI (defaults to process.env.MONGO_URI) */
58
- mongoUri?: string;
59
- }
60
- /**
61
- * Test harness for Arc resources
62
- *
63
- * Provides automatic test generation for:
64
- * - CRUD operations (create, read, update, delete)
65
- * - Schema validation
66
- * - Preset-specific functionality (softDelete, slugLookup, tree, etc.)
67
- */
68
- declare class TestHarness<T = unknown> {
69
- private resource;
70
- private fixtures;
71
- private setupFn?;
72
- private teardownFn?;
73
- private mongoUri;
74
- private _createdIds;
75
- private Model;
76
- constructor(resource: ResourceDefinition<unknown>, options: TestHarnessOptions<T>);
77
- /**
78
- * Run all baseline tests
79
- *
80
- * Executes CRUD, validation, and preset tests
81
- */
82
- runAll(): void;
83
- /**
84
- * Run CRUD operation tests
85
- *
86
- * Tests: create, read (list + getById), update, delete
87
- */
88
- runCrud(): void;
89
- /**
90
- * Run validation tests
91
- *
92
- * Tests schema validation, required fields, etc.
93
- */
94
- runValidation(): void;
95
- /**
96
- * Run preset-specific tests
97
- *
98
- * Auto-detects applied presets and tests their functionality:
99
- * - softDelete: deletedAt field, soft delete/restore
100
- * - slugLookup: slug generation
101
- * - tree: parent references, displayOrder
102
- * - multiTenant: organizationId requirement
103
- * - ownedByUser: userId requirement
104
- */
105
- runPresets(): void;
106
- }
107
- /**
108
- * Create a test harness for an Arc resource
109
- *
110
- * @param resource - The Arc resource definition to test
111
- * @param options - Test harness configuration
112
- * @returns Test harness instance
113
- *
114
- * @example
115
- * import { createTestHarness } from '@classytic/arc/testing';
116
- *
117
- * const harness = createTestHarness(productResource, {
118
- * fixtures: {
119
- * valid: { name: 'Product', price: 100 },
120
- * update: { name: 'Updated' },
121
- * },
122
- * });
123
- *
124
- * harness.runAll(); // Generates 50+ baseline tests
125
- */
126
- declare function createTestHarness<T = any>(resource: ResourceDefinition, options: TestHarnessOptions<T>): TestHarness<T>;
127
- /**
128
- * Test file generation options
129
- */
130
- interface GenerateTestFileOptions {
131
- /** Applied presets (e.g., ['softDelete', 'slugLookup']) */
132
- presets?: string[];
133
- /** Module path for imports (default: '.') */
134
- modulePath?: string;
135
- }
136
- /**
137
- * Generate test file content for a resource
138
- *
139
- * Useful for scaffolding new resource tests via CLI
140
- *
141
- * @param resourceName - Resource name in kebab-case (e.g., 'product')
142
- * @param options - Generation options
143
- * @returns Complete test file content as string
144
- *
145
- * @example
146
- * const testContent = generateTestFile('product', {
147
- * presets: ['softDelete'],
148
- * modulePath: './modules/catalog',
149
- * });
150
- * fs.writeFileSync('product.test.js', testContent);
151
- */
152
- declare function generateTestFile(resourceName: string, options?: GenerateTestFileOptions): string;
153
-
154
- /**
155
- * Testing Utilities - Test App Factory
156
- *
157
- * Create Fastify test instances with Arc configuration
158
- */
159
-
160
- interface CreateTestAppOptions extends Partial<CreateAppOptions> {
161
- /**
162
- * Use in-memory MongoDB for faster tests (default: true)
163
- * Requires: mongodb-memory-server
164
- *
165
- * Set to false to use a provided mongoUri instead
166
- */
167
- useInMemoryDb?: boolean;
168
- /**
169
- * MongoDB connection URI (only used if useInMemoryDb is false)
170
- */
171
- mongoUri?: string;
172
- }
173
- interface TestAppResult {
174
- /** Fastify app instance */
175
- app: FastifyInstance;
176
- /**
177
- * Cleanup function to close app and disconnect database
178
- * Call this in afterAll() or afterEach()
179
- */
180
- close: () => Promise<void>;
181
- /** MongoDB connection URI (useful for connecting models) */
182
- mongoUri?: string;
183
- }
184
- /**
185
- * Create a test application instance with optional in-memory MongoDB
186
- *
187
- * **Performance Boost**: Uses in-memory MongoDB by default for 10x faster tests.
188
- *
189
- * @example Basic usage with in-memory DB
190
- * ```typescript
191
- * import { createTestApp } from '@classytic/arc/testing';
192
- *
193
- * describe('API Tests', () => {
194
- * let testApp: TestAppResult;
195
- *
196
- * beforeAll(async () => {
197
- * testApp = await createTestApp({
198
- * auth: { jwt: { secret: 'test-secret' } },
199
- * });
200
- * });
201
- *
202
- * afterAll(async () => {
203
- * await testApp.close(); // Cleans up DB and disconnects
204
- * });
205
- *
206
- * test('GET /health', async () => {
207
- * const response = await testApp.app.inject({
208
- * method: 'GET',
209
- * url: '/health',
210
- * });
211
- * expect(response.statusCode).toBe(200);
212
- * });
213
- * });
214
- * ```
215
- *
216
- * @example Using external MongoDB
217
- * ```typescript
218
- * const testApp = await createTestApp({
219
- * auth: { jwt: { secret: 'test-secret' } },
220
- * useInMemoryDb: false,
221
- * mongoUri: 'mongodb://localhost:27017/test-db',
222
- * });
223
- * ```
224
- *
225
- * @example Accessing MongoDB URI for model connections
226
- * ```typescript
227
- * const testApp = await createTestApp({
228
- * auth: { jwt: { secret: 'test-secret' } },
229
- * });
230
- * await mongoose.connect(testApp.mongoUri); // Connect your models
231
- * ```
232
- */
233
- declare function createTestApp(options?: CreateTestAppOptions): Promise<TestAppResult>;
234
- /**
235
- * Create a minimal Fastify instance for unit tests
236
- *
237
- * Use when you don't need Arc's full plugin stack
238
- *
239
- * @example
240
- * const app = createMinimalTestApp();
241
- * app.get('/test', async () => ({ success: true }));
242
- *
243
- * const response = await app.inject({ method: 'GET', url: '/test' });
244
- * expect(response.json()).toEqual({ success: true });
245
- */
246
- declare function createMinimalTestApp(options?: Partial<any>): FastifyInstance;
247
- /**
248
- * Test request builder for cleaner tests
249
- *
250
- * @example
251
- * const request = new TestRequestBuilder(app)
252
- * .get('/products')
253
- * .withAuth(mockUser)
254
- * .withQuery({ page: 1, limit: 10 });
255
- *
256
- * const response = await request.send();
257
- * expect(response.statusCode).toBe(200);
258
- */
259
- declare class TestRequestBuilder {
260
- private app;
261
- private method;
262
- private url;
263
- private body?;
264
- private query?;
265
- private headers;
266
- constructor(app: FastifyInstance);
267
- get(url: string): this;
268
- post(url: string): this;
269
- put(url: string): this;
270
- patch(url: string): this;
271
- delete(url: string): this;
272
- withBody(body: any): this;
273
- withQuery(query: Record<string, any>): this;
274
- withHeader(key: string, value: string): this;
275
- withAuth(user: any): this;
276
- withContentType(type: string): this;
277
- send(): Promise<Fastify.LightMyRequestResponse>;
278
- }
279
- /**
280
- * Helper to create a test request builder
281
- */
282
- declare function request(app: FastifyInstance): TestRequestBuilder;
283
- /**
284
- * Test helper for authentication
285
- */
286
- declare function createTestAuth(app: FastifyInstance): {
287
- /**
288
- * Generate a JWT token for testing
289
- */
290
- generateToken(user: any): string;
291
- /**
292
- * Decode a JWT token
293
- */
294
- decodeToken(token: string): any;
295
- /**
296
- * Verify a JWT token
297
- */
298
- verifyToken(token: string): Promise<any>;
299
- };
300
- /**
301
- * Snapshot testing helper for API responses
302
- */
303
- declare function createSnapshotMatcher(): {
304
- /**
305
- * Match response structure (ignores dynamic values like timestamps)
306
- */
307
- matchStructure(response: any, expected: any): boolean;
308
- };
309
- /**
310
- * Bulk test data loader
311
- */
312
- declare class TestDataLoader {
313
- private app;
314
- private data;
315
- constructor(app: FastifyInstance);
316
- /**
317
- * Load test data into database
318
- */
319
- load(collection: string, items: any[]): Promise<any[]>;
320
- /**
321
- * Clear all loaded test data
322
- */
323
- cleanup(): Promise<void>;
324
- }
325
-
326
- /**
327
- * Testing Utilities - Mock Factories
328
- *
329
- * Create mock repositories, controllers, and services for testing.
330
- * Uses Vitest for mocking (compatible with Jest API).
331
- */
332
-
333
- /**
334
- * Extended repository interface for testing (includes optional preset methods)
335
- */
336
- interface MockRepository<T> extends CrudRepository<T> {
337
- getBySlug?: Mock;
338
- getDeleted?: Mock;
339
- restore?: Mock;
340
- getTree?: Mock;
341
- getChildren?: Mock;
342
- [key: string]: unknown;
343
- }
344
- /**
345
- * Create a mock repository for testing
346
- *
347
- * @example
348
- * const mockRepo = createMockRepository<Product>({
349
- * getById: vi.fn().mockResolvedValue({ id: '1', name: 'Test' }),
350
- * create: vi.fn().mockImplementation(data => Promise.resolve({ id: '1', ...data })),
351
- * });
352
- *
353
- * await mockRepo.getById('1'); // Returns mocked product
354
- */
355
- declare function createMockRepository<T extends AnyRecord = AnyRecord>(overrides?: Partial<MockRepository<T>>): MockRepository<T>;
356
- /**
357
- * Create a mock user for authentication testing
358
- */
359
- declare function createMockUser(overrides?: Partial<AnyRecord>): {
360
- _id: string;
361
- id: string;
362
- email: string;
363
- roles: string[];
364
- organizationId: null;
365
- };
366
- /**
367
- * Create a mock Fastify request
368
- */
369
- declare function createMockRequest(overrides?: Partial<AnyRecord>): unknown;
370
- /**
371
- * Create a mock Fastify reply
372
- */
373
- declare function createMockReply(): unknown;
374
- /**
375
- * Create a mock controller for testing
376
- */
377
- declare function createMockController(repository: CrudRepository<AnyRecord>): {
378
- repository: CrudRepository<AnyRecord>;
379
- list: Mock<(...args: any[]) => any>;
380
- get: Mock<(...args: any[]) => any>;
381
- create: Mock<(...args: any[]) => any>;
382
- update: Mock<(...args: any[]) => any>;
383
- delete: Mock<(...args: any[]) => any>;
384
- };
385
- /**
386
- * Create mock data factory
387
- *
388
- * @example
389
- * const productFactory = createDataFactory<Product>({
390
- * name: () => faker.commerce.productName(),
391
- * price: () => faker.number.int({ min: 10, max: 1000 }),
392
- * sku: (i) => `SKU-${i}`,
393
- * });
394
- *
395
- * const product = productFactory.build();
396
- * const products = productFactory.buildMany(10);
397
- */
398
- declare function createDataFactory<T extends AnyRecord>(template: Record<keyof T, (index: number) => unknown>): {
399
- build(overrides?: Partial<T>): T;
400
- buildMany(count: number, overrides?: Partial<T>): T[];
401
- reset(): void;
402
- };
403
- /**
404
- * Create a spy that tracks function calls
405
- *
406
- * Useful for testing side effects without full mocking
407
- */
408
- declare function createSpy<T extends (...args: unknown[]) => unknown>(_name?: string): Mock<T> & {
409
- getCalls(): unknown[][];
410
- getLastCall(): unknown[];
411
- };
412
- /**
413
- * Wait for a condition to be true
414
- *
415
- * Useful for async testing
416
- */
417
- declare function waitFor(condition: () => boolean | Promise<boolean>, options?: {
418
- timeout?: number;
419
- interval?: number;
420
- }): Promise<void>;
421
- /**
422
- * Create a test timer that can be controlled
423
- */
424
- declare function createTestTimer(): {
425
- now: () => number;
426
- advance: (ms: number) => void;
427
- set: (timestamp: number) => void;
428
- reset: () => void;
429
- };
430
-
431
- /**
432
- * Testing Utilities - Database Helpers
433
- *
434
- * Utilities for managing test databases and fixtures
435
- */
436
-
437
- /**
438
- * Test database manager
439
- */
440
- declare class TestDatabase {
441
- private connection?;
442
- private dbName;
443
- constructor(dbName?: string);
444
- /**
445
- * Connect to test database
446
- */
447
- connect(uri?: string): Promise<Connection>;
448
- /**
449
- * Disconnect and cleanup
450
- */
451
- disconnect(): Promise<void>;
452
- /**
453
- * Clear all collections
454
- */
455
- clear(): Promise<void>;
456
- /**
457
- * Get connection
458
- */
459
- getConnection(): Connection;
460
- }
461
- /**
462
- * Higher-order function to wrap tests with database setup/teardown
463
- *
464
- * @example
465
- * describe('Product Tests', () => {
466
- * withTestDb(async (db) => {
467
- * test('create product', async () => {
468
- * const Product = db.getConnection().model('Product', schema);
469
- * const product = await Product.create({ name: 'Test' });
470
- * expect(product.name).toBe('Test');
471
- * });
472
- * });
473
- * });
474
- */
475
- declare function withTestDb(tests: (db: TestDatabase) => void | Promise<void>, options?: {
476
- uri?: string;
477
- dbName?: string;
478
- }): void;
479
- /**
480
- * Create test fixtures
481
- *
482
- * @example
483
- * const fixtures = new TestFixtures(connection);
484
- *
485
- * await fixtures.load('products', [
486
- * { name: 'Product 1', price: 100 },
487
- * { name: 'Product 2', price: 200 },
488
- * ]);
489
- *
490
- * const products = await fixtures.get('products');
491
- */
492
- declare class TestFixtures {
493
- private connection;
494
- private fixtures;
495
- constructor(connection: Connection);
496
- /**
497
- * Load fixtures into a collection
498
- */
499
- load<T = any>(collectionName: string, data: Partial<T>[]): Promise<T[]>;
500
- /**
501
- * Get loaded fixtures
502
- */
503
- get<T = any>(collectionName: string): T[];
504
- /**
505
- * Get first fixture
506
- */
507
- getFirst<T = any>(collectionName: string): T | null;
508
- /**
509
- * Clear all fixtures
510
- */
511
- clear(): Promise<void>;
512
- }
513
- /**
514
- * In-memory MongoDB for ultra-fast tests
515
- *
516
- * Requires: mongodb-memory-server
517
- *
518
- * @example
519
- * import { InMemoryDatabase } from '@classytic/arc/testing';
520
- *
521
- * describe('Fast Tests', () => {
522
- * const memoryDb = new InMemoryDatabase();
523
- *
524
- * beforeAll(async () => {
525
- * await memoryDb.start();
526
- * });
527
- *
528
- * afterAll(async () => {
529
- * await memoryDb.stop();
530
- * });
531
- *
532
- * test('create user', async () => {
533
- * const uri = memoryDb.getUri();
534
- * // Use uri for connection
535
- * });
536
- * });
537
- */
538
- declare class InMemoryDatabase {
539
- private mongod?;
540
- private uri?;
541
- /**
542
- * Start in-memory MongoDB
543
- */
544
- start(): Promise<string>;
545
- /**
546
- * Stop in-memory MongoDB
547
- */
548
- stop(): Promise<void>;
549
- /**
550
- * Get connection URI
551
- */
552
- getUri(): string;
553
- }
554
- /**
555
- * Database transaction helper for testing
556
- */
557
- declare class TestTransaction {
558
- private connection;
559
- private session?;
560
- constructor(connection: Connection);
561
- /**
562
- * Start transaction
563
- */
564
- start(): Promise<void>;
565
- /**
566
- * Commit transaction
567
- */
568
- commit(): Promise<void>;
569
- /**
570
- * Rollback transaction
571
- */
572
- rollback(): Promise<void>;
573
- /**
574
- * Get session
575
- */
576
- getSession(): any;
577
- }
578
- /**
579
- * Seed data helper
580
- */
581
- declare class TestSeeder {
582
- private connection;
583
- constructor(connection: Connection);
584
- /**
585
- * Seed collection with data
586
- */
587
- seed<T>(collectionName: string, generator: () => T[], count?: number): Promise<T[]>;
588
- /**
589
- * Clear collection
590
- */
591
- clear(collectionName: string): Promise<void>;
592
- /**
593
- * Clear all collections
594
- */
595
- clearAll(): Promise<void>;
596
- }
597
- /**
598
- * Database snapshot helper for rollback testing
599
- */
600
- declare class DatabaseSnapshot {
601
- private connection;
602
- private snapshots;
603
- constructor(connection: Connection);
604
- /**
605
- * Take snapshot of current database state
606
- */
607
- take(): Promise<void>;
608
- /**
609
- * Restore database to snapshot
610
- */
611
- restore(): Promise<void>;
612
- /**
613
- * Clear snapshot
614
- */
615
- clear(): void;
616
- }
617
-
618
- export { type CreateTestAppOptions, DatabaseSnapshot, TestFixtures as DbTestFixtures, type GenerateTestFileOptions, InMemoryDatabase, type TestAppResult, TestDataLoader, TestDatabase, type TestFixtures$1 as TestFixtures, TestHarness, type TestHarnessOptions, TestRequestBuilder, TestSeeder, TestTransaction, createDataFactory, createMinimalTestApp, createMockController, createMockReply, createMockRepository, createMockRequest, createMockUser, createSnapshotMatcher, createSpy, createTestApp, createTestAuth, createTestHarness, createTestTimer, generateTestFile, request, waitFor, withTestDb };