sonamu 0.10.11 → 0.10.13

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 (519) hide show
  1. package/dist/ai/agents/agent.d.ts +1 -1
  2. package/dist/ai/agents/agent.d.ts.map +1 -1
  3. package/dist/ai/agents/agent.js +5 -6
  4. package/dist/ai/agents/types.d.ts +1 -1
  5. package/dist/ai/agents/types.d.ts.map +1 -1
  6. package/dist/ai/providers/rtzr/api.js +18 -18
  7. package/dist/ai/providers/rtzr/error.d.ts.map +1 -1
  8. package/dist/ai/providers/rtzr/error.js +17 -15
  9. package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
  10. package/dist/ai/providers/rtzr/model.js +3 -2
  11. package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
  12. package/dist/ai/providers/rtzr/options.js +16 -16
  13. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
  14. package/dist/ai/providers/rtzr/provider.js +9 -9
  15. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
  16. package/dist/ai/providers/rtzr/utils.js +1 -1
  17. package/dist/api/caster.d.ts.map +1 -1
  18. package/dist/api/caster.js +17 -17
  19. package/dist/api/code-converters.d.ts +4 -2
  20. package/dist/api/code-converters.d.ts.map +1 -1
  21. package/dist/api/code-converters.js +100 -19
  22. package/dist/api/config.d.ts +16 -1
  23. package/dist/api/config.d.ts.map +1 -1
  24. package/dist/api/config.js +28 -21
  25. package/dist/api/context.d.ts +2 -2
  26. package/dist/api/context.d.ts.map +1 -1
  27. package/dist/api/context.js +1 -1
  28. package/dist/api/decorators.d.ts.map +1 -1
  29. package/dist/api/decorators.js +18 -11
  30. package/dist/api/http-validator.d.ts +36 -0
  31. package/dist/api/http-validator.d.ts.map +1 -0
  32. package/dist/api/http-validator.js +72 -0
  33. package/dist/api/index.js +6 -4
  34. package/dist/api/sonamu.d.ts +59 -20
  35. package/dist/api/sonamu.d.ts.map +1 -1
  36. package/dist/api/sonamu.js +250 -106
  37. package/dist/api/websocket-helpers.d.ts +7 -5
  38. package/dist/api/websocket-helpers.d.ts.map +1 -1
  39. package/dist/api/websocket-helpers.js +6 -6
  40. package/dist/auth/audit-log/builders.d.ts.map +1 -1
  41. package/dist/auth/audit-log/builders.js +1 -1
  42. package/dist/auth/audit-log/client-ip.d.ts +1 -1
  43. package/dist/auth/audit-log/client-ip.d.ts.map +1 -1
  44. package/dist/auth/audit-log/client-ip.js +4 -2
  45. package/dist/auth/audit-log/events.d.ts +5 -1
  46. package/dist/auth/audit-log/events.d.ts.map +1 -1
  47. package/dist/auth/audit-log/events.js +1 -1
  48. package/dist/auth/audit-log/plugin.d.ts +0 -8
  49. package/dist/auth/audit-log/plugin.d.ts.map +1 -1
  50. package/dist/auth/audit-log/plugin.js +48 -52
  51. package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
  52. package/dist/auth/audit-log-ingestor.js +16 -12
  53. package/dist/auth/auth-generator.d.ts.map +1 -1
  54. package/dist/auth/auth-generator.js +1 -1
  55. package/dist/auth/better-auth-request.d.ts.map +1 -1
  56. package/dist/auth/better-auth-request.js +6 -5
  57. package/dist/auth/knex-adapter.js +1 -1
  58. package/dist/auth/plugins/entity-definitions/index.d.ts +13 -1
  59. package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
  60. package/dist/auth/plugins/entity-definitions/index.js +1 -1
  61. package/dist/auth/plugins/wrappers/admin.d.ts +1 -1
  62. package/dist/bin/build-config.d.ts +25 -0
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +105 -2
  65. package/dist/bin/cli.js +133 -29
  66. package/dist/bin/compiler-policy.d.ts +3 -0
  67. package/dist/bin/compiler-policy.d.ts.map +1 -0
  68. package/dist/bin/compiler-policy.js +24 -0
  69. package/dist/bin/fixture.d.ts.map +1 -1
  70. package/dist/bin/fixture.js +5 -3
  71. package/dist/bin/test-command.d.ts +22 -1
  72. package/dist/bin/test-command.d.ts.map +1 -1
  73. package/dist/bin/test-command.js +18 -10
  74. package/dist/bin/ts-loader-registration.d.ts +7 -1
  75. package/dist/bin/ts-loader-registration.d.ts.map +1 -1
  76. package/dist/bin/ts-loader-registration.js +13 -4
  77. package/dist/cache/decorator.d.ts.map +1 -1
  78. package/dist/cache/decorator.js +11 -4
  79. package/dist/compress/compress.d.ts.map +1 -1
  80. package/dist/compress/compress.js +1 -1
  81. package/dist/cone/cone-generator.d.ts +14 -1
  82. package/dist/cone/cone-generator.d.ts.map +1 -1
  83. package/dist/cone/cone-generator.js +13 -9
  84. package/dist/database/_batch_update.js +1 -1
  85. package/dist/database/base-model.d.ts +22 -10
  86. package/dist/database/base-model.d.ts.map +1 -1
  87. package/dist/database/base-model.js +26 -16
  88. package/dist/database/base-model.types.d.ts +15 -3
  89. package/dist/database/base-model.types.d.ts.map +1 -1
  90. package/dist/database/db.d.ts +12 -2
  91. package/dist/database/db.d.ts.map +1 -1
  92. package/dist/database/db.js +10 -7
  93. package/dist/database/knex.d.ts.map +1 -1
  94. package/dist/database/knex.js +17 -14
  95. package/dist/database/puri.d.ts +11 -9
  96. package/dist/database/puri.d.ts.map +1 -1
  97. package/dist/database/puri.js +93 -79
  98. package/dist/database/puri.types.d.ts +21 -21
  99. package/dist/database/puri.types.d.ts.map +1 -1
  100. package/dist/database/puri.types.js +1 -1
  101. package/dist/database/upsert-builder.d.ts +12 -10
  102. package/dist/database/upsert-builder.d.ts.map +1 -1
  103. package/dist/database/upsert-builder.js +20 -12
  104. package/dist/dict/sd.d.ts.map +1 -1
  105. package/dist/dict/sd.js +1 -1
  106. package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
  107. package/dist/dict/sonamu-dictionary.js +1 -1
  108. package/dist/dict/utils.d.ts.map +1 -1
  109. package/dist/dict/utils.js +7 -2
  110. package/dist/entity/entity-manager.d.ts +13 -4
  111. package/dist/entity/entity-manager.d.ts.map +1 -1
  112. package/dist/entity/entity-manager.js +19 -11
  113. package/dist/entity/entity-template-cone.d.ts +73 -5
  114. package/dist/entity/entity-template-cone.d.ts.map +1 -1
  115. package/dist/entity/entity-template-cone.js +4 -2
  116. package/dist/entity/entity.d.ts +6 -2
  117. package/dist/entity/entity.d.ts.map +1 -1
  118. package/dist/entity/entity.js +30 -28
  119. package/dist/env.d.ts +3 -1
  120. package/dist/env.d.ts.map +1 -1
  121. package/dist/env.js +1 -1
  122. package/dist/exceptions/error-handler.d.ts.map +1 -1
  123. package/dist/exceptions/error-handler.js +7 -2
  124. package/dist/exceptions/so-exceptions.d.ts +24 -20
  125. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  126. package/dist/exceptions/so-exceptions.js +4 -2
  127. package/dist/filter/utils.d.ts +7 -2
  128. package/dist/filter/utils.d.ts.map +1 -1
  129. package/dist/filter/utils.js +8 -6
  130. package/dist/index.d.ts +3 -0
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +13 -7
  133. package/dist/logger/configure.d.ts.map +1 -1
  134. package/dist/logger/configure.js +10 -10
  135. package/dist/migration/code-generation.d.ts.map +1 -1
  136. package/dist/migration/code-generation.js +50 -46
  137. package/dist/migration/index-where-predicate.d.ts.map +1 -1
  138. package/dist/migration/index-where-predicate.js +22 -8
  139. package/dist/migration/migration-set.d.ts.map +1 -1
  140. package/dist/migration/migration-set.js +1 -1
  141. package/dist/migration/migrator.d.ts +61 -36
  142. package/dist/migration/migrator.d.ts.map +1 -1
  143. package/dist/migration/migrator.js +276 -167
  144. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
  145. package/dist/migration/postgresql-schema-reader.js +51 -36
  146. package/dist/migration/slack-confirm.d.ts.map +1 -1
  147. package/dist/migration/slack-confirm.js +1 -1
  148. package/dist/migration/types.d.ts +54 -0
  149. package/dist/migration/types.d.ts.map +1 -1
  150. package/dist/naite/naite-reporter.js +2 -2
  151. package/dist/naite/naite.d.ts +74 -15
  152. package/dist/naite/naite.d.ts.map +1 -1
  153. package/dist/naite/naite.js +5 -19
  154. package/dist/runtime-type.d.ts +6 -0
  155. package/dist/runtime-type.d.ts.map +1 -0
  156. package/dist/runtime-type.js +26 -0
  157. package/dist/ssr/hmr-opt-out.d.ts +26 -0
  158. package/dist/ssr/hmr-opt-out.d.ts.map +1 -0
  159. package/dist/ssr/hmr-opt-out.js +59 -0
  160. package/dist/ssr/renderer.d.ts.map +1 -1
  161. package/dist/ssr/renderer.js +4 -1
  162. package/dist/storage/base-file.js +14 -14
  163. package/dist/storage/buffered-file.d.ts +2 -2
  164. package/dist/storage/buffered-file.d.ts.map +1 -1
  165. package/dist/storage/buffered-file.js +12 -12
  166. package/dist/storage/s3-driver.d.ts.map +1 -1
  167. package/dist/storage/s3-driver.js +1 -1
  168. package/dist/storage/uploaded-file.d.ts +2 -2
  169. package/dist/storage/uploaded-file.d.ts.map +1 -1
  170. package/dist/storage/uploaded-file.js +8 -8
  171. package/dist/stream/sse.js +11 -11
  172. package/dist/stream/ws-core.d.ts +1 -1
  173. package/dist/stream/ws-core.d.ts.map +1 -1
  174. package/dist/stream/ws-delivery.d.ts +1 -1
  175. package/dist/stream/ws-delivery.d.ts.map +1 -1
  176. package/dist/stream/ws-delivery.js +6 -4
  177. package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
  178. package/dist/stream/ws-local-connection-store.js +4 -2
  179. package/dist/stream/ws-presence-store.js +1 -1
  180. package/dist/stream/ws-registry.d.ts +4 -4
  181. package/dist/stream/ws-registry.d.ts.map +1 -1
  182. package/dist/stream/ws-registry.js +4 -2
  183. package/dist/stream/ws-telemetry.d.ts +16 -12
  184. package/dist/stream/ws-telemetry.d.ts.map +1 -1
  185. package/dist/stream/ws-telemetry.js +22 -18
  186. package/dist/stream/ws.d.ts +18 -12
  187. package/dist/stream/ws.d.ts.map +1 -1
  188. package/dist/stream/ws.js +26 -22
  189. package/dist/syncer/api-parser.js +1 -1
  190. package/dist/syncer/checksum.d.ts.map +1 -1
  191. package/dist/syncer/checksum.js +7 -8
  192. package/dist/syncer/code-generator.d.ts.map +1 -1
  193. package/dist/syncer/code-generator.js +13 -14
  194. package/dist/syncer/entity-operations.d.ts.map +1 -1
  195. package/dist/syncer/entity-operations.js +5 -6
  196. package/dist/syncer/file-copy.d.ts +5 -0
  197. package/dist/syncer/file-copy.d.ts.map +1 -0
  198. package/dist/syncer/file-copy.js +36 -0
  199. package/dist/syncer/file-patterns.d.ts +1 -0
  200. package/dist/syncer/file-patterns.d.ts.map +1 -1
  201. package/dist/syncer/file-patterns.js +5 -2
  202. package/dist/syncer/file-tracking.d.ts.map +1 -1
  203. package/dist/syncer/file-tracking.js +5 -4
  204. package/dist/syncer/filesystem-dependencies.d.ts +15 -0
  205. package/dist/syncer/filesystem-dependencies.d.ts.map +1 -0
  206. package/dist/syncer/filesystem-dependencies.js +53 -0
  207. package/dist/syncer/module-loader.d.ts +1 -1
  208. package/dist/syncer/module-loader.d.ts.map +1 -1
  209. package/dist/syncer/module-loader.js +6 -4
  210. package/dist/syncer/syncer-actions.d.ts +4 -0
  211. package/dist/syncer/syncer-actions.d.ts.map +1 -1
  212. package/dist/syncer/syncer-actions.js +34 -17
  213. package/dist/syncer/syncer.d.ts +17 -6
  214. package/dist/syncer/syncer.d.ts.map +1 -1
  215. package/dist/syncer/syncer.js +71 -29
  216. package/dist/syncer/watcher.d.ts.map +1 -1
  217. package/dist/syncer/watcher.js +3 -3
  218. package/dist/tasks/decorator.d.ts +6 -6
  219. package/dist/tasks/decorator.d.ts.map +1 -1
  220. package/dist/tasks/decorator.js +4 -4
  221. package/dist/tasks/step-wrapper.d.ts +6 -4
  222. package/dist/tasks/step-wrapper.d.ts.map +1 -1
  223. package/dist/tasks/step-wrapper.js +5 -5
  224. package/dist/tasks/workflow-manager.d.ts.map +1 -1
  225. package/dist/tasks/workflow-manager.js +13 -7
  226. package/dist/template/entity-converter.d.ts +1 -1
  227. package/dist/template/entity-converter.d.ts.map +1 -1
  228. package/dist/template/entity-converter.js +2 -2
  229. package/dist/template/helpers.d.ts +8 -6
  230. package/dist/template/helpers.d.ts.map +1 -1
  231. package/dist/template/helpers.js +1 -1
  232. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  233. package/dist/template/implementations/generated.template.js +4 -4
  234. package/dist/template/implementations/generated_http.template.d.ts +7 -4
  235. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  236. package/dist/template/implementations/generated_http.template.js +21 -21
  237. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  238. package/dist/template/implementations/generated_sso.template.js +6 -3
  239. package/dist/template/implementations/http_validators.template.d.ts +18 -0
  240. package/dist/template/implementations/http_validators.template.d.ts.map +1 -0
  241. package/dist/template/implementations/http_validators.template.js +127 -0
  242. package/dist/template/implementations/model.template.d.ts.map +1 -1
  243. package/dist/template/implementations/model.template.js +1 -1
  244. package/dist/template/implementations/queries.template.js +1 -1
  245. package/dist/template/implementations/sd.template.d.ts.map +1 -1
  246. package/dist/template/implementations/sd.template.js +79 -39
  247. package/dist/template/implementations/services.template.d.ts.map +1 -1
  248. package/dist/template/implementations/services.template.js +6 -4
  249. package/dist/template/implementations/view_form.template.d.ts +6 -1
  250. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  251. package/dist/template/implementations/view_form.template.js +23 -15
  252. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  253. package/dist/template/implementations/view_list.template.js +11 -6
  254. package/dist/template/template-manager.d.ts.map +1 -1
  255. package/dist/template/template-manager.js +9 -7
  256. package/dist/template/template-types.d.ts +12 -5
  257. package/dist/template/template-types.d.ts.map +1 -1
  258. package/dist/template/template-types.js +1 -1
  259. package/dist/template/template.d.ts +2 -2
  260. package/dist/template/template.d.ts.map +1 -1
  261. package/dist/template/template.js +6 -4
  262. package/dist/template/zod-converter.d.ts +0 -19
  263. package/dist/template/zod-converter.d.ts.map +1 -1
  264. package/dist/template/zod-converter.js +100 -84
  265. package/dist/testing/_relation-graph.d.ts.map +1 -1
  266. package/dist/testing/_relation-graph.js +2 -1
  267. package/dist/testing/bootstrap.d.ts.map +1 -1
  268. package/dist/testing/bootstrap.js +9 -6
  269. package/dist/testing/data-explorer.d.ts +32 -7
  270. package/dist/testing/data-explorer.d.ts.map +1 -1
  271. package/dist/testing/data-explorer.js +77 -31
  272. package/dist/testing/dev-test-routes.d.ts +8 -1
  273. package/dist/testing/dev-test-routes.d.ts.map +1 -1
  274. package/dist/testing/dev-test-routes.js +125 -108
  275. package/dist/testing/dev-vitest-manager.d.ts +54 -8
  276. package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
  277. package/dist/testing/dev-vitest-manager.js +24 -9
  278. package/dist/testing/faker-mappings.d.ts +412 -1
  279. package/dist/testing/faker-mappings.d.ts.map +1 -1
  280. package/dist/testing/faker-mappings.js +1 -1
  281. package/dist/testing/filesystem.d.ts +2 -0
  282. package/dist/testing/filesystem.d.ts.map +1 -0
  283. package/dist/testing/filesystem.js +7 -0
  284. package/dist/testing/fixture-generator.d.ts +25 -8
  285. package/dist/testing/fixture-generator.d.ts.map +1 -1
  286. package/dist/testing/fixture-generator.js +132 -73
  287. package/dist/testing/fixture-loader.d.ts +3 -1
  288. package/dist/testing/fixture-loader.d.ts.map +1 -1
  289. package/dist/testing/fixture-loader.js +1 -20
  290. package/dist/testing/fixture-manager.d.ts +8 -7
  291. package/dist/testing/fixture-manager.d.ts.map +1 -1
  292. package/dist/testing/fixture-manager.js +91 -59
  293. package/dist/testing/global-setup.d.ts.map +1 -1
  294. package/dist/testing/global-setup.js +5 -2
  295. package/dist/testing/index.d.ts +2 -0
  296. package/dist/testing/index.d.ts.map +1 -1
  297. package/dist/testing/index.js +6 -3
  298. package/dist/types/types.d.ts +101 -99
  299. package/dist/types/types.d.ts.map +1 -1
  300. package/dist/types/types.js +234 -225
  301. package/dist/ui/ai-api.d.ts.map +1 -1
  302. package/dist/ui/ai-api.js +1 -1
  303. package/dist/ui/ai-client.d.ts.map +1 -1
  304. package/dist/ui/ai-client.js +28 -18
  305. package/dist/ui/api.d.ts.map +1 -1
  306. package/dist/ui/api.js +146 -210
  307. package/dist/ui/async-route.d.ts +3 -0
  308. package/dist/ui/async-route.d.ts.map +1 -0
  309. package/dist/ui/async-route.js +12 -0
  310. package/dist/ui/cdd-service.d.ts +9 -7
  311. package/dist/ui/cdd-service.d.ts.map +1 -1
  312. package/dist/ui/cdd-service.js +7 -5
  313. package/dist/ui/migrations-api.d.ts +3 -0
  314. package/dist/ui/migrations-api.d.ts.map +1 -0
  315. package/dist/ui/migrations-api.js +215 -0
  316. package/dist/ui-web/assets/index-D3QNH-Dv.css +1 -0
  317. package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
  318. package/dist/ui-web/index.html +2 -2
  319. package/dist/utils/formatter.d.ts.map +1 -1
  320. package/dist/utils/formatter.js +7 -5
  321. package/dist/utils/fs-utils.d.ts +3 -3
  322. package/dist/utils/fs-utils.d.ts.map +1 -1
  323. package/dist/utils/fs-utils.js +6 -6
  324. package/dist/utils/model.d.ts +3 -5
  325. package/dist/utils/model.d.ts.map +1 -1
  326. package/dist/utils/model.js +1 -1
  327. package/dist/utils/object-utils.d.ts +1 -1
  328. package/dist/utils/object-utils.d.ts.map +1 -1
  329. package/dist/utils/object-utils.js +17 -16
  330. package/dist/utils/process-utils.d.ts.map +1 -1
  331. package/dist/utils/process-utils.js +4 -2
  332. package/dist/utils/runtime-value.d.ts +13 -0
  333. package/dist/utils/runtime-value.d.ts.map +1 -0
  334. package/dist/utils/runtime-value.js +40 -0
  335. package/dist/utils/sql-parser.d.ts +8 -1
  336. package/dist/utils/sql-parser.d.ts.map +1 -1
  337. package/dist/utils/sql-parser.js +6 -3
  338. package/dist/utils/type-utils.d.ts.map +1 -1
  339. package/dist/utils/type-utils.js +10 -8
  340. package/dist/utils/utils.d.ts +2 -2
  341. package/dist/utils/utils.d.ts.map +1 -1
  342. package/dist/utils/utils.js +11 -8
  343. package/dist/utils/zod-error.d.ts.map +1 -1
  344. package/dist/utils/zod-error.js +7 -4
  345. package/dist/vector/chunking.d.ts.map +1 -1
  346. package/dist/vector/chunking.js +1 -1
  347. package/dist/vector/embedding.d.ts.map +1 -1
  348. package/dist/vector/embedding.js +1 -1
  349. package/dist/vector/types.d.ts +3 -2
  350. package/dist/vector/types.d.ts.map +1 -1
  351. package/package.json +11 -7
  352. package/src/ai/agents/agent.ts +5 -5
  353. package/src/ai/agents/types.ts +1 -1
  354. package/src/ai/providers/rtzr/__tests__/model.test.ts +2 -2
  355. package/src/ai/providers/rtzr/error.ts +5 -3
  356. package/src/ai/providers/rtzr/model.ts +3 -2
  357. package/src/ai/providers/rtzr/options.ts +10 -5
  358. package/src/ai/providers/rtzr/provider.ts +10 -10
  359. package/src/ai/providers/rtzr/utils.ts +3 -1
  360. package/src/api/__tests__/config.test.ts +11 -21
  361. package/src/api/__tests__/sonamu.http-validator.test.ts +512 -0
  362. package/src/api/__tests__/sonamu.websocket.test.ts +51 -41
  363. package/src/api/__tests__/zod-compiler-policy.test.ts +95 -0
  364. package/src/api/caster.ts +6 -8
  365. package/src/api/code-converters.ts +136 -36
  366. package/src/api/config.ts +62 -4
  367. package/src/api/context.ts +3 -3
  368. package/src/api/decorators.ts +28 -17
  369. package/src/api/http-validator.ts +149 -0
  370. package/src/api/sonamu.ts +459 -152
  371. package/src/api/websocket-helpers.ts +24 -17
  372. package/src/auth/audit-log/builders.ts +3 -2
  373. package/src/auth/audit-log/client-ip.ts +4 -2
  374. package/src/auth/audit-log/events.ts +15 -1
  375. package/src/auth/audit-log/plugin.ts +129 -200
  376. package/src/auth/audit-log-ingestor.ts +19 -15
  377. package/src/auth/auth-generator.ts +10 -5
  378. package/src/auth/better-auth-request.ts +4 -3
  379. package/src/auth/knex-adapter.ts +8 -2
  380. package/src/auth/plugins/entity-definitions/index.ts +6 -5
  381. package/src/bin/__tests__/http-validator-benchmark.test.ts +94 -0
  382. package/src/bin/__tests__/test-command.test.ts +9 -15
  383. package/src/bin/__tests__/ts-loader-register.test.ts +15 -17
  384. package/src/bin/__tests__/zod-compiler-build.test.ts +307 -0
  385. package/src/bin/build-config.ts +167 -0
  386. package/src/bin/cli.ts +155 -38
  387. package/src/bin/compiler-policy.ts +35 -0
  388. package/src/bin/fixture.ts +14 -3
  389. package/src/bin/test-command.ts +74 -29
  390. package/src/bin/ts-loader-registration.ts +22 -4
  391. package/src/cache/decorator.ts +10 -3
  392. package/src/compress/compress.ts +17 -4
  393. package/src/cone/cone-generator.ts +34 -6
  394. package/src/database/__tests__/db.test.ts +1 -0
  395. package/src/database/__tests__/puri.test.ts +16 -15
  396. package/src/database/__tests__/transaction-scope.test.ts +5 -0
  397. package/src/database/_batch_update.ts +1 -0
  398. package/src/database/base-model.ts +81 -50
  399. package/src/database/base-model.types.ts +6 -6
  400. package/src/database/db.ts +29 -19
  401. package/src/database/knex.ts +30 -17
  402. package/src/database/puri-subset.test-d.ts +17 -0
  403. package/src/database/puri.ts +181 -143
  404. package/src/database/puri.types.test-d.ts +31 -1
  405. package/src/database/puri.types.ts +23 -21
  406. package/src/database/upsert-builder.ts +75 -53
  407. package/src/dict/sd.ts +15 -5
  408. package/src/dict/sonamu-dictionary.ts +6 -6
  409. package/src/dict/utils.ts +9 -1
  410. package/src/entity/entity-manager.ts +26 -9
  411. package/src/entity/entity-template-cone.ts +5 -10
  412. package/src/entity/entity.ts +50 -34
  413. package/src/env.ts +7 -3
  414. package/src/exceptions/error-handler.ts +17 -2
  415. package/src/exceptions/so-exceptions.ts +26 -20
  416. package/src/filter/utils.ts +21 -11
  417. package/src/index.ts +3 -0
  418. package/src/logger/configure.ts +26 -18
  419. package/src/migration/__tests__/migrator.test.ts +50 -57
  420. package/src/migration/code-generation.ts +132 -104
  421. package/src/migration/index-where-predicate.ts +51 -24
  422. package/src/migration/migration-set.ts +11 -5
  423. package/src/migration/migrator.ts +392 -244
  424. package/src/migration/postgresql-schema-reader.ts +52 -47
  425. package/src/migration/slack-confirm.ts +17 -15
  426. package/src/migration/types.ts +57 -0
  427. package/src/naite/naite-reporter.ts +1 -1
  428. package/src/naite/naite.ts +97 -24
  429. package/src/runtime-type.ts +34 -0
  430. package/src/ssr/hmr-opt-out.ts +78 -0
  431. package/src/ssr/renderer.ts +6 -0
  432. package/src/storage/base-file.ts +13 -13
  433. package/src/storage/buffered-file.ts +11 -11
  434. package/src/storage/s3-driver.ts +4 -1
  435. package/src/storage/uploaded-file.ts +8 -8
  436. package/src/stream/__tests__/ws-contracts.test.ts +4 -2
  437. package/src/stream/__tests__/ws-telemetry.test.ts +1 -1
  438. package/src/stream/__tests__/ws.test.ts +30 -6
  439. package/src/stream/sse.ts +12 -11
  440. package/src/stream/ws-core.ts +1 -1
  441. package/src/stream/ws-delivery.ts +16 -7
  442. package/src/stream/ws-local-connection-store.ts +2 -3
  443. package/src/stream/ws-presence-store.ts +6 -1
  444. package/src/stream/ws-registry.ts +16 -7
  445. package/src/stream/ws-telemetry.ts +66 -43
  446. package/src/stream/ws.ts +73 -39
  447. package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +3 -2
  448. package/src/syncer/__tests__/http-validator-registry.test.ts +137 -0
  449. package/src/syncer/api-parser.ts +67 -27
  450. package/src/syncer/checksum.ts +17 -11
  451. package/src/syncer/code-generator.ts +25 -17
  452. package/src/syncer/entity-operations.ts +3 -5
  453. package/src/syncer/file-copy.ts +46 -0
  454. package/src/syncer/file-patterns.ts +11 -8
  455. package/src/syncer/file-tracking.ts +3 -4
  456. package/src/syncer/filesystem-dependencies.ts +73 -0
  457. package/src/syncer/module-loader.ts +8 -4
  458. package/src/syncer/syncer-actions.ts +56 -18
  459. package/src/syncer/syncer.ts +116 -43
  460. package/src/syncer/watcher.ts +8 -4
  461. package/src/tasks/decorator.ts +20 -12
  462. package/src/tasks/step-wrapper.ts +19 -9
  463. package/src/tasks/workflow-manager.ts +15 -9
  464. package/src/template/__tests__/http_validators.template.test.ts +160 -0
  465. package/src/template/__tests__/services.template.mutation.test.ts +24 -23
  466. package/src/template/__tests__/services.template.websocket.test.ts +21 -25
  467. package/src/template/entity-converter.ts +5 -2
  468. package/src/template/helpers.ts +8 -9
  469. package/src/template/implementations/generated.template.ts +5 -4
  470. package/src/template/implementations/generated_http.template.ts +61 -15
  471. package/src/template/implementations/generated_sso.template.ts +15 -4
  472. package/src/template/implementations/http_validators.template.ts +175 -0
  473. package/src/template/implementations/model.template.ts +3 -1
  474. package/src/template/implementations/sd.template.ts +81 -41
  475. package/src/template/implementations/services.template.ts +2 -2
  476. package/src/template/implementations/view_form.template.ts +56 -39
  477. package/src/template/implementations/view_list.template.ts +31 -23
  478. package/src/template/template-manager.ts +15 -13
  479. package/src/template/template-types.ts +13 -5
  480. package/src/template/template.ts +4 -3
  481. package/src/template/zod-converter.ts +206 -91
  482. package/src/testing/__tests__/dev-test-routes.test.ts +85 -25
  483. package/src/testing/__tests__/dev-vitest-manager.test.ts +15 -15
  484. package/src/testing/_relation-graph.ts +4 -1
  485. package/src/testing/bootstrap.ts +12 -5
  486. package/src/testing/data-explorer.ts +102 -53
  487. package/src/testing/dev-test-routes.ts +87 -50
  488. package/src/testing/dev-vitest-manager.ts +88 -32
  489. package/src/testing/faker-mappings.ts +2 -2
  490. package/src/testing/filesystem.ts +1 -0
  491. package/src/testing/fixture-generator.ts +191 -131
  492. package/src/testing/fixture-loader.ts +5 -1
  493. package/src/testing/fixture-manager.ts +129 -90
  494. package/src/testing/global-setup.ts +7 -3
  495. package/src/testing/index.ts +5 -0
  496. package/src/types/__tests__/entity-json-schema-search-text.test.ts +9 -3
  497. package/src/types/types.ts +184 -158
  498. package/src/ui/ai-api.ts +9 -7
  499. package/src/ui/ai-client.ts +61 -56
  500. package/src/ui/api.ts +726 -770
  501. package/src/ui/async-route.ts +4 -0
  502. package/src/ui/cdd-service.ts +35 -12
  503. package/src/ui/migrations-api.ts +381 -0
  504. package/src/utils/formatter.ts +7 -3
  505. package/src/utils/fs-utils.ts +5 -5
  506. package/src/utils/model.ts +4 -5
  507. package/src/utils/object-utils.ts +32 -22
  508. package/src/utils/process-utils.ts +4 -1
  509. package/src/utils/runtime-value.ts +43 -0
  510. package/src/utils/sql-parser.ts +13 -6
  511. package/src/utils/type-utils.ts +9 -7
  512. package/src/utils/utils.ts +19 -21
  513. package/src/utils/zod-error.ts +4 -2
  514. package/src/vector/chunking.ts +6 -1
  515. package/src/vector/embedding.ts +2 -1
  516. package/src/vector/types.ts +4 -2
  517. package/tsdown.api.config.ts +5 -2
  518. package/dist/ui-web/assets/index-CJf8uJYf.js +0 -176
  519. package/dist/ui-web/assets/index-GMMIVGja.css +0 -1
package/src/api/config.ts CHANGED
@@ -23,8 +23,15 @@ import { type StorageConfig } from "../storage/types";
23
23
  import { type WebSocketRuntimeOptions } from "../stream/ws";
24
24
  import { type WorkflowOptions } from "../tasks/workflow-manager";
25
25
  import { type Executable, type SonamuFastifyConfig } from "../types/types";
26
+ import { isFunctionValue, isObjectValue } from "../utils/runtime-value";
26
27
  import { type Context, type WebSocketContext } from "./context";
27
28
 
29
+ function isExecutableConfig(
30
+ value: Executable<SonamuConfig>,
31
+ ): value is (() => SonamuConfig) | (() => Promise<SonamuConfig>) {
32
+ return isFunctionValue(value);
33
+ }
34
+
28
35
  export type DatabaseConfig = Omit<Knex.Config, "connection"> & {
29
36
  connection?: Knex.PgConnectionConfig;
30
37
  };
@@ -64,6 +71,40 @@ export type SonamuTestConfig = {
64
71
  devRunner?: SonamuDevRunnerConfig;
65
72
  };
66
73
 
74
+ export type ZodCompilerApiMode = false | "jit" | "aot";
75
+ export type ZodCompilerConfig =
76
+ | false
77
+ | {
78
+ api?: ZodCompilerApiMode;
79
+ };
80
+ export type NormalizedZodCompilerPolicy = {
81
+ api: ZodCompilerApiMode;
82
+ targets: Record<string, never>;
83
+ };
84
+
85
+ export function normalizeZodCompilerPolicy<Value>(
86
+ value: Value,
87
+ _syncTargets: readonly string[] = [],
88
+ ): NormalizedZodCompilerPolicy {
89
+ if (value === undefined || value === false) {
90
+ return { api: false, targets: {} };
91
+ }
92
+ if (!isObjectValue(value) || Array.isArray(value)) {
93
+ throw new Error("validation.zodCompiler must be false or an object");
94
+ }
95
+
96
+ const api = "api" in value ? (value.api ?? false) : false;
97
+ if (api !== false && api !== "jit" && api !== "aot") {
98
+ throw new Error("validation.zodCompiler.api must be false, 'jit', or 'aot'");
99
+ }
100
+
101
+ if ("targets" in value) {
102
+ throw new Error("validation.zodCompiler.targets is not supported in the API-only phase");
103
+ }
104
+
105
+ return { api, targets: {} };
106
+ }
107
+
67
108
  export type SonamuConfig<TSinkId extends string = string, TFilterId extends string = string> = {
68
109
  projectName?: string;
69
110
 
@@ -92,6 +133,10 @@ export type SonamuConfig<TSinkId extends string = string, TFilterId extends stri
92
133
  targets: string[]; // "web", "app" 등
93
134
  };
94
135
 
136
+ validation?: {
137
+ zodCompiler?: ZodCompilerConfig;
138
+ };
139
+
95
140
  database: {
96
141
  // 데이터베이스(pg는 pg 모듈, pgnative는 pg-native 모듈의 설치가 필요합니다.)
97
142
  database?: "pg" | "pgnative";
@@ -288,7 +333,7 @@ export type SonamuSSROptions = {
288
333
 
289
334
  // NOTE(Haze, 251209): config에는 T, Promise<T>, () => T, () => Promise<T>가 모두 올 수 있어야 함.
290
335
  export function defineConfig(config: Executable<SonamuConfig>): Promise<SonamuConfig> {
291
- if (typeof config === "function") {
336
+ if (isExecutableConfig(config)) {
292
337
  return Promise.resolve(config());
293
338
  }
294
339
 
@@ -308,7 +353,21 @@ export function defineConfig(config: Executable<SonamuConfig>): Promise<SonamuCo
308
353
  * @param rootPath
309
354
  * @returns
310
355
  */
311
- export async function loadConfig(rootPath: string): Promise<SonamuConfig> {
356
+ export interface ConfigLoaderDependencies {
357
+ ensureTsLoaderRegistered(rootPath: string): Promise<void>;
358
+ }
359
+
360
+ const defaultConfigLoaderDependencies: ConfigLoaderDependencies = {
361
+ async ensureTsLoaderRegistered(rootPath) {
362
+ const registration = await import("../bin/ts-loader-registration");
363
+ await registration.ensureTsLoaderRegistered(rootPath);
364
+ },
365
+ };
366
+
367
+ export async function loadConfig(
368
+ rootPath: string,
369
+ dependencies: ConfigLoaderDependencies = defaultConfigLoaderDependencies,
370
+ ): Promise<SonamuConfig> {
312
371
  applyCurrentSnapshotToProcessEnv(rootPath);
313
372
 
314
373
  const shouldLoadSourceConfig = process.env.HOT === "yes" || process.env.VITEST === "true";
@@ -317,8 +376,7 @@ export async function loadConfig(rootPath: string): Promise<SonamuConfig> {
317
376
  : `${rootPath}/dist/sonamu.config.js`;
318
377
 
319
378
  if (shouldLoadSourceConfig) {
320
- const { ensureTsLoaderRegistered } = await import("../bin/ts-loader-registration");
321
- await ensureTsLoaderRegistered(rootPath);
379
+ await dependencies.ensureTsLoaderRegistered(rootPath);
322
380
  }
323
381
 
324
382
  const { default: config } = await import(`file://${configPath}`);
@@ -14,7 +14,7 @@ import { type NaiteStore } from "../naite/naite";
14
14
  import { type BufferedFile } from "../storage/buffered-file";
15
15
  import { type UploadedFile } from "../storage/uploaded-file";
16
16
  import { type createSSEFactory } from "../stream/sse";
17
- import { type WebSocketConnection, type WebSocketEventMap } from "../stream/ws";
17
+ import { type WebSocketConnection } from "../stream/ws";
18
18
 
19
19
  // oxlint-disable-next-line @typescript-eslint/no-empty-interface -- Context 확장 타입
20
20
  export interface ContextExtend {}
@@ -41,8 +41,8 @@ export type Context = BaseContext & {
41
41
  } & ContextExtend;
42
42
 
43
43
  export type WebSocketContext<
44
- TOut extends WebSocketEventMap = WebSocketEventMap,
45
- TIn extends WebSocketEventMap = WebSocketEventMap,
44
+ TOut extends object = object,
45
+ TIn extends object = object,
46
46
  > = BaseContext & {
47
47
  transport: "ws";
48
48
  ws: WebSocketConnection<TOut, TIn>;
@@ -120,6 +120,8 @@ export type ExtendedApi = {
120
120
  };
121
121
  type DecoratorTarget = { constructor: { name: string } };
122
122
 
123
+ const decoratorTypesByTarget = new WeakMap<DecoratorTarget, Map<string, symbol>>();
124
+
123
125
  const DECORATOR_TYPES = {
124
126
  API: Symbol("api"),
125
127
  STREAM: Symbol("stream"),
@@ -128,13 +130,16 @@ const DECORATOR_TYPES = {
128
130
  } as const;
129
131
 
130
132
  function checkSingleDecorator(target: DecoratorTarget, propertyKey: string, decoratorType: symbol) {
131
- const method = target[propertyKey as keyof typeof target] as { __decoratorType?: symbol };
132
- if (method?.__decoratorType && method?.__decoratorType !== decoratorType) {
133
+ const decoratorTypes = decoratorTypesByTarget.get(target) ?? new Map<string, symbol>();
134
+ const existingDecoratorType = decoratorTypes.get(propertyKey);
135
+
136
+ if (existingDecoratorType && existingDecoratorType !== decoratorType) {
133
137
  throw new Error(
134
138
  `@${decoratorType.description ?? String(decoratorType)} decorator can only be used once on ${target.constructor.name}.${propertyKey}. You can use only one of @api, @stream, @websocket, or @upload decorator on the same method.`,
135
139
  );
136
140
  } else {
137
- method.__decoratorType = decoratorType;
141
+ decoratorTypes.set(propertyKey, decoratorType);
142
+ decoratorTypesByTarget.set(target, decoratorTypes);
138
143
  }
139
144
  }
140
145
 
@@ -165,7 +170,8 @@ export function api(options: ApiDecoratorOptions = {}) {
165
170
 
166
171
  // 기존 동일한 메서드가 있는지 확인 후 있는 경우 override
167
172
  const existingApi = registeredApis.find(
168
- (api) => api.modelName === modelName && api.methodName === methodName,
173
+ (registeredApi) =>
174
+ registeredApi.modelName === modelName && registeredApi.methodName === methodName,
169
175
  );
170
176
  if (existingApi) {
171
177
  // 기존의 path와 새로운 path가 다르다면(=빈 스트링이 아니었는데 다른 스트링으로 바뀌게 된다면) 에러를 터뜨려줍니다.
@@ -237,11 +243,13 @@ export function stream(options: StreamDecoratorOptions) {
237
243
  const { events: _, type: _type, ...apiOptions } = options;
238
244
  const optionsWithDefaults = {
239
245
  ...apiOptions,
240
- httpMethod: "GET" as HTTPMethods,
246
+ httpMethod:
247
+ /* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ "GET" as HTTPMethods,
241
248
  };
242
249
 
243
250
  const existingApi = registeredApis.find(
244
- (api) => api.modelName === modelName && api.methodName === methodName,
251
+ (registeredApi) =>
252
+ registeredApi.modelName === modelName && registeredApi.methodName === methodName,
245
253
  );
246
254
  if (existingApi) {
247
255
  // 기존의 path와 새로운 path가 다르다면(=빈 스트링이 아니었는데 다른 스트링으로 바뀌게 된다면) 에러를 터뜨려줍니다.
@@ -318,11 +326,13 @@ export function websocket(options: WebSocketDecoratorOptions) {
318
326
  const { outEvents: _outEvents, inEvents: _inEvents, ...apiOptions } = options;
319
327
  const optionsWithDefaults = {
320
328
  ...apiOptions,
321
- httpMethod: "GET" as HTTPMethods,
329
+ httpMethod:
330
+ /* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ "GET" as HTTPMethods,
322
331
  };
323
332
 
324
333
  const existingApi = registeredApis.find(
325
- (api) => api.modelName === modelName && api.methodName === methodName,
334
+ (registeredApi) =>
335
+ registeredApi.modelName === modelName && registeredApi.methodName === methodName,
326
336
  );
327
337
  if (existingApi) {
328
338
  assertNoConflictingPath("websocket", modelName, methodName, existingApi.path, path);
@@ -454,7 +464,8 @@ export function upload(options: UploadDecoratorOptions = { consume: "buffer" })
454
464
 
455
465
  // registeredApis에서 해당 API 찾아서 uploadOptions 추가
456
466
  const existingApi = registeredApis.find(
457
- (api) => api.modelName === modelName && api.methodName === methodName,
467
+ (registeredApi) =>
468
+ registeredApi.modelName === modelName && registeredApi.methodName === methodName,
458
469
  );
459
470
 
460
471
  if (existingApi) {
@@ -538,23 +549,23 @@ function assertNoConflictingPath(
538
549
  * @param existingOptions 기존의 옵션
539
550
  * @param newOptions 새로운 옵션
540
551
  */
541
- function assertNoConflictingOptions(
552
+ function assertNoConflictingOptions<ExistingOptions extends object, NewOptions extends object>(
542
553
  decoratorName: string,
543
554
  modelName: string,
544
555
  methodName: string,
545
- // oxlint-disable-next-line @typescript-eslint/no-explicit-any -- <아 쉽게쉽게 좀 갑시다>
546
- existingOptions: Record<string, any>,
547
- // oxlint-disable-next-line @typescript-eslint/no-explicit-any -- <이럴 때 아니면 any 언제 씁니까>
548
- newOptions: Record<string, any>,
556
+ existingOptions: ExistingOptions,
557
+ newOptions: NewOptions,
549
558
  ) {
550
- Object.keys(newOptions).forEach((key) => {
551
- if (existingOptions[key] && !isEqual(existingOptions[key], newOptions[key])) {
559
+ const existingEntries = new Map(Object.entries(existingOptions));
560
+ Object.entries(newOptions).forEach(([key, newValue]) => {
561
+ const existingValue = existingEntries.get(key);
562
+ if (existingValue && !isEqual(existingValue, newValue)) {
552
563
  // 이것이 무슨 상황이냐면요, api.options가 덮어씌워지는 상황입니다.
553
564
  // 가령 @api({ resourceName: "Users" }) 데코레이터가 붙어있는 메서드에
554
565
  // @stream({ resourceName: "Posts" }) 같은 것이 붙어 있는 상황입니다.
555
566
  // 이렇게 되면 두 데코레이터가 같은 api의 options 속 같은 필드를 건드리게 되므로, 에러를 터뜨려줍니다.
556
567
  throw new Error(
557
- `@${decoratorName} decorator on ${modelName}.${methodName} has conflicting options: ${key}. The decorator is trying to override the existing option(${JSON.stringify(existingOptions[key])}) with the new option(${JSON.stringify(newOptions[key])}).`,
568
+ `@${decoratorName} decorator on ${modelName}.${methodName} has conflicting options: ${key}. The decorator is trying to override the existing option(${JSON.stringify(existingValue)}) with the new option(${JSON.stringify(newValue)}).`,
558
569
  );
559
570
  }
560
571
  });
@@ -0,0 +1,149 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ import { type z } from "zod";
4
+
5
+ import { type LoadedTypes } from "../syncer/module-loader";
6
+ import { isObjectValue } from "../utils/runtime-value";
7
+ import { fastifyCaster } from "./caster";
8
+ import { getZodObjectFromApi } from "./code-converters";
9
+ import { type NormalizedZodCompilerPolicy } from "./config";
10
+ import { type ExtendedApi } from "./decorators";
11
+
12
+ export type HttpRequestValue =
13
+ | string
14
+ | number
15
+ | boolean
16
+ | bigint
17
+ | Date
18
+ | null
19
+ | undefined
20
+ | HttpRequestValue[]
21
+ | { [key: string]: HttpRequestValue };
22
+ export type HttpRequestParameters = Record<string, HttpRequestValue>;
23
+ export type HttpValidator = z.ZodType<object>;
24
+ type FastifyHttpValidator = ReturnType<typeof fastifyCaster>;
25
+ export type HttpValidatorRegistry = {
26
+ fingerprint: string;
27
+ validators: ReadonlyMap<string, HttpValidator>;
28
+ };
29
+
30
+ export function getHttpValidatorRouteKey(api: ExtendedApi): string {
31
+ return JSON.stringify([api.modelName, api.methodName, api.options.httpMethod ?? "GET", api.path]);
32
+ }
33
+
34
+ export function getHttpValidatorRouteIdentifier(api: ExtendedApi): string {
35
+ return createHash("sha256").update(getHttpValidatorRouteKey(api)).digest("hex");
36
+ }
37
+
38
+ function stableJson<Value>(value: Value): string {
39
+ if (Array.isArray(value)) {
40
+ return `[${value.map((item) => stableJson(item)).join(",")}]`;
41
+ }
42
+ if (isObjectValue(value) && value !== null) {
43
+ return `{${Object.entries(value)
44
+ .toSorted(([left], [right]) => left.localeCompare(right))
45
+ .map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`)
46
+ .join(",")}}`;
47
+ }
48
+ return JSON.stringify(value);
49
+ }
50
+
51
+ export function getHttpValidatorFingerprint(apis: readonly ExtendedApi[]): string {
52
+ const metadata = apis
53
+ .filter((api) => api.websocketOptions === undefined)
54
+ .map((api) => ({
55
+ key: getHttpValidatorRouteKey(api),
56
+ parameters: api.parameters,
57
+ typeParameters: api.typeParameters,
58
+ }))
59
+ .toSorted((left, right) => left.key.localeCompare(right.key));
60
+ return createHash("sha256").update(stableJson(metadata)).digest("hex");
61
+ }
62
+
63
+ export function assertHttpValidatorRegistry(
64
+ apis: readonly ExtendedApi[],
65
+ registry: HttpValidatorRegistry,
66
+ ): void {
67
+ const expectedApis = apis.filter((api) => api.websocketOptions === undefined);
68
+ const expectedFingerprint = getHttpValidatorFingerprint(expectedApis);
69
+ if (registry.fingerprint !== expectedFingerprint) {
70
+ throw new Error(
71
+ `HTTP validator registry fingerprint mismatch: expected ${expectedFingerprint}, received ${registry.fingerprint}`,
72
+ );
73
+ }
74
+
75
+ const expectedKeys = new Set(expectedApis.map(getHttpValidatorRouteKey));
76
+ if (registry.validators.size !== expectedKeys.size) {
77
+ throw new Error(
78
+ `HTTP validator registry coverage mismatch: expected ${expectedKeys.size}, received ${registry.validators.size}`,
79
+ );
80
+ }
81
+ for (const key of expectedKeys) {
82
+ if (!registry.validators.has(key)) {
83
+ throw new Error(`HTTP validator registry is missing ${key}`);
84
+ }
85
+ }
86
+ }
87
+
88
+ export interface HttpValidatorDependencies {
89
+ createSchema(api: ExtendedApi, types: LoadedTypes): z.ZodObject;
90
+ applyCaster(schema: z.ZodObject): FastifyHttpValidator;
91
+ compileJit(
92
+ validator: FastifyHttpValidator,
93
+ options: { eager: true },
94
+ ): Promise<FastifyHttpValidator>;
95
+ }
96
+
97
+ export const defaultHttpValidatorDependencies: HttpValidatorDependencies = {
98
+ createSchema: getZodObjectFromApi,
99
+ applyCaster: fastifyCaster,
100
+ async compileJit(validator, options) {
101
+ const { jit } = await import("zod-compiler/jit");
102
+ return jit(validator, options);
103
+ },
104
+ };
105
+
106
+ export async function createHttpValidator(
107
+ options: {
108
+ api: ExtendedApi;
109
+ policy: NormalizedZodCompilerPolicy;
110
+ types: LoadedTypes;
111
+ aotRegistry?: HttpValidatorRegistry;
112
+ allowAotSourceFallback?: boolean;
113
+ },
114
+ dependencies: HttpValidatorDependencies = defaultHttpValidatorDependencies,
115
+ ): Promise<HttpValidator> {
116
+ if (options.policy.api === "aot") {
117
+ const routeKey = getHttpValidatorRouteKey(options.api);
118
+ const compiled = options.aotRegistry?.validators.get(routeKey);
119
+ if (compiled !== undefined) {
120
+ return compiled;
121
+ }
122
+ if (options.allowAotSourceFallback === true) {
123
+ // source dev에서는 build registry를 실행하지 않으므로 cached plain validator로 대체합니다.
124
+ } else {
125
+ throw new Error(`HTTP validator registry is missing ${routeKey}`);
126
+ }
127
+ }
128
+
129
+ // Generic type parameter 처리 중 공유 references가 바뀌므로 route마다 사본을 넘깁니다.
130
+ const validator = dependencies.applyCaster(
131
+ dependencies.createSchema(options.api, { ...options.types }),
132
+ );
133
+ if (options.policy.api !== "jit") {
134
+ return validator;
135
+ }
136
+
137
+ const originalParse = validator.parse;
138
+ const originalSafeParse = validator.safeParse;
139
+ const compiled = await dependencies.compileJit(validator, { eager: true });
140
+
141
+ // upstream JIT는 컴파일 실패를 숨기므로 공개 메서드 설치 여부를 직접 확인합니다.
142
+ if (compiled.parse === originalParse || compiled.safeParse === originalSafeParse) {
143
+ throw new Error(
144
+ `validation.zodCompiler.api JIT compilation failed for ${getHttpValidatorRouteKey(options.api)}`,
145
+ );
146
+ }
147
+
148
+ return compiled;
149
+ }