sonamu 0.10.12 → 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 (513) 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 +131 -27
  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 +12 -6
  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 +3 -2
  142. package/dist/migration/migrator.d.ts.map +1 -1
  143. package/dist/migration/migrator.js +27 -21
  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/naite/naite-reporter.js +2 -2
  149. package/dist/naite/naite.d.ts +74 -15
  150. package/dist/naite/naite.d.ts.map +1 -1
  151. package/dist/naite/naite.js +5 -19
  152. package/dist/runtime-type.d.ts +6 -0
  153. package/dist/runtime-type.d.ts.map +1 -0
  154. package/dist/runtime-type.js +26 -0
  155. package/dist/ssr/hmr-opt-out.d.ts +26 -0
  156. package/dist/ssr/hmr-opt-out.d.ts.map +1 -0
  157. package/dist/ssr/hmr-opt-out.js +59 -0
  158. package/dist/ssr/renderer.d.ts.map +1 -1
  159. package/dist/ssr/renderer.js +4 -1
  160. package/dist/storage/base-file.js +14 -14
  161. package/dist/storage/buffered-file.d.ts +2 -2
  162. package/dist/storage/buffered-file.d.ts.map +1 -1
  163. package/dist/storage/buffered-file.js +12 -12
  164. package/dist/storage/s3-driver.d.ts.map +1 -1
  165. package/dist/storage/s3-driver.js +1 -1
  166. package/dist/storage/uploaded-file.d.ts +2 -2
  167. package/dist/storage/uploaded-file.d.ts.map +1 -1
  168. package/dist/storage/uploaded-file.js +8 -8
  169. package/dist/stream/sse.js +11 -11
  170. package/dist/stream/ws-core.d.ts +1 -1
  171. package/dist/stream/ws-core.d.ts.map +1 -1
  172. package/dist/stream/ws-delivery.d.ts +1 -1
  173. package/dist/stream/ws-delivery.d.ts.map +1 -1
  174. package/dist/stream/ws-delivery.js +6 -4
  175. package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
  176. package/dist/stream/ws-local-connection-store.js +4 -2
  177. package/dist/stream/ws-presence-store.js +1 -1
  178. package/dist/stream/ws-registry.d.ts +4 -4
  179. package/dist/stream/ws-registry.d.ts.map +1 -1
  180. package/dist/stream/ws-registry.js +4 -2
  181. package/dist/stream/ws-telemetry.d.ts +16 -12
  182. package/dist/stream/ws-telemetry.d.ts.map +1 -1
  183. package/dist/stream/ws-telemetry.js +22 -18
  184. package/dist/stream/ws.d.ts +18 -12
  185. package/dist/stream/ws.d.ts.map +1 -1
  186. package/dist/stream/ws.js +26 -22
  187. package/dist/syncer/api-parser.js +1 -1
  188. package/dist/syncer/checksum.d.ts.map +1 -1
  189. package/dist/syncer/checksum.js +7 -8
  190. package/dist/syncer/code-generator.d.ts.map +1 -1
  191. package/dist/syncer/code-generator.js +13 -14
  192. package/dist/syncer/entity-operations.d.ts.map +1 -1
  193. package/dist/syncer/entity-operations.js +5 -6
  194. package/dist/syncer/file-copy.d.ts +5 -0
  195. package/dist/syncer/file-copy.d.ts.map +1 -0
  196. package/dist/syncer/file-copy.js +36 -0
  197. package/dist/syncer/file-patterns.d.ts +1 -0
  198. package/dist/syncer/file-patterns.d.ts.map +1 -1
  199. package/dist/syncer/file-patterns.js +5 -2
  200. package/dist/syncer/file-tracking.d.ts.map +1 -1
  201. package/dist/syncer/file-tracking.js +5 -4
  202. package/dist/syncer/filesystem-dependencies.d.ts +15 -0
  203. package/dist/syncer/filesystem-dependencies.d.ts.map +1 -0
  204. package/dist/syncer/filesystem-dependencies.js +53 -0
  205. package/dist/syncer/module-loader.d.ts +1 -1
  206. package/dist/syncer/module-loader.d.ts.map +1 -1
  207. package/dist/syncer/module-loader.js +6 -4
  208. package/dist/syncer/syncer-actions.d.ts +4 -0
  209. package/dist/syncer/syncer-actions.d.ts.map +1 -1
  210. package/dist/syncer/syncer-actions.js +34 -17
  211. package/dist/syncer/syncer.d.ts +17 -6
  212. package/dist/syncer/syncer.d.ts.map +1 -1
  213. package/dist/syncer/syncer.js +71 -29
  214. package/dist/syncer/watcher.d.ts.map +1 -1
  215. package/dist/syncer/watcher.js +3 -3
  216. package/dist/tasks/decorator.d.ts +6 -6
  217. package/dist/tasks/decorator.d.ts.map +1 -1
  218. package/dist/tasks/decorator.js +4 -4
  219. package/dist/tasks/step-wrapper.d.ts +6 -4
  220. package/dist/tasks/step-wrapper.d.ts.map +1 -1
  221. package/dist/tasks/step-wrapper.js +5 -5
  222. package/dist/tasks/workflow-manager.d.ts.map +1 -1
  223. package/dist/tasks/workflow-manager.js +13 -7
  224. package/dist/template/entity-converter.d.ts +1 -1
  225. package/dist/template/entity-converter.d.ts.map +1 -1
  226. package/dist/template/entity-converter.js +2 -2
  227. package/dist/template/helpers.d.ts +8 -6
  228. package/dist/template/helpers.d.ts.map +1 -1
  229. package/dist/template/helpers.js +1 -1
  230. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  231. package/dist/template/implementations/generated.template.js +4 -4
  232. package/dist/template/implementations/generated_http.template.d.ts +7 -4
  233. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  234. package/dist/template/implementations/generated_http.template.js +21 -21
  235. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  236. package/dist/template/implementations/generated_sso.template.js +6 -3
  237. package/dist/template/implementations/http_validators.template.d.ts +18 -0
  238. package/dist/template/implementations/http_validators.template.d.ts.map +1 -0
  239. package/dist/template/implementations/http_validators.template.js +127 -0
  240. package/dist/template/implementations/model.template.d.ts.map +1 -1
  241. package/dist/template/implementations/model.template.js +1 -1
  242. package/dist/template/implementations/queries.template.js +1 -1
  243. package/dist/template/implementations/sd.template.d.ts.map +1 -1
  244. package/dist/template/implementations/sd.template.js +79 -39
  245. package/dist/template/implementations/services.template.d.ts.map +1 -1
  246. package/dist/template/implementations/services.template.js +6 -4
  247. package/dist/template/implementations/view_form.template.d.ts +6 -1
  248. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  249. package/dist/template/implementations/view_form.template.js +23 -15
  250. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  251. package/dist/template/implementations/view_list.template.js +11 -6
  252. package/dist/template/template-manager.d.ts.map +1 -1
  253. package/dist/template/template-manager.js +9 -7
  254. package/dist/template/template-types.d.ts +12 -5
  255. package/dist/template/template-types.d.ts.map +1 -1
  256. package/dist/template/template-types.js +1 -1
  257. package/dist/template/template.d.ts +2 -2
  258. package/dist/template/template.d.ts.map +1 -1
  259. package/dist/template/template.js +6 -4
  260. package/dist/template/zod-converter.d.ts +0 -19
  261. package/dist/template/zod-converter.d.ts.map +1 -1
  262. package/dist/template/zod-converter.js +100 -84
  263. package/dist/testing/_relation-graph.d.ts.map +1 -1
  264. package/dist/testing/_relation-graph.js +2 -1
  265. package/dist/testing/bootstrap.d.ts.map +1 -1
  266. package/dist/testing/bootstrap.js +9 -6
  267. package/dist/testing/data-explorer.d.ts +32 -7
  268. package/dist/testing/data-explorer.d.ts.map +1 -1
  269. package/dist/testing/data-explorer.js +77 -31
  270. package/dist/testing/dev-test-routes.d.ts +8 -1
  271. package/dist/testing/dev-test-routes.d.ts.map +1 -1
  272. package/dist/testing/dev-test-routes.js +125 -108
  273. package/dist/testing/dev-vitest-manager.d.ts +54 -8
  274. package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
  275. package/dist/testing/dev-vitest-manager.js +24 -9
  276. package/dist/testing/faker-mappings.d.ts +412 -1
  277. package/dist/testing/faker-mappings.d.ts.map +1 -1
  278. package/dist/testing/faker-mappings.js +1 -1
  279. package/dist/testing/filesystem.d.ts +2 -0
  280. package/dist/testing/filesystem.d.ts.map +1 -0
  281. package/dist/testing/filesystem.js +7 -0
  282. package/dist/testing/fixture-generator.d.ts +25 -8
  283. package/dist/testing/fixture-generator.d.ts.map +1 -1
  284. package/dist/testing/fixture-generator.js +132 -73
  285. package/dist/testing/fixture-loader.d.ts +3 -1
  286. package/dist/testing/fixture-loader.d.ts.map +1 -1
  287. package/dist/testing/fixture-loader.js +1 -20
  288. package/dist/testing/fixture-manager.d.ts +8 -7
  289. package/dist/testing/fixture-manager.d.ts.map +1 -1
  290. package/dist/testing/fixture-manager.js +91 -59
  291. package/dist/testing/global-setup.d.ts.map +1 -1
  292. package/dist/testing/global-setup.js +5 -2
  293. package/dist/testing/index.d.ts +2 -0
  294. package/dist/testing/index.d.ts.map +1 -1
  295. package/dist/testing/index.js +6 -3
  296. package/dist/types/types.d.ts +101 -99
  297. package/dist/types/types.d.ts.map +1 -1
  298. package/dist/types/types.js +234 -225
  299. package/dist/ui/ai-api.d.ts.map +1 -1
  300. package/dist/ui/ai-api.js +1 -1
  301. package/dist/ui/ai-client.d.ts.map +1 -1
  302. package/dist/ui/ai-client.js +28 -18
  303. package/dist/ui/api.d.ts.map +1 -1
  304. package/dist/ui/api.js +135 -128
  305. package/dist/ui/async-route.d.ts +3 -0
  306. package/dist/ui/async-route.d.ts.map +1 -0
  307. package/dist/ui/async-route.js +12 -0
  308. package/dist/ui/cdd-service.d.ts +9 -7
  309. package/dist/ui/cdd-service.d.ts.map +1 -1
  310. package/dist/ui/cdd-service.js +7 -5
  311. package/dist/ui/migrations-api.d.ts.map +1 -1
  312. package/dist/ui/migrations-api.js +17 -15
  313. package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
  314. package/dist/ui-web/index.html +1 -1
  315. package/dist/utils/formatter.d.ts.map +1 -1
  316. package/dist/utils/formatter.js +7 -5
  317. package/dist/utils/fs-utils.d.ts +3 -3
  318. package/dist/utils/fs-utils.d.ts.map +1 -1
  319. package/dist/utils/fs-utils.js +6 -6
  320. package/dist/utils/model.d.ts +3 -5
  321. package/dist/utils/model.d.ts.map +1 -1
  322. package/dist/utils/model.js +1 -1
  323. package/dist/utils/object-utils.d.ts +1 -1
  324. package/dist/utils/object-utils.d.ts.map +1 -1
  325. package/dist/utils/object-utils.js +17 -16
  326. package/dist/utils/process-utils.d.ts.map +1 -1
  327. package/dist/utils/process-utils.js +4 -2
  328. package/dist/utils/runtime-value.d.ts +13 -0
  329. package/dist/utils/runtime-value.d.ts.map +1 -0
  330. package/dist/utils/runtime-value.js +40 -0
  331. package/dist/utils/sql-parser.d.ts +8 -1
  332. package/dist/utils/sql-parser.d.ts.map +1 -1
  333. package/dist/utils/sql-parser.js +6 -3
  334. package/dist/utils/type-utils.d.ts.map +1 -1
  335. package/dist/utils/type-utils.js +10 -8
  336. package/dist/utils/utils.d.ts +2 -2
  337. package/dist/utils/utils.d.ts.map +1 -1
  338. package/dist/utils/utils.js +11 -8
  339. package/dist/utils/zod-error.d.ts.map +1 -1
  340. package/dist/utils/zod-error.js +7 -4
  341. package/dist/vector/chunking.d.ts.map +1 -1
  342. package/dist/vector/chunking.js +1 -1
  343. package/dist/vector/embedding.d.ts.map +1 -1
  344. package/dist/vector/embedding.js +1 -1
  345. package/dist/vector/types.d.ts +3 -2
  346. package/dist/vector/types.d.ts.map +1 -1
  347. package/package.json +5 -3
  348. package/src/ai/agents/agent.ts +5 -5
  349. package/src/ai/agents/types.ts +1 -1
  350. package/src/ai/providers/rtzr/__tests__/model.test.ts +2 -2
  351. package/src/ai/providers/rtzr/error.ts +5 -3
  352. package/src/ai/providers/rtzr/model.ts +3 -2
  353. package/src/ai/providers/rtzr/options.ts +10 -5
  354. package/src/ai/providers/rtzr/provider.ts +10 -10
  355. package/src/ai/providers/rtzr/utils.ts +3 -1
  356. package/src/api/__tests__/config.test.ts +11 -21
  357. package/src/api/__tests__/sonamu.http-validator.test.ts +512 -0
  358. package/src/api/__tests__/sonamu.websocket.test.ts +51 -41
  359. package/src/api/__tests__/zod-compiler-policy.test.ts +95 -0
  360. package/src/api/caster.ts +6 -8
  361. package/src/api/code-converters.ts +136 -36
  362. package/src/api/config.ts +62 -4
  363. package/src/api/context.ts +3 -3
  364. package/src/api/decorators.ts +28 -17
  365. package/src/api/http-validator.ts +149 -0
  366. package/src/api/sonamu.ts +459 -152
  367. package/src/api/websocket-helpers.ts +24 -17
  368. package/src/auth/audit-log/builders.ts +3 -2
  369. package/src/auth/audit-log/client-ip.ts +4 -2
  370. package/src/auth/audit-log/events.ts +15 -1
  371. package/src/auth/audit-log/plugin.ts +129 -200
  372. package/src/auth/audit-log-ingestor.ts +19 -15
  373. package/src/auth/auth-generator.ts +10 -5
  374. package/src/auth/better-auth-request.ts +4 -3
  375. package/src/auth/knex-adapter.ts +8 -2
  376. package/src/auth/plugins/entity-definitions/index.ts +6 -5
  377. package/src/bin/__tests__/http-validator-benchmark.test.ts +94 -0
  378. package/src/bin/__tests__/test-command.test.ts +9 -15
  379. package/src/bin/__tests__/ts-loader-register.test.ts +15 -17
  380. package/src/bin/__tests__/zod-compiler-build.test.ts +307 -0
  381. package/src/bin/build-config.ts +167 -0
  382. package/src/bin/cli.ts +153 -36
  383. package/src/bin/compiler-policy.ts +35 -0
  384. package/src/bin/fixture.ts +14 -3
  385. package/src/bin/test-command.ts +74 -29
  386. package/src/bin/ts-loader-registration.ts +22 -4
  387. package/src/cache/decorator.ts +10 -3
  388. package/src/compress/compress.ts +17 -4
  389. package/src/cone/cone-generator.ts +34 -6
  390. package/src/database/__tests__/db.test.ts +1 -0
  391. package/src/database/__tests__/puri.test.ts +16 -15
  392. package/src/database/__tests__/transaction-scope.test.ts +5 -0
  393. package/src/database/_batch_update.ts +1 -0
  394. package/src/database/base-model.ts +81 -50
  395. package/src/database/base-model.types.ts +6 -6
  396. package/src/database/db.ts +29 -19
  397. package/src/database/knex.ts +30 -17
  398. package/src/database/puri-subset.test-d.ts +17 -0
  399. package/src/database/puri.ts +181 -143
  400. package/src/database/puri.types.test-d.ts +31 -1
  401. package/src/database/puri.types.ts +23 -21
  402. package/src/database/upsert-builder.ts +75 -53
  403. package/src/dict/sd.ts +15 -5
  404. package/src/dict/sonamu-dictionary.ts +6 -6
  405. package/src/dict/utils.ts +9 -1
  406. package/src/entity/entity-manager.ts +26 -9
  407. package/src/entity/entity-template-cone.ts +5 -10
  408. package/src/entity/entity.ts +50 -34
  409. package/src/env.ts +7 -3
  410. package/src/exceptions/error-handler.ts +17 -2
  411. package/src/exceptions/so-exceptions.ts +26 -20
  412. package/src/filter/utils.ts +21 -11
  413. package/src/index.ts +3 -0
  414. package/src/logger/configure.ts +26 -18
  415. package/src/migration/__tests__/migrator.test.ts +50 -57
  416. package/src/migration/code-generation.ts +132 -104
  417. package/src/migration/index-where-predicate.ts +51 -24
  418. package/src/migration/migration-set.ts +11 -5
  419. package/src/migration/migrator.ts +68 -41
  420. package/src/migration/postgresql-schema-reader.ts +52 -47
  421. package/src/migration/slack-confirm.ts +17 -15
  422. package/src/naite/naite-reporter.ts +1 -1
  423. package/src/naite/naite.ts +97 -24
  424. package/src/runtime-type.ts +34 -0
  425. package/src/ssr/hmr-opt-out.ts +78 -0
  426. package/src/ssr/renderer.ts +6 -0
  427. package/src/storage/base-file.ts +13 -13
  428. package/src/storage/buffered-file.ts +11 -11
  429. package/src/storage/s3-driver.ts +4 -1
  430. package/src/storage/uploaded-file.ts +8 -8
  431. package/src/stream/__tests__/ws-contracts.test.ts +4 -2
  432. package/src/stream/__tests__/ws-telemetry.test.ts +1 -1
  433. package/src/stream/__tests__/ws.test.ts +30 -6
  434. package/src/stream/sse.ts +12 -11
  435. package/src/stream/ws-core.ts +1 -1
  436. package/src/stream/ws-delivery.ts +16 -7
  437. package/src/stream/ws-local-connection-store.ts +2 -3
  438. package/src/stream/ws-presence-store.ts +6 -1
  439. package/src/stream/ws-registry.ts +16 -7
  440. package/src/stream/ws-telemetry.ts +66 -43
  441. package/src/stream/ws.ts +73 -39
  442. package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +3 -2
  443. package/src/syncer/__tests__/http-validator-registry.test.ts +137 -0
  444. package/src/syncer/api-parser.ts +67 -27
  445. package/src/syncer/checksum.ts +17 -11
  446. package/src/syncer/code-generator.ts +25 -17
  447. package/src/syncer/entity-operations.ts +3 -5
  448. package/src/syncer/file-copy.ts +46 -0
  449. package/src/syncer/file-patterns.ts +11 -8
  450. package/src/syncer/file-tracking.ts +3 -4
  451. package/src/syncer/filesystem-dependencies.ts +73 -0
  452. package/src/syncer/module-loader.ts +8 -4
  453. package/src/syncer/syncer-actions.ts +56 -18
  454. package/src/syncer/syncer.ts +116 -43
  455. package/src/syncer/watcher.ts +8 -4
  456. package/src/tasks/decorator.ts +20 -12
  457. package/src/tasks/step-wrapper.ts +19 -9
  458. package/src/tasks/workflow-manager.ts +15 -9
  459. package/src/template/__tests__/http_validators.template.test.ts +160 -0
  460. package/src/template/__tests__/services.template.mutation.test.ts +24 -23
  461. package/src/template/__tests__/services.template.websocket.test.ts +21 -25
  462. package/src/template/entity-converter.ts +5 -2
  463. package/src/template/helpers.ts +8 -9
  464. package/src/template/implementations/generated.template.ts +5 -4
  465. package/src/template/implementations/generated_http.template.ts +61 -15
  466. package/src/template/implementations/generated_sso.template.ts +15 -4
  467. package/src/template/implementations/http_validators.template.ts +175 -0
  468. package/src/template/implementations/model.template.ts +3 -1
  469. package/src/template/implementations/sd.template.ts +81 -41
  470. package/src/template/implementations/services.template.ts +2 -2
  471. package/src/template/implementations/view_form.template.ts +56 -39
  472. package/src/template/implementations/view_list.template.ts +31 -23
  473. package/src/template/template-manager.ts +15 -13
  474. package/src/template/template-types.ts +13 -5
  475. package/src/template/template.ts +4 -3
  476. package/src/template/zod-converter.ts +206 -91
  477. package/src/testing/__tests__/dev-test-routes.test.ts +85 -25
  478. package/src/testing/__tests__/dev-vitest-manager.test.ts +15 -15
  479. package/src/testing/_relation-graph.ts +4 -1
  480. package/src/testing/bootstrap.ts +12 -5
  481. package/src/testing/data-explorer.ts +102 -53
  482. package/src/testing/dev-test-routes.ts +87 -50
  483. package/src/testing/dev-vitest-manager.ts +88 -32
  484. package/src/testing/faker-mappings.ts +2 -2
  485. package/src/testing/filesystem.ts +1 -0
  486. package/src/testing/fixture-generator.ts +191 -131
  487. package/src/testing/fixture-loader.ts +5 -1
  488. package/src/testing/fixture-manager.ts +129 -90
  489. package/src/testing/global-setup.ts +7 -3
  490. package/src/testing/index.ts +5 -0
  491. package/src/types/__tests__/entity-json-schema-search-text.test.ts +9 -3
  492. package/src/types/types.ts +184 -158
  493. package/src/ui/ai-api.ts +9 -7
  494. package/src/ui/ai-client.ts +61 -56
  495. package/src/ui/api.ts +727 -616
  496. package/src/ui/async-route.ts +4 -0
  497. package/src/ui/cdd-service.ts +35 -12
  498. package/src/ui/migrations-api.ts +63 -51
  499. package/src/utils/formatter.ts +7 -3
  500. package/src/utils/fs-utils.ts +5 -5
  501. package/src/utils/model.ts +4 -5
  502. package/src/utils/object-utils.ts +32 -22
  503. package/src/utils/process-utils.ts +4 -1
  504. package/src/utils/runtime-value.ts +43 -0
  505. package/src/utils/sql-parser.ts +13 -6
  506. package/src/utils/type-utils.ts +9 -7
  507. package/src/utils/utils.ts +19 -21
  508. package/src/utils/zod-error.ts +4 -2
  509. package/src/vector/chunking.ts +6 -1
  510. package/src/vector/embedding.ts +2 -1
  511. package/src/vector/types.ts +4 -2
  512. package/tsdown.api.config.ts +5 -2
  513. package/dist/ui-web/assets/index-C0m1pk6K.js +0 -177
@@ -0,0 +1,160 @@
1
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+
8
+ import { type SonamuConfig } from "../../api/config";
9
+ import { type ExtendedApi } from "../../api/decorators";
10
+ import { Sonamu } from "../../api/sonamu";
11
+ import { Syncer } from "../../syncer/syncer";
12
+ import { Template__http_validators } from "../implementations/http_validators.template";
13
+
14
+ function createApi(overrides: {
15
+ httpMethod: "GET" | "POST";
16
+ modelName: string;
17
+ path: string;
18
+ parameterType?: "number" | "string";
19
+ }): ExtendedApi {
20
+ return {
21
+ modelName: overrides.modelName,
22
+ methodName: "find",
23
+ path: overrides.path,
24
+ options: {
25
+ httpMethod: overrides.httpMethod,
26
+ },
27
+ typeParameters: [],
28
+ parameters: [
29
+ {
30
+ name: "filter",
31
+ optional: false,
32
+ type: {
33
+ t: "object",
34
+ props: [
35
+ {
36
+ name: "page",
37
+ optional: false,
38
+ type: overrides.parameterType ?? "number",
39
+ },
40
+ ],
41
+ },
42
+ },
43
+ ],
44
+ returnType: "unknown",
45
+ };
46
+ }
47
+
48
+ function readFingerprint(body: string): string {
49
+ const match = body.match(/fingerprint\w*\s*[:=]\s*["']([^"']+)["']/i);
50
+ if (match?.[1] === undefined) {
51
+ throw new Error("generated validator registry에 fingerprint가 없습니다");
52
+ }
53
+ return match[1];
54
+ }
55
+
56
+ const testConfig = {
57
+ api: { dir: ".", route: { prefix: "/api" } },
58
+ i18n: { defaultLocale: "ko", supportedLocales: ["ko"] },
59
+ sync: { targets: [] },
60
+ validation: { zodCompiler: { api: "aot" } },
61
+ database: {},
62
+ server: {
63
+ apiConfig: {
64
+ contextProvider: (defaultContext) => defaultContext,
65
+ guardHandler: () => undefined,
66
+ },
67
+ },
68
+ } satisfies SonamuConfig;
69
+
70
+ function setSyncerState(apis: ExtendedApi[]) {
71
+ const syncer = new Syncer();
72
+ syncer.apis = apis;
73
+ syncer.types = {};
74
+ Sonamu.syncer = syncer;
75
+ }
76
+
77
+ describe("Template__http_validators 생성 계약", () => {
78
+ const tempRoots: string[] = [];
79
+
80
+ beforeEach(() => {
81
+ Sonamu.config = testConfig;
82
+ });
83
+
84
+ afterEach(async () => {
85
+ await Promise.all(
86
+ tempRoots.splice(0).map((rootPath) => rm(rootPath, { recursive: true, force: true })),
87
+ );
88
+ });
89
+
90
+ it("충돌 없는 route key와 fingerprint로 최종 caster의 explicit compile registry를 결정적으로 만든다", () => {
91
+ const apis = [
92
+ createApi({ httpMethod: "GET", modelName: "ReportModel", path: "/report/find" }),
93
+ createApi({ httpMethod: "GET", modelName: "AuditModel", path: "/audit/find" }),
94
+ createApi({ httpMethod: "POST", modelName: "ReportModel", path: "/report/find" }),
95
+ createApi({ httpMethod: "GET", modelName: "ReportModel", path: "/report/find-alternate" }),
96
+ ];
97
+ const template = new Template__http_validators();
98
+
99
+ setSyncerState(apis);
100
+ const first = template.render();
101
+ setSyncerState(apis.toReversed());
102
+ const reordered = template.render();
103
+
104
+ expect(first.body).toBe(reordered.body);
105
+ expect(first.body.match(/\bcompile\(/g)).toHaveLength(4);
106
+ expect(first.body).toMatch(/compile\(\s*fastifyCaster\(/);
107
+ expect(readFingerprint(first.body)).toBe(readFingerprint(reordered.body));
108
+
109
+ const changedApis = [
110
+ ...apis.slice(0, -1),
111
+ createApi({
112
+ httpMethod: "GET",
113
+ modelName: "ReportModel",
114
+ parameterType: "string",
115
+ path: "/report/find-alternate",
116
+ }),
117
+ ];
118
+ setSyncerState(changedApis);
119
+ const changed = template.render();
120
+
121
+ expect(readFingerprint(changed.body)).not.toBe(readFingerprint(first.body));
122
+ });
123
+
124
+ it("동일한 canonical route key가 중복되면 registry 생성을 거부한다", () => {
125
+ const duplicatedApi = createApi({
126
+ httpMethod: "GET",
127
+ modelName: "ReportModel",
128
+ path: "/report/find",
129
+ });
130
+ setSyncerState([duplicatedApi, { ...duplicatedApi }]);
131
+
132
+ const template = new Template__http_validators();
133
+
134
+ expect(() => template.render()).toThrow();
135
+ });
136
+
137
+ it("REST API가 0개인 AOT registry는 compiler import 없이 내보내며 독립적으로 로드된다", async () => {
138
+ setSyncerState([]);
139
+
140
+ const rendered = new Template__http_validators().render();
141
+ const source = [...(rendered.customHeaders ?? []), rendered.body].join("\n");
142
+
143
+ expect(rendered.body).toMatch(/export const validators = new Map\(\[\s*\]\);/);
144
+ expect(rendered.body).toContain("export const routeIds = {}");
145
+ expect(source).not.toContain('from "zod-compiler"');
146
+ expect(source).not.toContain('from "sonamu"');
147
+ expect(source).not.toMatch(/\bcompile\(/);
148
+ expect(readFingerprint(rendered.body)).toHaveLength(64);
149
+
150
+ const tempRoot = await mkdtemp(path.join(os.tmpdir(), "sonamu-zero-registry-load-test-"));
151
+ tempRoots.push(tempRoot);
152
+ const modulePath = path.join(tempRoot, "sonamu.validators.generated.mjs");
153
+ await writeFile(modulePath, source);
154
+
155
+ await expect(import(`${pathToFileURL(modulePath).href}?test=zero`)).resolves.toMatchObject({
156
+ routeIds: {},
157
+ validators: expect.any(Map),
158
+ });
159
+ });
160
+ });
@@ -1,35 +1,36 @@
1
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
1
+ import { beforeEach, describe, expect, it } from "vitest";
2
2
 
3
3
  import { Sonamu } from "../../api";
4
+ import { type SonamuConfig } from "../../api/config";
4
5
  import { type ExtendedApi } from "../../api/decorators";
6
+ import { Syncer } from "../../syncer/syncer";
5
7
  import { Template__services } from "../implementations/services.template";
6
8
 
7
- describe("Template__services mutation hooks", () => {
8
- let originalConfig: unknown;
9
- let originalSyncer: unknown;
9
+ const testConfig = {
10
+ api: { dir: ".", route: { prefix: "/api" } },
11
+ i18n: { defaultLocale: "ko", supportedLocales: ["ko"] },
12
+ sync: { targets: [] },
13
+ database: {},
14
+ server: {
15
+ apiConfig: {
16
+ contextProvider: (defaultContext) => defaultContext,
17
+ guardHandler: () => undefined,
18
+ },
19
+ },
20
+ } satisfies SonamuConfig;
10
21
 
11
- beforeEach(() => {
12
- originalConfig = Reflect.get(Sonamu, "_config");
13
- originalSyncer = Reflect.get(Sonamu, "_syncer");
14
- Reflect.set(Sonamu, "_config", {
15
- api: {
16
- route: {
17
- prefix: "/api",
18
- },
19
- },
20
- });
21
- });
22
+ function renderServices(apis: ExtendedApi[]) {
23
+ const syncer = new Syncer();
24
+ syncer.apis = apis;
25
+ Sonamu.syncer = syncer;
26
+ return new Template__services().render({}).body;
27
+ }
22
28
 
23
- afterEach(() => {
24
- Reflect.set(Sonamu, "_config", originalConfig);
25
- Reflect.set(Sonamu, "_syncer", originalSyncer);
29
+ describe("Template__services mutation hooks", () => {
30
+ beforeEach(() => {
31
+ Sonamu.config = testConfig;
26
32
  });
27
33
 
28
- const renderServices = (apis: ExtendedApi[]) => {
29
- Reflect.set(Sonamu, "_syncer", { apis });
30
- return new Template__services().render({}).body;
31
- };
32
-
33
34
  it("파라미터가 있는 일반 mutation에서 namespace와 인자 순서를 유지한다", () => {
34
35
  const body = renderServices([
35
36
  {
@@ -1,33 +1,29 @@
1
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
1
+ import { describe, expect, it } from "vitest";
2
2
  import { z } from "zod";
3
3
 
4
4
  import { Sonamu } from "../../api";
5
+ import { type SonamuConfig } from "../../api/config";
5
6
  import { type ExtendedApi } from "../../api/decorators";
6
7
  import { EntityManager } from "../../entity/entity-manager";
8
+ import { Syncer } from "../../syncer/syncer";
7
9
  import { Template__services } from "../implementations/services.template";
8
10
 
9
- describe("Template__services websocket event refs", () => {
10
- let originalConfig: unknown;
11
- let originalSyncer: unknown;
12
-
13
- beforeEach(() => {
14
- originalConfig = Reflect.get(Sonamu, "_config");
15
- originalSyncer = Reflect.get(Sonamu, "_syncer");
16
- });
17
-
18
- afterEach(() => {
19
- Reflect.set(Sonamu, "_config", originalConfig);
20
- Reflect.set(Sonamu, "_syncer", originalSyncer);
21
- });
11
+ const testConfig = {
12
+ api: { dir: ".", route: { prefix: "/api" } },
13
+ i18n: { defaultLocale: "ko", supportedLocales: ["ko"] },
14
+ sync: { targets: [] },
15
+ database: {},
16
+ server: {
17
+ apiConfig: {
18
+ contextProvider: (defaultContext) => defaultContext,
19
+ guardHandler: () => undefined,
20
+ },
21
+ },
22
+ } satisfies SonamuConfig;
22
23
 
23
- it("reuses websocket event type names when they are importable", () => {
24
- Reflect.set(Sonamu, "_config", {
25
- api: {
26
- route: {
27
- prefix: "/api",
28
- },
29
- },
30
- });
24
+ describe("Template__services websocket event refs", () => {
25
+ it("가져올 수 있는 websocket 이벤트 타입 이름을 재사용한다", () => {
26
+ Sonamu.config = testConfig;
31
27
 
32
28
  const apis: ExtendedApi[] = [
33
29
  {
@@ -62,9 +58,9 @@ describe("Template__services websocket event refs", () => {
62
58
  returnType: "void",
63
59
  },
64
60
  ];
65
- Reflect.set(Sonamu, "_syncer", {
66
- apis,
67
- });
61
+ const syncer = new Syncer();
62
+ syncer.apis = apis;
63
+ Sonamu.syncer = syncer;
68
64
 
69
65
  EntityManager.setModulePath("ChatOutEvents", "chat/chat.types");
70
66
  EntityManager.setModulePath("ChatInEvents", "chat/chat.types");
@@ -1,6 +1,6 @@
1
1
  import assert from "assert";
2
2
 
3
- import z from "zod";
3
+ import { z } from "zod";
4
4
 
5
5
  import { SD } from "../dict/sd";
6
6
  import { EntityManager } from "../entity/entity-manager";
@@ -26,7 +26,10 @@ export async function getColumnsNode(entityId: string, subsetKey: string): Promi
26
26
  };
27
27
 
28
28
  // oxlint-disable-next-line @typescript-eslint/no-explicit-any -- zod 스키마를 로드할 때 사용하는 타입
29
- const columnsZodType = (await propNodeToZodType(rootPropNode)) as z.ZodObject<any>;
29
+ const columnsZodType =
30
+ /* SAFETY: 선행 Zod 종류 분기와 템플릿 입력 계약이 이 값의 타입을 보장한다. */ (await propNodeToZodType(
31
+ rootPropNode,
32
+ )) as z.ZodObject<any>;
30
33
 
31
34
  const columnsNode = zodTypeToRenderingNode(columnsZodType);
32
35
  assert(columnsNode.children !== undefined, "columnsNode.children is undefined");
@@ -5,6 +5,13 @@ import { type EntityNamesRecord } from "../entity/entity-manager";
5
5
  import { isEnumProp, isRelationProp } from "../types/types";
6
6
  import { type RelationProp } from "../types/types";
7
7
 
8
+ interface EnumColumnInfo {
9
+ id: string;
10
+ targetEntityNames: EntityNamesRecord;
11
+ targetEntityId: string;
12
+ title: string;
13
+ }
14
+
8
15
  /**
9
16
  * Enum의 표시용 라벨을 가져옵니다.
10
17
  * OrderBy, SearchField 등 특수한 경우와 일반 Enum을 구분하여 처리합니다.
@@ -29,15 +36,7 @@ export function getLabel(entityId: string, enumId: string): string {
29
36
  * 컬럼 이름으로부터 Enum 정보를 추출합니다.
30
37
  * Entity의 prop 중 enum 타입인 것을 찾아 관련 정보를 반환합니다.
31
38
  */
32
- export function getEnumInfoFromColName(
33
- entityId: string,
34
- colName: string,
35
- ): {
36
- id: string;
37
- targetEntityNames: EntityNamesRecord;
38
- targetEntityId: string;
39
- title: string;
40
- } {
39
+ export function getEnumInfoFromColName(entityId: string, colName: string): EnumColumnInfo {
41
40
  const baseEntity = EntityManager.get(entityId);
42
41
  const prop = baseEntity.props.find((p) => p.name === colName);
43
42
  if (prop && isEnumProp(prop)) {
@@ -70,7 +70,7 @@ export class Template__generated extends Template {
70
70
  importKeys: unique([...result.importKeys, ...ts.importKeys].toSorted()),
71
71
  };
72
72
  },
73
- {
73
+ /* SAFETY: reduce 누산기는 label을 제외한 SourceCode의 두 배열로 초기화된다. */ {
74
74
  lines: [],
75
75
  importKeys: [],
76
76
  } as Omit<SourceCode, "label">,
@@ -83,7 +83,7 @@ export class Template__generated extends Template {
83
83
  );
84
84
  if (cdImportKeys.length > 0) {
85
85
  const customScalarLines = cdImportKeys.flatMap((importKey) => {
86
- const entity = entities.find((entity) => entity.types[importKey]);
86
+ const entity = entities.find((candidateEntity) => candidateEntity.types[importKey]);
87
87
  if (!entity) {
88
88
  throw new Error(`ZodType not found ${importKey}`);
89
89
  }
@@ -109,7 +109,8 @@ export class Template__generated extends Template {
109
109
  // import
110
110
  // sourceCode.importKeys에 내장 타입의 스키마가 있으면 sonamu import에 추가
111
111
  const builtInSchemaNames = Object.values(BUILT_IN_TYPES).map(
112
- (info) => info.schemaName as string,
112
+ (info) =>
113
+ /* SAFETY: BUILT_IN_TYPES의 모든 항목은 생성 코드에 쓸 schemaName을 가진다. */ info.schemaName as string,
113
114
  );
114
115
  const builtInSchemas = sourceCode.importKeys.filter((key) => builtInSchemaNames.includes(key));
115
116
  const sonamuImports = [
@@ -146,7 +147,7 @@ export class Template__generated extends Template {
146
147
  return {
147
148
  label: `Enums: ${entity.id}`,
148
149
  lines: Object.entries(entity.enumLabels)
149
- .filter(([_, enumLabel]) => Object.keys(enumLabel).length > 0)
150
+ .filter(([, enumLabel]) => Object.keys(enumLabel).length > 0)
150
151
  .flatMap(([enumId, enumLabel]) => [
151
152
  `export const ${enumId} = z.enum([${Object.keys(enumLabel).map(
152
153
  (el) => `"${el}"`,
@@ -6,6 +6,20 @@ import { type ExtendedApi } from "../../api/decorators";
6
6
  import { Sonamu } from "../../api/sonamu";
7
7
  import { Template } from "../template";
8
8
 
9
+ type RequestDefaultValue =
10
+ | null
11
+ | undefined
12
+ | bigint
13
+ | boolean
14
+ | number
15
+ | string
16
+ | RequestDefaultValue[]
17
+ | RequestDefaultObject;
18
+
19
+ interface RequestDefaultObject {
20
+ [key: string]: RequestDefaultValue;
21
+ }
22
+
9
23
  export class Template__generated_http extends Template {
10
24
  constructor() {
11
25
  super("generated_http");
@@ -67,16 +81,23 @@ export class Template__generated_http extends Template {
67
81
  };
68
82
  }
69
83
 
70
- zodTypeToReqDefault(zodType: z.ZodType, name: string): unknown {
84
+ zodTypeToReqDefault(zodType: z.ZodType, name: string): RequestDefaultValue {
71
85
  if (zodType instanceof z.ZodObject) {
72
86
  return Object.fromEntries(
73
- Object.keys(zodType.shape).map((key) => [
87
+ Object.keys(zodType["shape"]).map((key) => [
74
88
  key,
75
- this.zodTypeToReqDefault(zodType.shape[key], key),
89
+ this.zodTypeToReqDefault(zodType["shape"][key], key),
76
90
  ]),
77
91
  );
78
92
  } else if (zodType instanceof z.ZodArray) {
79
- return [this.zodTypeToReqDefault((zodType as z.ZodArray<z.ZodType>).element, name)];
93
+ return [
94
+ this.zodTypeToReqDefault(
95
+ /* SAFETY: ZodArray 분기이므로 element가 배열 원소 스키마다. */ (
96
+ zodType as z.ZodArray<z.ZodType>
97
+ ).element,
98
+ name,
99
+ ),
100
+ ];
80
101
  } else if (zodType instanceof z.core.$ZodString) {
81
102
  // NOTE: z.ZodString으로 비교하면 z.url(), z.email() 등의 타입에서 문제가 생기므로 z.core.$ZodString으로 비교함
82
103
  if (name.endsWith("_at") || name.endsWith("_date") || name === "range") {
@@ -96,11 +117,21 @@ export class Template__generated_http extends Template {
96
117
  } else if (zodType instanceof z.ZodEnum) {
97
118
  return zodType.options[0];
98
119
  } else if (zodType instanceof z.ZodOptional) {
99
- return this.zodTypeToReqDefault((zodType as z.ZodOptional<z.ZodType>).def.innerType, name);
120
+ return this.zodTypeToReqDefault(
121
+ /* SAFETY: ZodOptional 분기이므로 innerType이 선택 속성의 스키마다. */ (
122
+ zodType as z.ZodOptional<z.ZodType>
123
+ ).def.innerType,
124
+ name,
125
+ );
100
126
  } else if (zodType instanceof z.ZodNullable) {
101
127
  return null;
102
128
  } else if (zodType instanceof z.ZodUnion) {
103
- return this.zodTypeToReqDefault((zodType as z.ZodUnion<z.ZodType[]>).def.options[0], name);
129
+ return this.zodTypeToReqDefault(
130
+ /* SAFETY: ZodUnion 분기이므로 options의 첫 항목이 유효한 대안 스키마다. */ (
131
+ zodType as z.ZodUnion<z.ZodType[]>
132
+ ).def.options[0],
133
+ name,
134
+ );
104
135
  } else if (zodType instanceof z.ZodUnknown) {
105
136
  return "unknown";
106
137
  } else if (zodType instanceof z.ZodTuple) {
@@ -112,20 +143,36 @@ export class Template__generated_http extends Template {
112
143
  return zodType.value;
113
144
  } else if (zodType instanceof z.ZodRecord || zodType instanceof z.ZodMap) {
114
145
  // oxlint-disable-next-line @typescript-eslint/no-explicit-any -- ZodRecord 타입 사용
115
- const kvDef = (zodType as z.ZodRecord<any, z.ZodType> | z.ZodMap<z.ZodType, z.ZodType>).def;
146
+ const kvDef = /* SAFETY: ZodRecord/ZodMap 분기이므로 def가 키-값 스키마 정의다. */ (
147
+ zodType as z.ZodRecord<any, z.ZodType> | z.ZodMap<z.ZodType, z.ZodType>
148
+ ).def;
116
149
  // oxlint-disable-next-line @typescript-eslint/no-explicit-any -- ZodIntersection 타입 사용
117
- const key = this.zodTypeToReqDefault(kvDef.keyType, name) as any;
150
+ const key = String(this.zodTypeToReqDefault(kvDef.keyType, name));
118
151
  const value = this.zodTypeToReqDefault(kvDef.valueType, name);
119
152
  return { [key]: value };
120
153
  } else if (zodType instanceof z.ZodSet) {
121
- return [this.zodTypeToReqDefault((zodType as z.ZodSet<z.ZodType>).def.valueType, name)];
154
+ return [
155
+ this.zodTypeToReqDefault(
156
+ /* SAFETY: ZodSet 분기이므로 valueType이 집합 원소 스키마다. */ (
157
+ zodType as z.ZodSet<z.ZodType>
158
+ ).def.valueType,
159
+ name,
160
+ ),
161
+ ];
122
162
  } else if (zodType instanceof z.ZodIntersection) {
123
163
  return this.zodTypeToReqDefault(
124
- (zodType as z.ZodIntersection<z.ZodType, z.ZodType>).def.right,
164
+ /* SAFETY: ZodIntersection 분기이므로 right가 교차 타입의 우측 스키마다. */ (
165
+ zodType as z.ZodIntersection<z.ZodType, z.ZodType>
166
+ ).def.right,
125
167
  name,
126
168
  );
127
169
  } else if (zodType instanceof z.ZodDefault) {
128
- return this.zodTypeToReqDefault((zodType as z.ZodDefault<z.ZodType>).def.innerType, name);
170
+ return this.zodTypeToReqDefault(
171
+ /* SAFETY: ZodDefault 분기이므로 innerType이 기본값 적용 전 스키마다. */ (
172
+ zodType as z.ZodDefault<z.ZodType>
173
+ ).def.innerType,
174
+ name,
175
+ );
129
176
  } else {
130
177
  // console.log(zodType);
131
178
  return `unknown-${zodType.type}`;
@@ -135,12 +182,11 @@ export class Template__generated_http extends Template {
135
182
  resolveApiParams(
136
183
  api: ExtendedApi,
137
184
  references: { [typeName: string]: z.ZodType },
138
- ): { [key: string]: unknown } {
185
+ ): RequestDefaultObject {
139
186
  const reqType = getZodObjectFromApi(api, references);
140
187
  try {
141
- const def = this.zodTypeToReqDefault(reqType, "unknownName") as {
142
- [key: string]: unknown;
143
- };
188
+ // SAFETY: getZodObjectFromApi는 객체 스키마를 반환하므로 기본값도 객체이다.
189
+ const def = this.zodTypeToReqDefault(reqType, "unknownName") as RequestDefaultObject;
144
190
  return def;
145
191
  } catch (error) {
146
192
  console.error(error);
@@ -36,6 +36,13 @@ function mapBetterAuthFieldType(type: string): string {
36
36
  }
37
37
  }
38
38
 
39
+ function addLoaderIdTypeSafetyComments(query: string): string {
40
+ return query.replaceAll(
41
+ /fromIds as (?:number|string)\[\]/g,
42
+ "/* SAFETY: 로더가 전달하는 ID는 소스 엔티티의 기본 키 타입과 일치한다. */ $&",
43
+ );
44
+ }
45
+
39
46
  export class Template__generated_sso extends Template {
40
47
  constructor() {
41
48
  super("generated_sso");
@@ -88,7 +95,8 @@ export class Template__generated_sso extends Template {
88
95
  lines: [
89
96
  `export const ${entityCamelName}LoaderQueries = {`,
90
97
  ...subsetKeys.map((subsetKey) => {
91
- return `${subsetKey}: ${entity.getPuriLoaderQuery(subsetKey)},`;
98
+ const query = entity.getPuriLoaderQuery(subsetKey);
99
+ return `${subsetKey}: ${addLoaderIdTypeSafetyComments(query)},`;
92
100
  }),
93
101
  `} as const satisfies PuriLoaderQueries<${subsetKeyTypeName}>;`,
94
102
  "",
@@ -128,7 +136,7 @@ export class Template__generated_sso extends Template {
128
136
  importKeys: unique([...result.importKeys, ...ts.importKeys]),
129
137
  };
130
138
  },
131
- {
139
+ /* SAFETY: reduce 누산기는 label을 제외한 SourceCode의 두 배열로 초기화된다. */ {
132
140
  lines: [],
133
141
  importKeys: [],
134
142
  } as Omit<SourceCode, "label">,
@@ -295,7 +303,9 @@ export class Template__generated_sso extends Template {
295
303
  }
296
304
 
297
305
  // oxlint-disable-next-line @typescript-eslint/no-explicit-any -- additionalFields 타입이 동적임
298
- const additionalFields = (authConfig as any)?.user?.additionalFields;
306
+ const additionalFields =
307
+ /* SAFETY: better-auth 설정의 user.additionalFields는 동적 필드 맵이다. */ (authConfig as any)
308
+ ?.user?.additionalFields;
299
309
  if (!additionalFields || Object.keys(additionalFields).length === 0) {
300
310
  // additionalFields가 없으면 기본 User 타입만 사용
301
311
  return {
@@ -310,7 +320,8 @@ export class Template__generated_sso extends Template {
310
320
  // additionalFields를 TypeScript 타입으로 변환
311
321
  const fieldLines = Object.entries(additionalFields).map(([key, value]) => {
312
322
  // oxlint-disable-next-line @typescript-eslint/no-explicit-any -- better-auth additionalFields 구조
313
- const fieldConfig = value as any;
323
+ const fieldConfig =
324
+ /* SAFETY: additionalFields의 각 값은 better-auth 필드 설정 객체이다. */ value as any;
314
325
  const isRequired = fieldConfig.required !== false;
315
326
 
316
327
  let fieldType: string;