@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,334 +0,0 @@
1
- import { existsSync, mkdirSync, writeFileSync } from 'fs';
2
- import { join } from 'path';
3
-
4
- // src/cli/commands/generate.ts
5
- function isTypeScriptProject() {
6
- return existsSync(join(process.cwd(), "tsconfig.json"));
7
- }
8
- function getTemplates(ts) {
9
- return {
10
- model: (name) => `/**
11
- * ${name} Model
12
- * Generated by Arc CLI
13
- */
14
-
15
- import mongoose${ts ? ", { type HydratedDocument }" : ""} from 'mongoose';
16
-
17
- const { Schema } = mongoose;
18
- ${ts ? `
19
- type ${name} = {
20
- name: string;
21
- description?: string;
22
- isActive: boolean;
23
- };
24
-
25
- export type ${name}Document = HydratedDocument<${name}>;
26
- ` : ""}
27
- const ${name.toLowerCase()}Schema = new Schema${ts ? `<${name}>` : ""}(
28
- {
29
- name: { type: String, required: true, trim: true },
30
- description: { type: String, trim: true },
31
- isActive: { type: Boolean, default: true },
32
- },
33
- { timestamps: true }
34
- );
35
-
36
- // Indexes
37
- ${name.toLowerCase()}Schema.index({ name: 1 });
38
- ${name.toLowerCase()}Schema.index({ isActive: 1 });
39
-
40
- const ${name} = mongoose.models.${name}${ts ? ` as mongoose.Model<${name}>` : ""} || mongoose.model${ts ? `<${name}>` : ""}('${name}', ${name.toLowerCase()}Schema);
41
- export default ${name};
42
- `,
43
- repository: (name) => `/**
44
- * ${name} Repository
45
- * Generated by Arc CLI
46
- */
47
-
48
- import {
49
- Repository,
50
- methodRegistryPlugin,
51
- softDeletePlugin,
52
- mongoOperationsPlugin,
53
- } from '@classytic/mongokit';
54
- ${ts ? `import type { ${name}Document } from './${name.toLowerCase()}.model.js';` : ""}
55
- import ${name} from './${name.toLowerCase()}.model.js';
56
-
57
- class ${name}Repository extends Repository${ts ? `<${name}Document>` : ""} {
58
- constructor() {
59
- super(${name}${ts ? " as any" : ""}, [
60
- methodRegistryPlugin(),
61
- softDeletePlugin(),
62
- mongoOperationsPlugin(),
63
- ]);
64
- }
65
-
66
- /**
67
- * Find all active records
68
- */
69
- async findActive() {
70
- return this.Model.find({ isActive: true, deletedAt: null }).lean();
71
- }
72
-
73
- // Add custom repository methods here
74
- }
75
-
76
- const ${name.toLowerCase()}Repository = new ${name}Repository();
77
- export default ${name.toLowerCase()}Repository;
78
- export { ${name}Repository };
79
- `,
80
- controller: (name) => `/**
81
- * ${name} Controller
82
- * Generated by Arc CLI
83
- */
84
-
85
- import { BaseController } from '@classytic/arc';
86
- import ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';
87
- import { ${name.toLowerCase()}SchemaOptions } from './${name.toLowerCase()}.schemas.js';
88
-
89
- class ${name}Controller extends BaseController {
90
- constructor() {
91
- super(${name.toLowerCase()}Repository${ts ? " as any" : ""}, { schemaOptions: ${name.toLowerCase()}SchemaOptions });
92
- }
93
-
94
- // Add custom controller methods here
95
- }
96
-
97
- const ${name.toLowerCase()}Controller = new ${name}Controller();
98
- export default ${name.toLowerCase()}Controller;
99
- `,
100
- schemas: (name) => `/**
101
- * ${name} Schemas
102
- * Generated by Arc CLI
103
- */
104
-
105
- import ${name} from './${name.toLowerCase()}.model.js';
106
- import { buildCrudSchemasFromModel } from '@classytic/mongokit/utils';
107
-
108
- /**
109
- * CRUD Schemas with Field Rules
110
- */
111
- const crudSchemas = buildCrudSchemasFromModel(${name}, {
112
- strictAdditionalProperties: true,
113
- fieldRules: {
114
- // Mark fields as system-managed (excluded from create/update)
115
- // deletedAt: { systemManaged: true },
116
- },
117
- query: {
118
- filterableFields: {
119
- isActive: 'boolean',
120
- createdAt: 'date',
121
- },
122
- },
123
- });
124
-
125
- // Schema options for controller
126
- export const ${name.toLowerCase()}SchemaOptions${ts ? ": any" : ""} = {
127
- query: {
128
- filterableFields: {
129
- isActive: 'boolean',
130
- createdAt: 'date',
131
- },
132
- },
133
- };
134
-
135
- export default crudSchemas;
136
- `,
137
- resource: (name) => `/**
138
- * ${name} Resource
139
- * Generated by Arc CLI
140
- */
141
-
142
- import { defineResource } from '@classytic/arc';
143
- import { createAdapter } from '#shared/adapter.js';
144
- import { publicReadPermissions } from '#shared/permissions.js';
145
- import ${name} from './${name.toLowerCase()}.model.js';
146
- import ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';
147
- import ${name.toLowerCase()}Controller from './${name.toLowerCase()}.controller.js';
148
-
149
- const ${name.toLowerCase()}Resource = defineResource({
150
- name: '${name.toLowerCase()}',
151
- displayName: '${name}s',
152
- prefix: '/${name.toLowerCase()}s',
153
-
154
- adapter: createAdapter(${name}, ${name.toLowerCase()}Repository),
155
- controller: ${name.toLowerCase()}Controller,
156
-
157
- presets: ['softDelete'],
158
-
159
- permissions: publicReadPermissions,
160
-
161
- // Add custom routes here:
162
- // additionalRoutes: [
163
- // {
164
- // method: 'GET',
165
- // path: '/custom',
166
- // summary: 'Custom endpoint',
167
- // handler: async (request, reply) => { ... },
168
- // },
169
- // ],
170
- });
171
-
172
- export default ${name.toLowerCase()}Resource;
173
- `,
174
- test: (name) => `/**
175
- * ${name} Tests
176
- * Generated by Arc CLI
177
- */
178
-
179
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
180
- import mongoose from 'mongoose';
181
- import { createAppInstance } from '../src/app.js';
182
- ${ts ? "import type { FastifyInstance } from 'fastify';\n" : ""}
183
- describe('${name} Resource', () => {
184
- let app${ts ? ": FastifyInstance" : ""};
185
-
186
- beforeAll(async () => {
187
- const testDbUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/test-${name.toLowerCase()}';
188
- await mongoose.connect(testDbUri);
189
- app = await createAppInstance();
190
- await app.ready();
191
- });
192
-
193
- afterAll(async () => {
194
- await app.close();
195
- await mongoose.connection.close();
196
- });
197
-
198
- describe('GET /${name.toLowerCase()}s', () => {
199
- it('should return a list', async () => {
200
- const response = await app.inject({
201
- method: 'GET',
202
- url: '/${name.toLowerCase()}s',
203
- });
204
-
205
- expect(response.statusCode).toBe(200);
206
- const body = JSON.parse(response.body);
207
- expect(body).toHaveProperty('docs');
208
- });
209
- });
210
- });
211
- `
212
- };
213
- }
214
- async function generate(type, args) {
215
- if (!type) {
216
- console.error("Error: Missing type argument");
217
- console.log("Usage: arc generate <resource|controller|model|repository|schemas> <name>");
218
- process.exit(1);
219
- }
220
- const [name] = args;
221
- if (!name) {
222
- console.error("Error: Missing name argument");
223
- console.log("Usage: arc generate <type> <name>");
224
- console.log("Example: arc generate resource product");
225
- process.exit(1);
226
- }
227
- const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);
228
- const lowerName = name.toLowerCase();
229
- const ts = isTypeScriptProject();
230
- const ext = ts ? "ts" : "js";
231
- const templates = getTemplates(ts);
232
- const resourcePath = join(process.cwd(), "src", "resources", lowerName);
233
- switch (type) {
234
- case "resource":
235
- case "r":
236
- await generateResource(capitalizedName, lowerName, resourcePath, templates, ext);
237
- break;
238
- case "controller":
239
- case "c":
240
- await generateFile(capitalizedName, lowerName, resourcePath, "controller", templates.controller, ext);
241
- break;
242
- case "model":
243
- case "m":
244
- await generateFile(capitalizedName, lowerName, resourcePath, "model", templates.model, ext);
245
- break;
246
- case "repository":
247
- case "repo":
248
- await generateFile(capitalizedName, lowerName, resourcePath, "repository", templates.repository, ext);
249
- break;
250
- case "schemas":
251
- case "s":
252
- await generateFile(capitalizedName, lowerName, resourcePath, "schemas", templates.schemas, ext);
253
- break;
254
- default:
255
- console.error(`Unknown type: ${type}`);
256
- console.log("Available types: resource, controller, model, repository, schemas");
257
- process.exit(1);
258
- }
259
- }
260
- async function generateResource(name, lowerName, resourcePath, templates, ext) {
261
- console.log(`
262
- 📦 Generating resource: ${name}...
263
- `);
264
- if (!existsSync(resourcePath)) {
265
- mkdirSync(resourcePath, { recursive: true });
266
- console.log(` 📁 Created: src/resources/${lowerName}/`);
267
- }
268
- const files = {
269
- [`${lowerName}.model.${ext}`]: templates.model(name),
270
- [`${lowerName}.repository.${ext}`]: templates.repository(name),
271
- [`${lowerName}.controller.${ext}`]: templates.controller(name),
272
- [`${lowerName}.schemas.${ext}`]: templates.schemas(name),
273
- [`${lowerName}.resource.${ext}`]: templates.resource(name)
274
- };
275
- for (const [filename, content] of Object.entries(files)) {
276
- const filepath = join(resourcePath, filename);
277
- if (existsSync(filepath)) {
278
- console.warn(` ⚠ Skipped: ${filename} (already exists)`);
279
- } else {
280
- writeFileSync(filepath, content);
281
- console.log(` ✅ Created: ${filename}`);
282
- }
283
- }
284
- const testsDir = join(process.cwd(), "tests");
285
- if (!existsSync(testsDir)) {
286
- mkdirSync(testsDir, { recursive: true });
287
- }
288
- const testPath = join(testsDir, `${lowerName}.test.${ext}`);
289
- if (!existsSync(testPath)) {
290
- writeFileSync(testPath, templates.test(name));
291
- console.log(` ✅ Created: tests/${lowerName}.test.${ext}`);
292
- }
293
- console.log(`
294
- ╔═══════════════════════════════════════════════════════════════╗
295
- ║ ✅ Resource Generated! ║
296
- ╚═══════════════════════════════════════════════════════════════╝
297
-
298
- Next steps:
299
-
300
- 1. Register in src/resources/index.${ext}:
301
- import ${lowerName}Resource from './${lowerName}/${lowerName}.resource.js';
302
-
303
- export const resources = [
304
- // ... existing resources
305
- ${lowerName}Resource,
306
- ];
307
-
308
- 2. Customize the model schema in:
309
- src/resources/${lowerName}/${lowerName}.model.${ext}
310
-
311
- 3. Run tests:
312
- npm test
313
- `);
314
- }
315
- async function generateFile(name, lowerName, resourcePath, fileType, template, ext) {
316
- console.log(`
317
- 📦 Generating ${fileType}: ${name}...
318
- `);
319
- if (!existsSync(resourcePath)) {
320
- mkdirSync(resourcePath, { recursive: true });
321
- console.log(` 📁 Created: src/resources/${lowerName}/`);
322
- }
323
- const filename = `${lowerName}.${fileType}.${ext}`;
324
- const filepath = join(resourcePath, filename);
325
- if (existsSync(filepath)) {
326
- console.error(` ❌ Error: ${filename} already exists`);
327
- process.exit(1);
328
- }
329
- writeFileSync(filepath, template(name));
330
- console.log(` ✅ Created: ${filename}`);
331
- }
332
- var generate_default = generate;
333
-
334
- export { generate_default as default, generate };
@@ -1,8 +0,0 @@
1
- /**
2
- * Arc CLI - Introspect Command
3
- *
4
- * Shows all registered resources and their configuration
5
- */
6
- declare function introspect(args: string[]): Promise<void>;
7
-
8
- export { introspect as default, introspect };
@@ -1,338 +0,0 @@
1
- import fp from 'fastify-plugin';
2
-
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __esm = (fn, res) => function __init() {
6
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
- };
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
-
13
- // src/registry/ResourceRegistry.ts
14
- var ResourceRegistry, registryKey, globalScope, resourceRegistry;
15
- var init_ResourceRegistry = __esm({
16
- "src/registry/ResourceRegistry.ts"() {
17
- ResourceRegistry = class {
18
- _resources;
19
- _frozen;
20
- constructor() {
21
- this._resources = /* @__PURE__ */ new Map();
22
- this._frozen = false;
23
- }
24
- /**
25
- * Register a resource
26
- */
27
- register(resource, options = {}) {
28
- if (this._frozen) {
29
- throw new Error(
30
- `Registry frozen. Cannot register '${resource.name}' after startup.`
31
- );
32
- }
33
- if (this._resources.has(resource.name)) {
34
- throw new Error(`Resource '${resource.name}' already registered.`);
35
- }
36
- const entry = {
37
- name: resource.name,
38
- displayName: resource.displayName,
39
- tag: resource.tag,
40
- prefix: resource.prefix,
41
- module: options.module ?? void 0,
42
- adapter: resource.adapter ? {
43
- type: resource.adapter.type,
44
- name: resource.adapter.name
45
- } : null,
46
- permissions: resource.permissions,
47
- presets: resource._appliedPresets ?? [],
48
- routes: [],
49
- // Populated later by getIntrospection()
50
- additionalRoutes: resource.additionalRoutes.map((r) => ({
51
- method: r.method,
52
- path: r.path,
53
- handler: typeof r.handler === "string" ? r.handler : r.handler.name || "anonymous",
54
- summary: r.summary,
55
- description: r.description,
56
- permissions: r.permissions,
57
- wrapHandler: r.wrapHandler,
58
- schema: r.schema
59
- // Include schema for OpenAPI docs
60
- })),
61
- events: Object.keys(resource.events ?? {}),
62
- registeredAt: (/* @__PURE__ */ new Date()).toISOString(),
63
- disableDefaultRoutes: resource.disableDefaultRoutes,
64
- openApiSchemas: options.openApiSchemas,
65
- plugin: resource.toPlugin()
66
- // Store plugin factory
67
- };
68
- this._resources.set(resource.name, entry);
69
- return this;
70
- }
71
- /**
72
- * Get resource by name
73
- */
74
- get(name) {
75
- return this._resources.get(name);
76
- }
77
- /**
78
- * Get all resources
79
- */
80
- getAll() {
81
- return Array.from(this._resources.values());
82
- }
83
- /**
84
- * Get resources by module
85
- */
86
- getByModule(moduleName) {
87
- return this.getAll().filter((r) => r.module === moduleName);
88
- }
89
- /**
90
- * Get resources by preset
91
- */
92
- getByPreset(presetName) {
93
- return this.getAll().filter((r) => r.presets.includes(presetName));
94
- }
95
- /**
96
- * Check if resource exists
97
- */
98
- has(name) {
99
- return this._resources.has(name);
100
- }
101
- /**
102
- * Get registry statistics
103
- */
104
- getStats() {
105
- const resources = this.getAll();
106
- const presetCounts = {};
107
- for (const r of resources) {
108
- for (const preset of r.presets) {
109
- presetCounts[preset] = (presetCounts[preset] ?? 0) + 1;
110
- }
111
- }
112
- return {
113
- totalResources: resources.length,
114
- byModule: this._groupBy(resources, "module"),
115
- presetUsage: presetCounts,
116
- totalRoutes: resources.reduce((sum, r) => {
117
- const defaultRouteCount = r.disableDefaultRoutes ? 0 : 5;
118
- return sum + (r.additionalRoutes?.length ?? 0) + defaultRouteCount;
119
- }, 0),
120
- totalEvents: resources.reduce((sum, r) => sum + (r.events?.length ?? 0), 0)
121
- };
122
- }
123
- /**
124
- * Get full introspection data
125
- */
126
- getIntrospection() {
127
- return {
128
- resources: this.getAll().map((r) => {
129
- const defaultRoutes = r.disableDefaultRoutes ? [] : [
130
- { method: "GET", path: r.prefix, operation: "list" },
131
- { method: "GET", path: `${r.prefix}/:id`, operation: "get" },
132
- { method: "POST", path: r.prefix, operation: "create" },
133
- { method: "PATCH", path: `${r.prefix}/:id`, operation: "update" },
134
- { method: "DELETE", path: `${r.prefix}/:id`, operation: "delete" }
135
- ];
136
- return {
137
- name: r.name,
138
- displayName: r.displayName,
139
- prefix: r.prefix,
140
- module: r.module,
141
- presets: r.presets,
142
- permissions: r.permissions,
143
- routes: [
144
- ...defaultRoutes,
145
- ...r.additionalRoutes?.map((ar) => ({
146
- method: ar.method,
147
- path: `${r.prefix}${ar.path}`,
148
- operation: typeof ar.handler === "string" ? ar.handler : "custom",
149
- handler: typeof ar.handler === "string" ? ar.handler : void 0,
150
- summary: ar.summary
151
- })) ?? []
152
- ],
153
- events: r.events
154
- };
155
- }),
156
- stats: this.getStats(),
157
- generatedAt: (/* @__PURE__ */ new Date()).toISOString()
158
- };
159
- }
160
- /**
161
- * Freeze registry (prevent further registrations)
162
- */
163
- freeze() {
164
- this._frozen = true;
165
- }
166
- /**
167
- * Check if frozen
168
- */
169
- isFrozen() {
170
- return this._frozen;
171
- }
172
- /**
173
- * Unfreeze registry (for testing)
174
- */
175
- _unfreeze() {
176
- this._frozen = false;
177
- }
178
- /**
179
- * Clear all resources (for testing)
180
- */
181
- _clear() {
182
- this._resources.clear();
183
- this._frozen = false;
184
- }
185
- /**
186
- * Group by key
187
- */
188
- _groupBy(arr, key) {
189
- const result = {};
190
- for (const item of arr) {
191
- const k = String(item[key] ?? "uncategorized");
192
- result[k] = (result[k] ?? 0) + 1;
193
- }
194
- return result;
195
- }
196
- };
197
- registryKey = /* @__PURE__ */ Symbol.for("arc.resourceRegistry");
198
- globalScope = globalThis;
199
- resourceRegistry = globalScope[registryKey] ?? new ResourceRegistry();
200
- if (!globalScope[registryKey]) {
201
- globalScope[registryKey] = resourceRegistry;
202
- }
203
- }
204
- });
205
- var introspectionPlugin, introspectionPlugin_default;
206
- var init_introspectionPlugin = __esm({
207
- "src/registry/introspectionPlugin.ts"() {
208
- init_ResourceRegistry();
209
- introspectionPlugin = async (fastify, opts = {}) => {
210
- const {
211
- prefix = "/_resources",
212
- authRoles = ["superadmin"],
213
- enabled = process.env.NODE_ENV !== "production" || process.env.ENABLE_INTROSPECTION === "true"
214
- } = opts;
215
- if (!enabled) {
216
- fastify.log?.info?.("Introspection plugin disabled");
217
- return;
218
- }
219
- const typedFastify = fastify;
220
- const authMiddleware = authRoles.length > 0 && typedFastify.authenticate ? [
221
- typedFastify.authenticate,
222
- typedFastify.authorize?.(...authRoles)
223
- ].filter(Boolean) : [];
224
- await fastify.register(async (instance) => {
225
- instance.get(
226
- "/",
227
- {
228
- preHandler: authMiddleware
229
- },
230
- async (_req, _reply) => {
231
- return resourceRegistry.getIntrospection();
232
- }
233
- );
234
- instance.get(
235
- "/stats",
236
- {
237
- preHandler: authMiddleware
238
- },
239
- async (_req, _reply) => {
240
- return resourceRegistry.getStats();
241
- }
242
- );
243
- instance.get(
244
- "/:name",
245
- {
246
- schema: {
247
- params: {
248
- type: "object",
249
- properties: {
250
- name: { type: "string" }
251
- },
252
- required: ["name"]
253
- }
254
- },
255
- preHandler: authMiddleware
256
- },
257
- async (req, reply) => {
258
- const resource = resourceRegistry.get(req.params.name);
259
- if (!resource) {
260
- return reply.code(404).send({
261
- error: `Resource '${req.params.name}' not found`
262
- });
263
- }
264
- return resource;
265
- }
266
- );
267
- }, { prefix });
268
- fastify.log?.info?.(`Introspection API at ${prefix}`);
269
- };
270
- introspectionPlugin_default = fp(introspectionPlugin, { name: "arc-introspection" });
271
- }
272
- });
273
-
274
- // src/registry/index.ts
275
- var registry_exports = {};
276
- __export(registry_exports, {
277
- ResourceRegistry: () => ResourceRegistry,
278
- introspectionPlugin: () => introspectionPlugin_default,
279
- introspectionPluginFn: () => introspectionPlugin,
280
- resourceRegistry: () => resourceRegistry
281
- });
282
- var init_registry = __esm({
283
- "src/registry/index.ts"() {
284
- init_ResourceRegistry();
285
- init_introspectionPlugin();
286
- }
287
- });
288
-
289
- // src/cli/commands/introspect.ts
290
- async function introspect(args) {
291
- console.log("Introspecting Arc resources...\n");
292
- try {
293
- const { resourceRegistry: resourceRegistry2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
294
- const resources = resourceRegistry2.getAll();
295
- if (resources.length === 0) {
296
- console.log("⚠️ No resources registered.");
297
- console.log("\nTo introspect resources, you need to load them first:");
298
- console.log(" arc introspect --entry ./index.js");
299
- console.log("\nWhere index.js imports all your resource definitions.");
300
- return;
301
- }
302
- console.log(`Found ${resources.length} resource(s):
303
- `);
304
- resources.forEach((resource, index) => {
305
- console.log(`${index + 1}. ${resource.name}`);
306
- console.log(` Display Name: ${resource.displayName}`);
307
- console.log(` Prefix: ${resource.prefix}`);
308
- console.log(` Module: ${resource.module || "none"}`);
309
- if (resource.permissions) {
310
- console.log(` Permissions:`);
311
- Object.entries(resource.permissions).forEach(([op, roles]) => {
312
- console.log(` ${op}: [${roles.join(", ")}]`);
313
- });
314
- }
315
- if (resource.presets && resource.presets.length > 0) {
316
- console.log(` Presets: ${resource.presets.join(", ")}`);
317
- }
318
- if (resource.additionalRoutes && resource.additionalRoutes.length > 0) {
319
- console.log(` Additional Routes: ${resource.additionalRoutes.length}`);
320
- }
321
- console.log("");
322
- });
323
- const stats = resourceRegistry2.getStats();
324
- console.log("Summary:");
325
- console.log(` Total Resources: ${stats.totalResources}`);
326
- console.log(` With Presets: ${resources.filter((r) => r.presets?.length > 0).length}`);
327
- console.log(
328
- ` With Custom Routes: ${resources.filter((r) => r.additionalRoutes && r.additionalRoutes.length > 0).length}`
329
- );
330
- } catch (error) {
331
- console.error("Error:", error.message);
332
- console.log("\nTip: Run this command after starting your application.");
333
- process.exit(1);
334
- }
335
- }
336
- var introspect_default = introspect;
337
-
338
- export { introspect_default as default, introspect };
@@ -1,4 +0,0 @@
1
- export { default as generate } from './commands/generate.js';
2
- export { default as init } from './commands/init.js';
3
- export { default as introspect } from './commands/introspect.js';
4
- export { exportDocs } from './commands/docs.js';