@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,628 @@
1
+ import { h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, m as RESERVED_QUERY_PARAMS, r as DEFAULT_LIMIT } from "./constants-DdXFXQtN.mjs";
2
+
3
+ //#region src/adapters/types.ts
4
+ /**
5
+ * Check if value is a Mongoose model
6
+ */
7
+ function isMongooseModel(value) {
8
+ return typeof value === "function" && value.prototype && "modelName" in value && "schema" in value;
9
+ }
10
+ /**
11
+ * Check if value is a repository
12
+ */
13
+ function isRepository(value) {
14
+ return typeof value === "object" && value !== null && "getAll" in value && "getById" in value && "create" in value && "update" in value && "delete" in value;
15
+ }
16
+
17
+ //#endregion
18
+ //#region src/adapters/mongoose.ts
19
+ /**
20
+ * Mongoose data adapter with proper type safety
21
+ *
22
+ * @typeParam TDoc - The document type
23
+ */
24
+ var MongooseAdapter = class {
25
+ type = "mongoose";
26
+ name;
27
+ model;
28
+ repository;
29
+ schemaGenerator;
30
+ constructor(options) {
31
+ if (!isMongooseModel(options.model)) throw new TypeError("MongooseAdapter: Invalid model. Expected Mongoose Model instance.\nUsage: createMongooseAdapter({ model: YourModel, repository: yourRepo })");
32
+ if (!isRepository(options.repository)) throw new TypeError("MongooseAdapter: Invalid repository. Expected CrudRepository instance.\nUsage: createMongooseAdapter({ model: YourModel, repository: yourRepo })");
33
+ this.model = options.model;
34
+ this.repository = options.repository;
35
+ this.schemaGenerator = options.schemaGenerator;
36
+ this.name = `MongooseAdapter<${options.model.modelName}>`;
37
+ }
38
+ /**
39
+ * Get schema metadata from Mongoose model
40
+ */
41
+ getSchemaMetadata() {
42
+ const paths = this.model.schema.paths;
43
+ const fields = {};
44
+ for (const [fieldName, schemaType] of Object.entries(paths)) {
45
+ if (fieldName.startsWith("_") && fieldName !== "_id") continue;
46
+ const typeInfo = schemaType;
47
+ fields[fieldName] = {
48
+ type: {
49
+ String: "string",
50
+ Number: "number",
51
+ Boolean: "boolean",
52
+ Date: "date",
53
+ ObjectID: "objectId",
54
+ ObjectId: "objectId",
55
+ Array: "array",
56
+ Mixed: "object",
57
+ Buffer: "object",
58
+ Embedded: "object"
59
+ }[typeInfo.instance || "Mixed"] ?? "object",
60
+ required: !!typeInfo.isRequired,
61
+ ref: typeInfo.options?.ref
62
+ };
63
+ }
64
+ return {
65
+ name: this.model.modelName,
66
+ fields,
67
+ relations: this.extractRelations(paths)
68
+ };
69
+ }
70
+ /**
71
+ * Generate OpenAPI schemas from Mongoose model.
72
+ *
73
+ * If a `schemaGenerator` plugin was provided (e.g. MongoKit's buildCrudSchemasFromModel),
74
+ * it is used instead of the built-in basic conversion.
75
+ */
76
+ generateSchemas(schemaOptions) {
77
+ try {
78
+ if (this.schemaGenerator) return this.schemaGenerator(this.model, schemaOptions);
79
+ const paths = this.model.schema.paths;
80
+ const properties = {};
81
+ const required = [];
82
+ const fieldRules = schemaOptions?.fieldRules || {};
83
+ const blockedFields = new Set(Object.entries(fieldRules).filter(([, rules]) => rules.systemManaged || rules.hidden).map(([field]) => field));
84
+ for (const [fieldName, schemaType] of Object.entries(paths)) {
85
+ if (fieldName.startsWith("__")) continue;
86
+ if (blockedFields.has(fieldName)) continue;
87
+ const typeInfo = schemaType;
88
+ properties[fieldName] = this.mongooseTypeToOpenApi(typeInfo);
89
+ if (typeInfo.isRequired) required.push(fieldName);
90
+ }
91
+ const systemFieldSet = new Set(SYSTEM_FIELDS);
92
+ const inputProperties = Object.fromEntries(Object.entries(properties).filter(([field]) => !systemFieldSet.has(field)));
93
+ const inputRequired = required.filter((field) => !systemFieldSet.has(field));
94
+ return {
95
+ createBody: {
96
+ type: "object",
97
+ properties: inputProperties,
98
+ required: inputRequired.length > 0 ? inputRequired : void 0
99
+ },
100
+ updateBody: {
101
+ type: "object",
102
+ properties: inputProperties
103
+ },
104
+ response: {
105
+ type: "object",
106
+ properties
107
+ }
108
+ };
109
+ } catch {
110
+ return null;
111
+ }
112
+ }
113
+ /**
114
+ * Extract relation metadata
115
+ */
116
+ extractRelations(paths) {
117
+ const relations = {};
118
+ for (const [fieldName, schemaType] of Object.entries(paths)) {
119
+ const ref = schemaType.options?.ref;
120
+ if (ref) relations[fieldName] = {
121
+ type: "one-to-one",
122
+ target: ref,
123
+ foreignKey: fieldName
124
+ };
125
+ }
126
+ return Object.keys(relations).length > 0 ? relations : void 0;
127
+ }
128
+ /**
129
+ * Convert Mongoose type to OpenAPI type
130
+ */
131
+ mongooseTypeToOpenApi(typeInfo) {
132
+ const instance = typeInfo.instance;
133
+ const options = typeInfo.options || {};
134
+ const baseType = {};
135
+ switch (instance) {
136
+ case "String":
137
+ baseType.type = "string";
138
+ if (options.enum) baseType.enum = options.enum;
139
+ if (options.minlength) baseType.minLength = options.minlength;
140
+ if (options.maxlength) baseType.maxLength = options.maxlength;
141
+ break;
142
+ case "Number":
143
+ baseType.type = "number";
144
+ if (options.min !== void 0) baseType.minimum = options.min;
145
+ if (options.max !== void 0) baseType.maximum = options.max;
146
+ break;
147
+ case "Boolean":
148
+ baseType.type = "boolean";
149
+ break;
150
+ case "Date":
151
+ baseType.type = "string";
152
+ baseType.format = "date-time";
153
+ break;
154
+ case "ObjectID":
155
+ case "ObjectId":
156
+ baseType.type = "string";
157
+ baseType.pattern = "^[a-f\\d]{24}$";
158
+ break;
159
+ case "Array":
160
+ baseType.type = "array";
161
+ baseType.items = { type: "string" };
162
+ break;
163
+ default: baseType.type = "object";
164
+ }
165
+ return baseType;
166
+ }
167
+ };
168
+ function createMongooseAdapter(modelOrOptions, repository) {
169
+ if (isMongooseModel(modelOrOptions)) {
170
+ if (!repository) throw new TypeError("createMongooseAdapter: repository is required when using 2-arg form.\nUsage: createMongooseAdapter(Model, repository)");
171
+ return new MongooseAdapter({
172
+ model: modelOrOptions,
173
+ repository
174
+ });
175
+ }
176
+ return new MongooseAdapter(modelOrOptions);
177
+ }
178
+
179
+ //#endregion
180
+ //#region src/adapters/prisma.ts
181
+ /**
182
+ * Prisma Query Parser - Converts URL parameters to Prisma query format
183
+ *
184
+ * Translates Arc's query format to Prisma's where/orderBy/take/skip structure.
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * const parser = new PrismaQueryParser();
189
+ *
190
+ * // URL: ?status=active&price[gte]=100&sort=-createdAt&page=2&limit=10
191
+ * const prismaQuery = parser.toPrismaQuery(parsedQuery);
192
+ * // Returns:
193
+ * // {
194
+ * // where: { status: 'active', price: { gte: 100 }, deletedAt: null },
195
+ * // orderBy: { createdAt: 'desc' },
196
+ * // take: 10,
197
+ * // skip: 10,
198
+ * // }
199
+ * ```
200
+ */
201
+ var PrismaQueryParser = class {
202
+ maxLimit;
203
+ defaultLimit;
204
+ softDeleteEnabled;
205
+ softDeleteField;
206
+ /** Map Arc operators to Prisma operators */
207
+ operatorMap = {
208
+ $eq: "equals",
209
+ $ne: "not",
210
+ $gt: "gt",
211
+ $gte: "gte",
212
+ $lt: "lt",
213
+ $lte: "lte",
214
+ $in: "in",
215
+ $nin: "notIn",
216
+ $regex: "contains",
217
+ $exists: void 0
218
+ };
219
+ constructor(options = {}) {
220
+ this.maxLimit = options.maxLimit ?? DEFAULT_MAX_LIMIT;
221
+ this.defaultLimit = options.defaultLimit ?? DEFAULT_LIMIT;
222
+ this.softDeleteEnabled = options.softDeleteEnabled ?? true;
223
+ this.softDeleteField = options.softDeleteField ?? "deletedAt";
224
+ }
225
+ /**
226
+ * Parse URL query parameters (delegates to ArcQueryParser format)
227
+ */
228
+ parse(query) {
229
+ const q = query ?? {};
230
+ const page = this.parseNumber(q.page, 1);
231
+ const limit = Math.min(this.parseNumber(q.limit, this.defaultLimit), this.maxLimit);
232
+ return {
233
+ filters: this.parseFilters(q),
234
+ limit,
235
+ page,
236
+ sort: this.parseSort(q.sort),
237
+ search: q.search,
238
+ select: this.parseSelect(q.select)
239
+ };
240
+ }
241
+ /**
242
+ * Convert ParsedQuery to Prisma query options
243
+ */
244
+ toPrismaQuery(parsed, policyFilters) {
245
+ const where = {};
246
+ if (parsed.filters) Object.assign(where, this.translateFilters(parsed.filters));
247
+ if (policyFilters) Object.assign(where, this.translateFilters(policyFilters));
248
+ if (this.softDeleteEnabled) where[this.softDeleteField] = null;
249
+ const orderBy = parsed.sort ? Object.entries(parsed.sort).map(([field, dir]) => ({ [field]: dir === 1 ? "asc" : "desc" })) : void 0;
250
+ const take = parsed.limit ?? this.defaultLimit;
251
+ const skip = parsed.page ? (parsed.page - 1) * take : 0;
252
+ const select = parsed.select ? Object.fromEntries(Object.entries(parsed.select).filter(([, v]) => v === 1).map(([k]) => [k, true])) : void 0;
253
+ return {
254
+ where: Object.keys(where).length > 0 ? where : void 0,
255
+ orderBy: orderBy && orderBy.length > 0 ? orderBy : void 0,
256
+ take,
257
+ skip,
258
+ select: select && Object.keys(select).length > 0 ? select : void 0
259
+ };
260
+ }
261
+ /**
262
+ * Translate Arc/MongoDB-style filters to Prisma where clause
263
+ */
264
+ translateFilters(filters) {
265
+ const result = {};
266
+ for (const [field, value] of Object.entries(filters)) {
267
+ if (value === null || value === void 0) continue;
268
+ if (typeof value === "object" && !Array.isArray(value)) {
269
+ const prismaCondition = {};
270
+ for (const [op, opValue] of Object.entries(value)) {
271
+ if (op === "$exists") {
272
+ result[field] = opValue ? { not: null } : null;
273
+ continue;
274
+ }
275
+ const prismaOp = this.operatorMap[op];
276
+ if (prismaOp) prismaCondition[prismaOp] = opValue;
277
+ }
278
+ if (Object.keys(prismaCondition).length > 0) result[field] = prismaCondition;
279
+ } else result[field] = value;
280
+ }
281
+ return result;
282
+ }
283
+ parseNumber(value, defaultValue) {
284
+ if (value === void 0 || value === null) return defaultValue;
285
+ const num = parseInt(String(value), 10);
286
+ return Number.isNaN(num) ? defaultValue : Math.max(1, num);
287
+ }
288
+ parseSort(value) {
289
+ if (!value) return void 0;
290
+ const sortStr = String(value);
291
+ const result = {};
292
+ for (const field of sortStr.split(",")) {
293
+ const trimmed = field.trim();
294
+ if (!trimmed || !/^-?[a-zA-Z_][a-zA-Z0-9_.]*$/.test(trimmed)) continue;
295
+ if (trimmed.startsWith("-")) result[trimmed.slice(1)] = -1;
296
+ else result[trimmed] = 1;
297
+ }
298
+ return Object.keys(result).length > 0 ? result : void 0;
299
+ }
300
+ parseSelect(value) {
301
+ if (!value) return void 0;
302
+ const result = {};
303
+ for (const field of String(value).split(",")) {
304
+ const trimmed = field.trim();
305
+ if (!trimmed || !/^-?[a-zA-Z_][a-zA-Z0-9_.]*$/.test(trimmed)) continue;
306
+ result[trimmed.startsWith("-") ? trimmed.slice(1) : trimmed] = trimmed.startsWith("-") ? 0 : 1;
307
+ }
308
+ return Object.keys(result).length > 0 ? result : void 0;
309
+ }
310
+ parseFilters(query) {
311
+ const filters = {};
312
+ const operators = {
313
+ eq: "$eq",
314
+ ne: "$ne",
315
+ gt: "$gt",
316
+ gte: "$gte",
317
+ lt: "$lt",
318
+ lte: "$lte",
319
+ in: "$in",
320
+ nin: "$nin",
321
+ like: "$regex",
322
+ contains: "$regex",
323
+ exists: "$exists"
324
+ };
325
+ for (const [key, value] of Object.entries(query)) {
326
+ if (RESERVED_QUERY_PARAMS.has(key) || value === void 0 || value === null) continue;
327
+ const match = key.match(/^([a-zA-Z_][a-zA-Z0-9_.]*)(?:\[([a-z]+)\])?$/);
328
+ if (!match) continue;
329
+ const [, fieldName, operator] = match;
330
+ if (!fieldName) continue;
331
+ if (operator && operators[operator]) {
332
+ if (!filters[fieldName]) filters[fieldName] = {};
333
+ filters[fieldName][operators[operator]] = this.coerceValue(value, operator);
334
+ } else if (!operator) filters[fieldName] = this.coerceValue(value);
335
+ }
336
+ return filters;
337
+ }
338
+ coerceValue(value, operator) {
339
+ if (operator === "in" || operator === "nin") {
340
+ if (Array.isArray(value)) return value.map((v) => this.coerceValue(v));
341
+ if (typeof value === "string" && value.includes(",")) return value.split(",").map((v) => this.coerceValue(v.trim()));
342
+ return [this.coerceValue(value)];
343
+ }
344
+ if (operator === "exists") return String(value).toLowerCase() === "true" || value === "1";
345
+ if (value === "true") return true;
346
+ if (value === "false") return false;
347
+ if (value === "null") return null;
348
+ if (typeof value === "string") {
349
+ const num = Number(value);
350
+ if (!Number.isNaN(num) && value.trim() !== "") return num;
351
+ }
352
+ return value;
353
+ }
354
+ };
355
+ var PrismaAdapter = class {
356
+ type = "prisma";
357
+ name;
358
+ repository;
359
+ queryParser;
360
+ client;
361
+ modelName;
362
+ dmmf;
363
+ softDeleteEnabled;
364
+ softDeleteField;
365
+ constructor(options) {
366
+ this.client = options.client;
367
+ this.modelName = options.modelName;
368
+ this.repository = options.repository;
369
+ this.dmmf = options.dmmf;
370
+ this.name = `prisma:${options.modelName}`;
371
+ this.softDeleteEnabled = options.softDeleteEnabled ?? true;
372
+ this.softDeleteField = options.softDeleteField ?? "deletedAt";
373
+ this.queryParser = options.queryParser ?? new PrismaQueryParser({
374
+ softDeleteEnabled: this.softDeleteEnabled,
375
+ softDeleteField: this.softDeleteField
376
+ });
377
+ }
378
+ /**
379
+ * Parse URL query parameters and convert to Prisma query options
380
+ */
381
+ parseQuery(query, policyFilters) {
382
+ const parsed = this.queryParser.parse(query);
383
+ return this.queryParser.toPrismaQuery(parsed, policyFilters);
384
+ }
385
+ /**
386
+ * Apply policy filters to existing Prisma where clause
387
+ * Used for multi-tenant, ownership, and other security filters
388
+ */
389
+ applyPolicyFilters(where, policyFilters) {
390
+ return {
391
+ ...where,
392
+ ...policyFilters
393
+ };
394
+ }
395
+ generateSchemas(options) {
396
+ if (!this.dmmf) return null;
397
+ try {
398
+ const model = this.dmmf.datamodel?.models?.find((m) => m.name.toLowerCase() === this.modelName.toLowerCase());
399
+ if (!model) return null;
400
+ return {
401
+ entity: this.buildEntitySchema(model, options),
402
+ createBody: this.buildCreateSchema(model, options),
403
+ updateBody: this.buildUpdateSchema(model, options),
404
+ params: {
405
+ type: "object",
406
+ properties: { id: { type: "string" } },
407
+ required: ["id"]
408
+ },
409
+ listQuery: {
410
+ type: "object",
411
+ properties: {
412
+ page: {
413
+ type: "number",
414
+ minimum: 1,
415
+ description: "Page number for pagination"
416
+ },
417
+ limit: {
418
+ type: "number",
419
+ minimum: 1,
420
+ maximum: 100,
421
+ description: "Items per page"
422
+ },
423
+ sort: {
424
+ type: "string",
425
+ description: "Sort field (e.g., \"name\", \"-createdAt\")"
426
+ }
427
+ }
428
+ }
429
+ };
430
+ } catch {
431
+ return null;
432
+ }
433
+ }
434
+ getSchemaMetadata() {
435
+ if (!this.dmmf) return null;
436
+ try {
437
+ const model = this.dmmf.datamodel?.models?.find((m) => m.name.toLowerCase() === this.modelName.toLowerCase());
438
+ if (!model) return null;
439
+ const fields = {};
440
+ for (const field of model.fields) fields[field.name] = this.convertPrismaFieldToMetadata(field);
441
+ return {
442
+ name: model.name,
443
+ fields,
444
+ indexes: model.uniqueIndexes?.map((idx) => ({
445
+ fields: idx.fields,
446
+ unique: true
447
+ }))
448
+ };
449
+ } catch (err) {
450
+ return null;
451
+ }
452
+ }
453
+ async validate(data) {
454
+ if (!data || typeof data !== "object") return {
455
+ valid: false,
456
+ errors: [{
457
+ field: "root",
458
+ message: "Data must be an object"
459
+ }]
460
+ };
461
+ if (this.dmmf) try {
462
+ const model = this.dmmf.datamodel?.models?.find((m) => m.name.toLowerCase() === this.modelName.toLowerCase());
463
+ if (model) {
464
+ const requiredFields = model.fields.filter((f) => f.isRequired && !f.hasDefaultValue && !f.isGenerated);
465
+ const errors = [];
466
+ for (const field of requiredFields) if (!(field.name in data)) errors.push({
467
+ field: field.name,
468
+ message: `${field.name} is required`
469
+ });
470
+ if (errors.length > 0) return {
471
+ valid: false,
472
+ errors
473
+ };
474
+ }
475
+ } catch (err) {}
476
+ return { valid: true };
477
+ }
478
+ async healthCheck() {
479
+ try {
480
+ const delegateName = this.modelName.charAt(0).toLowerCase() + this.modelName.slice(1);
481
+ const delegate = this.client[delegateName];
482
+ if (!delegate) return false;
483
+ await delegate.findMany({ take: 1 });
484
+ return true;
485
+ } catch (err) {
486
+ return false;
487
+ }
488
+ }
489
+ async close() {
490
+ try {
491
+ await this.client.$disconnect();
492
+ } catch (err) {}
493
+ }
494
+ buildEntitySchema(model, options) {
495
+ const properties = {};
496
+ const required = [];
497
+ for (const field of model.fields) {
498
+ if (this.shouldSkipField(field, options)) continue;
499
+ properties[field.name] = this.convertPrismaFieldToJsonSchema(field);
500
+ if (field.isRequired && !field.hasDefaultValue) required.push(field.name);
501
+ }
502
+ return {
503
+ type: "object",
504
+ properties,
505
+ ...required.length > 0 && { required }
506
+ };
507
+ }
508
+ buildCreateSchema(model, options) {
509
+ const properties = {};
510
+ const required = [];
511
+ for (const field of model.fields) {
512
+ if (field.isGenerated || field.relationName) continue;
513
+ if (this.shouldSkipField(field, options)) continue;
514
+ properties[field.name] = this.convertPrismaFieldToJsonSchema(field);
515
+ if (field.isRequired && !field.hasDefaultValue) required.push(field.name);
516
+ }
517
+ return {
518
+ type: "object",
519
+ properties,
520
+ ...required.length > 0 && { required }
521
+ };
522
+ }
523
+ buildUpdateSchema(model, options) {
524
+ const properties = {};
525
+ for (const field of model.fields) {
526
+ if (field.isGenerated || field.isId || field.relationName) continue;
527
+ if (this.shouldSkipField(field, options)) continue;
528
+ properties[field.name] = this.convertPrismaFieldToJsonSchema(field);
529
+ }
530
+ return {
531
+ type: "object",
532
+ properties
533
+ };
534
+ }
535
+ shouldSkipField(field, options) {
536
+ if (options?.excludeFields?.includes(field.name)) return true;
537
+ if (field.name.startsWith("_")) return true;
538
+ return false;
539
+ }
540
+ convertPrismaFieldToJsonSchema(field) {
541
+ const schema = {};
542
+ switch (field.type) {
543
+ case "String":
544
+ schema.type = "string";
545
+ break;
546
+ case "Int":
547
+ case "BigInt":
548
+ schema.type = "integer";
549
+ break;
550
+ case "Float":
551
+ case "Decimal":
552
+ schema.type = "number";
553
+ break;
554
+ case "Boolean":
555
+ schema.type = "boolean";
556
+ break;
557
+ case "DateTime":
558
+ schema.type = "string";
559
+ schema.format = "date-time";
560
+ break;
561
+ case "Json":
562
+ schema.type = "object";
563
+ break;
564
+ default: if (field.kind === "enum") {
565
+ schema.type = "string";
566
+ if (this.dmmf?.datamodel?.enums) {
567
+ const enumDef = this.dmmf.datamodel.enums.find((e) => e.name === field.type);
568
+ if (enumDef) schema.enum = enumDef.values.map((v) => v.name);
569
+ }
570
+ } else schema.type = "string";
571
+ }
572
+ if (field.isList) return {
573
+ type: "array",
574
+ items: schema
575
+ };
576
+ if (field.documentation) schema.description = field.documentation;
577
+ return schema;
578
+ }
579
+ convertPrismaFieldToMetadata(field) {
580
+ const metadata = {
581
+ type: this.mapPrismaTypeToMetadataType(field.type, field.kind),
582
+ required: field.isRequired,
583
+ array: field.isList
584
+ };
585
+ if (field.isUnique) metadata.unique = true;
586
+ if (field.hasDefaultValue) metadata.default = field.default;
587
+ if (field.documentation) metadata.description = field.documentation;
588
+ if (field.relationName) metadata.ref = field.type;
589
+ return metadata;
590
+ }
591
+ mapPrismaTypeToMetadataType(type, kind) {
592
+ if (kind === "enum") return "enum";
593
+ switch (type) {
594
+ case "String": return "string";
595
+ case "Int":
596
+ case "BigInt":
597
+ case "Float":
598
+ case "Decimal": return "number";
599
+ case "Boolean": return "boolean";
600
+ case "DateTime": return "date";
601
+ case "Json": return "object";
602
+ default: return "string";
603
+ }
604
+ }
605
+ };
606
+ /**
607
+ * Factory function to create Prisma adapter
608
+ *
609
+ * @example
610
+ * import { PrismaClient } from '@prisma/client';
611
+ * import { createPrismaAdapter } from '@classytic/arc';
612
+ *
613
+ * const prisma = new PrismaClient();
614
+ *
615
+ * const userAdapter = createPrismaAdapter({
616
+ * client: prisma,
617
+ * modelName: 'user',
618
+ * repository: userRepository,
619
+ * dmmf: Prisma.dmmf, // Optional: for schema generation
620
+ * });
621
+ */
622
+ function createPrismaAdapter(options) {
623
+ return new PrismaAdapter(options);
624
+ }
625
+
626
+ //#endregion
627
+ export { createMongooseAdapter as a, MongooseAdapter as i, PrismaQueryParser as n, createPrismaAdapter as r, PrismaAdapter as t };
628
+ //# sourceMappingURL=prisma-DJbMt3yf.mjs.map