sonamu 0.5.6 → 0.6.0

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 (365) hide show
  1. package/dist/api/base-frame.js +12 -2
  2. package/dist/api/caster.js +66 -2
  3. package/dist/api/code-converters.js +489 -2
  4. package/dist/api/config.d.ts +76 -0
  5. package/dist/api/config.d.ts.map +1 -0
  6. package/dist/api/config.js +32 -0
  7. package/dist/api/context.d.ts +1 -0
  8. package/dist/api/context.d.ts.map +1 -1
  9. package/dist/api/context.js +3 -2
  10. package/dist/api/decorators.d.ts +1 -0
  11. package/dist/api/decorators.d.ts.map +1 -1
  12. package/dist/api/decorators.js +142 -2
  13. package/dist/api/index.js +9 -2
  14. package/dist/api/sonamu.d.ts +8 -22
  15. package/dist/api/sonamu.d.ts.map +1 -1
  16. package/dist/api/sonamu.js +482 -2
  17. package/dist/bin/build-config.d.ts +2 -1
  18. package/dist/bin/build-config.d.ts.map +1 -1
  19. package/dist/bin/build-config.js +12 -2
  20. package/dist/bin/cli-wrapper.js +71 -2
  21. package/dist/bin/cli.js +418 -2
  22. package/dist/bin/hot-hook-register.d.ts +11 -0
  23. package/dist/bin/hot-hook-register.d.ts.map +1 -0
  24. package/dist/bin/hot-hook-register.js +21 -0
  25. package/dist/database/_batch_update.js +78 -2
  26. package/dist/database/base-model.js +247 -2
  27. package/dist/database/code-generator.js +53 -2
  28. package/dist/database/db.d.ts +5 -16
  29. package/dist/database/db.d.ts.map +1 -1
  30. package/dist/database/db.js +132 -2
  31. package/dist/database/knex-plugins/knex-on-duplicate-update.js +39 -2
  32. package/dist/database/puri-wrapper.d.ts +22 -10
  33. package/dist/database/puri-wrapper.d.ts.map +1 -1
  34. package/dist/database/puri-wrapper.js +109 -2
  35. package/dist/database/puri.d.ts +105 -73
  36. package/dist/database/puri.d.ts.map +1 -1
  37. package/dist/database/puri.js +539 -2
  38. package/dist/database/puri.types.d.ts +33 -42
  39. package/dist/database/puri.types.d.ts.map +1 -1
  40. package/dist/database/puri.types.js +3 -2
  41. package/dist/database/transaction-context.d.ts +3 -3
  42. package/dist/database/transaction-context.d.ts.map +1 -1
  43. package/dist/database/transaction-context.js +14 -2
  44. package/dist/database/upsert-builder.js +215 -2
  45. package/dist/entity/entity-manager.d.ts +3 -1
  46. package/dist/entity/entity-manager.d.ts.map +1 -1
  47. package/dist/entity/entity-manager.js +114 -2
  48. package/dist/entity/entity-utils.js +210 -2
  49. package/dist/entity/entity.d.ts.map +1 -1
  50. package/dist/entity/entity.js +651 -2
  51. package/dist/exceptions/error-handler.js +29 -2
  52. package/dist/exceptions/so-exceptions.js +85 -2
  53. package/dist/file-storage/driver.js +79 -2
  54. package/dist/file-storage/file-storage.js +75 -2
  55. package/dist/index.d.ts +2 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +28 -2
  58. package/dist/migration/code-generation.js +558 -2
  59. package/dist/migration/migration-set.js +364 -2
  60. package/dist/migration/migrator.d.ts +0 -9
  61. package/dist/migration/migrator.d.ts.map +1 -1
  62. package/dist/migration/migrator.js +510 -2
  63. package/dist/migration/types.js +3 -2
  64. package/dist/naite/naite.d.ts +12 -0
  65. package/dist/naite/naite.d.ts.map +1 -0
  66. package/dist/naite/naite.js +72 -0
  67. package/dist/stream/index.js +3 -2
  68. package/dist/stream/sse.js +38 -2
  69. package/dist/syncer/api-parser.d.ts +20 -0
  70. package/dist/syncer/api-parser.d.ts.map +1 -0
  71. package/dist/syncer/api-parser.js +229 -0
  72. package/dist/syncer/checksum.d.ts +21 -0
  73. package/dist/syncer/checksum.d.ts.map +1 -0
  74. package/dist/syncer/checksum.js +98 -0
  75. package/dist/syncer/code-generator.d.ts +20 -0
  76. package/dist/syncer/code-generator.d.ts.map +1 -0
  77. package/dist/syncer/code-generator.js +141 -0
  78. package/dist/syncer/entity-operations.d.ts +17 -0
  79. package/dist/syncer/entity-operations.d.ts.map +1 -0
  80. package/dist/syncer/entity-operations.js +58 -0
  81. package/dist/syncer/file-patterns.d.ts +29 -0
  82. package/dist/syncer/file-patterns.d.ts.map +1 -0
  83. package/dist/syncer/file-patterns.js +38 -0
  84. package/dist/syncer/index.d.ts +6 -0
  85. package/dist/syncer/index.d.ts.map +1 -1
  86. package/dist/syncer/index.js +9 -2
  87. package/dist/syncer/module-loader.d.ts +35 -0
  88. package/dist/syncer/module-loader.d.ts.map +1 -0
  89. package/dist/syncer/module-loader.js +82 -0
  90. package/dist/syncer/syncer.d.ts +93 -108
  91. package/dist/syncer/syncer.d.ts.map +1 -1
  92. package/dist/syncer/syncer.js +375 -2
  93. package/dist/template/entity-converter.d.ts +14 -0
  94. package/dist/template/entity-converter.d.ts.map +1 -0
  95. package/dist/template/entity-converter.js +101 -0
  96. package/dist/template/helpers.d.ts +23 -0
  97. package/dist/template/helpers.d.ts.map +1 -0
  98. package/dist/template/helpers.js +64 -0
  99. package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
  100. package/dist/template/implementations/entity.template.d.ts.map +1 -0
  101. package/dist/template/implementations/entity.template.js +87 -0
  102. package/dist/{templates → template/implementations}/generated.template.d.ts +3 -3
  103. package/dist/template/implementations/generated.template.d.ts.map +1 -0
  104. package/dist/template/implementations/generated.template.js +232 -0
  105. package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -3
  106. package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
  107. package/dist/template/implementations/generated_http.template.js +131 -0
  108. package/dist/{templates → template/implementations}/generated_sso.template.d.ts +3 -3
  109. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
  110. package/dist/template/implementations/generated_sso.template.js +105 -0
  111. package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
  112. package/dist/template/implementations/init_types.template.d.ts.map +1 -0
  113. package/dist/template/implementations/init_types.template.js +38 -0
  114. package/dist/template/implementations/model.template.d.ts +17 -0
  115. package/dist/template/implementations/model.template.d.ts.map +1 -0
  116. package/dist/template/implementations/model.template.js +171 -0
  117. package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
  118. package/dist/template/implementations/model_test.template.d.ts.map +1 -0
  119. package/dist/template/implementations/model_test.template.js +35 -0
  120. package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
  121. package/dist/template/implementations/service.template.d.ts.map +1 -0
  122. package/dist/template/implementations/service.template.js +193 -0
  123. package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
  124. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
  125. package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
  126. package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
  127. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
  128. package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
  129. package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
  130. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
  131. package/dist/template/implementations/view_enums_select.template.js +55 -0
  132. package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
  133. package/dist/template/implementations/view_form.template.d.ts.map +1 -0
  134. package/dist/template/implementations/view_form.template.js +337 -0
  135. package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
  136. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
  137. package/dist/template/implementations/view_id_all_select.template.js +31 -0
  138. package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
  139. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
  140. package/dist/template/implementations/view_id_async_select.template.js +105 -0
  141. package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
  142. package/dist/template/implementations/view_list.template.d.ts.map +1 -0
  143. package/dist/template/implementations/view_list.template.js +465 -0
  144. package/dist/{templates → template/implementations}/view_list_columns.template.d.ts +3 -3
  145. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
  146. package/dist/template/implementations/view_list_columns.template.js +49 -0
  147. package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
  148. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
  149. package/dist/template/implementations/view_search_input.template.js +64 -0
  150. package/dist/template/index.d.ts +5 -0
  151. package/dist/template/index.d.ts.map +1 -0
  152. package/dist/template/index.js +6 -0
  153. package/dist/template/template.d.ts +39 -0
  154. package/dist/template/template.d.ts.map +1 -0
  155. package/dist/template/template.js +47 -0
  156. package/dist/template/zod-converter.d.ts +18 -0
  157. package/dist/template/zod-converter.d.ts.map +1 -0
  158. package/dist/template/zod-converter.js +166 -0
  159. package/dist/testing/_relation-graph.js +80 -2
  160. package/dist/testing/fixture-manager.d.ts.map +1 -1
  161. package/dist/testing/fixture-manager.js +521 -2
  162. package/dist/types/types.d.ts +39 -40
  163. package/dist/types/types.d.ts.map +1 -1
  164. package/dist/types/types.js +289 -2
  165. package/dist/typings/knex.d.js +3 -2
  166. package/dist/utils/async-utils.d.ts +7 -0
  167. package/dist/utils/async-utils.d.ts.map +1 -1
  168. package/dist/utils/async-utils.js +57 -2
  169. package/dist/utils/console-util.d.ts +2 -0
  170. package/dist/utils/console-util.d.ts.map +1 -0
  171. package/dist/utils/console-util.js +6 -0
  172. package/dist/utils/controller.js +26 -2
  173. package/dist/utils/esm-utils.d.ts +45 -0
  174. package/dist/utils/esm-utils.d.ts.map +1 -0
  175. package/dist/utils/esm-utils.js +56 -0
  176. package/dist/utils/fs-utils.js +17 -2
  177. package/dist/utils/lodash-able.js +6 -2
  178. package/dist/utils/model.js +22 -2
  179. package/dist/utils/path-utils.d.ts +89 -0
  180. package/dist/utils/path-utils.d.ts.map +1 -0
  181. package/dist/utils/path-utils.js +60 -0
  182. package/dist/utils/process-utils.d.ts +13 -0
  183. package/dist/utils/process-utils.d.ts.map +1 -0
  184. package/dist/utils/process-utils.js +36 -0
  185. package/dist/utils/sql-parser.js +35 -2
  186. package/dist/utils/utils.d.ts +4 -7
  187. package/dist/utils/utils.d.ts.map +1 -1
  188. package/dist/utils/utils.js +33 -2
  189. package/dist/utils/zod-error.d.ts.map +1 -1
  190. package/dist/utils/zod-error.js +19 -2
  191. package/package.json +21 -9
  192. package/src/api/code-converters.ts +2 -2
  193. package/src/api/config.ts +142 -0
  194. package/src/api/context.ts +1 -0
  195. package/src/api/decorators.ts +15 -5
  196. package/src/api/sonamu.ts +102 -87
  197. package/src/bin/build-config.ts +2 -1
  198. package/src/bin/cli-wrapper.ts +10 -3
  199. package/src/bin/cli.ts +108 -56
  200. package/src/bin/hot-hook-register.ts +22 -0
  201. package/src/database/base-model.ts +1 -1
  202. package/src/database/code-generator.ts +1 -1
  203. package/src/database/db.ts +53 -60
  204. package/src/database/puri-wrapper.ts +104 -26
  205. package/src/database/puri.ts +477 -580
  206. package/src/database/puri.types.ts +111 -201
  207. package/src/database/transaction-context.ts +4 -4
  208. package/src/database/upsert-builder.ts +1 -1
  209. package/src/entity/entity-manager.ts +19 -15
  210. package/src/entity/entity.ts +4 -3
  211. package/src/index.ts +2 -0
  212. package/src/migration/code-generation.ts +1 -1
  213. package/src/migration/migration-set.ts +1 -1
  214. package/src/migration/migrator.ts +23 -152
  215. package/src/naite/naite.ts +70 -0
  216. package/src/syncer/api-parser.ts +299 -0
  217. package/src/syncer/checksum.ts +152 -0
  218. package/src/syncer/code-generator.ts +202 -0
  219. package/src/syncer/entity-operations.ts +68 -0
  220. package/src/syncer/file-patterns.ts +56 -0
  221. package/src/syncer/index.ts +6 -0
  222. package/src/syncer/module-loader.ts +125 -0
  223. package/src/syncer/syncer.ts +363 -1420
  224. package/src/template/entity-converter.ts +123 -0
  225. package/src/template/helpers.ts +84 -0
  226. package/src/{templates → template/implementations}/entity.template.ts +4 -4
  227. package/src/{templates → template/implementations}/generated.template.ts +9 -9
  228. package/src/{templates → template/implementations}/generated_http.template.ts +9 -6
  229. package/src/{templates → template/implementations}/generated_sso.template.ts +7 -7
  230. package/src/{templates → template/implementations}/init_types.template.ts +4 -4
  231. package/src/{templates → template/implementations}/model.template.ts +9 -9
  232. package/src/{templates → template/implementations}/model_test.template.ts +5 -5
  233. package/src/{templates → template/implementations}/service.template.ts +29 -12
  234. package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
  235. package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +5 -21
  236. package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
  237. package/src/{templates → template/implementations}/view_form.template.ts +11 -13
  238. package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
  239. package/src/{templates → template/implementations}/view_id_async_select.template.ts +3 -3
  240. package/src/{templates → template/implementations}/view_list.template.ts +13 -64
  241. package/src/{templates → template/implementations}/view_list_columns.template.ts +3 -3
  242. package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
  243. package/src/template/index.ts +4 -0
  244. package/src/template/template.ts +86 -0
  245. package/src/template/zod-converter.ts +219 -0
  246. package/src/testing/fixture-manager.ts +8 -1
  247. package/src/types/types.ts +39 -62
  248. package/src/utils/async-utils.ts +17 -0
  249. package/src/utils/console-util.ts +4 -0
  250. package/src/utils/esm-utils.ts +69 -0
  251. package/src/utils/path-utils.ts +102 -0
  252. package/src/utils/process-utils.ts +46 -0
  253. package/src/utils/sql-parser.ts +1 -1
  254. package/src/utils/utils.ts +14 -40
  255. package/src/utils/zod-error.ts +0 -1
  256. package/dist/api/base-frame.js.map +0 -1
  257. package/dist/api/caster.js.map +0 -1
  258. package/dist/api/code-converters.js.map +0 -1
  259. package/dist/api/context.js.map +0 -1
  260. package/dist/api/decorators.js.map +0 -1
  261. package/dist/api/index.js.map +0 -1
  262. package/dist/api/sonamu.js.map +0 -1
  263. package/dist/bin/build-config.js.map +0 -1
  264. package/dist/bin/cli-wrapper.js.map +0 -1
  265. package/dist/bin/cli.js.map +0 -1
  266. package/dist/database/_batch_update.js.map +0 -1
  267. package/dist/database/base-model.js.map +0 -1
  268. package/dist/database/code-generator.js.map +0 -1
  269. package/dist/database/db.js.map +0 -1
  270. package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
  271. package/dist/database/puri-wrapper.js.map +0 -1
  272. package/dist/database/puri.js.map +0 -1
  273. package/dist/database/puri.types.js.map +0 -1
  274. package/dist/database/transaction-context.js.map +0 -1
  275. package/dist/database/upsert-builder.js.map +0 -1
  276. package/dist/entity/entity-manager.js.map +0 -1
  277. package/dist/entity/entity-utils.js.map +0 -1
  278. package/dist/entity/entity.js.map +0 -1
  279. package/dist/exceptions/error-handler.js.map +0 -1
  280. package/dist/exceptions/so-exceptions.js.map +0 -1
  281. package/dist/file-storage/driver.js.map +0 -1
  282. package/dist/file-storage/file-storage.js.map +0 -1
  283. package/dist/index.js.map +0 -1
  284. package/dist/migration/code-generation.js.map +0 -1
  285. package/dist/migration/migration-set.js.map +0 -1
  286. package/dist/migration/migrator.js.map +0 -1
  287. package/dist/migration/types.js.map +0 -1
  288. package/dist/stream/index.js.map +0 -1
  289. package/dist/stream/sse.js.map +0 -1
  290. package/dist/syncer/index.js.map +0 -1
  291. package/dist/syncer/syncer.js.map +0 -1
  292. package/dist/templates/base-template.d.ts +0 -13
  293. package/dist/templates/base-template.d.ts.map +0 -1
  294. package/dist/templates/base-template.js +0 -2
  295. package/dist/templates/base-template.js.map +0 -1
  296. package/dist/templates/entity.template.d.ts.map +0 -1
  297. package/dist/templates/entity.template.js +0 -2
  298. package/dist/templates/entity.template.js.map +0 -1
  299. package/dist/templates/generated.template.d.ts.map +0 -1
  300. package/dist/templates/generated.template.js +0 -2
  301. package/dist/templates/generated.template.js.map +0 -1
  302. package/dist/templates/generated_http.template.d.ts.map +0 -1
  303. package/dist/templates/generated_http.template.js +0 -2
  304. package/dist/templates/generated_http.template.js.map +0 -1
  305. package/dist/templates/generated_sso.template.d.ts.map +0 -1
  306. package/dist/templates/generated_sso.template.js +0 -2
  307. package/dist/templates/generated_sso.template.js.map +0 -1
  308. package/dist/templates/index.d.ts +0 -2
  309. package/dist/templates/index.d.ts.map +0 -1
  310. package/dist/templates/index.js +0 -2
  311. package/dist/templates/index.js.map +0 -1
  312. package/dist/templates/init_types.template.d.ts.map +0 -1
  313. package/dist/templates/init_types.template.js +0 -2
  314. package/dist/templates/init_types.template.js.map +0 -1
  315. package/dist/templates/model.template.d.ts +0 -17
  316. package/dist/templates/model.template.d.ts.map +0 -1
  317. package/dist/templates/model.template.js +0 -2
  318. package/dist/templates/model.template.js.map +0 -1
  319. package/dist/templates/model_test.template.d.ts.map +0 -1
  320. package/dist/templates/model_test.template.js +0 -2
  321. package/dist/templates/model_test.template.js.map +0 -1
  322. package/dist/templates/service.template.d.ts.map +0 -1
  323. package/dist/templates/service.template.js +0 -2
  324. package/dist/templates/service.template.js.map +0 -1
  325. package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
  326. package/dist/templates/view_enums_buttonset.template.js +0 -2
  327. package/dist/templates/view_enums_buttonset.template.js.map +0 -1
  328. package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
  329. package/dist/templates/view_enums_dropdown.template.js +0 -2
  330. package/dist/templates/view_enums_dropdown.template.js.map +0 -1
  331. package/dist/templates/view_enums_select.template.d.ts.map +0 -1
  332. package/dist/templates/view_enums_select.template.js +0 -2
  333. package/dist/templates/view_enums_select.template.js.map +0 -1
  334. package/dist/templates/view_form.template.d.ts.map +0 -1
  335. package/dist/templates/view_form.template.js +0 -2
  336. package/dist/templates/view_form.template.js.map +0 -1
  337. package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
  338. package/dist/templates/view_id_all_select.template.js +0 -2
  339. package/dist/templates/view_id_all_select.template.js.map +0 -1
  340. package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
  341. package/dist/templates/view_id_async_select.template.js +0 -2
  342. package/dist/templates/view_id_async_select.template.js.map +0 -1
  343. package/dist/templates/view_list.template.d.ts.map +0 -1
  344. package/dist/templates/view_list.template.js +0 -2
  345. package/dist/templates/view_list.template.js.map +0 -1
  346. package/dist/templates/view_list_columns.template.d.ts.map +0 -1
  347. package/dist/templates/view_list_columns.template.js +0 -2
  348. package/dist/templates/view_list_columns.template.js.map +0 -1
  349. package/dist/templates/view_search_input.template.d.ts.map +0 -1
  350. package/dist/templates/view_search_input.template.js +0 -2
  351. package/dist/templates/view_search_input.template.js.map +0 -1
  352. package/dist/testing/_relation-graph.js.map +0 -1
  353. package/dist/testing/fixture-manager.js.map +0 -1
  354. package/dist/types/types.js.map +0 -1
  355. package/dist/typings/knex.d.js.map +0 -1
  356. package/dist/utils/async-utils.js.map +0 -1
  357. package/dist/utils/controller.js.map +0 -1
  358. package/dist/utils/fs-utils.js.map +0 -1
  359. package/dist/utils/lodash-able.js.map +0 -1
  360. package/dist/utils/model.js.map +0 -1
  361. package/dist/utils/sql-parser.js.map +0 -1
  362. package/dist/utils/utils.js.map +0 -1
  363. package/dist/utils/zod-error.js.map +0 -1
  364. package/src/templates/base-template.ts +0 -19
  365. package/src/templates/index.ts +0 -1
@@ -0,0 +1,123 @@
1
+ import z from "zod";
2
+ import { EntityManager } from "../entity/entity-manager";
3
+ import { ServiceUnavailableException } from "../exceptions/so-exceptions";
4
+ import { EntityPropNode, RenderingNode } from "../types/types";
5
+ import { zodTypeToRenderingNode, propToZodType } from "./zod-converter";
6
+
7
+ /**
8
+ * 엔티티의 특정 subset을 RenderingNode로 변환합니다.
9
+ * subset의 필드들을 Zod 타입으로 변환한 후 UI 렌더링용 노드로 만듭니다.
10
+ * object와 array의 경우 적절한 pick 필드를 자동으로 선택합니다.
11
+ */
12
+ export async function getColumnsNode(
13
+ entityId: string,
14
+ subsetKey: string
15
+ ): Promise<RenderingNode> {
16
+ const entity = EntityManager.get(entityId);
17
+ const subset = entity.subsets[subsetKey];
18
+ if (subset === undefined) {
19
+ throw new ServiceUnavailableException(`Subset ${subsetKey} 가 없습니다.`);
20
+ }
21
+ const propNodes = entity.fieldExprsToPropNodes(subset);
22
+ const rootPropNode: EntityPropNode = {
23
+ nodeType: "object",
24
+ children: propNodes,
25
+ };
26
+
27
+ const columnsZodType = (await propNodeToZodType(
28
+ rootPropNode
29
+ )) as z.ZodObject<any>;
30
+
31
+ const columnsNode = zodTypeToRenderingNode(columnsZodType);
32
+ columnsNode.children = columnsNode.children!.map((child) => {
33
+ if (child.renderType === "object") {
34
+ const pickedCol = child.children!.find((cc) =>
35
+ ["title", "name"].includes(cc.name)
36
+ );
37
+ if (pickedCol) {
38
+ return {
39
+ ...child,
40
+ renderType: "object-pick",
41
+ config: {
42
+ picked: pickedCol.name,
43
+ },
44
+ };
45
+ } else {
46
+ return child;
47
+ }
48
+ } else if (
49
+ child.renderType === "array" &&
50
+ child.element &&
51
+ child.element.renderType === "object"
52
+ ) {
53
+ const pickedCol = child.element!.children!.find((cc) =>
54
+ ["title", "name"].includes(cc.name)
55
+ );
56
+ if (pickedCol) {
57
+ return {
58
+ ...child,
59
+ element: {
60
+ ...child.element,
61
+ renderType: "object-pick",
62
+ config: {
63
+ picked: pickedCol.name,
64
+ },
65
+ },
66
+ };
67
+ } else {
68
+ return child;
69
+ }
70
+ }
71
+ return child;
72
+ });
73
+
74
+ return columnsNode;
75
+ }
76
+
77
+ /**
78
+ * EntityPropNode를 Zod 타입으로 변환합니다.
79
+ * plain, array, object 세 가지 nodeType을 재귀적으로 처리합니다.
80
+ */
81
+ export async function propNodeToZodType(
82
+ propNode: EntityPropNode
83
+ ): Promise<z.ZodTypeAny> {
84
+ if (propNode.nodeType === "plain") {
85
+ return propToZodType(propNode.prop);
86
+ } else if (propNode.nodeType === "array") {
87
+ if (propNode.prop === undefined) {
88
+ throw new Error();
89
+ } else if (propNode.children.length > 0) {
90
+ return (
91
+ await propNodeToZodType({
92
+ ...propNode,
93
+ nodeType: "object",
94
+ })
95
+ ).array();
96
+ } else {
97
+ const innerType = await propToZodType(propNode.prop);
98
+ if (propNode.prop.nullable === true) {
99
+ return z.array(innerType).nullable();
100
+ } else {
101
+ return z.array(innerType);
102
+ }
103
+ }
104
+ } else if (propNode.nodeType === "object") {
105
+ const obj = await propNode.children.reduce(
106
+ async (promise, childPropNode) => {
107
+ const result = await promise;
108
+ result[childPropNode.prop!.name] =
109
+ await propNodeToZodType(childPropNode);
110
+ return result;
111
+ },
112
+ {} as any
113
+ );
114
+
115
+ if (propNode.prop?.nullable === true) {
116
+ return z.object(obj).nullable();
117
+ } else {
118
+ return z.object(obj);
119
+ }
120
+ } else {
121
+ throw Error;
122
+ }
123
+ }
@@ -0,0 +1,84 @@
1
+ import inflection from "inflection";
2
+ import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
+ import { isEnumProp, isRelationProp, RelationProp } from "../types/types";
4
+
5
+ /**
6
+ * Enum의 표시용 라벨을 가져옵니다.
7
+ * OrderBy, SearchField 등 특수한 경우와 일반 Enum을 구분하여 처리합니다.
8
+ */
9
+ export function getLabel(entityId: string, enumId: string): string {
10
+ if (enumId.endsWith("OrderBy")) {
11
+ return "정렬";
12
+ } else if (enumId.endsWith("SearchField")) {
13
+ return "검색";
14
+ } else {
15
+ const enumProp = EntityManager.get(entityId).props.find(
16
+ (prop) => `${entityId}${inflection.camelize(prop.name)}` === enumId
17
+ );
18
+ if (enumProp && enumProp.desc) {
19
+ return enumProp.desc;
20
+ }
21
+ return enumId;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * 컬럼 이름으로부터 Enum 정보를 추출합니다.
27
+ * Entity의 prop 중 enum 타입인 것을 찾아 관련 정보를 반환합니다.
28
+ */
29
+ export function getEnumInfoFromColName(
30
+ entityId: string,
31
+ colName: string
32
+ ): {
33
+ id: string;
34
+ targetEntityNames: EntityNamesRecord;
35
+ targetEntityId: string;
36
+ title: string;
37
+ } {
38
+ const baseEntity = EntityManager.get(entityId);
39
+ const prop = baseEntity.props.find((p) => p.name === colName);
40
+ if (prop && isEnumProp(prop)) {
41
+ return {
42
+ id: prop.id,
43
+ targetEntityId: entityId,
44
+ targetEntityNames: EntityManager.getNamesFromId(entityId),
45
+ title: prop.desc ?? prop.id,
46
+ };
47
+ } else {
48
+ const idCandidate = inflection.camelize(
49
+ inflection.underscore(entityId) + "_" + inflection.underscore(colName),
50
+ false
51
+ );
52
+ try {
53
+ const targetEntityNames = EntityManager.getNamesFromId(entityId);
54
+ return {
55
+ id: idCandidate,
56
+ targetEntityId: entityId,
57
+ targetEntityNames: targetEntityNames,
58
+ title: idCandidate,
59
+ };
60
+ } catch {}
61
+ throw new Error(`찾을 수 없는 EnumProp ${colName}`);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 컬럼 이름으로부터 Relation prop 정보를 가져옵니다.
67
+ * 관계형 prop이 아닌 경우 에러를 발생시킵니다.
68
+ */
69
+ export function getRelationPropFromColName(
70
+ entityId: string,
71
+ colName: string
72
+ ): RelationProp {
73
+ const baseEntity = EntityManager.get(entityId);
74
+ const relProp = baseEntity.props.find((prop) => prop.name === colName);
75
+ if (isRelationProp(relProp)) {
76
+ const relEntity = EntityManager.get(relProp.with);
77
+ if (relEntity.parentId !== undefined) {
78
+ throw new Error("Only parent entities can be used as relation props");
79
+ }
80
+ return relProp;
81
+ } else {
82
+ throw new Error(`찾을 수 없는 Relation ${colName}`);
83
+ }
84
+ }
@@ -1,7 +1,7 @@
1
- import { TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
4
- import { Sonamu } from "../api";
1
+ import { TemplateOptions } from "../../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
3
+ import { Template } from "../template";
4
+ import { Sonamu } from "../../api";
5
5
 
6
6
  export class Template__entity extends Template {
7
7
  constructor() {
@@ -1,12 +1,12 @@
1
- import _ from "lodash";
2
- import { TemplateOptions } from "../types/types";
3
- import { EntityManager } from "../entity/entity-manager";
4
- import { Entity } from "../entity/entity";
5
- import { EntityPropNode } from "../types/types";
6
- import { propNodeToZodTypeDef, zodTypeToZodCode } from "../api/code-converters";
7
- import { Template } from "./base-template";
8
- import { nonNullable } from "../utils/utils";
9
- import { Sonamu } from "../api";
1
+ import * as _ from "lodash-es";
2
+ import { TemplateOptions } from "../../types/types";
3
+ import { EntityManager } from "../../entity/entity-manager";
4
+ import { Entity } from "../../entity/entity";
5
+ import { EntityPropNode } from "../../types/types";
6
+ import { propNodeToZodTypeDef, zodTypeToZodCode } from "../../api/code-converters";
7
+ import { Template } from "../template";
8
+ import { nonNullable } from "../../utils/utils";
9
+ import { Sonamu } from "../../api";
10
10
 
11
11
  export type SourceCode = {
12
12
  label: string;
@@ -1,11 +1,11 @@
1
1
  import qs from "qs";
2
2
  import { z } from "zod";
3
- import { TemplateOptions } from "../types/types";
4
- import { getZodObjectFromApi } from "../api/code-converters";
5
- import { ExtendedApi } from "../api/decorators";
6
- import { Template } from "./base-template";
3
+ import { TemplateOptions } from "../../types/types";
4
+ import { getZodObjectFromApi } from "../../api/code-converters";
5
+ import { ExtendedApi } from "../../api/decorators";
6
+ import { Template } from "../template";
7
7
  import prettier from "prettier";
8
- import { Sonamu } from "../api/sonamu";
8
+ import { Sonamu } from "../../api/sonamu";
9
9
 
10
10
  export class Template__generated_http extends Template {
11
11
  constructor() {
@@ -25,7 +25,9 @@ export class Template__generated_http extends Template {
25
25
  const {
26
26
  syncer: { types, apis },
27
27
  config: {
28
- route: { prefix },
28
+ api: {
29
+ route: { prefix },
30
+ },
29
31
  },
30
32
  } = Sonamu;
31
33
 
@@ -170,6 +172,7 @@ export class Template__generated_http extends Template {
170
172
  };
171
173
  return def;
172
174
  } catch (error) {
175
+ console.error(error);
173
176
  throw new Error(
174
177
  `Invalid zod type detected on ${api.modelName}:${api.methodName}`
175
178
  );
@@ -2,15 +2,15 @@ import {
2
2
  isManyToManyRelationProp,
3
3
  SubsetQuery,
4
4
  TemplateOptions,
5
- } from "../types/types";
6
- import { EntityManager } from "../entity/entity-manager";
7
- import { Template } from "./base-template";
5
+ } from "../../types/types";
6
+ import { EntityManager } from "../../entity/entity-manager";
7
+ import { Template } from "../template";
8
8
  import inflection from "inflection";
9
9
  import { SourceCode } from "./generated.template";
10
- import _ from "lodash";
11
- import { nonNullable } from "../utils/utils";
12
- import { Sonamu } from "../api";
13
- import { Entity } from "../entity/entity";
10
+ import * as _ from "lodash-es";
11
+ import { nonNullable } from "../../utils/utils";
12
+ import { Sonamu } from "../../api";
13
+ import { Entity } from "../../entity/entity";
14
14
 
15
15
  export class Template__generated_sso extends Template {
16
16
  constructor() {
@@ -1,7 +1,7 @@
1
- import { TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
4
- import { Sonamu } from "../api";
1
+ import { TemplateOptions } from "../../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
3
+ import { Template } from "../template";
4
+ import { Sonamu } from "../../api";
5
5
 
6
6
  export class Template__init_types extends Template {
7
7
  constructor() {
@@ -1,8 +1,9 @@
1
- import { RenderingNode, TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
1
+ import { TemplateOptions } from "../../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
3
+ import { Template } from "../template";
4
4
  import { Template__view_list } from "./view_list.template";
5
- import { Sonamu } from "../api";
5
+ import { Sonamu } from "../../api";
6
+ import { getZodTypeById, zodTypeToRenderingNode } from "../zod-converter";
6
7
 
7
8
  export class Template__model extends Template {
8
9
  constructor() {
@@ -18,11 +19,10 @@ export class Template__model extends Template {
18
19
  };
19
20
  }
20
21
 
21
- render(
22
- { entityId }: TemplateOptions["model"],
23
- _columnsNode: RenderingNode,
24
- listParamsNode: RenderingNode
25
- ) {
22
+ async render({ entityId }: TemplateOptions["model"]) {
23
+ const listParamsZodType = await getZodTypeById(`${entityId}ListParams`);
24
+ const listParamsNode = zodTypeToRenderingNode(listParamsZodType);
25
+
26
26
  const names = EntityManager.getNamesFromId(entityId);
27
27
  const entity = EntityManager.get(entityId);
28
28
 
@@ -1,7 +1,7 @@
1
- import { TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
4
- import { Sonamu } from "../api";
1
+ import { TemplateOptions } from "../../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
3
+ import { Template } from "../template";
4
+ import { Sonamu } from "../../api";
5
5
 
6
6
  export class Template__model_test extends Template {
7
7
  constructor() {
@@ -26,7 +26,7 @@ export class Template__model_test extends Template {
26
26
  import { describe, test, expect } from "vitest";
27
27
  import { bootstrap } from '../../testing/bootstrap';
28
28
 
29
- bootstrap([]);
29
+ bootstrap();
30
30
  describe.skip("${entityId}ModelTest", () => {
31
31
  test("Query", async () => {
32
32
  expect(true).toBe(true);
@@ -1,18 +1,18 @@
1
1
  import inflection from "inflection";
2
- import _ from "lodash";
3
- import { TemplateOptions } from "../types/types";
4
- import { EntityNamesRecord } from "../entity/entity-manager";
5
- import { ApiParamType, ApiParam } from "../types/types";
2
+ import * as _ from "lodash-es";
3
+ import { TemplateOptions } from "../../types/types";
4
+ import { EntityNamesRecord } from "../../entity/entity-manager";
5
+ import { ApiParamType, ApiParam } from "../../types/types";
6
6
  import {
7
7
  apiParamTypeToTsType,
8
8
  apiParamToTsCode,
9
9
  unwrapPromiseOnce,
10
10
  zodTypeToTsTypeDef,
11
11
  apiParamToTsCodeAsObject,
12
- } from "../api/code-converters";
13
- import { ExtendedApi } from "../api/decorators";
14
- import { Template } from "./base-template";
15
- import { Sonamu } from "../api/sonamu";
12
+ } from "../../api/code-converters";
13
+ import { ExtendedApi } from "../../api/decorators";
14
+ import { Template } from "../template";
15
+ import { Sonamu } from "../../api/sonamu";
16
16
 
17
17
  export class Template__service extends Template {
18
18
  constructor() {
@@ -26,9 +26,17 @@ export class Template__service extends Template {
26
26
  };
27
27
  }
28
28
 
29
- render({ namesRecord }: TemplateOptions["service"], apis: ExtendedApi[]) {
29
+ render({ namesRecord }: TemplateOptions["service"]) {
30
+ const {
31
+ syncer: { apis },
32
+ } = Sonamu;
33
+
34
+ const apisForThisModel = apis.filter(
35
+ (api) => api.modelName === `${namesRecord.capital}Model`
36
+ );
37
+
30
38
  // 서비스 TypeSource
31
- const { lines, importKeys } = this.getTypeSource(apis);
39
+ const { lines, importKeys } = this.getTypeSource(apisForThisModel);
32
40
 
33
41
  // AxiosProgressEvent 있는지 확인
34
42
  const hasAxiosProgressEvent = apis.find((api) =>
@@ -110,7 +118,7 @@ export class Template__service extends Template {
110
118
  .join(", ")} }`;
111
119
 
112
120
  // 기본 URL
113
- const apiBaseUrl = `${Sonamu.config.route.prefix}${api.path}`;
121
+ const apiBaseUrl = `${Sonamu.config.api.route.prefix}${api.path}`;
114
122
 
115
123
  return [
116
124
  // 클라이언트별로 생성
@@ -195,6 +203,7 @@ export async function ${methodNameAxios}${typeParamsDef}(${paramsDef}): Promise<
195
203
  return fetch({
196
204
  method: "GET",
197
205
  url: \`${apiBaseUrl}?\${qs.stringify(${payloadDef})}\`,
206
+ ${api.options.timeout ? `signal: AbortSignal.timeout(${api.options.timeout}),` : ""}
198
207
  });
199
208
  }
200
209
  `.trim();
@@ -205,6 +214,7 @@ export async function ${methodNameAxios}${typeParamsDef}(${paramsDef}): Promise<
205
214
  method: '${api.options.httpMethod}',
206
215
  url: \`${apiBaseUrl}\`,
207
216
  data: ${payloadDef},
217
+ ${api.options.timeout ? `signal: AbortSignal.timeout(${api.options.timeout}),` : ""}
208
218
  });
209
219
  }
210
220
  `.trim();
@@ -256,6 +266,7 @@ export async function ${api.methodName}${typeParamsDef}(
256
266
  },
257
267
  onUploadProgress,
258
268
  data: formData,
269
+ ${api.options.timeout ? `signal: AbortSignal.timeout(${api.options.timeout}),` : ""}
259
270
  });
260
271
  }
261
272
  `.trim();
@@ -283,6 +294,8 @@ export async function ${api.methodName}${typeParamsDef}(
283
294
  ${payloadDef},
284
295
  ], swrOptions?.conditional)${
285
296
  api.options.httpMethod === "POST" ? ", swrPostFetcher" : ""
297
+ }${
298
+ api.options.timeout ? `, { loadingTimeout: ${api.options.timeout} }` : ""
286
299
  });
287
300
  }`;
288
301
  }
@@ -296,7 +309,11 @@ export async function ${api.methodName}${typeParamsDef}(
296
309
  ) {
297
310
  return `
298
311
  export async function ${api.methodName}${typeParamsDef}(${paramsDef}): Promise<Response> {
299
- return window.fetch(\`${apiBaseUrl}?\${qs.stringify(${payloadDef})}\`);
312
+ return window.fetch(\`${apiBaseUrl}?\${qs.stringify(${payloadDef})}\`${
313
+ api.options.timeout
314
+ ? `, { signal: AbortSignal.timeout(${api.options.timeout}) }`
315
+ : ""
316
+ });
300
317
  }
301
318
  `.trim();
302
319
  }
@@ -1,6 +1,6 @@
1
- import { TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
1
+ import { TemplateOptions } from "../../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
3
+ import { Template } from "../template";
4
4
 
5
5
  export class Template__view_enums_buttonset extends Template {
6
6
  constructor() {
@@ -1,7 +1,7 @@
1
- import { TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
4
- import inflection from "inflection";
1
+ import { TemplateOptions } from "../../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
3
+ import { Template } from "../template";
4
+ import { getLabel } from "../helpers";
5
5
 
6
6
  export class Template__view_enums_dropdown extends Template {
7
7
  constructor() {
@@ -50,20 +50,4 @@ export function ${enumId}Dropdown(props: DropdownProps) {
50
50
  importKeys: [],
51
51
  };
52
52
  }
53
- }
54
-
55
- export function getLabel(entityId: string, enumId: string): string {
56
- if (enumId.endsWith("OrderBy")) {
57
- return "정렬";
58
- } else if (enumId.endsWith("SearchField")) {
59
- return "검색";
60
- } else {
61
- const enumProp = EntityManager.get(entityId).props.find(
62
- (prop) => `${entityId}${inflection.camelize(prop.name)}` === enumId
63
- );
64
- if (enumProp && enumProp.desc) {
65
- return enumProp.desc;
66
- }
67
- return enumId;
68
- }
69
- }
53
+ }
@@ -1,7 +1,7 @@
1
- import { TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
4
- import { getLabel } from "./view_enums_dropdown.template";
1
+ import { TemplateOptions } from "../../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
3
+ import { Template } from "../template";
4
+ import { getLabel } from "../helpers";
5
5
 
6
6
  export class Template__view_enums_select extends Template {
7
7
  constructor() {
@@ -1,14 +1,12 @@
1
1
  import inflection from "inflection";
2
2
  import { z } from "zod";
3
- import { RenderingNode, TemplateKey, TemplateOptions } from "../types/types";
4
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
5
- import { RenderedTemplate } from "../syncer/syncer";
6
- import { Template } from "./base-template";
7
- import {
8
- getEnumInfoFromColName,
9
- getRelationPropFromColName,
10
- } from "./view_list.template";
11
- import _ from "lodash";
3
+ import { RenderingNode, TemplateKey, TemplateOptions } from "../../types/types";
4
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
5
+ import { RenderedTemplate } from "../template";
6
+ import { Template } from "../template";
7
+ import { getRelationPropFromColName, getEnumInfoFromColName } from "../helpers";
8
+ import * as _ from "lodash-es";
9
+ import { getZodTypeById, zodTypeToRenderingNode } from "../zod-converter";
12
10
 
13
11
  export class Template__view_form extends Template {
14
12
  constructor() {
@@ -173,10 +171,10 @@ export class Template__view_form extends Template {
173
171
  );
174
172
  }
175
173
 
176
- render(
177
- { entityId }: TemplateOptions["view_form"],
178
- saveParamsNode: RenderingNode
179
- ) {
174
+ async render({ entityId }: TemplateOptions["view_form"]) {
175
+ const saveParamsZodType = await getZodTypeById(`${entityId}SaveParams`);
176
+ const saveParamsNode = zodTypeToRenderingNode(saveParamsZodType);
177
+
180
178
  const entity = EntityManager.get(entityId);
181
179
  const names = EntityManager.getNamesFromId(entityId);
182
180
  const columns = (saveParamsNode.children as RenderingNode[])
@@ -1,6 +1,6 @@
1
- import { TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
1
+ import { TemplateOptions } from "../../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
3
+ import { Template } from "../template";
4
4
 
5
5
  export class Template__view_id_all_select extends Template {
6
6
  constructor() {
@@ -1,6 +1,6 @@
1
- import { TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
1
+ import { TemplateOptions } from "../../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../../entity/entity-manager";
3
+ import { Template } from "../template";
4
4
 
5
5
  export class Template__view_id_async_select extends Template {
6
6
  constructor() {