sonamu 0.6.0 → 0.7.1

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 (406) hide show
  1. package/.swcrc.project-default +18 -0
  2. package/bin/cli.js +24 -0
  3. package/dist/ai/agents/agent.d.ts +11 -0
  4. package/dist/ai/agents/agent.d.ts.map +1 -0
  5. package/dist/ai/agents/agent.js +65 -0
  6. package/dist/ai/agents/index.d.ts +3 -0
  7. package/dist/ai/agents/index.d.ts.map +1 -0
  8. package/dist/ai/agents/index.js +4 -0
  9. package/dist/ai/agents/types.d.ts +43 -0
  10. package/dist/ai/agents/types.d.ts.map +1 -0
  11. package/dist/ai/agents/types.js +3 -0
  12. package/dist/ai/index.d.ts +2 -0
  13. package/dist/ai/index.d.ts.map +1 -0
  14. package/dist/ai/index.js +3 -0
  15. package/dist/ai/providers/rtzr/api.d.ts +22 -0
  16. package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
  17. package/dist/ai/providers/rtzr/api.js +28 -0
  18. package/dist/ai/providers/rtzr/error.d.ts +18 -0
  19. package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
  20. package/dist/ai/providers/rtzr/error.js +29 -0
  21. package/dist/ai/providers/rtzr/index.d.ts +5 -0
  22. package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
  23. package/dist/ai/providers/rtzr/index.js +6 -0
  24. package/dist/ai/providers/rtzr/model.d.ts +52 -0
  25. package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
  26. package/dist/ai/providers/rtzr/model.js +137 -0
  27. package/dist/ai/providers/rtzr/options.d.ts +7 -0
  28. package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
  29. package/dist/ai/providers/rtzr/options.js +47 -0
  30. package/dist/ai/providers/rtzr/provider.d.ts +18 -0
  31. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
  32. package/dist/ai/providers/rtzr/provider.js +54 -0
  33. package/dist/ai/providers/rtzr/utils.d.ts +19 -0
  34. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
  35. package/dist/ai/providers/rtzr/utils.js +88 -0
  36. package/dist/api/base-frame.d.ts +2 -2
  37. package/dist/api/base-frame.d.ts.map +1 -1
  38. package/dist/api/base-frame.js +2 -1
  39. package/dist/api/caster.d.ts.map +1 -1
  40. package/dist/api/caster.js +6 -1
  41. package/dist/api/code-converters.d.ts +58 -14
  42. package/dist/api/code-converters.d.ts.map +1 -1
  43. package/dist/api/code-converters.js +178 -409
  44. package/dist/api/config.d.ts +27 -13
  45. package/dist/api/config.d.ts.map +1 -1
  46. package/dist/api/config.js +19 -26
  47. package/dist/api/context.d.ts +4 -3
  48. package/dist/api/context.d.ts.map +1 -1
  49. package/dist/api/context.js +1 -1
  50. package/dist/api/decorators.d.ts +20 -6
  51. package/dist/api/decorators.d.ts.map +1 -1
  52. package/dist/api/decorators.js +111 -18
  53. package/dist/api/index.d.ts +2 -2
  54. package/dist/api/index.d.ts.map +1 -1
  55. package/dist/api/index.js +3 -3
  56. package/dist/api/sonamu.d.ts +7 -7
  57. package/dist/api/sonamu.d.ts.map +1 -1
  58. package/dist/api/sonamu.js +83 -51
  59. package/dist/api/validator.d.ts +6 -0
  60. package/dist/api/validator.d.ts.map +1 -0
  61. package/dist/api/validator.js +81 -0
  62. package/dist/bin/build-config.d.ts +5 -1
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +5 -2
  65. package/dist/bin/cli.js +165 -64
  66. package/dist/bin/loader-register.d.ts +2 -0
  67. package/dist/bin/loader-register.d.ts.map +1 -0
  68. package/dist/bin/loader-register.js +34 -0
  69. package/dist/database/_batch_update.d.ts +5 -3
  70. package/dist/database/_batch_update.d.ts.map +1 -1
  71. package/dist/database/_batch_update.js +30 -13
  72. package/dist/database/base-model.d.ts +96 -10
  73. package/dist/database/base-model.d.ts.map +1 -1
  74. package/dist/database/base-model.js +232 -89
  75. package/dist/database/base-model.types.d.ts +93 -0
  76. package/dist/database/base-model.types.d.ts.map +1 -0
  77. package/dist/database/base-model.types.js +10 -0
  78. package/dist/database/code-generator.d.ts +1 -1
  79. package/dist/database/code-generator.d.ts.map +1 -1
  80. package/dist/database/code-generator.js +11 -10
  81. package/dist/database/db.d.ts +5 -6
  82. package/dist/database/db.d.ts.map +1 -1
  83. package/dist/database/db.js +22 -25
  84. package/dist/database/puri-subset.test-d.js +81 -0
  85. package/dist/database/puri-subset.types.d.ts +123 -0
  86. package/dist/database/puri-subset.types.d.ts.map +1 -0
  87. package/dist/database/puri-subset.types.js +16 -0
  88. package/dist/database/puri-wrapper.d.ts +13 -11
  89. package/dist/database/puri-wrapper.d.ts.map +1 -1
  90. package/dist/database/puri-wrapper.js +2 -2
  91. package/dist/database/puri.d.ts +25 -14
  92. package/dist/database/puri.d.ts.map +1 -1
  93. package/dist/database/puri.js +83 -21
  94. package/dist/database/puri.types.d.ts +21 -7
  95. package/dist/database/puri.types.d.ts.map +1 -1
  96. package/dist/database/puri.types.js +4 -1
  97. package/dist/database/transaction-context.d.ts +1 -1
  98. package/dist/database/transaction-context.d.ts.map +1 -1
  99. package/dist/database/transaction-context.js +1 -1
  100. package/dist/database/upsert-builder.d.ts +9 -3
  101. package/dist/database/upsert-builder.d.ts.map +1 -1
  102. package/dist/database/upsert-builder.js +227 -78
  103. package/dist/entity/entity-manager.d.ts +165 -2
  104. package/dist/entity/entity-manager.d.ts.map +1 -1
  105. package/dist/entity/entity-manager.js +26 -10
  106. package/dist/entity/entity.d.ts +5 -3
  107. package/dist/entity/entity.d.ts.map +1 -1
  108. package/dist/entity/entity.js +153 -54
  109. package/dist/exceptions/error-handler.d.ts +1 -1
  110. package/dist/exceptions/error-handler.d.ts.map +1 -1
  111. package/dist/exceptions/error-handler.js +1 -1
  112. package/dist/exceptions/so-exceptions.d.ts +1 -1
  113. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  114. package/dist/exceptions/so-exceptions.js +1 -1
  115. package/dist/file-storage/driver.d.ts +1 -1
  116. package/dist/file-storage/driver.d.ts.map +1 -1
  117. package/dist/file-storage/driver.js +1 -1
  118. package/dist/file-storage/file-storage.js +2 -2
  119. package/dist/index.d.ts +18 -11
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +19 -13
  122. package/dist/migration/code-generation.d.ts +1 -1
  123. package/dist/migration/code-generation.d.ts.map +1 -1
  124. package/dist/migration/code-generation.js +123 -67
  125. package/dist/migration/migration-set.d.ts +2 -10
  126. package/dist/migration/migration-set.d.ts.map +1 -1
  127. package/dist/migration/migration-set.js +67 -218
  128. package/dist/migration/migrator.d.ts +24 -73
  129. package/dist/migration/migrator.d.ts.map +1 -1
  130. package/dist/migration/migrator.js +121 -301
  131. package/dist/migration/postgresql-schema-reader.d.ts +51 -0
  132. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
  133. package/dist/migration/postgresql-schema-reader.js +245 -0
  134. package/dist/migration/types.d.ts +6 -38
  135. package/dist/migration/types.d.ts.map +1 -1
  136. package/dist/migration/types.js +1 -1
  137. package/dist/naite/messaging-types.d.ts +43 -0
  138. package/dist/naite/messaging-types.d.ts.map +1 -0
  139. package/dist/naite/messaging-types.js +7 -0
  140. package/dist/naite/naite-reporter.d.ts +41 -0
  141. package/dist/naite/naite-reporter.d.ts.map +1 -0
  142. package/dist/naite/naite-reporter.js +102 -0
  143. package/dist/naite/naite.d.ts +91 -8
  144. package/dist/naite/naite.d.ts.map +1 -1
  145. package/dist/naite/naite.js +285 -41
  146. package/dist/stream/sse.d.ts +2 -2
  147. package/dist/stream/sse.d.ts.map +1 -1
  148. package/dist/stream/sse.js +1 -1
  149. package/dist/syncer/api-parser.d.ts +3 -13
  150. package/dist/syncer/api-parser.d.ts.map +1 -1
  151. package/dist/syncer/api-parser.js +67 -56
  152. package/dist/syncer/checksum.d.ts +2 -2
  153. package/dist/syncer/checksum.d.ts.map +1 -1
  154. package/dist/syncer/checksum.js +11 -11
  155. package/dist/syncer/code-generator.d.ts +3 -3
  156. package/dist/syncer/code-generator.d.ts.map +1 -1
  157. package/dist/syncer/code-generator.js +37 -17
  158. package/dist/syncer/entity-operations.d.ts +2 -2
  159. package/dist/syncer/entity-operations.d.ts.map +1 -1
  160. package/dist/syncer/entity-operations.js +9 -8
  161. package/dist/syncer/file-patterns.d.ts +1 -1
  162. package/dist/syncer/file-patterns.d.ts.map +1 -1
  163. package/dist/syncer/file-patterns.js +1 -1
  164. package/dist/syncer/index.d.ts +4 -4
  165. package/dist/syncer/index.d.ts.map +1 -1
  166. package/dist/syncer/index.js +5 -5
  167. package/dist/syncer/module-loader.d.ts +4 -4
  168. package/dist/syncer/module-loader.d.ts.map +1 -1
  169. package/dist/syncer/module-loader.js +17 -12
  170. package/dist/syncer/syncer.d.ts +31 -24
  171. package/dist/syncer/syncer.d.ts.map +1 -1
  172. package/dist/syncer/syncer.js +92 -45
  173. package/dist/template/entity-converter.d.ts +1 -1
  174. package/dist/template/entity-converter.d.ts.map +1 -1
  175. package/dist/template/entity-converter.js +15 -8
  176. package/dist/template/helpers.d.ts +2 -2
  177. package/dist/template/helpers.d.ts.map +1 -1
  178. package/dist/template/helpers.js +3 -3
  179. package/dist/template/implementations/entity.template.d.ts +2 -2
  180. package/dist/template/implementations/entity.template.d.ts.map +1 -1
  181. package/dist/template/implementations/entity.template.js +4 -5
  182. package/dist/template/implementations/generated.template.d.ts +2 -3
  183. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  184. package/dist/template/implementations/generated.template.js +46 -29
  185. package/dist/template/implementations/generated_http.template.d.ts +2 -3
  186. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  187. package/dist/template/implementations/generated_http.template.js +9 -9
  188. package/dist/template/implementations/generated_sso.template.d.ts +3 -4
  189. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  190. package/dist/template/implementations/generated_sso.template.js +54 -25
  191. package/dist/template/implementations/init_types.template.d.ts +2 -2
  192. package/dist/template/implementations/init_types.template.d.ts.map +1 -1
  193. package/dist/template/implementations/init_types.template.js +2 -2
  194. package/dist/template/implementations/model.template.d.ts +2 -2
  195. package/dist/template/implementations/model.template.d.ts.map +1 -1
  196. package/dist/template/implementations/model.template.js +47 -37
  197. package/dist/template/implementations/model_test.template.d.ts +2 -2
  198. package/dist/template/implementations/model_test.template.d.ts.map +1 -1
  199. package/dist/template/implementations/model_test.template.js +2 -2
  200. package/dist/template/implementations/service.template.d.ts +4 -4
  201. package/dist/template/implementations/service.template.d.ts.map +1 -1
  202. package/dist/template/implementations/service.template.js +24 -16
  203. package/dist/template/implementations/view_enums_buttonset.template.d.ts +2 -2
  204. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -1
  205. package/dist/template/implementations/view_enums_buttonset.template.js +1 -1
  206. package/dist/template/implementations/view_enums_dropdown.template.d.ts +2 -2
  207. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -1
  208. package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
  209. package/dist/template/implementations/view_enums_select.template.d.ts +2 -2
  210. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -1
  211. package/dist/template/implementations/view_enums_select.template.js +2 -2
  212. package/dist/template/implementations/view_form.template.d.ts +2 -2
  213. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  214. package/dist/template/implementations/view_form.template.js +4 -4
  215. package/dist/template/implementations/view_id_all_select.template.d.ts +2 -2
  216. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
  217. package/dist/template/implementations/view_id_all_select.template.js +1 -1
  218. package/dist/template/implementations/view_id_async_select.template.d.ts +2 -2
  219. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -1
  220. package/dist/template/implementations/view_id_async_select.template.js +1 -1
  221. package/dist/template/implementations/view_list.template.d.ts +2 -2
  222. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  223. package/dist/template/implementations/view_list.template.js +29 -19
  224. package/dist/template/implementations/view_list_columns.template.d.ts +3 -3
  225. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -1
  226. package/dist/template/implementations/view_list_columns.template.js +1 -1
  227. package/dist/template/implementations/view_search_input.template.d.ts +2 -2
  228. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
  229. package/dist/template/implementations/view_search_input.template.js +1 -1
  230. package/dist/template/index.d.ts +4 -2
  231. package/dist/template/index.d.ts.map +1 -1
  232. package/dist/template/index.js +5 -3
  233. package/dist/template/template-manager.d.ts +56 -0
  234. package/dist/template/template-manager.d.ts.map +1 -0
  235. package/dist/template/template-manager.js +125 -0
  236. package/dist/template/template-types.d.ts +16 -0
  237. package/dist/template/template-types.d.ts.map +1 -0
  238. package/dist/template/template-types.js +7 -0
  239. package/dist/template/template.d.ts +12 -2
  240. package/dist/template/template.d.ts.map +1 -1
  241. package/dist/template/template.js +19 -6
  242. package/dist/template/zod-converter.d.ts +40 -7
  243. package/dist/template/zod-converter.d.ts.map +1 -1
  244. package/dist/template/zod-converter.js +386 -58
  245. package/dist/testing/_relation-graph.d.ts +1 -1
  246. package/dist/testing/_relation-graph.d.ts.map +1 -1
  247. package/dist/testing/_relation-graph.js +12 -3
  248. package/dist/testing/fixture-manager.d.ts +42 -11
  249. package/dist/testing/fixture-manager.d.ts.map +1 -1
  250. package/dist/testing/fixture-manager.js +338 -236
  251. package/dist/types/types.d.ts +709 -104
  252. package/dist/types/types.d.ts.map +1 -1
  253. package/dist/types/types.js +309 -52
  254. package/dist/typings/knex.d.js +2 -2
  255. package/dist/utils/async-utils.d.ts.map +1 -1
  256. package/dist/utils/async-utils.js +3 -3
  257. package/dist/utils/console-util.js +1 -1
  258. package/dist/utils/controller.d.ts +1 -0
  259. package/dist/utils/controller.d.ts.map +1 -1
  260. package/dist/utils/controller.js +4 -1
  261. package/dist/utils/esm-utils.d.ts +0 -6
  262. package/dist/utils/esm-utils.d.ts.map +1 -1
  263. package/dist/utils/esm-utils.js +2 -9
  264. package/dist/utils/formatter.d.ts +3 -0
  265. package/dist/utils/formatter.d.ts.map +1 -0
  266. package/dist/utils/formatter.js +110 -0
  267. package/dist/utils/fs-utils.d.ts +1 -1
  268. package/dist/utils/fs-utils.d.ts.map +1 -1
  269. package/dist/utils/fs-utils.js +1 -1
  270. package/dist/utils/lodash-able.d.ts.map +1 -1
  271. package/dist/utils/lodash-able.js +1 -1
  272. package/dist/utils/object-utils.d.ts +44 -0
  273. package/dist/utils/object-utils.d.ts.map +1 -0
  274. package/dist/utils/object-utils.js +191 -0
  275. package/dist/utils/path-utils.d.ts +1 -1
  276. package/dist/utils/path-utils.d.ts.map +1 -1
  277. package/dist/utils/path-utils.js +3 -3
  278. package/dist/utils/process-utils.js +1 -1
  279. package/dist/utils/sql-parser.d.ts +5 -1
  280. package/dist/utils/sql-parser.d.ts.map +1 -1
  281. package/dist/utils/sql-parser.js +14 -3
  282. package/dist/utils/type-utils.d.ts +23 -0
  283. package/dist/utils/type-utils.d.ts.map +1 -0
  284. package/dist/utils/type-utils.js +45 -0
  285. package/dist/utils/utils.d.ts +7 -1
  286. package/dist/utils/utils.d.ts.map +1 -1
  287. package/dist/utils/utils.js +44 -5
  288. package/dist/utils/zod-error.d.ts +1 -1
  289. package/dist/utils/zod-error.d.ts.map +1 -1
  290. package/dist/utils/zod-error.js +1 -1
  291. package/package.json +55 -30
  292. package/src/ai/agents/agent.ts +87 -0
  293. package/src/ai/agents/index.ts +2 -0
  294. package/src/ai/agents/types.ts +47 -0
  295. package/src/ai/index.ts +1 -0
  296. package/src/ai/providers/rtzr/api.ts +37 -0
  297. package/src/ai/providers/rtzr/error.ts +34 -0
  298. package/src/ai/providers/rtzr/index.ts +4 -0
  299. package/src/ai/providers/rtzr/model.ts +201 -0
  300. package/src/ai/providers/rtzr/options.ts +49 -0
  301. package/src/ai/providers/rtzr/provider.ts +91 -0
  302. package/src/ai/providers/rtzr/utils.ts +127 -0
  303. package/src/api/base-frame.ts +4 -2
  304. package/src/api/caster.ts +17 -23
  305. package/src/api/code-converters.ts +176 -533
  306. package/src/api/config.ts +39 -56
  307. package/src/api/context.ts +7 -18
  308. package/src/api/decorators.ts +175 -46
  309. package/src/api/index.ts +2 -2
  310. package/src/api/sonamu.ts +133 -124
  311. package/src/api/validator.ts +83 -0
  312. package/src/bin/build-config.ts +7 -1
  313. package/src/bin/cli.ts +192 -110
  314. package/src/bin/loader-register.ts +38 -0
  315. package/src/database/_batch_update.ts +46 -31
  316. package/src/database/base-model.ts +390 -182
  317. package/src/database/base-model.types.ts +155 -0
  318. package/src/database/code-generator.ts +13 -32
  319. package/src/database/db.ts +36 -50
  320. package/src/database/puri-subset.test-d.ts +471 -0
  321. package/src/database/puri-subset.types.ts +195 -0
  322. package/src/database/puri-wrapper.ts +58 -67
  323. package/src/database/puri.ts +182 -126
  324. package/src/database/puri.types.ts +64 -31
  325. package/src/database/transaction-context.ts +1 -1
  326. package/src/database/upsert-builder.ts +261 -132
  327. package/src/entity/entity-manager.ts +36 -28
  328. package/src/entity/entity.ts +330 -249
  329. package/src/exceptions/error-handler.ts +3 -3
  330. package/src/exceptions/so-exceptions.ts +11 -11
  331. package/src/file-storage/driver.ts +5 -5
  332. package/src/file-storage/file-storage.ts +2 -2
  333. package/src/index.ts +18 -12
  334. package/src/migration/code-generation.ts +185 -172
  335. package/src/migration/migration-set.ts +80 -293
  336. package/src/migration/migrator.ts +182 -425
  337. package/src/migration/mysql-schema-reader.ts.txt +272 -0
  338. package/src/migration/postgresql-schema-reader.ts +310 -0
  339. package/src/migration/types.ts +6 -39
  340. package/src/naite/messaging-types.ts +51 -0
  341. package/src/naite/naite-reporter.ts +128 -0
  342. package/src/naite/naite.ts +378 -33
  343. package/src/shared/web.shared.ts.txt +20 -24
  344. package/src/stream/sse.ts +5 -5
  345. package/src/syncer/api-parser.ts +52 -69
  346. package/src/syncer/checksum.ts +25 -37
  347. package/src/syncer/code-generator.ts +58 -62
  348. package/src/syncer/entity-operations.ts +12 -15
  349. package/src/syncer/file-patterns.ts +2 -2
  350. package/src/syncer/index.ts +4 -4
  351. package/src/syncer/module-loader.ts +28 -25
  352. package/src/syncer/syncer.ts +155 -162
  353. package/src/template/entity-converter.ts +18 -27
  354. package/src/template/helpers.ts +8 -11
  355. package/src/template/implementations/entity.template.ts +6 -6
  356. package/src/template/implementations/generated.template.ts +99 -99
  357. package/src/template/implementations/generated_http.template.ts +21 -54
  358. package/src/template/implementations/generated_sso.template.ts +78 -65
  359. package/src/template/implementations/init_types.template.ts +4 -6
  360. package/src/template/implementations/model.template.ts +47 -38
  361. package/src/template/implementations/model_test.template.ts +3 -3
  362. package/src/template/implementations/service.template.ts +56 -80
  363. package/src/template/implementations/view_enums_buttonset.template.ts +2 -2
  364. package/src/template/implementations/view_enums_dropdown.template.ts +4 -4
  365. package/src/template/implementations/view_enums_select.template.ts +3 -3
  366. package/src/template/implementations/view_form.template.ts +34 -75
  367. package/src/template/implementations/view_id_all_select.template.ts +2 -2
  368. package/src/template/implementations/view_id_async_select.template.ts +9 -23
  369. package/src/template/implementations/view_list.template.ts +54 -95
  370. package/src/template/implementations/view_list_columns.template.ts +4 -10
  371. package/src/template/implementations/view_search_input.template.ts +2 -2
  372. package/src/template/index.ts +4 -2
  373. package/src/template/template-manager.ts +166 -0
  374. package/src/template/template-types.ts +16 -0
  375. package/src/template/template.ts +29 -10
  376. package/src/template/zod-converter.ts +459 -101
  377. package/src/testing/_relation-graph.ts +18 -11
  378. package/src/testing/fixture-manager.ts +468 -362
  379. package/src/types/types.ts +516 -248
  380. package/src/typings/knex.d.ts +7 -9
  381. package/src/utils/async-utils.ts +8 -12
  382. package/src/utils/console-util.ts +1 -1
  383. package/src/utils/controller.ts +3 -0
  384. package/src/utils/esm-utils.ts +8 -18
  385. package/src/utils/formatter.ts +109 -0
  386. package/src/utils/fs-utils.ts +1 -1
  387. package/src/utils/lodash-able.ts +1 -4
  388. package/src/utils/object-utils.ts +217 -0
  389. package/src/utils/path-utils.ts +3 -6
  390. package/src/utils/process-utils.ts +1 -1
  391. package/src/utils/sql-parser.ts +23 -5
  392. package/src/utils/type-utils.ts +83 -0
  393. package/src/utils/utils.ts +58 -9
  394. package/src/utils/zod-error.ts +3 -3
  395. package/dist/bin/cli-wrapper.d.ts +0 -3
  396. package/dist/bin/cli-wrapper.d.ts.map +0 -1
  397. package/dist/bin/cli-wrapper.js +0 -72
  398. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
  399. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
  400. package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -39
  401. package/dist/entity/entity-utils.d.ts +0 -61
  402. package/dist/entity/entity-utils.d.ts.map +0 -1
  403. package/dist/entity/entity-utils.js +0 -210
  404. package/src/bin/cli-wrapper.ts +0 -82
  405. package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
  406. package/src/entity/entity-utils.ts +0 -291
@@ -1,108 +1,59 @@
1
+ /**
2
+ * code-converters는 API 타입 정의들을 Zod 객체나 TypeScript 코드로 변환하는 함수들을 제공합니다.
3
+ *
4
+ * 1. API 시리즈들:
5
+ * - ExtendedApi, ApiParam, ApiParamType
6
+ * - API 메타데이터를 표현하는 타입 정의들
7
+ *
8
+ * 2. ZodObject 변환
9
+ * - API 타입 정의 → Zod 타입 인스턴스 (런타임 밸리데이션용)
10
+ * - getZodTypeFromApiParamType → getZodObjectFromApiParams → getZodObjectFromApi
11
+ *
12
+ * 3. TsTypeDef 변환
13
+ * - API 타입 정의 → TypeScript 타입 코드 문자열 (코드 생성용)
14
+ * - apiParamTypeToTsType → apiParamToTsCode, apiParamToTsCodeAsObject
15
+ *
16
+ * 참고:
17
+ * - ZodTypeDef 생성 (Zod 코드 문자열): zod-converter.ts의 zodTypeToZodCode 사용
18
+ * - EntityProp 변환: zod-converter.ts 참조
19
+ */
20
+
1
21
  import { z } from "zod";
2
- import type { $ZodLooseShape } from "zod/v4/core"
3
- import {
4
- ApiParam,
5
- ApiParamType,
6
- EntityProp,
7
- EntityPropNode,
8
- TextProp,
9
- isBelongsToOneRelationProp,
10
- isBigIntegerProp,
11
- isBooleanProp,
12
- isDateProp,
13
- isDateTimeProp,
14
- isDecimalProp,
15
- isDoubleProp,
16
- isEnumProp,
17
- isFloatProp,
18
- isIntegerProp,
19
- isJsonProp,
20
- isOneToOneRelationProp,
21
- isRelationProp,
22
- isStringProp,
23
- isTextProp,
24
- isTimeProp,
25
- isTimestampProp,
26
- isUuidProp,
27
- isVirtualProp,
28
- } from "../types/types";
29
- import { ExtendedApi } from "./decorators";
30
22
  import type { core } from "zod/v4";
23
+ import type { $ZodLooseShape } from "zod/v4/core";
24
+ import { type ApiParam, ApiParamType } from "../types/types";
25
+ import type { ExtendedApi } from "./decorators";
31
26
 
32
27
  // <any>를 자제하고, Zod에서 제약하는 기본적인 Generic Type Parameter를 사용함.
33
- type AnyZodRecord = z.ZodRecord<z.ZodString | z.ZodNumber | z.ZodSymbol, z.ZodType>;
34
28
  type AnyZodObject = z.ZodObject<$ZodLooseShape>;
35
- type AnyZodArray = z.ZodArray<z.ZodType>;
36
- type AnyZodNullable = z.ZodNullable<z.ZodType>;
37
- type AnyZodOptional = z.ZodOptional<z.ZodType>;
38
- type AnyZodDefault = z.ZodDefault<z.ZodType>;
39
29
  type AnyZodLiteral = z.ZodLiteral<core.util.Literal>;
40
- type AnyZodUnion = z.ZodUnion<z.ZodType[]>;
41
30
 
42
- /*
43
- ExtendedApi 에서 ZodObject 리턴
44
- */
45
- export function getZodObjectFromApi(
46
- api: ExtendedApi,
47
- references: {
48
- [id: string]: AnyZodObject;
49
- } = {}
50
- ) {
51
- if (api.typeParameters?.length > 0) {
52
- api.typeParameters.map((typeParam) => {
53
- if (typeParam.constraint) {
54
- let zodType = getZodTypeFromApiParamType(
55
- typeParam.constraint,
56
- references
57
- );
58
- (references[typeParam.id] as any) = zodType;
59
- }
60
- });
31
+ /**
32
+ * Promise 타입을 한 번 언래핑하여 내부 타입을 반환합니다.
33
+ * Promise가 아닌 경우 원본 타입을 그대로 반환합니다.
34
+ */
35
+ export function unwrapPromiseOnce(paramType: ApiParamType) {
36
+ if (ApiParamType.isPromise(paramType)) {
37
+ return paramType.args?.[0];
38
+ } else {
39
+ return paramType;
61
40
  }
62
-
63
- const ReqType = getZodObjectFromApiParams(
64
- api.parameters.filter(
65
- (param) =>
66
- !ApiParamType.isContext(param.type) &&
67
- !ApiParamType.isRefKnex(param.type) &&
68
- !(param.optional === true && param.name.startsWith("_")) // _로 시작하는 파라미터는 제외
69
- ),
70
- references
71
- );
72
- return ReqType;
73
41
  }
74
42
 
75
43
  /*
76
- ZodObject통해 ApiParam 리턴
77
- */
78
- export function getZodObjectFromApiParams(
79
- apiParams: ApiParam[],
80
- references: {
81
- [id: string]: AnyZodObject;
82
- } = {}
83
- ): z.ZodObject {
84
- return z.object(
85
- apiParams.reduce((r, param) => {
86
- let zodType = getZodTypeFromApiParamType(param.type, references);
87
- if (param.optional) {
88
- zodType = zodType.optional();
89
- }
90
- return {
91
- ...r,
92
- [param.name]: zodType,
93
- };
94
- }, {})
95
- );
96
- }
44
+ * API구성하는 요소들을 ZodObject로 변환하기 위한 함수들입니다.
45
+ */
97
46
 
98
- /*
99
- ApiParamType으로 ZodType 컨버팅
100
- */
47
+ /**
48
+ * ApiParamType Zod 타입 인스턴스로 변환합니다.
49
+ * string, number, array, union 등 모든 ApiParamType을 처리하며,
50
+ * 순환참조가 발생하는 경우 z.unknown()으로 fallback합니다.
51
+ */
101
52
  export function getZodTypeFromApiParamType(
102
53
  paramType: ApiParamType,
103
54
  references: {
104
55
  [id: string]: AnyZodObject;
105
- }
56
+ },
106
57
  ): z.ZodType<unknown> {
107
58
  switch (paramType) {
108
59
  case "string":
@@ -111,58 +62,52 @@ export function getZodTypeFromApiParamType(
111
62
  return z.number();
112
63
  case "boolean":
113
64
  return z.boolean();
114
- default:
115
- const advType = paramType as { t: string };
65
+ default: {
66
+ const advType = paramType as { t: string; value?: string | number };
116
67
  switch (advType.t) {
117
68
  case "string-literal":
118
69
  case "numeric-literal":
119
- return z.literal((advType as any).value);
120
- case "object":
70
+ return z.literal(advType.value);
71
+ case "object": {
121
72
  const objType = paramType as { t: string; props: ApiParam[] };
122
73
  return getZodObjectFromApiParams(objType.props);
123
- case "array":
74
+ }
75
+ case "array": {
124
76
  const arrType = paramType as {
125
77
  t: string;
126
78
  elementsType: ApiParamType;
127
79
  };
128
- return z.array(
129
- getZodTypeFromApiParamType(arrType.elementsType, references)
130
- );
131
- case "ref":
80
+ return z.array(getZodTypeFromApiParamType(arrType.elementsType, references));
81
+ }
82
+ case "ref": {
132
83
  const refType = paramType as {
133
84
  t: string;
134
85
  id: string;
135
86
  args?: ApiParamType[];
136
87
  };
137
-
138
88
  // Date 타입 처리
139
89
  if (refType.id === "Date") {
140
90
  return z.date();
141
91
  }
142
-
143
92
  // 객체 키 관리 유틸리티
144
93
  if (["Pick", "Omit"].includes(refType.id)) {
145
94
  if (refType.args?.length !== 2) {
146
95
  throw new Error(`잘못된 ${refType.id}`);
147
96
  }
148
- const [obj, literalOrUnion] = refType.args!.map((arg) =>
149
- getZodTypeFromApiParamType(arg, references)
97
+ const [obj, literalOrUnion] = refType.args.map(
98
+ (arg) => getZodTypeFromApiParamType(arg, references),
99
+ // biome-ignore lint/suspicious/noExplicitAny: 생성되는 ZodUnion의 타입을 추적하기 어려움
150
100
  ) as [AnyZodObject, z.ZodUnion<any> | AnyZodLiteral];
101
+
151
102
  let keys: string[] = [];
152
103
  if (literalOrUnion instanceof z.ZodUnion) {
153
104
  keys = literalOrUnion.def.options.map(
154
- (option: { def: { value: string } }) => option.def.value
105
+ (option: { def: { values: string[] } }) => option.def.values[0],
155
106
  );
156
107
  } else {
157
108
  keys = (literalOrUnion as z.ZodLiteral<string>).def.values;
158
109
  }
159
- const keyRecord = keys.reduce((result, key) => {
160
- return {
161
- ...result,
162
- [key]: true,
163
- };
164
- }, {} as any);
165
-
110
+ const keyRecord = Object.fromEntries(keys.map((key) => [key, true as const]));
166
111
  if (refType.id === "Pick") {
167
112
  if (obj.pick) {
168
113
  return obj.pick(keyRecord);
@@ -178,303 +123,130 @@ export function getZodTypeFromApiParamType(
178
123
  throw new Error(`잘못된 ${refType.id}`);
179
124
  }
180
125
  const obj = getZodTypeFromApiParamType(refType.args[0], references);
181
- return (obj as any).partial();
126
+ // biome-ignore lint/suspicious/noExplicitAny: Partial 인수 타입 캐스팅
127
+ return (obj as z.ZodObject<any>).partial();
182
128
  }
183
-
184
129
  const reference = references[refType.id];
185
130
  if (reference === undefined) {
186
- return z.string();
131
+ return z.unknown();
187
132
  // throw new Error(`ref 참조 불가 ${refType.id}`);
188
133
  }
189
134
  return reference;
190
- case "union":
135
+ }
136
+ case "union": {
191
137
  const unionType = paramType as {
192
138
  t: string;
193
139
  types: ApiParamType[];
194
140
  };
195
141
  // nullable 유니온
196
- if (
197
- unionType.types.length === 2 &&
198
- unionType.types.some((type) => type === "null")
199
- ) {
142
+ if (unionType.types.length === 2 && unionType.types.some((type) => type === "null")) {
200
143
  if (unionType.types[0] === "null") {
201
- return getZodTypeFromApiParamType(
202
- unionType.types[1],
203
- references
204
- ).nullable();
144
+ return getZodTypeFromApiParamType(unionType.types[1], references).nullable();
205
145
  } else {
206
- return getZodTypeFromApiParamType(
207
- unionType.types[0],
208
- references
209
- ).nullable();
146
+ return getZodTypeFromApiParamType(unionType.types[0], references).nullable();
210
147
  }
211
148
  }
212
-
213
149
  // 일반 유니온
214
150
  return z.union(
215
- unionType.types.map((type) =>
216
- getZodTypeFromApiParamType(type, references)
217
- ) as any
151
+ unionType.types.map((type) => getZodTypeFromApiParamType(type, references)),
218
152
  );
219
- case "intersection":
153
+ }
154
+ case "intersection": {
220
155
  const intersectionType = paramType as {
221
156
  t: string;
222
157
  types: ApiParamType[];
223
158
  };
224
- return intersectionType.types.reduce((result, type, index) => {
225
- const resolvedType = getZodTypeFromApiParamType(type, references);
226
- if (index === 0) {
227
- return resolvedType;
228
- } else {
229
- return z.intersection(result as any, resolvedType);
230
- }
231
- }, z.unknown() as any) as any;
232
- case "tuple-type":
159
+ return intersectionType.types.reduce(
160
+ (result, type, index) => {
161
+ const resolvedType = getZodTypeFromApiParamType(type, references);
162
+ if (index === 0) {
163
+ return resolvedType;
164
+ } else {
165
+ return z.intersection(result, resolvedType);
166
+ }
167
+ },
168
+ z.unknown() as z.ZodType<unknown>,
169
+ );
170
+ }
171
+ case "tuple-type": {
233
172
  const tupleType = paramType as ApiParamType.TupleType;
234
173
  return z.tuple(
235
- tupleType.elements.map((elem) =>
236
- getZodTypeFromApiParamType(elem, references)
237
- ) as any
174
+ // biome-ignore lint/suspicious/noExplicitAny: 생성되는 ZodTuple의 타입을 추적하기 어려움
175
+ tupleType.elements.map((elem) => getZodTypeFromApiParamType(elem, references)) as any,
238
176
  );
177
+ }
239
178
  }
240
179
  return z.unknown();
241
- }
242
- }
243
-
244
- export function propNodeToZodTypeDef(
245
- propNode: EntityPropNode,
246
- injectImportKeys: string[]
247
- ): string {
248
- if (propNode.nodeType === "plain") {
249
- return propToZodTypeDef(propNode.prop, injectImportKeys);
250
- } else if (propNode.nodeType === "array") {
251
- return [
252
- propNode.prop ? `${propNode.prop.name}: ` : "",
253
- "z.array(z.object({",
254
- propNode.children
255
- .map((childPropNode) =>
256
- propNodeToZodTypeDef(childPropNode, injectImportKeys)
257
- )
258
- .join("\n"),
259
- "",
260
- "})),",
261
- ].join("\n");
262
- } else if (propNode.nodeType === "object") {
263
- return [
264
- propNode.prop ? `${propNode.prop.name}: ` : "",
265
- "z.object({",
266
- propNode.children
267
- .map((childPropNode) =>
268
- propNodeToZodTypeDef(childPropNode, injectImportKeys)
269
- )
270
- .join("\n"),
271
- "",
272
- `})${propNode.prop && propNode.prop.nullable ? ".nullable()" : ""},`,
273
- ].join("\n");
274
- } else {
275
- throw Error;
276
- }
277
- }
278
-
279
- export function getTextTypeLength(textType: TextProp["textType"]): number {
280
- switch (textType) {
281
- case "text":
282
- return 1024 * 64 - 1;
283
- case "mediumtext":
284
- return 1024 * 1024 * 16 - 1;
285
- case "longtext":
286
- return 1024 * 1024 * 1024 * 4 - 1;
287
- }
288
- }
289
-
290
- export function propToZodTypeDef(
291
- prop: EntityProp,
292
- injectImportKeys: string[]
293
- ): string {
294
- let stmt: string;
295
- if (isIntegerProp(prop)) {
296
- stmt = `${prop.name}: z.int()`;
297
- } else if (isBigIntegerProp(prop)) {
298
- stmt = `${prop.name}: z.bigint()`;
299
- } else if (isTextProp(prop)) {
300
- stmt = `${prop.name}: z.string().max(${getTextTypeLength(prop.textType)})`;
301
- } else if (isEnumProp(prop)) {
302
- stmt = `${prop.name}: ${prop.id}`;
303
- injectImportKeys.push(prop.id);
304
- } else if (isStringProp(prop)) {
305
- stmt = `${prop.name}: z.string().max(${prop.length})`;
306
- } else if (isDecimalProp(prop)) {
307
- stmt = `${prop.name}: z.string()`;
308
- } else if (isFloatProp(prop) || isDoubleProp(prop)) {
309
- stmt = `${prop.name}: z.number()`;
310
- } else if (isBooleanProp(prop)) {
311
- stmt = `${prop.name}: z.boolean()`;
312
- } else if (isDateProp(prop)) {
313
- stmt = `${prop.name}: z.string().length(10)`;
314
- } else if (isTimeProp(prop)) {
315
- stmt = `${prop.name}: z.string().length(8)`;
316
- } else if (isDateTimeProp(prop)) {
317
- stmt = `${prop.name}: z.date()`;
318
- } else if (isTimestampProp(prop)) {
319
- stmt = `${prop.name}: z.date()`;
320
- } else if (isJsonProp(prop)) {
321
- stmt = `${prop.name}: ${prop.id}`;
322
- injectImportKeys.push(prop.id);
323
- } else if (isUuidProp(prop)) {
324
- stmt = `${prop.name}: z.uuid()`;
325
- } else if (isVirtualProp(prop)) {
326
- stmt = `${prop.name}: ${prop.id}`;
327
- injectImportKeys.push(prop.id);
328
- } else if (isRelationProp(prop)) {
329
- if (
330
- isBelongsToOneRelationProp(prop) ||
331
- (isOneToOneRelationProp(prop) && prop.hasJoinColumn)
332
- ) {
333
- stmt = `${prop.name}_id: z.int()`;
334
- } else {
335
- // 그외 relation 케이스 제외
336
- return `// ${prop.name}: ${prop.relationType} ${prop.with}`;
337
180
  }
338
- } else {
339
- return "// unable to resolve";
340
- }
341
-
342
- if ((prop as { unsigned?: boolean }).unsigned) {
343
- stmt += ".nonnegative()";
344
181
  }
345
- if (prop.nullable) {
346
- stmt += ".nullable()";
347
- }
348
-
349
- return stmt + ",";
350
182
  }
351
183
 
352
- // TODO(Haze, 251031): "template_literal", "file"에 대한 지원이 필요함.
353
- export function zodTypeToZodCode(zt: z.ZodType): string {
354
- switch (zt.def.type) {
355
- case "string":
356
- return "z.string()";
357
- case "number":
358
- return "z.number()";
359
- case "bigint":
360
- return "z.bigint()";
361
- case "boolean":
362
- return "z.boolean()";
363
- case "date":
364
- return "z.date()";
365
- case "null":
366
- return "z.null()";
367
- case "undefined":
368
- return "z.undefined()";
369
- case "any":
370
- return "z.any()";
371
- case "unknown":
372
- return "z.unknown()";
373
- case "never":
374
- return "z.never()";
375
- case "nullable":
376
- return zodTypeToZodCode((zt as AnyZodNullable).def.innerType) + ".nullable()";
377
- case "default":
378
- const zDefaultDef = (zt as AnyZodDefault).def;
379
- return (
380
- zodTypeToZodCode(zDefaultDef.innerType) +
381
- `.default(${zDefaultDef.defaultValue})`
382
- );
383
- case "record":
384
- const zRecordDef = (zt as AnyZodRecord).def;
385
- return `z.record(${zodTypeToZodCode(zRecordDef.keyType)}, ${zodTypeToZodCode(
386
- zRecordDef.valueType
387
- )})`;
388
- case "literal":
389
- const items = Array.from((zt as z.ZodLiteral<any>).values).map(value => {
390
- if (typeof value === "string") {
391
- return `"${value}"`;
392
- }
393
-
394
- if (value === null) {
395
- return `null`;
396
- }
397
-
398
- if (value === undefined) {
399
- return `undefined`;
184
+ /**
185
+ * ApiParam 배열을 ZodObject로 변환합니다.
186
+ * 각 파라미터의 optional 여부를 반영하여 Zod 스키마를 생성합니다.
187
+ */
188
+ export function getZodObjectFromApiParams(
189
+ apiParams: ApiParam[],
190
+ references: {
191
+ [id: string]: AnyZodObject;
192
+ } = {},
193
+ ): z.ZodObject {
194
+ return z.object(
195
+ Object.fromEntries(
196
+ apiParams.map((param) => {
197
+ let zodType = getZodTypeFromApiParamType(param.type, references);
198
+ if (param.optional) {
199
+ zodType = zodType.optional();
400
200
  }
201
+ return [param.name, zodType];
202
+ }),
203
+ ),
204
+ );
205
+ }
401
206
 
402
- return `${value}`;
403
- });
404
-
405
- if (items.length === 1) {
406
- return `z.literal(${items[0]})`;
207
+ /**
208
+ * ExtendedApi를 ZodObject로 변환합니다.
209
+ * TypeParameter와 일반 파라미터를 처리하며,
210
+ * Context, RefKnex, _로 시작하는 optional 파라미터는 제외합니다.
211
+ */
212
+ export function getZodObjectFromApi(
213
+ api: ExtendedApi,
214
+ references: {
215
+ [id: string]: AnyZodObject;
216
+ } = {},
217
+ ) {
218
+ if (api.typeParameters?.length > 0) {
219
+ for (const typeParam of api.typeParameters) {
220
+ if (typeParam.constraint) {
221
+ const zodType = getZodTypeFromApiParamType(typeParam.constraint, references);
222
+ // biome-ignore lint/suspicious/noExplicitAny: 레퍼런스 타입 캐스팅
223
+ (references[typeParam.id] as z.ZodType<any>) = zodType;
407
224
  }
408
- return `z.literal([${items.join(", ")}])`;
409
- case "union":
410
- return `z.union([${(zt as AnyZodUnion).def.options
411
- .map((option: z.ZodType) => zodTypeToZodCode(option))
412
- .join(",")}])`;
413
- case "enum":
414
- // NOTE: z.enum(["A", "B"])도 z.enum({ A: "A", B: "B" })로 처리됨.
415
- return `z.enum({${Object.entries((zt as z.ZodEnum).def.entries)
416
- .map(([key, val]) =>
417
- typeof val === "string" ? `${key}: "${val}"` : `${key}: ${val}`)
418
- .join(", ")}})`;
419
- case "array":
420
- return `z.array(${zodTypeToZodCode((zt as z.ZodArray<z.ZodType>).def.element)})`;
421
- case "object":
422
- const shape = (zt as any).shape;
423
- return [
424
- "z.object({",
425
- ...Object.keys(shape).map(
426
- (key) => `${key}: ${zodTypeToZodCode(shape[key])},`
427
- ),
428
- "})",
429
- ].join("\n");
430
- case "optional":
431
- return zodTypeToZodCode((zt as z.ZodOptional<z.ZodType>).def.innerType) + ".optional()";
432
- case "file":
433
- return `z.file()`;
434
- case "intersection":
435
- const zIntersectionDef = (zt as z.ZodIntersection<z.ZodType, z.ZodType>).def;
436
- return `z.intersection(${zodTypeToZodCode(zIntersectionDef.left)}, ${zodTypeToZodCode(zIntersectionDef.right)})`;
437
- case "file":
438
- return `z.file()`;
439
- default:
440
- throw new Error(`처리되지 않은 ZodType ${zt.def.type}`);
225
+ }
441
226
  }
442
- }
443
-
444
- export function apiParamToTsCode(
445
- params: ApiParam[],
446
- injectImportKeys: string[]
447
- ): string {
448
- return params
449
- .map((param) => {
450
- return `${param.name}${
451
- param.optional && !param.defaultDef ? "?" : ""
452
- }: ${apiParamTypeToTsType(param.type, injectImportKeys)}${
453
- param.defaultDef ? `= ${param.defaultDef}` : ""
454
- }`;
455
- })
456
- .join(", ");
457
- }
458
-
459
- export function apiParamToTsCodeAsObject(
460
- params: ApiParam[],
461
- injectImportKeys: string[]
462
- ): string {
463
- return `{ ${params
464
- .map(
227
+ const ReqType = getZodObjectFromApiParams(
228
+ // api parsing한 결과가 api params
229
+ api.parameters.filter(
465
230
  (param) =>
466
- `${param.name}${param.optional ? "?" : ""}: ${apiParamTypeToTsType(
467
- param.type,
468
- injectImportKeys
469
- )}${param.defaultDef ? `= ${param.defaultDef}` : ""}`
470
- )
471
- .join(", ")} }`;
231
+ !ApiParamType.isContext(param.type) &&
232
+ !ApiParamType.isRefKnex(param.type) &&
233
+ !(param.optional === true && param.name.startsWith("_")), // _로 시작하는 파라미터는 제외
234
+ ),
235
+ references,
236
+ );
237
+ return ReqType;
472
238
  }
473
239
 
474
- export function apiParamTypeToTsType(
475
- paramType: ApiParamType,
476
- injectImportKeys: string[]
477
- ): string {
240
+ /*
241
+ * API 타입 정의를 TypeScript 코드 문자열로 변환하기 위한 함수들입니다.
242
+ */
243
+
244
+ /**
245
+ * ApiParamType을 TypeScript 타입 문자열로 변환합니다.
246
+ * union, intersection, array, ref 등 모든 타입을 TS 문법으로 표현하며,
247
+ * import가 필요한 타입 ID는 injectImportKeys에 수집합니다.
248
+ */
249
+ export function apiParamTypeToTsType(paramType: ApiParamType, injectImportKeys: string[]): string {
478
250
  if (
479
251
  [
480
252
  "string",
@@ -497,22 +269,13 @@ export function apiParamTypeToTsType(
497
269
  } else if (ApiParamType.isNumericLiteral(paramType)) {
498
270
  return String(paramType.value);
499
271
  } else if (ApiParamType.isUnion(paramType)) {
500
- return paramType.types
501
- .map((type) => apiParamTypeToTsType(type, injectImportKeys))
502
- .join(" | ");
272
+ return paramType.types.map((type) => apiParamTypeToTsType(type, injectImportKeys)).join(" | ");
503
273
  } else if (ApiParamType.isIntersection(paramType)) {
504
- return paramType.types
505
- .map((type) => apiParamTypeToTsType(type, injectImportKeys))
506
- .join(" & ");
274
+ return paramType.types.map((type) => apiParamTypeToTsType(type, injectImportKeys)).join(" & ");
507
275
  } else if (ApiParamType.isArray(paramType)) {
508
- return (
509
- apiParamTypeToTsType(paramType.elementsType, injectImportKeys) + "[]"
510
- );
276
+ return `${apiParamTypeToTsType(paramType.elementsType, injectImportKeys)}[]`;
511
277
  } else if (ApiParamType.isRef(paramType)) {
512
- if (
513
- ["Pick", "Omit", "Promise", "Partial", "Date"].includes(paramType.id) ===
514
- false
515
- ) {
278
+ if (["Pick", "Omit", "Promise", "Partial", "Date"].includes(paramType.id) === false) {
516
279
  // importKeys 인젝션
517
280
  injectImportKeys.push(paramType.id);
518
281
  }
@@ -526,19 +289,14 @@ export function apiParamTypeToTsType(
526
289
  } else if (ApiParamType.isIndexedAccess(paramType)) {
527
290
  return `${apiParamTypeToTsType(
528
291
  paramType.object,
529
- injectImportKeys
292
+ injectImportKeys,
530
293
  )}[${apiParamTypeToTsType(paramType.index, injectImportKeys)}]`;
531
294
  } else if (ApiParamType.isTupleType(paramType)) {
532
- return `[ ${paramType.elements.map((elem) =>
533
- apiParamTypeToTsType(elem, injectImportKeys)
534
- )} ]`;
295
+ return `[ ${paramType.elements.map((elem) => apiParamTypeToTsType(elem, injectImportKeys))} ]`;
535
296
  } else if (ApiParamType.isTypeParam(paramType)) {
536
297
  return `<${paramType.id}${
537
298
  paramType.constraint
538
- ? ` extends ${apiParamTypeToTsType(
539
- paramType.constraint,
540
- injectImportKeys
541
- )}`
299
+ ? ` extends ${apiParamTypeToTsType(paramType.constraint, injectImportKeys)}`
542
300
  : ""
543
301
  }>`;
544
302
  } else {
@@ -546,149 +304,34 @@ export function apiParamTypeToTsType(
546
304
  }
547
305
  }
548
306
 
549
- export function unwrapPromiseOnce(paramType: ApiParamType) {
550
- if (ApiParamType.isPromise(paramType)) {
551
- return paramType.args![0];
552
- } else {
553
- return paramType;
554
- }
555
- }
556
-
557
- // TODO(Haze, 251031): "template_literal", "file"에 대한 지원이 필요함.
558
- export function serializeZodType(zt: z.ZodType): any {
559
- switch (zt.def.type) {
560
- case "object":
561
- return {
562
- type: "object",
563
- shape: Object.keys((zt as AnyZodObject).shape).reduce(
564
- (result, key) => {
565
- return {
566
- ...result,
567
- [key]: serializeZodType((zt as AnyZodObject).shape[key]),
568
- };
569
- },
570
- {}
571
- ),
572
- };
573
- case "array":
574
- return {
575
- type: "array",
576
- element: serializeZodType((zt as AnyZodArray).def.element),
577
- };
578
- case "enum":
579
- return {
580
- type: "enum",
581
- values: (zt as z.ZodEnum).def.entries,
582
- };
583
- case "string":
584
- return {
585
- type: "string",
586
- checks: zt.def.checks,
587
- };
588
- case "number":
589
- return {
590
- type: "number",
591
- checks: zt.def.checks,
592
- };
593
- case "boolean":
594
- return {
595
- type: "boolean",
596
- };
597
- case "nullable":
598
- return {
599
- ...serializeZodType((zt as AnyZodNullable).def.innerType),
600
- nullable: true,
601
- };
602
- case "optional":
603
- return {
604
- ...serializeZodType((zt as AnyZodOptional).def.innerType),
605
- optional: true,
606
- };
607
- case "any":
608
- return {
609
- type: "any",
610
- };
611
- case "record":
612
- return {
613
- type: "record",
614
- keyType: serializeZodType((zt as AnyZodRecord).def.keyType),
615
- valueType: serializeZodType((zt as AnyZodRecord).def.valueType),
616
- };
617
- case "union":
618
- return {
619
- type: "union",
620
- options: (zt.def as AnyZodUnion).options.map((option) =>
621
- serializeZodType(option)
622
- ),
623
- };
624
- default:
625
- throw new Error(
626
- `Serialize 로직이 정의되지 않은 ZodType: ${zt.def.type}`
627
- );
628
- }
307
+ /**
308
+ * ApiParam 배열을 TypeScript 함수 파라미터 코드로 변환합니다.
309
+ * 예: "name: string, age?: number, active: boolean = true"
310
+ */
311
+ export function apiParamToTsCode(params: ApiParam[], injectImportKeys: string[]): string {
312
+ return params
313
+ .map((param) => {
314
+ return `${param.name}${
315
+ param.optional && !param.defaultDef ? "?" : ""
316
+ }: ${apiParamTypeToTsType(param.type, injectImportKeys)}${
317
+ param.defaultDef ? `= ${param.defaultDef}` : ""
318
+ }`;
319
+ })
320
+ .join(", ");
629
321
  }
630
322
 
631
- // TODO(Haze, 251031): "template_literal", "file"에 대한 지원이 필요함.
632
- export function zodTypeToTsTypeDef(zt: z.ZodType): string {
633
- switch (zt.def.type) {
634
- case "string":
635
- case "number":
636
- case "boolean":
637
- case "bigint":
638
- case "date":
639
- case "null":
640
- case "undefined":
641
- case "any":
642
- case "unknown":
643
- case "never":
644
- return zt.def.type;
645
- case "nullable":
646
- return zodTypeToTsTypeDef((zt as AnyZodNullable).def.innerType) + " | null";
647
- case "default":
648
- return zodTypeToTsTypeDef((zt as AnyZodDefault).def.innerType);
649
- case "record":
650
- const recordType = zt as AnyZodRecord;
651
- return `{ [ key: ${zodTypeToTsTypeDef(recordType.def.keyType)} ]: ${zodTypeToTsTypeDef(recordType.def.valueType)}}`;
652
- case "literal":
653
- return Array.from((zt as z.ZodLiteral).values).map(value => {
654
- if (typeof value === "string") {
655
- return `"${value}"`;
656
- }
657
-
658
- if (value === null) {
659
- return `null`;
660
- }
661
-
662
- if (value === undefined) {
663
- return `undefined`;
664
- }
665
-
666
- return `${value}`;
667
- }).join(" | ")
668
- case "union":
669
- return `${(zt as AnyZodUnion).options
670
- .map((option) => zodTypeToTsTypeDef(option))
671
- .join(" | ")}`;
672
- case "enum":
673
- return `${(zt as z.ZodEnum).options.map((val) => `"${val}"`).join(" | ")}`;
674
- case "array":
675
- return `${zodTypeToTsTypeDef((zt as AnyZodArray).element)}[]`;
676
- case "object":
677
- const shape = (zt as AnyZodObject).shape;
678
- return [
679
- "{",
680
- ...Object.keys(shape).map((key) => {
681
- if (shape[key].def.type === "optional") {
682
- return `${key}?: ${zodTypeToTsTypeDef(shape[key].def.innerType)},`;
683
- } else {
684
- return `${key}: ${zodTypeToTsTypeDef(shape[key])},`;
685
- }
686
- }),
687
- "}",
688
- ].join("\n");
689
- case "optional":
690
- return zodTypeToTsTypeDef((zt as AnyZodOptional).def.innerType) + " | undefined";
691
- default:
692
- throw new Error(`처리되지 않은 ZodType ${zt.def.type}`);
693
- }
323
+ /**
324
+ * ApiParam 배열을 TypeScript 객체 타입 코드로 변환합니다.
325
+ * 예: "{ name: string, age?: number, active: boolean = true }"
326
+ */
327
+ export function apiParamToTsCodeAsObject(params: ApiParam[], injectImportKeys: string[]): string {
328
+ return `{ ${params
329
+ .map(
330
+ (param) =>
331
+ `${param.name}${param.optional ? "?" : ""}: ${apiParamTypeToTsType(
332
+ param.type,
333
+ injectImportKeys,
334
+ )}${param.defaultDef ? `= ${param.defaultDef}` : ""}`,
335
+ )
336
+ .join(", ")} }`;
694
337
  }