sonamu 0.5.7 → 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 (358) 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.map +1 -1
  11. package/dist/api/decorators.js +142 -2
  12. package/dist/api/index.js +9 -2
  13. package/dist/api/sonamu.d.ts +8 -22
  14. package/dist/api/sonamu.d.ts.map +1 -1
  15. package/dist/api/sonamu.js +482 -2
  16. package/dist/bin/build-config.d.ts +2 -1
  17. package/dist/bin/build-config.d.ts.map +1 -1
  18. package/dist/bin/build-config.js +12 -2
  19. package/dist/bin/cli-wrapper.js +71 -2
  20. package/dist/bin/cli.js +418 -2
  21. package/dist/bin/hot-hook-register.d.ts +11 -0
  22. package/dist/bin/hot-hook-register.d.ts.map +1 -0
  23. package/dist/bin/hot-hook-register.js +21 -0
  24. package/dist/database/_batch_update.js +78 -2
  25. package/dist/database/base-model.js +247 -2
  26. package/dist/database/code-generator.js +53 -2
  27. package/dist/database/db.d.ts +2 -16
  28. package/dist/database/db.d.ts.map +1 -1
  29. package/dist/database/db.js +132 -2
  30. package/dist/database/knex-plugins/knex-on-duplicate-update.js +39 -2
  31. package/dist/database/puri-wrapper.js +109 -2
  32. package/dist/database/puri.d.ts +23 -16
  33. package/dist/database/puri.d.ts.map +1 -1
  34. package/dist/database/puri.js +539 -2
  35. package/dist/database/puri.types.d.ts +8 -3
  36. package/dist/database/puri.types.d.ts.map +1 -1
  37. package/dist/database/puri.types.js +3 -2
  38. package/dist/database/transaction-context.js +14 -2
  39. package/dist/database/upsert-builder.js +215 -2
  40. package/dist/entity/entity-manager.d.ts +3 -1
  41. package/dist/entity/entity-manager.d.ts.map +1 -1
  42. package/dist/entity/entity-manager.js +114 -2
  43. package/dist/entity/entity-utils.js +210 -2
  44. package/dist/entity/entity.d.ts.map +1 -1
  45. package/dist/entity/entity.js +651 -2
  46. package/dist/exceptions/error-handler.js +29 -2
  47. package/dist/exceptions/so-exceptions.js +85 -2
  48. package/dist/file-storage/driver.js +79 -2
  49. package/dist/file-storage/file-storage.js +75 -2
  50. package/dist/index.d.ts +2 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +28 -2
  53. package/dist/migration/code-generation.js +558 -2
  54. package/dist/migration/migration-set.js +364 -2
  55. package/dist/migration/migrator.d.ts +0 -9
  56. package/dist/migration/migrator.d.ts.map +1 -1
  57. package/dist/migration/migrator.js +510 -2
  58. package/dist/migration/types.js +3 -2
  59. package/dist/naite/naite.d.ts +12 -0
  60. package/dist/naite/naite.d.ts.map +1 -0
  61. package/dist/naite/naite.js +72 -0
  62. package/dist/stream/index.js +3 -2
  63. package/dist/stream/sse.js +38 -2
  64. package/dist/syncer/api-parser.d.ts +20 -0
  65. package/dist/syncer/api-parser.d.ts.map +1 -0
  66. package/dist/syncer/api-parser.js +229 -0
  67. package/dist/syncer/checksum.d.ts +21 -0
  68. package/dist/syncer/checksum.d.ts.map +1 -0
  69. package/dist/syncer/checksum.js +98 -0
  70. package/dist/syncer/code-generator.d.ts +20 -0
  71. package/dist/syncer/code-generator.d.ts.map +1 -0
  72. package/dist/syncer/code-generator.js +141 -0
  73. package/dist/syncer/entity-operations.d.ts +17 -0
  74. package/dist/syncer/entity-operations.d.ts.map +1 -0
  75. package/dist/syncer/entity-operations.js +58 -0
  76. package/dist/syncer/file-patterns.d.ts +29 -0
  77. package/dist/syncer/file-patterns.d.ts.map +1 -0
  78. package/dist/syncer/file-patterns.js +38 -0
  79. package/dist/syncer/index.d.ts +6 -0
  80. package/dist/syncer/index.d.ts.map +1 -1
  81. package/dist/syncer/index.js +9 -2
  82. package/dist/syncer/module-loader.d.ts +35 -0
  83. package/dist/syncer/module-loader.d.ts.map +1 -0
  84. package/dist/syncer/module-loader.js +82 -0
  85. package/dist/syncer/syncer.d.ts +93 -108
  86. package/dist/syncer/syncer.d.ts.map +1 -1
  87. package/dist/syncer/syncer.js +375 -2
  88. package/dist/template/entity-converter.d.ts +14 -0
  89. package/dist/template/entity-converter.d.ts.map +1 -0
  90. package/dist/template/entity-converter.js +101 -0
  91. package/dist/template/helpers.d.ts +23 -0
  92. package/dist/template/helpers.d.ts.map +1 -0
  93. package/dist/template/helpers.js +64 -0
  94. package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
  95. package/dist/template/implementations/entity.template.d.ts.map +1 -0
  96. package/dist/template/implementations/entity.template.js +87 -0
  97. package/dist/{templates → template/implementations}/generated.template.d.ts +3 -3
  98. package/dist/template/implementations/generated.template.d.ts.map +1 -0
  99. package/dist/template/implementations/generated.template.js +232 -0
  100. package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -3
  101. package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
  102. package/dist/template/implementations/generated_http.template.js +131 -0
  103. package/dist/{templates → template/implementations}/generated_sso.template.d.ts +3 -3
  104. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
  105. package/dist/template/implementations/generated_sso.template.js +105 -0
  106. package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
  107. package/dist/template/implementations/init_types.template.d.ts.map +1 -0
  108. package/dist/template/implementations/init_types.template.js +38 -0
  109. package/dist/template/implementations/model.template.d.ts +17 -0
  110. package/dist/template/implementations/model.template.d.ts.map +1 -0
  111. package/dist/template/implementations/model.template.js +171 -0
  112. package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
  113. package/dist/template/implementations/model_test.template.d.ts.map +1 -0
  114. package/dist/template/implementations/model_test.template.js +35 -0
  115. package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
  116. package/dist/template/implementations/service.template.d.ts.map +1 -0
  117. package/dist/template/implementations/service.template.js +193 -0
  118. package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
  119. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
  120. package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
  121. package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
  122. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
  123. package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
  124. package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
  125. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
  126. package/dist/template/implementations/view_enums_select.template.js +55 -0
  127. package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
  128. package/dist/template/implementations/view_form.template.d.ts.map +1 -0
  129. package/dist/template/implementations/view_form.template.js +337 -0
  130. package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
  131. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
  132. package/dist/template/implementations/view_id_all_select.template.js +31 -0
  133. package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
  134. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
  135. package/dist/template/implementations/view_id_async_select.template.js +105 -0
  136. package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
  137. package/dist/template/implementations/view_list.template.d.ts.map +1 -0
  138. package/dist/template/implementations/view_list.template.js +465 -0
  139. package/dist/{templates → template/implementations}/view_list_columns.template.d.ts +3 -3
  140. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
  141. package/dist/template/implementations/view_list_columns.template.js +49 -0
  142. package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
  143. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
  144. package/dist/template/implementations/view_search_input.template.js +64 -0
  145. package/dist/template/index.d.ts +5 -0
  146. package/dist/template/index.d.ts.map +1 -0
  147. package/dist/template/index.js +6 -0
  148. package/dist/template/template.d.ts +39 -0
  149. package/dist/template/template.d.ts.map +1 -0
  150. package/dist/template/template.js +47 -0
  151. package/dist/template/zod-converter.d.ts +18 -0
  152. package/dist/template/zod-converter.d.ts.map +1 -0
  153. package/dist/template/zod-converter.js +166 -0
  154. package/dist/testing/_relation-graph.js +80 -2
  155. package/dist/testing/fixture-manager.d.ts.map +1 -1
  156. package/dist/testing/fixture-manager.js +521 -2
  157. package/dist/types/types.d.ts +39 -40
  158. package/dist/types/types.d.ts.map +1 -1
  159. package/dist/types/types.js +289 -2
  160. package/dist/typings/knex.d.js +3 -2
  161. package/dist/utils/async-utils.d.ts +7 -0
  162. package/dist/utils/async-utils.d.ts.map +1 -1
  163. package/dist/utils/async-utils.js +57 -2
  164. package/dist/utils/console-util.d.ts +2 -0
  165. package/dist/utils/console-util.d.ts.map +1 -0
  166. package/dist/utils/console-util.js +6 -0
  167. package/dist/utils/controller.js +26 -2
  168. package/dist/utils/esm-utils.d.ts +45 -0
  169. package/dist/utils/esm-utils.d.ts.map +1 -0
  170. package/dist/utils/esm-utils.js +56 -0
  171. package/dist/utils/fs-utils.js +17 -2
  172. package/dist/utils/lodash-able.js +6 -2
  173. package/dist/utils/model.js +22 -2
  174. package/dist/utils/path-utils.d.ts +89 -0
  175. package/dist/utils/path-utils.d.ts.map +1 -0
  176. package/dist/utils/path-utils.js +60 -0
  177. package/dist/utils/process-utils.d.ts +13 -0
  178. package/dist/utils/process-utils.d.ts.map +1 -0
  179. package/dist/utils/process-utils.js +36 -0
  180. package/dist/utils/sql-parser.js +35 -2
  181. package/dist/utils/utils.d.ts +4 -7
  182. package/dist/utils/utils.d.ts.map +1 -1
  183. package/dist/utils/utils.js +33 -2
  184. package/dist/utils/zod-error.d.ts.map +1 -1
  185. package/dist/utils/zod-error.js +19 -2
  186. package/package.json +21 -8
  187. package/src/api/code-converters.ts +2 -2
  188. package/src/api/config.ts +142 -0
  189. package/src/api/context.ts +1 -0
  190. package/src/api/decorators.ts +1 -0
  191. package/src/api/sonamu.ts +81 -67
  192. package/src/bin/build-config.ts +2 -1
  193. package/src/bin/cli-wrapper.ts +10 -3
  194. package/src/bin/cli.ts +108 -56
  195. package/src/bin/hot-hook-register.ts +22 -0
  196. package/src/database/base-model.ts +1 -1
  197. package/src/database/code-generator.ts +1 -1
  198. package/src/database/db.ts +10 -52
  199. package/src/database/puri.ts +78 -53
  200. package/src/database/puri.types.ts +18 -5
  201. package/src/database/upsert-builder.ts +1 -1
  202. package/src/entity/entity-manager.ts +19 -15
  203. package/src/entity/entity.ts +4 -3
  204. package/src/index.ts +2 -0
  205. package/src/migration/code-generation.ts +1 -1
  206. package/src/migration/migration-set.ts +1 -1
  207. package/src/migration/migrator.ts +23 -152
  208. package/src/naite/naite.ts +70 -0
  209. package/src/syncer/api-parser.ts +299 -0
  210. package/src/syncer/checksum.ts +152 -0
  211. package/src/syncer/code-generator.ts +202 -0
  212. package/src/syncer/entity-operations.ts +68 -0
  213. package/src/syncer/file-patterns.ts +56 -0
  214. package/src/syncer/index.ts +6 -0
  215. package/src/syncer/module-loader.ts +125 -0
  216. package/src/syncer/syncer.ts +363 -1420
  217. package/src/template/entity-converter.ts +123 -0
  218. package/src/template/helpers.ts +84 -0
  219. package/src/{templates → template/implementations}/entity.template.ts +4 -4
  220. package/src/{templates → template/implementations}/generated.template.ts +9 -9
  221. package/src/{templates → template/implementations}/generated_http.template.ts +9 -6
  222. package/src/{templates → template/implementations}/generated_sso.template.ts +7 -7
  223. package/src/{templates → template/implementations}/init_types.template.ts +4 -4
  224. package/src/{templates → template/implementations}/model.template.ts +9 -9
  225. package/src/{templates → template/implementations}/model_test.template.ts +5 -5
  226. package/src/{templates → template/implementations}/service.template.ts +19 -11
  227. package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
  228. package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +5 -21
  229. package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
  230. package/src/{templates → template/implementations}/view_form.template.ts +11 -13
  231. package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
  232. package/src/{templates → template/implementations}/view_id_async_select.template.ts +3 -3
  233. package/src/{templates → template/implementations}/view_list.template.ts +13 -64
  234. package/src/{templates → template/implementations}/view_list_columns.template.ts +3 -3
  235. package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
  236. package/src/template/index.ts +4 -0
  237. package/src/template/template.ts +86 -0
  238. package/src/template/zod-converter.ts +219 -0
  239. package/src/testing/fixture-manager.ts +8 -1
  240. package/src/types/types.ts +38 -61
  241. package/src/utils/async-utils.ts +17 -0
  242. package/src/utils/console-util.ts +4 -0
  243. package/src/utils/esm-utils.ts +69 -0
  244. package/src/utils/path-utils.ts +102 -0
  245. package/src/utils/process-utils.ts +46 -0
  246. package/src/utils/sql-parser.ts +1 -1
  247. package/src/utils/utils.ts +14 -40
  248. package/src/utils/zod-error.ts +0 -1
  249. package/dist/api/base-frame.js.map +0 -1
  250. package/dist/api/caster.js.map +0 -1
  251. package/dist/api/code-converters.js.map +0 -1
  252. package/dist/api/context.js.map +0 -1
  253. package/dist/api/decorators.js.map +0 -1
  254. package/dist/api/index.js.map +0 -1
  255. package/dist/api/sonamu.js.map +0 -1
  256. package/dist/bin/build-config.js.map +0 -1
  257. package/dist/bin/cli-wrapper.js.map +0 -1
  258. package/dist/bin/cli.js.map +0 -1
  259. package/dist/database/_batch_update.js.map +0 -1
  260. package/dist/database/base-model.js.map +0 -1
  261. package/dist/database/code-generator.js.map +0 -1
  262. package/dist/database/db.js.map +0 -1
  263. package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
  264. package/dist/database/puri-wrapper.js.map +0 -1
  265. package/dist/database/puri.js.map +0 -1
  266. package/dist/database/puri.types.js.map +0 -1
  267. package/dist/database/transaction-context.js.map +0 -1
  268. package/dist/database/upsert-builder.js.map +0 -1
  269. package/dist/entity/entity-manager.js.map +0 -1
  270. package/dist/entity/entity-utils.js.map +0 -1
  271. package/dist/entity/entity.js.map +0 -1
  272. package/dist/exceptions/error-handler.js.map +0 -1
  273. package/dist/exceptions/so-exceptions.js.map +0 -1
  274. package/dist/file-storage/driver.js.map +0 -1
  275. package/dist/file-storage/file-storage.js.map +0 -1
  276. package/dist/index.js.map +0 -1
  277. package/dist/migration/code-generation.js.map +0 -1
  278. package/dist/migration/migration-set.js.map +0 -1
  279. package/dist/migration/migrator.js.map +0 -1
  280. package/dist/migration/types.js.map +0 -1
  281. package/dist/stream/index.js.map +0 -1
  282. package/dist/stream/sse.js.map +0 -1
  283. package/dist/syncer/index.js.map +0 -1
  284. package/dist/syncer/syncer.js.map +0 -1
  285. package/dist/templates/base-template.d.ts +0 -13
  286. package/dist/templates/base-template.d.ts.map +0 -1
  287. package/dist/templates/base-template.js +0 -2
  288. package/dist/templates/base-template.js.map +0 -1
  289. package/dist/templates/entity.template.d.ts.map +0 -1
  290. package/dist/templates/entity.template.js +0 -2
  291. package/dist/templates/entity.template.js.map +0 -1
  292. package/dist/templates/generated.template.d.ts.map +0 -1
  293. package/dist/templates/generated.template.js +0 -2
  294. package/dist/templates/generated.template.js.map +0 -1
  295. package/dist/templates/generated_http.template.d.ts.map +0 -1
  296. package/dist/templates/generated_http.template.js +0 -2
  297. package/dist/templates/generated_http.template.js.map +0 -1
  298. package/dist/templates/generated_sso.template.d.ts.map +0 -1
  299. package/dist/templates/generated_sso.template.js +0 -2
  300. package/dist/templates/generated_sso.template.js.map +0 -1
  301. package/dist/templates/index.d.ts +0 -2
  302. package/dist/templates/index.d.ts.map +0 -1
  303. package/dist/templates/index.js +0 -2
  304. package/dist/templates/index.js.map +0 -1
  305. package/dist/templates/init_types.template.d.ts.map +0 -1
  306. package/dist/templates/init_types.template.js +0 -2
  307. package/dist/templates/init_types.template.js.map +0 -1
  308. package/dist/templates/model.template.d.ts +0 -17
  309. package/dist/templates/model.template.d.ts.map +0 -1
  310. package/dist/templates/model.template.js +0 -2
  311. package/dist/templates/model.template.js.map +0 -1
  312. package/dist/templates/model_test.template.d.ts.map +0 -1
  313. package/dist/templates/model_test.template.js +0 -2
  314. package/dist/templates/model_test.template.js.map +0 -1
  315. package/dist/templates/service.template.d.ts.map +0 -1
  316. package/dist/templates/service.template.js +0 -2
  317. package/dist/templates/service.template.js.map +0 -1
  318. package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
  319. package/dist/templates/view_enums_buttonset.template.js +0 -2
  320. package/dist/templates/view_enums_buttonset.template.js.map +0 -1
  321. package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
  322. package/dist/templates/view_enums_dropdown.template.js +0 -2
  323. package/dist/templates/view_enums_dropdown.template.js.map +0 -1
  324. package/dist/templates/view_enums_select.template.d.ts.map +0 -1
  325. package/dist/templates/view_enums_select.template.js +0 -2
  326. package/dist/templates/view_enums_select.template.js.map +0 -1
  327. package/dist/templates/view_form.template.d.ts.map +0 -1
  328. package/dist/templates/view_form.template.js +0 -2
  329. package/dist/templates/view_form.template.js.map +0 -1
  330. package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
  331. package/dist/templates/view_id_all_select.template.js +0 -2
  332. package/dist/templates/view_id_all_select.template.js.map +0 -1
  333. package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
  334. package/dist/templates/view_id_async_select.template.js +0 -2
  335. package/dist/templates/view_id_async_select.template.js.map +0 -1
  336. package/dist/templates/view_list.template.d.ts.map +0 -1
  337. package/dist/templates/view_list.template.js +0 -2
  338. package/dist/templates/view_list.template.js.map +0 -1
  339. package/dist/templates/view_list_columns.template.d.ts.map +0 -1
  340. package/dist/templates/view_list_columns.template.js +0 -2
  341. package/dist/templates/view_list_columns.template.js.map +0 -1
  342. package/dist/templates/view_search_input.template.d.ts.map +0 -1
  343. package/dist/templates/view_search_input.template.js +0 -2
  344. package/dist/templates/view_search_input.template.js.map +0 -1
  345. package/dist/testing/_relation-graph.js.map +0 -1
  346. package/dist/testing/fixture-manager.js.map +0 -1
  347. package/dist/types/types.js.map +0 -1
  348. package/dist/typings/knex.d.js.map +0 -1
  349. package/dist/utils/async-utils.js.map +0 -1
  350. package/dist/utils/controller.js.map +0 -1
  351. package/dist/utils/fs-utils.js.map +0 -1
  352. package/dist/utils/lodash-able.js.map +0 -1
  353. package/dist/utils/model.js.map +0 -1
  354. package/dist/utils/sql-parser.js.map +0 -1
  355. package/dist/utils/utils.js.map +0 -1
  356. package/dist/utils/zod-error.js.map +0 -1
  357. package/src/templates/base-template.ts +0 -19
  358. package/src/templates/index.ts +0 -1
@@ -0,0 +1,4 @@
1
+ export * from "./template";
2
+ export * from "./helpers";
3
+ export * from "./entity-converter";
4
+ export * from "./zod-converter";
@@ -0,0 +1,86 @@
1
+ import { TemplateKey, TemplateOptions } from "../types/types";
2
+ import { EntityNamesRecord } from "../entity/entity-manager";
3
+ import { globAsync } from "../utils/async-utils";
4
+ import { importMembers } from "../utils/esm-utils";
5
+ import path from "path";
6
+
7
+ export type RenderedTemplate = {
8
+ target: string;
9
+ path: string;
10
+ body: string;
11
+ importKeys: string[];
12
+ customHeaders?: string[];
13
+ preTemplates?: {
14
+ key: TemplateKey;
15
+ options: TemplateOptions[TemplateKey];
16
+ }[];
17
+ };
18
+
19
+ /**
20
+ * 템플릿을 나타내는 베이스 클래스입니다.
21
+ */
22
+ export abstract class Template {
23
+ private static templates: Map<TemplateKey, Template> = new Map();
24
+
25
+ constructor(public key: TemplateKey) {}
26
+
27
+ /**
28
+ * 템플릿 구현체가 있는 디렉토리의 모든 템플릿을 로드합니다.
29
+ * 템플릿이 필요(Template.find)해지기 전에 최소 한 번 호출해주셔야 합니다.
30
+ */
31
+ public static async autoload() {
32
+ const templateFiles = await globAsync(
33
+ // Sonamu의 코드베이스는 항상 빌드된 채로 dist 속에 머무르므로,
34
+ // 현재 파일을 기준으로 마찬가지로 dist 속에 있는 템플릿 구현체 js 파일들을 찾습니다.
35
+ path.join(import.meta.dirname, "implementations/*.template.js")
36
+ );
37
+
38
+ for (const templateFile of templateFiles) {
39
+ const templates = await importMembers<any>(templateFile);
40
+ if (
41
+ templates.length === 1 &&
42
+ typeof templates[0].value === "function" &&
43
+ templates[0].value.prototype instanceof Template
44
+ ) {
45
+ // 클래스의 인스턴스를 생성하여 등록
46
+ const instance = new templates[0].value();
47
+ this.templates.set(instance.key, instance);
48
+ } else {
49
+ throw new Error(
50
+ `Template ${templateFile} should export only one class that extends Template`
51
+ );
52
+ }
53
+ }
54
+
55
+ // console.log(
56
+ // chalk.gray(`[Loading] Loaded ${this.templates.size} templates.`)
57
+ // );
58
+ }
59
+
60
+ /**
61
+ * 템플릿 **인스턴스**를 key로 찾아옵니다.
62
+ * 만약 템플릿이 로드(loadAll)되지 않았거나 찾는 템플릿이 없다면 에러를 던집니다.
63
+ * @param key
64
+ * @returns
65
+ */
66
+ public static find(key: TemplateKey): Template {
67
+ const instance = this.templates.get(key);
68
+ if (!instance) {
69
+ throw new Error(`Template ${key} not found. It might be becasuse you tried to find a template before loading all templates. Did you call Template.loadAll()?`);
70
+ }
71
+ return instance;
72
+ }
73
+
74
+ public abstract render(
75
+ options: TemplateOptions[TemplateKey],
76
+ ...extra: unknown[]
77
+ ): RenderedTemplate | Promise<RenderedTemplate>;
78
+
79
+ public abstract getTargetAndPath(
80
+ names?: EntityNamesRecord,
81
+ ...extra: unknown[]
82
+ ): {
83
+ target: string;
84
+ path: string;
85
+ };
86
+ }
@@ -0,0 +1,219 @@
1
+ import z from "zod";
2
+ import { EntityManager } from "../entity/entity-manager";
3
+ import {
4
+ EntityProp,
5
+ isBelongsToOneRelationProp,
6
+ isBigIntegerProp,
7
+ isBooleanProp,
8
+ isDateProp,
9
+ isDateTimeProp,
10
+ isDecimalProp,
11
+ isDoubleProp,
12
+ isEnumProp,
13
+ isFloatProp,
14
+ isIntegerProp,
15
+ isJsonProp,
16
+ isOneToOneRelationProp,
17
+ isRelationProp,
18
+ isStringProp,
19
+ isTextProp,
20
+ isTimeProp,
21
+ isTimestampProp,
22
+ isUuidProp,
23
+ isVirtualProp,
24
+ RenderingNode,
25
+ } from "../types/types";
26
+ import path from "path";
27
+ import { createImportUrl } from "../utils/esm-utils";
28
+ import { Sonamu } from "../api/sonamu";
29
+ import inflection from "inflection";
30
+ import { getTextTypeLength } from "../api";
31
+
32
+ /**
33
+ * Zod 타입 ID로부터 동적으로 Zod 스키마를 로드합니다.
34
+ * dist 디렉토리에서 ESM으로 import하여 가져옵니다.
35
+ */
36
+ export async function getZodTypeById(zodTypeId: string): Promise<z.ZodTypeAny> {
37
+ const modulePath = EntityManager.getModulePath(zodTypeId);
38
+ const moduleAbsPath = path.join(
39
+ Sonamu.apiRootPath,
40
+ "dist",
41
+ "application",
42
+ modulePath + ".js"
43
+ );
44
+ const importUrl = createImportUrl(moduleAbsPath);
45
+ const imported = await import(importUrl);
46
+
47
+ if (!imported[zodTypeId]) {
48
+ throw new Error(`존재하지 않는 zodTypeId ${zodTypeId}`);
49
+ }
50
+ return imported[zodTypeId].describe(zodTypeId);
51
+ }
52
+
53
+ /**
54
+ * Zod 타입을 UI 렌더링에 사용할 수 있는 RenderingNode로 변환합니다.
55
+ * 재귀적으로 중첩된 타입들을 처리합니다.
56
+ */
57
+ export function zodTypeToRenderingNode(
58
+ zodType: z.ZodType<any>,
59
+ baseKey: string = "root"
60
+ ): RenderingNode {
61
+ const def = {
62
+ name: baseKey,
63
+ label: inflection.camelize(baseKey, false),
64
+ zodType,
65
+ };
66
+ if (zodType instanceof z.ZodObject) {
67
+ const columnKeys = Object.keys(zodType.shape);
68
+ const children = columnKeys.map((key) => {
69
+ const innerType = zodType.shape[key];
70
+ return zodTypeToRenderingNode(innerType, key);
71
+ });
72
+ return {
73
+ ...def,
74
+ renderType: "object",
75
+ children,
76
+ };
77
+ } else if (zodType instanceof z.ZodArray) {
78
+ const innerType = (zodType as z.ZodArray<z.ZodType<any>>).def.element;
79
+ if (innerType instanceof z.ZodString && baseKey.includes("images")) {
80
+ return {
81
+ ...def,
82
+ renderType: "array-images",
83
+ };
84
+ }
85
+ return {
86
+ ...def,
87
+ renderType: "array",
88
+ element: zodTypeToRenderingNode(innerType, baseKey),
89
+ };
90
+ } else if (zodType instanceof z.ZodUnion) {
91
+ const optionNodes = (zodType as z.ZodUnion<z.ZodType[]>).def.options.map(
92
+ (opt) => zodTypeToRenderingNode(opt, baseKey)
93
+ );
94
+ // TODO: ZodUnion이 들어있는 경우 핸들링
95
+ return optionNodes[0];
96
+ } else if (zodType instanceof z.ZodOptional) {
97
+ return {
98
+ ...zodTypeToRenderingNode(
99
+ (zodType as z.ZodOptional<z.ZodType>).def.innerType,
100
+ baseKey
101
+ ),
102
+ optional: true,
103
+ };
104
+ } else if (zodType instanceof z.ZodNullable) {
105
+ return {
106
+ ...zodTypeToRenderingNode(
107
+ (zodType as z.ZodNullable<z.ZodType>).def.innerType,
108
+ baseKey
109
+ ),
110
+ nullable: true,
111
+ };
112
+ } else {
113
+ return {
114
+ ...def,
115
+ renderType: resolveRenderType(baseKey, zodType),
116
+ };
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Zod 타입과 키 이름으로부터 적절한 RenderType을 결정합니다.
122
+ */
123
+ function resolveRenderType(
124
+ key: string,
125
+ zodType: z.ZodTypeAny
126
+ ): RenderingNode["renderType"] {
127
+ if (zodType instanceof z.ZodDate) {
128
+ return "datetime";
129
+ } else if (zodType instanceof z.ZodString) {
130
+ if (key.includes("img") || key.includes("image")) {
131
+ return "string-image";
132
+ } else if (zodType.description === "SQLDateTimeString") {
133
+ return "string-datetime";
134
+ } else if (key.endsWith("date")) {
135
+ return "string-date";
136
+ } else {
137
+ return "string-plain";
138
+ }
139
+ } else if (zodType instanceof z.ZodNumber) {
140
+ if (key === "id") {
141
+ return "number-id";
142
+ } else if (key.endsWith("_id")) {
143
+ return "number-fk_id";
144
+ } else {
145
+ return "number-plain";
146
+ }
147
+ } else if (zodType instanceof z.ZodBoolean) {
148
+ return "boolean";
149
+ } else if (zodType instanceof z.ZodEnum) {
150
+ return "enums";
151
+ } else if (zodType instanceof z.ZodRecord) {
152
+ return "record";
153
+ } else if (zodType instanceof z.ZodAny || zodType instanceof z.ZodUnknown) {
154
+ return "string-plain";
155
+ } else if (zodType instanceof z.ZodUnion) {
156
+ return "string-plain";
157
+ } else if (zodType instanceof z.ZodLiteral) {
158
+ return "string-plain";
159
+ } else {
160
+ throw new Error(`타입 파싱 불가 ${key} ${zodType.def.type}`);
161
+ }
162
+ }
163
+
164
+ /**
165
+ * EntityProp을 Zod 타입으로 변환합니다.
166
+ * 각 prop의 타입에 따라 적절한 Zod validator를 생성합니다.
167
+ */
168
+ export async function propToZodType(prop: EntityProp): Promise<z.ZodTypeAny> {
169
+ let zodType: z.ZodTypeAny = z.unknown();
170
+ if (isIntegerProp(prop)) {
171
+ zodType = z.number().int();
172
+ } else if (isBigIntegerProp(prop)) {
173
+ zodType = z.bigint();
174
+ } else if (isTextProp(prop)) {
175
+ zodType = z.string().max(getTextTypeLength(prop.textType));
176
+ } else if (isEnumProp(prop)) {
177
+ zodType = await getZodTypeById(prop.id);
178
+ } else if (isStringProp(prop)) {
179
+ zodType = z.string().max(prop.length);
180
+ } else if (isFloatProp(prop) || isDoubleProp(prop)) {
181
+ zodType = z.number();
182
+ } else if (isDecimalProp(prop)) {
183
+ zodType = z.string();
184
+ } else if (isBooleanProp(prop)) {
185
+ zodType = z.boolean();
186
+ } else if (isDateProp(prop)) {
187
+ zodType = z.string().length(10);
188
+ } else if (isTimeProp(prop)) {
189
+ zodType = z.string().length(8);
190
+ } else if (isDateTimeProp(prop)) {
191
+ zodType = z.date();
192
+ } else if (isTimestampProp(prop)) {
193
+ zodType = z.date();
194
+ } else if (isJsonProp(prop)) {
195
+ zodType = await getZodTypeById(prop.id);
196
+ } else if (isUuidProp(prop)) {
197
+ zodType = z.uuid();
198
+ } else if (isVirtualProp(prop)) {
199
+ zodType = await getZodTypeById(prop.id);
200
+ } else if (isRelationProp(prop)) {
201
+ if (
202
+ isBelongsToOneRelationProp(prop) ||
203
+ (isOneToOneRelationProp(prop) && prop.hasJoinColumn)
204
+ ) {
205
+ zodType = z.number().int();
206
+ }
207
+ } else {
208
+ throw new Error(`prop을 zodType으로 변환하는데 실패 ${prop}}`);
209
+ }
210
+
211
+ if ((prop as { unsigned?: boolean }).unsigned) {
212
+ zodType = (zodType as z.ZodNumber).nonnegative();
213
+ }
214
+ if (prop.nullable) {
215
+ zodType = zodType.nullable();
216
+ }
217
+
218
+ return zodType;
219
+ }
@@ -1,5 +1,5 @@
1
1
  import chalk from "chalk";
2
- import _ from "lodash";
2
+ import * as _ from "lodash-es";
3
3
  import { Sonamu } from "../api";
4
4
  import { EntityManager } from "../entity/entity-manager";
5
5
  import {
@@ -404,6 +404,9 @@ export class FixtureManagerClass {
404
404
  }
405
405
  }
406
406
 
407
+ await targetDB.destroy();
408
+ await sourceDB.destroy();
409
+
407
410
  return _.uniqBy(fixtures, (f) => f.fixtureId);
408
411
  }
409
412
 
@@ -554,6 +557,8 @@ export class FixtureManagerClass {
554
557
  });
555
558
  }
556
559
 
560
+ await db.destroy();
561
+
557
562
  return _.uniqBy(records, (r) => `${r.entityId}#${r.data.id}`);
558
563
  }
559
564
 
@@ -606,6 +611,8 @@ export class FixtureManagerClass {
606
611
 
607
612
  const q = db.insert(insertData).into(entity.table);
608
613
  await q.onDuplicateUpdate.apply(q, Object.keys(insertData));
614
+ console.log(chalk.green(`Inserted into ${entity.table}: #${fixture.id}`));
615
+
609
616
  return {
610
617
  entityId: fixture.entityId,
611
618
  id: fixture.id,
@@ -1,24 +1,7 @@
1
1
  import type { GuardKey } from "./../api/decorators";
2
- import type { FastifyCorsOptions } from "@fastify/cors";
3
- import type { FastifyFormbodyOptions } from "@fastify/formbody";
4
- import type {
5
- FastifyInstance,
6
- FastifyReply,
7
- FastifyRequest,
8
- FastifyServerOptions,
9
- } from "fastify";
10
- import type { QsPluginOptions } from "fastify-qs";
2
+ import type { FastifyReply, FastifyRequest } from "fastify";
11
3
  import { z } from "zod";
12
4
  import type { ApiDecoratorOptions, AuthContext, Context } from "../api";
13
- import type { FastifyMultipartOptions } from "@fastify/multipart";
14
- import type { Driver } from "../file-storage/driver";
15
- import type { SsePluginOptions } from "fastify-sse-v2/lib/types";
16
- import type { FastifyStaticOptions } from "@fastify/static";
17
- import { SecureSessionPluginOptions } from "@fastify/secure-session";
18
- import {
19
- DeserializeFunction,
20
- SerializeFunction,
21
- } from "@fastify/passport/dist/Authenticator";
22
5
 
23
6
  /*
24
7
  Enums
@@ -256,6 +239,22 @@ export type SMDInput<T extends string> = {
256
239
  PropNode
257
240
  */
258
241
 
242
+ /**
243
+ * 엔티티의 필드 구조를 트리 형태로 표현하는 중간 노드입니다.
244
+ *
245
+ * **목적**: Entity의 subset 필드 표현식(예: "id", "user.name", "tags[]")을
246
+ * 재귀적인 트리 구조로 파싱하여 Zod 스키마 생성의 중간 단계로 사용합니다.
247
+ *
248
+ * **변환 흐름**:
249
+ * Entity subset → EntityPropNode (트리 구조) → Zod 스키마 → RenderingNode (UI용)
250
+ *
251
+ * **nodeType**:
252
+ * - "plain": 단일 필드 (예: "id", "name")
253
+ * - "object": 중첩 객체 (예: "user.name" → user 객체)
254
+ * - "array": 배열 (예: "tags[]" → tags 배열)
255
+ *
256
+ * **사용 위치**: entity-converter.ts의 propNodeToZodType()
257
+ */
259
258
  export type EntityPropNode =
260
259
  | {
261
260
  nodeType: "plain";
@@ -639,6 +638,26 @@ export type ApiParamType =
639
638
  | ApiParamType.TupleType;
640
639
 
641
640
  /* Template */
641
+ /**
642
+ * UI 컴포넌트 렌더링을 위한 메타데이터 노드입니다.
643
+ *
644
+ * **목적**: Zod 스키마로부터 프론트엔드 UI 컴포넌트를 자동 생성하기 위한
645
+ * 렌더링 정보를 담은 트리 구조입니다. 각 필드가 어떤 UI 컴포넌트로
646
+ * 표현되어야 하는지(텍스트, 이미지, 날짜, Enum 선택 등)를 명시합니다.
647
+ *
648
+ * **변환 흐름**:
649
+ * Entity subset → EntityPropNode → Zod 스키마 → RenderingNode (UI용) → React 컴포넌트 코드 생성
650
+ *
651
+ * **주요 필드**:
652
+ * - `renderType`: UI 컴포넌트 유형 (string-plain, number-fk_id, enums, array 등)
653
+ * - `zodType`: 원본 Zod 스키마 (validation 용)
654
+ * - `children`: 중첩된 객체 필드들 (object일 때)
655
+ * - `element`: 배열 요소 타입 (array일 때)
656
+ *
657
+ * **사용 위치**:
658
+ * - zod-converter.ts의 zodTypeToRenderingNode()에서 생성
659
+ * - view_form.template.ts, view_list.template.ts 등에서 React 컴포넌트 코드 생성에 사용
660
+ */
642
661
  // 셀프 참조 타입이므로 Zod 생략하고 직접 정의
643
662
  export const RenderingNode = z.any();
644
663
  export type RenderingNode = {
@@ -842,7 +861,7 @@ export type SonamuFastifyConfig = {
842
861
  contextProvider: (
843
862
  defaultContext: Pick<
844
863
  Context,
845
- "request" | "reply" | "headers" | "createSSE"
864
+ "request" | "reply" | "headers" | "createSSE" | "naiteStore"
846
865
  > &
847
866
  AuthContext,
848
867
  request: FastifyRequest,
@@ -880,45 +899,3 @@ export type SonamuFastifyConfig = {
880
899
  };
881
900
  };
882
901
  };
883
-
884
- export type SonamuServerOptions = {
885
- fastify?: FastifyServerOptions;
886
-
887
- listen?: {
888
- port: number;
889
- host?: string;
890
- };
891
-
892
- plugins?: {
893
- cors?: boolean | FastifyCorsOptions;
894
- formbody?: boolean | FastifyFormbodyOptions;
895
- multipart?: boolean | FastifyMultipartOptions;
896
- qs?: boolean | QsPluginOptions;
897
- sse?: boolean | SsePluginOptions;
898
- static?: boolean | FastifyStaticOptions;
899
- session?: boolean | SecureSessionPluginOptions;
900
-
901
- custom?: (server: FastifyInstance) => void;
902
- };
903
-
904
- auth?:
905
- | boolean
906
- | {
907
- userSerializer: SerializeFunction<unknown, unknown>;
908
- userDeserializer: DeserializeFunction<unknown, unknown>;
909
- };
910
-
911
- apiConfig: SonamuFastifyConfig;
912
-
913
- storage?: Driver;
914
-
915
- lifecycle?: {
916
- onStart?: (server: FastifyInstance) => Promise<void> | void;
917
- onShutdown?: (server: FastifyInstance) => Promise<void> | void;
918
- onError?: (
919
- error: Error,
920
- request: FastifyRequest,
921
- reply: FastifyReply
922
- ) => Promise<void> | void;
923
- };
924
- };
@@ -1,3 +1,6 @@
1
+ import { glob } from "fs/promises";
2
+ import path from "path";
3
+
1
4
  /**
2
5
  * 비동기 조건으로 배열을 필터링합니다
3
6
  * @example
@@ -62,3 +65,17 @@ export async function reduceAsync<T, U>(
62
65
  }
63
66
  return accumulator;
64
67
  }
68
+
69
+ /**
70
+ * 비동기 glob 함수입니다.
71
+ * AsyncIterableIterator로 날아오는 glob의 반환을 받아 끝까지 돌아서 배열로 반환합니다.
72
+ * @param pathPattern
73
+ * @returns
74
+ */
75
+ export async function globAsync(pathPattern: string): Promise<string[]> {
76
+ const files: string[] = [];
77
+ for await (const file of glob(path.resolve(pathPattern))) {
78
+ files.push(file);
79
+ }
80
+ return files;
81
+ }
@@ -0,0 +1,4 @@
1
+ export function centerText(text: string): string {
2
+ const margin = (process.stdout.columns - text.length) / 2;
3
+ return " ".repeat(margin) + text + " ".repeat(margin);
4
+ }
@@ -0,0 +1,69 @@
1
+ import { fileURLToPath, pathToFileURL } from 'url';
2
+ import { dirname } from 'path';
3
+
4
+ /**
5
+ * import.meta.url로부터 __filename 생성
6
+ *
7
+ * @example
8
+ * const __filename = getFilename(import.meta.url);
9
+ */
10
+ export function getFilename(metaUrl: string): string {
11
+ return fileURLToPath(metaUrl);
12
+ }
13
+
14
+ /**
15
+ * import.meta.url로부터 __dirname 생성
16
+ *
17
+ * @example
18
+ * const __dirname = getDirname(import.meta.url);
19
+ */
20
+ export function getDirname(metaUrl: string): string {
21
+ return dirname(fileURLToPath(metaUrl));
22
+ }
23
+
24
+ /**
25
+ * 절대 경로를 file:// URL로 변환 (동적 임포트용)
26
+ *
27
+ * @param absolutePath - 절대 파일 경로
28
+ * @returns file:// URL 문자열
29
+ *
30
+ * @example
31
+ * const url = createImportUrl('/path/to/file.js');
32
+ * await import(url);
33
+ */
34
+ export function createImportUrl(
35
+ absolutePath: string
36
+ ): string {
37
+ const fileUrl = pathToFileURL(absolutePath).href;
38
+ return fileUrl;
39
+ }
40
+
41
+ /**
42
+ * HMR 환경 감지
43
+ *
44
+ * @returns hot reload 환경인지 여부
45
+ */
46
+ export function isHotReloadServer(): boolean {
47
+ return process.env.HOT === 'yes';
48
+ }
49
+
50
+ /**
51
+ * 캐시를 무시하고 새로 임포트(cache busting)하는데, 이때 가져온 모듈의 exported members들을 배열로 가져옵니다.
52
+ *
53
+ * 가령 모듈에서 `export const user = { id: number; name: string; }` 이렇게 정의했다면,
54
+ * 이 함수는 `[{ name: "user", value: { id: number; name: string; } }]` 이렇게 반환합니다.
55
+ *
56
+ * @param filePath
57
+ * @returns { name: string; value: ExportedMemberT }[]
58
+ */
59
+ export async function importMembers<ExportedMemberT>(
60
+ filePath: string
61
+ ): Promise<{ name: string; value: ExportedMemberT }[]> {
62
+ const imported = await import(createImportUrl(filePath));
63
+
64
+ const allExportedMembers = Object.entries<ExportedMemberT>(imported).map(
65
+ ([name, value]) => ({ name, value })
66
+ );
67
+
68
+ return allExportedMembers;
69
+ }
@@ -0,0 +1,102 @@
1
+ import { isHotReloadServer } from "./esm-utils.js";
2
+
3
+ /**
4
+ * API 패키지 내부 상대 경로 (src/ 또는 dist/로 시작)
5
+ *
6
+ * **사용 위치**: API 패키지 내부 파일 참조
7
+ * **예시**:
8
+ * - `"src/application/user/user.model.ts"`
9
+ * - `"dist/application/user/user.model.js"`
10
+ *
11
+ * **기준점**: `Sonamu.apiRootPath` (일반적으로 프로젝트의 `/api` 디렉토리)
12
+ */
13
+ export type ApiRelativePath = `${"src" | "dist"}/${string}` | 'sonamu.config.ts';
14
+
15
+ /**
16
+ * 앱 루트 기준 상대 경로 (api/, web/ 등 타겟 디렉토리로 시작)
17
+ *
18
+ * **사용 위치**: 다른 타겟(api, web 등)의 파일 참조
19
+ * **예시**:
20
+ * - `"api/src/application/user/user.model.ts"`
21
+ * - `"web/src/pages/admin/users/index.tsx"`
22
+ * - `"app/dist/index.js"`
23
+ *
24
+ * **기준점**: `Sonamu.appRootPath` (일반적으로 모노레포 루트)
25
+ */
26
+ export type AppRelativePath = `${string}/${"src" | "dist"}/${string}`;
27
+
28
+ /**
29
+ * 시스템 절대 경로 (루트 / 부터 시작)
30
+ *
31
+ * **사용 위치**: 파일시스템 직접 접근, glob 패턴
32
+ * **예시**: `"/Users/potados/Projects/sonamu/api/src/application/user/user.model.ts"`
33
+ *
34
+ * **중요**:
35
+ * - import 시에는 로더가 알아서 src/dist 변환해주므로 어느 경로든 가능
36
+ * - fs 직접 접근 시에는 실제 존재하는 경로를 사용해야 함
37
+ * - Dev: src/*.ts 경로 사용
38
+ * - Prod: dist/*.js 경로 사용
39
+ */
40
+ export type AbsolutePath = `/${string}`;
41
+
42
+ /**
43
+ * 어떤 경로가 들어오든, 현재 실행 환경에 맞는 경로로 바꿔줍니다.
44
+ *
45
+ * "src/application/user/user.model.ts"가 들어왔을 때 개발 모드라면?
46
+ * -> "src/application/user/user.model.ts"
47
+ * "src/application/user/user.model.ts"가 들어왔을 때 배포 모드라면?
48
+ * -> "dist/application/user/user.model.js"
49
+ * "dist/application/user/user.model.js"가 들어왔을 때 개발 모드라면?
50
+ * -> "src/application/user/user.model.ts"
51
+ * "dist/application/user/user.model.js"가 들어왔을 때 배포 모드라면?
52
+ * -> "dist/application/user/user.model.js"
53
+ *
54
+ * "/src/application/user/user.model.ts"가 들어왔을 때 개발 모드라면?
55
+ * -> "/src/application/user/user.model.ts"
56
+ * "/src/application/user/user.model.ts"가 들어왔을 때 배포 모드라면?
57
+ * -> "/dist/application/user/user.model.js"
58
+ * "/dist/application/user/user.model.js"가 들어왔을 때 개발 모드라면?
59
+ * -> "/dist/application/user/user.model.js"
60
+ * "/dist/application/user/user.model.js"가 들어왔을 때 배포 모드라면?
61
+ * -> "/dist/application/user/user.model.js"
62
+ *
63
+ * "/Users/potados/Projects/sonamu/api/src/application/user/user.model.ts"가 들어왔을 때 개발 모드라면?
64
+ * -> "/Users/potados/Projects/sonamu/api/src/application/user/user.model.ts"
65
+ * "/Users/potados/Projects/sonamu/api/src/application/user/user.model.ts"가 들어왔을 때 배포 모드라면?
66
+ * -> "/Users/potados/Projects/sonamu/api/dist/application/user/user.model.js"
67
+ * "/Users/potados/Projects/sonamu/api/dist/application/user/user.model.js"가 들어왔을 때 개발 모드라면?
68
+ * -> "/Users/potados/Projects/sonamu/api/src/application/user/user.model.ts"
69
+ * "/Users/potados/Projects/sonamu/api/dist/application/user/user.model.js"가 들어왔을 때 배포 모드라면?
70
+ * -> "/Users/potados/Projects/sonamu/api/dist/application/user/user.model.js"
71
+ *
72
+ * "src/application/user/user.model.ts?hot=1234567890"가 들어왔을 때 개발 모드라면?
73
+ * -> "src/application/user/user.model.ts?hot=1234567890"
74
+ * "src/application/user/user.model.ts?hot=1234567890"가 들어왔을 때 배포 모드라면?
75
+ * -> "dist/application/user/user.model.js?hot=1234567890"
76
+ * "dist/application/user/user.model.js?hot=1234567890"가 들어왔을 때 개발 모드라면?
77
+ * -> "src/application/user/user.model.ts?hot=1234567890"
78
+ * "dist/application/user/user.model.js?hot=1234567890"가 들어왔을 때 배포 모드라면?
79
+ * -> "dist/application/user/user.model.js?hot=1234567890"
80
+ *
81
+ * "/Users/potados/Projects/sonamu/api/src/application/user/user.model.ts?hot=1234567890"가 들어왔을 때 개발 모드라면?
82
+ * -> "/Users/potados/Projects/sonamu/api/src/application/user/user.model.ts?hot=1234567890"
83
+ * "/Users/potados/Projects/sonamu/api/src/application/user/user.model.ts?hot=1234567890"가 들어왔을 때 배포 모드라면?
84
+ * -> "/Users/potados/Projects/sonamu/api/dist/application/user/user.model.js?hot=1234567890"
85
+ * "/Users/potados/Projects/sonamu/api/dist/application/user/user.model.js?hot=1234567890"가 들어왔을 때 개발 모드라면?
86
+ * -> "/Users/potados/Projects/sonamu/api/src/application/user/user.model.ts?hot=1234567890"
87
+ * "/Users/potados/Projects/sonamu/api/dist/application/user/user.model.js?hot=1234567890"가 들어왔을 때 배포 모드라면?
88
+ * -> "/Users/potados/Projects/sonamu/api/dist/application/user/user.model.js?hot=1234567890"
89
+ *
90
+ * @param anyPath
91
+ * @returns
92
+ */
93
+ export function runtimePath(
94
+ anyPath: string,
95
+ isDev: boolean = isHotReloadServer()
96
+ ): string {
97
+ if (isDev) {
98
+ return anyPath.replace(/dist\//, "src/").replace(/\.js/, ".ts");
99
+ } else {
100
+ return anyPath.replace(/src\//, "dist/").replace(/\.ts/, ".js");
101
+ }
102
+ }