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,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
+ }
@@ -0,0 +1,46 @@
1
+ import chalk from "chalk";
2
+ import { setTimeout as setTimeoutPromises } from "timers/promises";
3
+
4
+ /**
5
+ * 주어진 작업을 실행합니다.
6
+ * 주어진 프로세스 이벤트(=시그널)가 발생하였을 때에도 최대 한계(delayBeforeShutdown) 동안 작업을 기다린 후 종료합니다.
7
+ * @param {() => Promise<void>} job - 실행할 작업
8
+ * @param {event: NodeJS.Signals; delayBeforeShutdown: number} options - 옵션
9
+ * @param {NodeJS.Signals} options.event - 프로세스 이벤트
10
+ * @param {number} options.delayBeforeShutdown - 최대 한계 시간
11
+ */
12
+ export async function runWithGracefulShutdown(
13
+ job: () => Promise<void>,
14
+ {
15
+ whenThisHappens: event,
16
+ waitForUpTo: delayBeforeShutdown,
17
+ }: { whenThisHappens: NodeJS.Signals; waitForUpTo: number } = {
18
+ whenThisHappens: "SIGUSR2",
19
+ waitForUpTo: 20000,
20
+ }
21
+ ): Promise<void> {
22
+ let isRunning = true as boolean;
23
+
24
+ const abortController = new AbortController();
25
+ const onEvent = async () => {
26
+ if (!isRunning) {
27
+ process.exit(0);
28
+ }
29
+ console.log(chalk.magentaBright(`wait for syncing done....`));
30
+
31
+ try {
32
+ await setTimeoutPromises(delayBeforeShutdown, "waiting-sync", {
33
+ signal: abortController.signal,
34
+ });
35
+ } catch {}
36
+ console.log(chalk.magentaBright(`Syncing DONE!`));
37
+ process.exit(0);
38
+ };
39
+ process.on(event, onEvent);
40
+
41
+ await job();
42
+
43
+ isRunning = false;
44
+ abortController.abort();
45
+ process.off(event, onEvent);
46
+ }
@@ -1,4 +1,4 @@
1
- import _ from "lodash";
1
+ import * as _ from "lodash-es";
2
2
  import { AST, ColumnRef, Expr, ExpressionValue, Select } from "node-sql-parser";
3
3
 
4
4
  export function getTableName(expr: ColumnRef) {
@@ -1,60 +1,30 @@
1
1
  import path from "path";
2
- import { glob } from "fs/promises";
3
2
  import fs from "fs";
3
+ import { AbsolutePath } from "./path-utils";
4
4
 
5
- export async function globAsync(pathPattern: string): Promise<string[]> {
6
- const files: string[] = [];
7
- for await (const file of glob(path.resolve(pathPattern))) {
8
- files.push(file);
9
- }
10
- return files;
11
- }
12
- export async function importMultiple(
13
- filePaths: string[],
14
- doRefresh: boolean = false
15
- ): Promise<{ filePath: string; imported: any }[]> {
16
- const results: { filePath: string; imported: any }[] = [];
17
-
18
- for (const filePath of filePaths) {
19
- let importPath = "./" + path.relative(__dirname, filePath);
20
-
21
- if (doRefresh) {
22
- if (require.resolve) {
23
- delete require.cache[require.resolve(importPath)];
24
- } else {
25
- importPath += `?t=${Date.now()}`;
26
- }
27
- }
28
-
29
- const imported = await import(importPath);
30
- results.push({
31
- filePath,
32
- imported,
33
- });
34
- }
35
-
36
- return results;
37
- }
38
- export async function findAppRootPath() {
5
+ export async function findAppRootPath(): Promise<AbsolutePath> {
39
6
  const apiRootPath = findApiRootPath();
40
- return apiRootPath.split(path.sep).slice(0, -1).join(path.sep);
7
+ return apiRootPath
8
+ .split(path.sep)
9
+ .slice(0, -1)
10
+ .join(path.sep) as AbsolutePath;
41
11
  }
42
12
 
43
- export function findApiRootPath() {
13
+ export function findApiRootPath(): AbsolutePath {
44
14
  // NOTE: for support npm / yarn workspaces
45
15
  const workspacePath = process.env["INIT_CWD"];
46
16
  if (workspacePath && workspacePath.length !== 0) {
47
- return workspacePath;
17
+ return workspacePath as AbsolutePath;
48
18
  }
49
19
 
50
- const basePath = require.main?.path ?? __dirname;
20
+ const basePath = import.meta.filename;
51
21
  let dir = path.dirname(basePath);
52
22
  if (dir.includes("/.yarn/")) {
53
23
  dir = dir.split("/.yarn/")[0];
54
24
  }
55
25
  do {
56
26
  if (fs.existsSync(path.join(dir, "/package.json"))) {
57
- return dir.split(path.sep).join(path.sep);
27
+ return dir.split(path.sep).join(path.sep) as AbsolutePath;
58
28
  }
59
29
  dir = dir.split(path.sep).slice(0, -1).join(path.sep);
60
30
  } while (dir.split(path.sep).length > 1);
@@ -64,3 +34,7 @@ export function findApiRootPath() {
64
34
  export function nonNullable<T>(value: T): value is NonNullable<T> {
65
35
  return value !== null && value !== undefined;
66
36
  }
37
+
38
+ export function exhaustive(_param: never) {
39
+ throw new Error(`exhaustive`);
40
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  import { z } from 'zod';
3
2
 
4
3
  type ValidationError = {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/api/base-frame.ts"],"sourcesContent":["import { Knex } from \"knex\";\nimport { DB, DBPreset } from \"../database/db\";\nimport { UpsertBuilder } from \"../database/upsert-builder\";\n\nexport abstract class BaseFrameClass {\n getDB(which: DBPreset): Knex {\n return DB.getDB(which);\n }\n\n getUpsertBuilder() {\n return new UpsertBuilder();\n }\n}\n"],"names":["BaseFrameClass","getDB","which","DB","getUpsertBuilder","UpsertBuilder"],"mappings":"oGAIsBA,wDAAAA,kCAHO,6CACC,qpBAEvB,IAAA,AAAeA,4BAAf,iCAAeA,wCAAAA,8BAAAA,iBACpBC,IAAAA,cAAAA,SAAAA,MAAMC,KAAe,EACnB,OAAOC,MAAE,CAACF,KAAK,CAACC,MAClB,IAEAE,IAAAA,yBAAAA,SAAAA,mBACE,OAAO,IAAIC,4BAAa,AAC1B,YAPoBL"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/api/caster.ts"],"sourcesContent":["import assert from \"assert\";\nimport { z } from \"zod\";\nimport type { $ZodType } from \"zod/v4/core\";\n\nfunction isNumberType(zodType: $ZodType): zodType is z.ZodNumber {\n return zodType instanceof z.ZodNumber;\n}\n\nfunction isNullOrOptional(zodType: $ZodType): zodType is z.ZodNullable | z.ZodOptional {\n return zodType instanceof z.ZodNullable || zodType instanceof z.ZodOptional;\n}\n\n// optional, nullable 무관하게 ZodNumber 체크\nfunction isZodNumberAnyway(zodType: $ZodType) {\n if (isNumberType(zodType)) {\n return true;\n }\n\n // ZodNullable 또는 ZodOptional일 때\n if (isNullOrOptional(zodType) && isNumberType(zodType.def.innerType)) {\n return true;\n }\n\n return false;\n}\n\n// ZodType을 이용해 raw를 Type Coercing\nexport function caster(zodType: $ZodType, raw: any): any {\n if (isZodNumberAnyway(zodType) && typeof raw === \"string\") {\n // number\n return Number(raw);\n } else if (\n zodType instanceof z.ZodUnion &&\n zodType.options.some((opt) => isZodNumberAnyway(opt))\n ) {\n // zArrayable Number 케이스 처리\n if (Array.isArray(raw)) {\n const numType = zodType.options.find(opt => isNumberType(opt));\n assert(numType !== undefined);\n return raw.map((elem: any) => caster(numType, elem));\n } else {\n return Number(raw);\n }\n } else if (\n zodType instanceof z.ZodBoolean &&\n (raw === \"true\" || raw === \"false\")\n ) {\n // boolean\n return raw === \"true\";\n } else if (\n raw !== null &&\n Array.isArray(raw) &&\n zodType instanceof z.ZodArray\n ) {\n // array\n return raw.map((elem: any) => caster(zodType.element, elem));\n } else if (\n zodType instanceof z.ZodObject &&\n typeof raw === \"object\" &&\n raw !== null\n ) {\n // object\n return Object.keys(raw).reduce((r, rawKey) => {\n r[rawKey] = caster(zodType.shape[rawKey], raw[rawKey]);\n return r;\n }, {} as any);\n } else if (zodType instanceof z.ZodOptional) {\n // optional\n return caster(zodType.def.innerType, raw);\n } else if (zodType instanceof z.ZodNullable) {\n // nullable\n return caster(zodType.def.innerType, raw);\n } else if (\n zodType instanceof z.ZodDate &&\n new Date(raw).toString() !== \"Invalid Date\"\n ) {\n // date\n return new Date(raw);\n } else {\n // 나머지는 처리 안함\n return raw;\n }\n}\n\nexport function fastifyCaster(schema: z.ZodObject<any>) {\n return z.preprocess((raw: any) => {\n return caster(schema, raw);\n }, schema);\n}\n"],"names":["caster","fastifyCaster","isNumberType","zodType","z","ZodNumber","isNullOrOptional","ZodNullable","ZodOptional","isZodNumberAnyway","def","innerType","raw","Number","ZodUnion","options","some","opt","Array","isArray","numType","find","assert","undefined","map","elem","ZodBoolean","ZodArray","element","ZodObject","Object","keys","reduce","r","rawKey","shape","ZodDate","Date","toString","schema","preprocess"],"mappings":"mPA2BgBA,gBAAAA,YAyDAC,uBAAAA,2EApFG,4BACD,oZAGlB,SAASC,aAAaC,OAAiB,EACrC,OAAOA,AAAO,YAAPA,QAAmBC,MAAC,CAACC,SAAS,CACvC,CAEA,SAASC,iBAAiBH,OAAiB,EACzC,OAAOA,AAAO,YAAPA,QAAmBC,MAAC,CAACG,WAAW,GAAIJ,AAAO,YAAPA,QAAmBC,MAAC,CAACI,WAAW,CAC7E,CAGA,SAASC,kBAAkBN,OAAiB,EAC1C,GAAID,aAAaC,SAAU,CACzB,OAAO,IACT,CAGA,GAAIG,iBAAiBH,UAAYD,aAAaC,QAAQO,GAAG,CAACC,SAAS,EAAG,CACpE,OAAO,IACT,CAEA,OAAO,KACT,CAGO,SAASX,OAAOG,OAAiB,CAAES,GAAQ,EAChD,GAAIH,kBAAkBN,UAAY,OAAOS,MAAQ,SAAU,CAEzD,OAAOC,OAAOD,IAChB,MAAO,GACLT,AAAO,YAAPA,QAAmBC,MAAC,CAACU,QAAQ,GAC7BX,QAAQY,OAAO,CAACC,IAAI,CAAC,SAACC,YAAQR,kBAAkBQ,OAChD,CAEA,GAAIC,MAAMC,OAAO,CAACP,KAAM,CACtB,IAAMQ,QAAUjB,QAAQY,OAAO,CAACM,IAAI,CAACJ,SAAAA,YAAOf,aAAae,OACzDK,GAAAA,eAAM,EAACF,UAAYG,WACnB,OAAOX,IAAIY,GAAG,CAAC,SAACC,aAAczB,OAAOoB,QAASK,OAChD,KAAO,CACL,OAAOZ,OAAOD,IAChB,CACF,MAAO,GACLT,AAAO,YAAPA,QAAmBC,MAAC,CAACsB,UAAU,GAC9Bd,CAAAA,MAAQ,QAAUA,MAAQ,OAAM,EACjC,CAEA,OAAOA,MAAQ,MACjB,MAAO,GACLA,MAAQ,MACRM,MAAMC,OAAO,CAACP,MACdT,AAAO,YAAPA,QAAmBC,MAAC,CAACuB,QAAQ,EAC7B,CAEA,OAAOf,IAAIY,GAAG,CAAC,SAACC,aAAczB,OAAOG,QAAQyB,OAAO,CAAEH,OACxD,MAAO,GACLtB,AAAO,YAAPA,QAAmBC,MAAC,CAACyB,SAAS,GAC9B,CAAA,OAAOjB,8BAAP,SAAOA,IAAE,IAAM,UACfA,MAAQ,KACR,CAEA,OAAOkB,OAAOC,IAAI,CAACnB,KAAKoB,MAAM,CAAC,SAACC,EAAGC,QACjCD,CAAC,CAACC,OAAO,CAAGlC,OAAOG,QAAQgC,KAAK,CAACD,OAAO,CAAEtB,GAAG,CAACsB,OAAO,EACrD,OAAOD,CACT,EAAG,CAAC,EACN,MAAO,GAAI9B,AAAO,YAAPA,QAAmBC,MAAC,CAACI,WAAW,EAAE,CAE3C,OAAOR,OAAOG,QAAQO,GAAG,CAACC,SAAS,CAAEC,IACvC,MAAO,GAAIT,AAAO,YAAPA,QAAmBC,MAAC,CAACG,WAAW,EAAE,CAE3C,OAAOP,OAAOG,QAAQO,GAAG,CAACC,SAAS,CAAEC,IACvC,MAAO,GACLT,AAAO,YAAPA,QAAmBC,MAAC,CAACgC,OAAO,GAC5B,IAAIC,KAAKzB,KAAK0B,QAAQ,KAAO,eAC7B,CAEA,OAAO,IAAID,KAAKzB,IAClB,KAAO,CAEL,OAAOA,GACT,CACF,CAEO,SAASX,cAAcsC,MAAwB,EACpD,OAAOnC,MAAC,CAACoC,UAAU,CAAC,SAAC5B,KACnB,OAAOZ,OAAOuC,OAAQ3B,IACxB,EAAG2B,OACL"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/api/code-converters.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type { $ZodLooseShape } from \"zod/v4/core\"\nimport {\n ApiParam,\n ApiParamType,\n EntityProp,\n EntityPropNode,\n TextProp,\n isBelongsToOneRelationProp,\n isBigIntegerProp,\n isBooleanProp,\n isDateProp,\n isDateTimeProp,\n isDecimalProp,\n isDoubleProp,\n isEnumProp,\n isFloatProp,\n isIntegerProp,\n isJsonProp,\n isOneToOneRelationProp,\n isRelationProp,\n isStringProp,\n isTextProp,\n isTimeProp,\n isTimestampProp,\n isUuidProp,\n isVirtualProp,\n} from \"../types/types\";\nimport { ExtendedApi } from \"./decorators\";\nimport type { Literal } from \"zod/v4/core/util\";\n\n// <any>를 자제하고, Zod에서 제약하는 기본적인 Generic Type Parameter를 사용함.\ntype AnyZodRecord = z.ZodRecord<z.ZodString | z.ZodNumber | z.ZodSymbol, z.ZodType>;\ntype AnyZodObject = z.ZodObject<$ZodLooseShape>;\ntype AnyZodArray = z.ZodArray<z.ZodType>;\ntype AnyZodNullable = z.ZodNullable<z.ZodType>;\ntype AnyZodOptional = z.ZodOptional<z.ZodType>;\ntype AnyZodDefault = z.ZodDefault<z.ZodType>;\ntype AnyZodLiteral = z.ZodLiteral<Literal>;\ntype AnyZodUnion = z.ZodUnion<z.ZodType[]>;\n\n/*\n ExtendedApi 에서 ZodObject 리턴\n*/\nexport function getZodObjectFromApi(\n api: ExtendedApi,\n references: {\n [id: string]: AnyZodObject;\n } = {}\n) {\n if (api.typeParameters?.length > 0) {\n api.typeParameters.map((typeParam) => {\n if (typeParam.constraint) {\n let zodType = getZodTypeFromApiParamType(\n typeParam.constraint,\n references\n );\n (references[typeParam.id] as any) = zodType;\n }\n });\n }\n\n const ReqType = getZodObjectFromApiParams(\n api.parameters.filter(\n (param) =>\n !ApiParamType.isContext(param.type) &&\n !ApiParamType.isRefKnex(param.type) &&\n !(param.optional === true && param.name.startsWith(\"_\")) // _로 시작하는 파라미터는 제외\n ),\n references\n );\n return ReqType;\n}\n\n/*\n ZodObject를 통해 ApiParam 리턴\n*/\nexport function getZodObjectFromApiParams(\n apiParams: ApiParam[],\n references: {\n [id: string]: AnyZodObject;\n } = {}\n): z.ZodObject {\n return z.object(\n apiParams.reduce((r, param) => {\n let zodType = getZodTypeFromApiParamType(param.type, references);\n if (param.optional) {\n zodType = zodType.optional();\n }\n return {\n ...r,\n [param.name]: zodType,\n };\n }, {})\n );\n}\n\n/*\n ApiParamType으로 ZodType 컨버팅\n*/\nexport function getZodTypeFromApiParamType(\n paramType: ApiParamType,\n references: {\n [id: string]: AnyZodObject;\n }\n): z.ZodType<unknown> {\n switch (paramType) {\n case \"string\":\n return z.string();\n case \"number\":\n return z.number();\n case \"boolean\":\n return z.boolean();\n default:\n const advType = paramType as { t: string };\n switch (advType.t) {\n case \"string-literal\":\n case \"numeric-literal\":\n return z.literal((advType as any).value);\n case \"object\":\n const objType = paramType as { t: string; props: ApiParam[] };\n return getZodObjectFromApiParams(objType.props);\n case \"array\":\n const arrType = paramType as {\n t: string;\n elementsType: ApiParamType;\n };\n return z.array(\n getZodTypeFromApiParamType(arrType.elementsType, references)\n );\n case \"ref\":\n const refType = paramType as {\n t: string;\n id: string;\n args?: ApiParamType[];\n };\n\n // Date 타입 처리\n if (refType.id === \"Date\") {\n return z.date();\n }\n\n // 객체 키 관리 유틸리티\n if ([\"Pick\", \"Omit\"].includes(refType.id)) {\n if (refType.args?.length !== 2) {\n throw new Error(`잘못된 ${refType.id}`);\n }\n const [obj, literalOrUnion] = refType.args!.map((arg) =>\n getZodTypeFromApiParamType(arg, references)\n ) as [AnyZodObject, z.ZodUnion<any> | AnyZodLiteral];\n let keys: string[] = [];\n if (literalOrUnion instanceof z.ZodUnion) {\n keys = literalOrUnion.def.options.map(\n (option: { def: { value: string } }) => option.def.value\n );\n } else {\n keys = (literalOrUnion as z.ZodLiteral<string>).def.values;\n }\n const keyRecord = keys.reduce((result, key) => {\n return {\n ...result,\n [key]: true,\n };\n }, {} as any);\n\n if (refType.id === \"Pick\") {\n if (obj.pick) {\n return obj.pick(keyRecord);\n }\n } else {\n if (obj.omit) {\n return obj.omit(keyRecord);\n }\n }\n }\n if ([\"Partial\"].includes(refType.id)) {\n if (refType.args?.length !== 1) {\n throw new Error(`잘못된 ${refType.id}`);\n }\n const obj = getZodTypeFromApiParamType(refType.args[0], references);\n return (obj as any).partial();\n }\n\n const reference = references[refType.id];\n if (reference === undefined) {\n return z.string();\n // throw new Error(`ref 참조 불가 ${refType.id}`);\n }\n return reference;\n case \"union\":\n const unionType = paramType as {\n t: string;\n types: ApiParamType[];\n };\n // nullable 유니온\n if (\n unionType.types.length === 2 &&\n unionType.types.some((type) => type === \"null\")\n ) {\n if (unionType.types[0] === \"null\") {\n return getZodTypeFromApiParamType(\n unionType.types[1],\n references\n ).nullable();\n } else {\n return getZodTypeFromApiParamType(\n unionType.types[0],\n references\n ).nullable();\n }\n }\n\n // 일반 유니온\n return z.union(\n unionType.types.map((type) =>\n getZodTypeFromApiParamType(type, references)\n ) as any\n );\n case \"intersection\":\n const intersectionType = paramType as {\n t: string;\n types: ApiParamType[];\n };\n return intersectionType.types.reduce((result, type, index) => {\n const resolvedType = getZodTypeFromApiParamType(type, references);\n if (index === 0) {\n return resolvedType;\n } else {\n return z.intersection(result as any, resolvedType);\n }\n }, z.unknown() as any) as any;\n case \"tuple-type\":\n const tupleType = paramType as ApiParamType.TupleType;\n return z.tuple(\n tupleType.elements.map((elem) =>\n getZodTypeFromApiParamType(elem, references)\n ) as any\n );\n }\n return z.unknown();\n }\n}\n\nexport function propNodeToZodTypeDef(\n propNode: EntityPropNode,\n injectImportKeys: string[]\n): string {\n if (propNode.nodeType === \"plain\") {\n return propToZodTypeDef(propNode.prop, injectImportKeys);\n } else if (propNode.nodeType === \"array\") {\n return [\n propNode.prop ? `${propNode.prop.name}: ` : \"\",\n \"z.array(z.object({\",\n propNode.children\n .map((childPropNode) =>\n propNodeToZodTypeDef(childPropNode, injectImportKeys)\n )\n .join(\"\\n\"),\n \"\",\n \"})),\",\n ].join(\"\\n\");\n } else if (propNode.nodeType === \"object\") {\n return [\n propNode.prop ? `${propNode.prop.name}: ` : \"\",\n \"z.object({\",\n propNode.children\n .map((childPropNode) =>\n propNodeToZodTypeDef(childPropNode, injectImportKeys)\n )\n .join(\"\\n\"),\n \"\",\n `})${propNode.prop && propNode.prop.nullable ? \".nullable()\" : \"\"},`,\n ].join(\"\\n\");\n } else {\n throw Error;\n }\n}\n\nexport function getTextTypeLength(textType: TextProp[\"textType\"]): number {\n switch (textType) {\n case \"text\":\n return 1024 * 64 - 1;\n case \"mediumtext\":\n return 1024 * 1024 * 16 - 1;\n case \"longtext\":\n return 1024 * 1024 * 1024 * 4 - 1;\n }\n}\n\nexport function propToZodTypeDef(\n prop: EntityProp,\n injectImportKeys: string[]\n): string {\n let stmt: string;\n if (isIntegerProp(prop)) {\n stmt = `${prop.name}: z.int()`;\n } else if (isBigIntegerProp(prop)) {\n stmt = `${prop.name}: z.bigint()`;\n } else if (isTextProp(prop)) {\n stmt = `${prop.name}: z.string().max(${getTextTypeLength(prop.textType)})`;\n } else if (isEnumProp(prop)) {\n stmt = `${prop.name}: ${prop.id}`;\n injectImportKeys.push(prop.id);\n } else if (isStringProp(prop)) {\n stmt = `${prop.name}: z.string().max(${prop.length})`;\n } else if (isDecimalProp(prop)) {\n stmt = `${prop.name}: z.string()`;\n } else if (isFloatProp(prop) || isDoubleProp(prop)) {\n stmt = `${prop.name}: z.number()`;\n } else if (isBooleanProp(prop)) {\n stmt = `${prop.name}: z.boolean()`;\n } else if (isDateProp(prop)) {\n stmt = `${prop.name}: z.string().length(10)`;\n } else if (isTimeProp(prop)) {\n stmt = `${prop.name}: z.string().length(8)`;\n } else if (isDateTimeProp(prop)) {\n stmt = `${prop.name}: z.date()`;\n } else if (isTimestampProp(prop)) {\n stmt = `${prop.name}: z.date()`;\n } else if (isJsonProp(prop)) {\n stmt = `${prop.name}: ${prop.id}`;\n injectImportKeys.push(prop.id);\n } else if (isUuidProp(prop)) {\n stmt = `${prop.name}: z.uuid()`;\n } else if (isVirtualProp(prop)) {\n stmt = `${prop.name}: ${prop.id}`;\n injectImportKeys.push(prop.id);\n } else if (isRelationProp(prop)) {\n if (\n isBelongsToOneRelationProp(prop) ||\n (isOneToOneRelationProp(prop) && prop.hasJoinColumn)\n ) {\n stmt = `${prop.name}_id: z.int()`;\n } else {\n // 그외 relation 케이스 제외\n return `// ${prop.name}: ${prop.relationType} ${prop.with}`;\n }\n } else {\n return \"// unable to resolve\";\n }\n\n if ((prop as { unsigned?: boolean }).unsigned) {\n stmt += \".nonnegative()\";\n }\n if (prop.nullable) {\n stmt += \".nullable()\";\n }\n\n return stmt + \",\";\n}\n\n// TODO(Haze, 251031): \"template_literal\", \"file\"에 대한 지원이 필요함.\nexport function zodTypeToZodCode(zt: z.ZodType): string {\n switch (zt.def.type) {\n case \"string\":\n return \"z.string()\";\n case \"number\":\n return \"z.number()\";\n case \"bigint\":\n return \"z.bigint()\";\n case \"boolean\":\n return \"z.boolean()\";\n case \"date\":\n return \"z.date()\";\n case \"null\":\n return \"z.null()\";\n case \"undefined\":\n return \"z.undefined()\";\n case \"any\":\n return \"z.any()\";\n case \"unknown\":\n return \"z.unknown()\";\n case \"never\":\n return \"z.never()\";\n case \"nullable\":\n return zodTypeToZodCode((zt as AnyZodNullable).def.innerType) + \".nullable()\";\n case \"default\":\n const zDefaultDef = (zt as AnyZodDefault).def;\n return (\n zodTypeToZodCode(zDefaultDef.innerType) +\n `.default(${zDefaultDef.defaultValue})`\n );\n case \"record\":\n const zRecordDef = (zt as AnyZodRecord).def;\n return `z.record(${zodTypeToZodCode(zRecordDef.keyType)}, ${zodTypeToZodCode(\n zRecordDef.valueType\n )})`;\n case \"literal\":\n const items = Array.from((zt as z.ZodLiteral<any>).values).map(value => {\n if (typeof value === \"string\") {\n return `\"${value}\"`;\n }\n\n if (value === null) {\n return `null`;\n }\n\n if (value === undefined) {\n return `undefined`;\n }\n\n return `${value}`;\n });\n\n if (items.length === 1) {\n return `z.literal(${items[0]})`;\n }\n return `z.literal([${items.join(\", \")}])`;\n case \"union\":\n return `z.union([${(zt as AnyZodUnion).def.options\n .map((option: z.ZodType) => zodTypeToZodCode(option))\n .join(\",\")}])`;\n case \"enum\":\n // NOTE: z.enum([\"A\", \"B\"])도 z.enum({ A: \"A\", B: \"B\" })로 처리됨.\n return `z.enum({${Object.entries((zt as z.ZodEnum).def.entries)\n .map(([key, val]) =>\n typeof val === \"string\" ? `${key}: \"${val}\"` : `${key}: ${val}`)\n .join(\", \")}})`;\n case \"array\":\n return `z.array(${zodTypeToZodCode((zt as z.ZodArray<z.ZodType>).def.element)})`;\n case \"object\":\n const shape = (zt as any).shape;\n return [\n \"z.object({\",\n ...Object.keys(shape).map(\n (key) => `${key}: ${zodTypeToZodCode(shape[key])},`\n ),\n \"})\",\n ].join(\"\\n\");\n case \"optional\":\n return zodTypeToZodCode((zt as z.ZodOptional<z.ZodType>).def.innerType) + \".optional()\";\n case \"file\":\n return `z.file()`;\n case \"intersection\":\n const zIntersectionDef = (zt as z.ZodIntersection<z.ZodType, z.ZodType>).def;\n return `z.intersection(${zodTypeToZodCode(zIntersectionDef.left)}, ${zodTypeToZodCode(zIntersectionDef.right)})`;\n case \"file\":\n return `z.file()`;\n default:\n throw new Error(`처리되지 않은 ZodType ${zt.def.type}`);\n }\n}\n\nexport function apiParamToTsCode(\n params: ApiParam[],\n injectImportKeys: string[]\n): string {\n return params\n .map((param) => {\n return `${param.name}${\n param.optional && !param.defaultDef ? \"?\" : \"\"\n }: ${apiParamTypeToTsType(param.type, injectImportKeys)}${\n param.defaultDef ? `= ${param.defaultDef}` : \"\"\n }`;\n })\n .join(\", \");\n}\n\nexport function apiParamToTsCodeAsObject(\n params: ApiParam[],\n injectImportKeys: string[]\n): string {\n return `{ ${params\n .map(\n (param) =>\n `${param.name}${param.optional ? \"?\" : \"\"}: ${apiParamTypeToTsType(\n param.type,\n injectImportKeys\n )}${param.defaultDef ? `= ${param.defaultDef}` : \"\"}`\n )\n .join(\", \")} }`;\n}\n\nexport function apiParamTypeToTsType(\n paramType: ApiParamType,\n injectImportKeys: string[]\n): string {\n if (\n [\n \"string\",\n \"number\",\n \"boolean\",\n \"true\",\n \"false\",\n \"null\",\n \"undefined\",\n \"void\",\n \"any\",\n \"unknown\",\n ].includes(paramType as string)\n ) {\n return paramType as string;\n } else if (ApiParamType.isObject(paramType)) {\n return `{ ${apiParamToTsCode(paramType.props, injectImportKeys)} }`;\n } else if (ApiParamType.isStringLiteral(paramType)) {\n return `\"${paramType.value}\"`;\n } else if (ApiParamType.isNumericLiteral(paramType)) {\n return String(paramType.value);\n } else if (ApiParamType.isUnion(paramType)) {\n return paramType.types\n .map((type) => apiParamTypeToTsType(type, injectImportKeys))\n .join(\" | \");\n } else if (ApiParamType.isIntersection(paramType)) {\n return paramType.types\n .map((type) => apiParamTypeToTsType(type, injectImportKeys))\n .join(\" & \");\n } else if (ApiParamType.isArray(paramType)) {\n return (\n apiParamTypeToTsType(paramType.elementsType, injectImportKeys) + \"[]\"\n );\n } else if (ApiParamType.isRef(paramType)) {\n if (\n [\"Pick\", \"Omit\", \"Promise\", \"Partial\", \"Date\"].includes(paramType.id) ===\n false\n ) {\n // importKeys 인젝션\n injectImportKeys.push(paramType.id);\n }\n if (paramType.args === undefined || paramType.args.length === 0) {\n return paramType.id;\n } else {\n return `${paramType.id}<${paramType.args\n .map((arg) => apiParamTypeToTsType(arg, injectImportKeys))\n .join(\",\")}>`;\n }\n } else if (ApiParamType.isIndexedAccess(paramType)) {\n return `${apiParamTypeToTsType(\n paramType.object,\n injectImportKeys\n )}[${apiParamTypeToTsType(paramType.index, injectImportKeys)}]`;\n } else if (ApiParamType.isTupleType(paramType)) {\n return `[ ${paramType.elements.map((elem) =>\n apiParamTypeToTsType(elem, injectImportKeys)\n )} ]`;\n } else if (ApiParamType.isTypeParam(paramType)) {\n return `<${paramType.id}${\n paramType.constraint\n ? ` extends ${apiParamTypeToTsType(\n paramType.constraint,\n injectImportKeys\n )}`\n : \"\"\n }>`;\n } else {\n throw new Error(`resolve 불가 ApiParamType ${paramType}`);\n }\n}\n\nexport function unwrapPromiseOnce(paramType: ApiParamType) {\n if (ApiParamType.isPromise(paramType)) {\n return paramType.args![0];\n } else {\n return paramType;\n }\n}\n\n// TODO(Haze, 251031): \"template_literal\", \"file\"에 대한 지원이 필요함.\nexport function serializeZodType(zt: z.ZodType): any {\n switch (zt.def.type) {\n case \"object\":\n return {\n type: \"object\",\n shape: Object.keys((zt as AnyZodObject).shape).reduce(\n (result, key) => {\n return {\n ...result,\n [key]: serializeZodType((zt as AnyZodObject).shape[key]),\n };\n },\n {}\n ),\n };\n case \"array\":\n return {\n type: \"array\",\n element: serializeZodType((zt as AnyZodArray).def.element),\n };\n case \"enum\":\n return {\n type: \"enum\",\n values: (zt as z.ZodEnum).def.entries,\n };\n case \"string\":\n return {\n type: \"string\",\n checks: zt.def.checks,\n };\n case \"number\":\n return {\n type: \"number\",\n checks: zt.def.checks,\n };\n case \"boolean\":\n return {\n type: \"boolean\",\n };\n case \"nullable\":\n return {\n ...serializeZodType((zt as AnyZodNullable).def.innerType),\n nullable: true,\n };\n case \"optional\":\n return {\n ...serializeZodType((zt as AnyZodOptional).def.innerType),\n optional: true,\n };\n case \"any\":\n return {\n type: \"any\",\n };\n case \"record\":\n return {\n type: \"record\",\n keyType: serializeZodType((zt as AnyZodRecord).def.keyType),\n valueType: serializeZodType((zt as AnyZodRecord).def.valueType),\n };\n case \"union\":\n return {\n type: \"union\",\n options: (zt.def as AnyZodUnion).options.map((option) =>\n serializeZodType(option)\n ),\n };\n default:\n throw new Error(\n `Serialize 로직이 정의되지 않은 ZodType: ${zt.def.type}`\n );\n }\n}\n\n// TODO(Haze, 251031): \"template_literal\", \"file\"에 대한 지원이 필요함.\nexport function zodTypeToTsTypeDef(zt: z.ZodType): string {\n switch (zt.def.type) {\n case \"string\":\n case \"number\":\n case \"boolean\":\n case \"bigint\":\n case \"date\":\n case \"null\":\n case \"undefined\":\n case \"any\":\n case \"unknown\":\n case \"never\":\n return zt.def.type;\n case \"nullable\":\n return zodTypeToTsTypeDef((zt as AnyZodNullable).def.innerType) + \" | null\";\n case \"default\":\n return zodTypeToTsTypeDef((zt as AnyZodDefault).def.innerType);\n case \"record\":\n const recordType = zt as AnyZodRecord;\n return `{ [ key: ${zodTypeToTsTypeDef(recordType.def.keyType)} ]: ${zodTypeToTsTypeDef(recordType.def.valueType)}}`;\n case \"literal\":\n return Array.from((zt as z.ZodLiteral).values).map(value => {\n if (typeof value === \"string\") {\n return `\"${value}\"`;\n }\n\n if (value === null) {\n return `null`;\n }\n\n if (value === undefined) {\n return `undefined`;\n }\n\n return `${value}`;\n }).join(\" | \")\n case \"union\":\n return `${(zt as AnyZodUnion).options\n .map((option) => zodTypeToTsTypeDef(option))\n .join(\" | \")}`;\n case \"enum\":\n return `${(zt as z.ZodEnum).options.map((val) => `\"${val}\"`).join(\" | \")}`;\n case \"array\":\n return `${zodTypeToTsTypeDef((zt as AnyZodArray).element)}[]`;\n case \"object\":\n const shape = (zt as AnyZodObject).shape;\n return [\n \"{\",\n ...Object.keys(shape).map((key) => {\n if (shape[key].def.type === \"optional\") {\n return `${key}?: ${zodTypeToTsTypeDef(shape[key].def.innerType)},`;\n } else {\n return `${key}: ${zodTypeToTsTypeDef(shape[key])},`;\n }\n }),\n \"}\",\n ].join(\"\\n\");\n case \"optional\":\n return zodTypeToTsTypeDef((zt as AnyZodOptional).def.innerType) + \" | undefined\";\n default:\n throw new Error(`처리되지 않은 ZodType ${zt.def.type}`);\n }\n}\n"],"names":["apiParamToTsCode","apiParamToTsCodeAsObject","apiParamTypeToTsType","getTextTypeLength","getZodObjectFromApi","getZodObjectFromApiParams","getZodTypeFromApiParamType","propNodeToZodTypeDef","propToZodTypeDef","serializeZodType","unwrapPromiseOnce","zodTypeToTsTypeDef","zodTypeToZodCode","api","references","typeParameters","length","map","typeParam","constraint","zodType","id","ReqType","parameters","filter","param","ApiParamType","isContext","type","isRefKnex","optional","name","startsWith","apiParams","z","object","reduce","r","paramType","string","number","boolean","advType","t","literal","value","objType","props","arrType","array","elementsType","refType","date","includes","args","Error","arg","obj","literalOrUnion","keys","ZodUnion","def","options","option","values","keyRecord","result","key","pick","omit","partial","reference","undefined","unionType","types","some","nullable","union","intersectionType","index","resolvedType","intersection","unknown","tupleType","tuple","elements","elem","propNode","injectImportKeys","nodeType","prop","children","childPropNode","join","textType","stmt","isIntegerProp","isBigIntegerProp","isTextProp","isEnumProp","push","isStringProp","isDecimalProp","isFloatProp","isDoubleProp","isBooleanProp","isDateProp","isTimeProp","isDateTimeProp","isTimestampProp","isJsonProp","isUuidProp","isVirtualProp","isRelationProp","isBelongsToOneRelationProp","isOneToOneRelationProp","hasJoinColumn","relationType","with","unsigned","zt","innerType","zDefaultDef","defaultValue","zRecordDef","keyType","valueType","items","Array","from","Object","entries","val","element","shape","zIntersectionDef","left","right","params","defaultDef","isObject","isStringLiteral","isNumericLiteral","String","isUnion","isIntersection","isArray","isRef","isIndexedAccess","isTupleType","isTypeParam","isPromise","checks","recordType"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/api/context.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/api/decorators.ts"],"sourcesContent":["import type { HTTPMethods } from \"fastify\";\nimport inflection from \"inflection\";\nimport type { ApiParam, ApiParamType } from \"../types/types\";\nimport { z } from \"zod\";\nimport { PuriWrapper, TransactionalOptions } from \"../database/puri-wrapper\";\nimport { DB } from \"../database/db\";\nimport { Sonamu } from \"./sonamu\";\nimport type { UploadContext } from \"./context\";\n\nexport interface GuardKeys {\n query: true;\n admin: true;\n user: true;\n}\nexport type GuardKey = keyof GuardKeys;\nexport type ServiceClient =\n | \"axios\"\n | \"axios-multipart\"\n | \"swr\"\n | \"window-fetch\";\nexport type ApiDecoratorOptions = {\n httpMethod?: HTTPMethods;\n contentType?:\n | \"text/plain\"\n | \"text/html\"\n | \"text/xml\"\n | \"application/json\"\n | \"application/octet-stream\";\n clients?: ServiceClient[];\n path?: string;\n resourceName?: string;\n guards?: GuardKey[];\n description?: string;\n};\nexport type StreamDecoratorOptions = {\n type: \"sse\"; // | 'ws\n events: z.ZodObject<any>;\n path?: string;\n resourceName?: string;\n guards?: GuardKey[];\n description?: string;\n};\nexport type UploadDecoratorOptions = {\n mode?: \"single\" | \"multiple\";\n};\nexport const registeredApis: {\n modelName: string;\n methodName: string;\n path: string;\n options: ApiDecoratorOptions;\n streamOptions?: StreamDecoratorOptions;\n uploadOptions?: UploadDecoratorOptions;\n}[] = [];\nexport type ExtendedApi = {\n modelName: string;\n methodName: string;\n path: string;\n options: ApiDecoratorOptions;\n streamOptions?: StreamDecoratorOptions;\n uploadOptions?: UploadDecoratorOptions;\n typeParameters: ApiParamType.TypeParam[];\n parameters: ApiParam[];\n returnType: ApiParamType;\n};\n\nexport function api(options: ApiDecoratorOptions = {}) {\n options = {\n httpMethod: \"GET\",\n contentType: \"application/json\",\n clients: [\"axios\"],\n ...options,\n };\n\n return function (target: Object, propertyKey: string) {\n const modelName = target.constructor.name.match(/(.+)Class$/)![1];\n const methodName = propertyKey;\n\n const defaultPath = `/${inflection.camelize(\n modelName.replace(/Model$/, \"\").replace(/Frame$/, \"\"),\n true\n )}/${inflection.camelize(propertyKey, true)}`;\n\n // 기존 동일한 메서드가 있는지 확인 후 있는 경우 override\n const existingApi = registeredApis.find(\n (api) => api.modelName === modelName && api.methodName === methodName\n );\n if (existingApi) {\n existingApi.options = options;\n } else {\n registeredApis.push({\n modelName,\n methodName,\n path: options.path ?? defaultPath,\n options,\n });\n }\n };\n}\n\nexport function stream(options: StreamDecoratorOptions) {\n return function (target: Object, propertyKey: string) {\n const modelName = target.constructor.name.match(/(.+)Class$/)![1];\n const methodName = propertyKey;\n\n const defaultPath = `/${inflection.camelize(\n modelName.replace(/Model$/, \"\").replace(/Frame$/, \"\"),\n true\n )}/${inflection.camelize(propertyKey, true)}`;\n\n const existingApi = registeredApis.find(\n (api) => api.modelName === modelName && api.methodName === methodName\n );\n if (existingApi) {\n existingApi.options = options;\n } else {\n registeredApis.push({\n modelName,\n methodName,\n path: options.path ?? defaultPath,\n options: {\n ...options,\n httpMethod: \"GET\",\n },\n streamOptions: options,\n });\n }\n };\n}\n\nexport function transactional(options: TransactionalOptions = {}) {\n const { isolation, readOnly, dbPreset = \"w\" } = options;\n\n return function (\n _target: Object,\n _propertyKey: string,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (this: any, ...args: any[]) {\n const existingContext = DB.transactionStorage.getStore();\n\n // 이미 AsyncLocalStorage 컨텍스트 안에 있는지 확인\n if (existingContext) {\n // 해당 preset의 트랜잭션이 이미 있으면 재사용\n if (existingContext.getTransaction(dbPreset)) {\n return originalMethod.apply(this, args);\n }\n }\n\n // AsyncLocalStorage 컨텍스트 없거나 해당 preset의 트랜잭션이 없으면 새로 시작\n const startTransaction = async () => {\n const puri = this.getPuri(dbPreset) as PuriWrapper;\n\n return puri.transaction(\n async (trx: PuriWrapper) => {\n // TransactionContext에 트랜잭션 저장\n DB.getTransactionContext().setTransaction(dbPreset, trx);\n\n try {\n return await originalMethod.apply(this, args);\n } finally {\n // 트랜잭션 제거\n DB.getTransactionContext().deleteTransaction(dbPreset);\n }\n },\n { isolation, readOnly }\n );\n };\n\n // AsyncLocalStorage 컨텍스트가 없으면 새로 생성\n if (!existingContext) {\n return DB.runWithTransaction(startTransaction);\n } else {\n // 컨텍스트는 있지만 이 preset의 트랜잭션은 없는 경우 (같은 컨텍스트 내에서 실행)\n return startTransaction();\n }\n };\n\n return descriptor;\n };\n}\n\nexport function upload(options: UploadDecoratorOptions = {}) {\n return function (\n _target: Object,\n _propertyKey: string,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value;\n const modelName = _target.constructor.name.match(/(.+)Class$/)![1];\n const methodName = _propertyKey;\n\n // registeredApis에서 해당 API 찾아서 uploadOptions 추가\n const existingApi = registeredApis.find(\n (api) => api.modelName === modelName && api.methodName === methodName\n );\n if (existingApi) {\n existingApi.uploadOptions = options;\n }\n\n descriptor.value = async function (this: any, ...args: any[]) {\n const { request } = Sonamu.getContext();\n const uploadContext: UploadContext = {\n file: undefined,\n files: [],\n };\n\n const storage = Sonamu.storage;\n if (!storage) {\n throw new Error(\"Storage가 설정되지 않았습니다.\");\n }\n\n const { FileStorage } = await import(\"../file-storage/file-storage\");\n if (options.mode === \"multiple\") {\n const rawFilesIterator = request.files();\n for await (const rawFile of rawFilesIterator) {\n if (rawFile) {\n uploadContext.files.push(new FileStorage(rawFile, storage));\n }\n }\n } else {\n const rawFile = await request.file();\n if (rawFile) {\n uploadContext.file = new FileStorage(rawFile, storage);\n }\n }\n\n return Sonamu.uploadStorage.run({ uploadContext }, () => {\n return originalMethod.apply(this, args);\n });\n };\n\n return descriptor;\n };\n}\n"],"names":["api","registeredApis","stream","transactional","upload","options","httpMethod","contentType","clients","target","propertyKey","modelName","name","match","methodName","defaultPath","inflection","camelize","replace","existingApi","find","push","path","streamOptions","isolation","readOnly","dbPreset","_target","_propertyKey","descriptor","originalMethod","value","args","existingContext","startTransaction","DB","transactionStorage","getStore","getTransaction","apply","puri","getPuri","transaction","trx","getTransactionContext","setTransaction","deleteTransaction","runWithTransaction","uploadOptions","request","uploadContext","storage","FileStorage","rawFilesIterator","rawFile","Sonamu","getContext","file","undefined","files","Error","mode","uploadStorage","run"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/api/index.ts"],"sourcesContent":["export * from \"./caster\";\nexport * from \"./code-converters\";\nexport * from \"./context\";\nexport * from \"./decorators\";\nexport * from \"../file-storage/driver\";\nexport * from \"../file-storage/file-storage\";\nexport * from \"./sonamu\";\n"],"names":[],"mappings":"2FAAc,0CACA,mDACA,2CACA,8CACA,wDACA,8DACA"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/api/sonamu.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\nimport chalk from \"chalk\";\nimport fastify from \"fastify\";\nimport { readFile } from \"fs/promises\";\nimport path from \"path\";\nimport { exists } from \"../utils/fs-utils\";\n\nimport type { FSWatcher } from \"chokidar\";\nimport { formatInTimeZone } from \"date-fns-tz\";\nimport type { FastifyInstance, FastifyReply, FastifyRequest } from \"fastify\";\nimport type { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { ZodError, ZodObject } from \"zod\";\nimport { DB, SonamuDBConfig } from \"../database/db\";\nimport { attachOnDuplicateUpdate } from \"../database/knex-plugins/knex-on-duplicate-update\";\nimport {\n BadRequestException,\n NotFoundException,\n} from \"../exceptions/so-exceptions\";\nimport type { Driver } from \"../file-storage/driver\";\nimport { createSSEFactory } from \"../stream/sse\";\nimport type { Syncer } from \"../syncer/syncer\";\nimport {\n ApiParamType,\n SonamuFastifyConfig,\n SonamuServerOptions,\n} from \"../types/types\";\nimport { isLocal, isTest } from \"../utils/controller\";\nimport { findApiRootPath } from \"../utils/utils\";\nimport { humanizeZodError } from \"../utils/zod-error\";\nimport { fastifyCaster } from \"./caster\";\nimport { getZodObjectFromApi } from \"./code-converters\";\nimport type { AuthContext, Context, UploadContext } from \"./context\";\nimport type { ExtendedApi } from \"./decorators\";\nimport fastifyPassport from \"@fastify/passport\";\n\nexport type SonamuConfig = {\n projectName?: string;\n api: {\n dir: string;\n };\n sync: {\n targets: string[];\n };\n route: {\n prefix: string;\n };\n timezone?: string;\n ui?: {\n port: number;\n };\n};\nexport type SonamuSecrets = {\n [key: string]: string;\n};\nclass SonamuClass {\n public isInitialized: boolean = false;\n public asyncLocalStorage: AsyncLocalStorage<{\n context: Context;\n }> = new AsyncLocalStorage();\n\n public uploadStorage: AsyncLocalStorage<{\n uploadContext: UploadContext;\n }> = new AsyncLocalStorage();\n\n public getContext(): Context {\n const store = this.asyncLocalStorage.getStore();\n if (store?.context) {\n return store.context;\n }\n throw new Error(\"Sonamu cannot find context\");\n }\n\n public getUploadContext(): UploadContext {\n const store = this.uploadStorage.getStore();\n if (store?.uploadContext) {\n return store.uploadContext;\n }\n throw new Error(\n \"Sonamu cannot find upload context. Did you use @upload decorator?\"\n );\n }\n\n private _apiRootPath: string | null = null;\n set apiRootPath(apiRootPath: string) {\n this._apiRootPath = apiRootPath;\n }\n get apiRootPath(): string {\n if (this._apiRootPath === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._apiRootPath!;\n }\n get appRootPath(): string {\n return this.apiRootPath.split(path.sep).slice(0, -1).join(path.sep);\n }\n\n private _dbConfig: SonamuDBConfig | null = null;\n set dbConfig(dbConfig: SonamuDBConfig) {\n this._dbConfig = dbConfig;\n }\n get dbConfig(): SonamuDBConfig {\n if (this._dbConfig === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._dbConfig!;\n }\n\n private _syncer: Syncer | null = null;\n set syncer(syncer: Syncer) {\n this._syncer = syncer;\n }\n get syncer(): Syncer {\n if (this._syncer === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._syncer!;\n }\n\n private _config: SonamuConfig | null = null;\n set config(config: SonamuConfig) {\n this._config = config;\n }\n get config(): SonamuConfig {\n if (this._config === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._config;\n }\n\n private _secrets: SonamuSecrets | null = null;\n set secrets(secrets: SonamuSecrets) {\n this._secrets = secrets;\n }\n get secrets(): SonamuSecrets | null {\n return this._secrets;\n }\n\n private _storage: Driver | null = null;\n set storage(storage: Driver) {\n this._storage = storage;\n }\n get storage(): Driver | null {\n return this._storage;\n }\n\n // HMR 처리\n public watcher: FSWatcher | null = null;\n private pendingFiles: string[] = [];\n private hmrStartTime: number = 0;\n\n public server: FastifyInstance | null = null;\n\n async initForTesting() {\n await this.init(true, false, undefined, true);\n }\n\n async init(\n doSilent: boolean = false,\n enableSync: boolean = true,\n apiRootPath?: string,\n forTesting: boolean = false\n ) {\n if (this.isInitialized) {\n return;\n }\n !doSilent &&\n console.time(\n chalk.cyan(`Sonamu.init${forTesting ? \" for testing\" : \"\"}`)\n );\n\n // API 루트 패스\n this.apiRootPath = apiRootPath ?? findApiRootPath();\n const configPath = path.join(this.apiRootPath, \"sonamu.config.json\");\n const secretsPath = path.join(this.apiRootPath, \"sonamu.secrets.json\");\n if (!(await exists(configPath))) {\n throw new Error(`Cannot find sonamu.config.json in ${configPath}`);\n }\n this.config = JSON.parse(\n (await readFile(configPath)).toString()\n ) as SonamuConfig;\n if (await exists(secretsPath)) {\n this.secrets = JSON.parse(\n (await readFile(secretsPath)).toString()\n ) as SonamuSecrets;\n }\n\n // DB 로드\n this.dbConfig = await DB.readKnexfile();\n !doSilent && console.log(chalk.green(\"DB Config Loaded!\"));\n attachOnDuplicateUpdate();\n\n // 테스팅인 경우 엔티티 로드 & 싱크 없이 중단\n if (forTesting) {\n this.isInitialized = true;\n return;\n }\n\n // Entity 로드\n const { EntityManager } = await import(\"../entity/entity-manager\");\n await EntityManager.autoload(doSilent);\n\n // Syncer\n const { Syncer } = await import(\"../syncer/syncer\");\n this.syncer = new Syncer();\n\n // Autoload: Models / Types / APIs\n await this.syncer.autoloadModels();\n await this.syncer.autoloadTypes();\n await this.syncer.autoloadApis();\n\n if (isLocal() && !isTest() && enableSync) {\n await this.syncer.sync();\n\n // FIXME: hmr 설정된 경우만 워처 시작\n this.startWatcher();\n\n this.syncer.syncUI();\n }\n\n this.isInitialized = true;\n !doSilent && console.timeEnd(chalk.cyan(\"Sonamu.init\"));\n }\n\n async createServer(\n options: SonamuServerOptions,\n initOptions?: {\n enableSync?: boolean;\n doSilent?: boolean;\n }\n ) {\n const server = fastify(options.fastify);\n this.server = server;\n\n // Storage 설정 저장\n if (options.storage) {\n this.storage = options.storage;\n }\n\n // 플러그인 등록\n if (options.plugins) {\n this.registerPlugins(server, options.plugins);\n }\n\n if (options.auth) {\n if (!options.plugins?.session) {\n throw new Error(\n \"Auth requires session plugin. Please add plugins.session configuration.\"\n );\n }\n\n this.registerAuth(server, options.auth);\n }\n\n // API 라우팅 설정\n await this.withFastify(server, options.apiConfig, {\n enableSync: initOptions?.enableSync,\n doSilent: initOptions?.doSilent,\n });\n\n // 서버 시작\n await this.boot(server, options);\n\n return server;\n }\n\n async withFastify(\n server: FastifyInstance<Server, IncomingMessage, ServerResponse>,\n config: SonamuFastifyConfig,\n options?: {\n enableSync?: boolean;\n doSilent?: boolean;\n }\n ) {\n if (this.isInitialized === false) {\n await this.init(options?.doSilent, options?.enableSync);\n }\n\n this.server = server;\n\n // timezone 설정\n const timezone = this.config.timezone;\n if (timezone) {\n const DATE_FORMAT = \"yyyy-MM-dd'T'HH:mm:ssXXX\";\n // ISO 8601 날짜 형식 정규식 (예: 2024-01-15T09:30:00.000Z)\n const ISO_DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$/;\n\n server.setReplySerializer((payload) => {\n return JSON.stringify(payload, (_key, value) => {\n if (typeof value === \"string\" && ISO_DATE_REGEX.test(value)) {\n return formatInTimeZone(new Date(value), timezone, DATE_FORMAT);\n }\n return value;\n });\n });\n !options?.doSilent &&\n console.log(chalk.green(`Timezone set to ${timezone}`));\n }\n\n // 전체 라우팅 리스트\n server.get(\n `${this.config.route.prefix}/routes`,\n async (_request, _reply): Promise<any> => {\n return this.syncer.apis;\n }\n );\n\n // Healthcheck API\n server.get(\n `${this.config.route.prefix}/healthcheck`,\n async (_request, _reply): Promise<string> => {\n return \"ok\";\n }\n );\n\n // API 라우팅 (로컬HMR 상태와 구분)\n if (isLocal()) {\n server.all(\"*\", (request, reply) => {\n const found = this.syncer.apis.find(\n (api) =>\n this.config.route.prefix + api.path === request.url.split(\"?\")[0] &&\n (api.options.httpMethod ?? \"GET\") === request.method.toUpperCase()\n );\n if (found) {\n return this.getApiHandler(found, config)(request, reply);\n }\n throw new NotFoundException(\"존재하지 않는 API 접근입니다.\");\n });\n } else {\n this.syncer.apis.map((api) => {\n // model\n if (this.syncer.models[api.modelName] === undefined) {\n throw new Error(`정의되지 않은 모델에 접근 ${api.modelName}`);\n }\n\n // route\n server.route({\n method: api.options.httpMethod!,\n url: this.config.route.prefix + api.path,\n handler: this.getApiHandler(api, config),\n }); // END server.route\n });\n }\n }\n\n getApiHandler(api: ExtendedApi, config: SonamuFastifyConfig) {\n return async (\n request: FastifyRequest,\n reply: FastifyReply\n ): Promise<unknown> => {\n (api.options.guards ?? []).every((guard) =>\n config.guardHandler(guard, request, api)\n );\n\n // 파라미터 정보로 zod 스키마 빌드\n const ReqType = getZodObjectFromApi(api, this.syncer.types);\n\n // request 파싱\n const which = api.options.httpMethod === \"GET\" ? \"query\" : \"body\";\n let reqBody: {\n [key: string]: unknown;\n };\n try {\n reqBody = fastifyCaster(ReqType).parse(request[which] ?? {});\n } catch (e) {\n if (e instanceof ZodError) {\n const messages = humanizeZodError(e)\n .map((issue) => issue.message)\n .join(\" \");\n throw new BadRequestException(messages, {\n zodError: e,\n });\n } else {\n throw e;\n }\n }\n\n // Content-Type\n reply.type(api.options.contentType ?? \"application/json\");\n\n // 캐시\n const { cacheKey, cacheTtl, cachedData } = await (async () => {\n if (config.cache) {\n try {\n const cacheKeyRes = config.cache.resolveKey(api.path, reqBody);\n if (cacheKeyRes.cache === false) {\n return { cacheKey: null, cachedData: null };\n }\n\n const cacheKey = cacheKeyRes.key;\n const cacheTtl = cacheKeyRes.ttl;\n const cachedData = await config.cache.get(cacheKey);\n return { cacheKey, cacheTtl, cachedData };\n } catch (e) {\n console.error(e);\n }\n return { cacheKey: null, cachedData: null };\n }\n return { cacheKey: null, cachedData: null };\n })();\n if (cachedData !== null) {\n return cachedData;\n }\n\n // createSSEFactory 함수에 미리 request의 socket과 reply를 바인딩.\n const createSSE = (<T extends ZodObject>(\n _request: FastifyRequest,\n _reply: FastifyReply,\n _events: T\n ) => createSSEFactory(_request.socket, _reply, _events)).bind(\n null,\n request,\n reply\n );\n\n const context: Context = {\n ...config.contextProvider(\n {\n request,\n reply,\n headers: request.headers,\n createSSE,\n\n // auth\n user: request.user ?? null,\n passport: {\n login: request.login.bind(\n request\n ) as AuthContext[\"passport\"][\"login\"],\n logout: request.logout.bind(\n request\n ) as AuthContext[\"passport\"][\"logout\"],\n },\n },\n request,\n reply\n ),\n };\n\n const model = this.syncer.models[api.modelName];\n return this.asyncLocalStorage.run({ context }, async () => {\n const result = await (model as any)[api.methodName].apply(\n model,\n api.parameters.map((param) => {\n // Context 인젝션\n if (ApiParamType.isContext(param.type)) {\n return context;\n } else {\n return reqBody[param.name];\n }\n })\n );\n reply.type(api.options.contentType ?? \"application/json\");\n\n // 캐시 키 있는 경우 갱신 후 저장\n if (config.cache && cacheKey) {\n await config.cache.put(cacheKey, result, cacheTtl);\n }\n return result;\n });\n };\n }\n\n startWatcher(): void {\n const watchPath = path.join(this.apiRootPath, \"src\");\n const chokidar = require(\"chokidar\") as typeof import(\"chokidar\");\n this.watcher = chokidar.watch(watchPath, {\n ignored: (path, stats) =>\n (!!stats?.isFile() &&\n !path.endsWith(\".ts\") &&\n !path.endsWith(\".json\")) ||\n path.endsWith(\"src/index.ts\"),\n persistent: true,\n ignoreInitial: true,\n });\n this.watcher.on(\"all\", async (event: string, filePath: string) => {\n if (event !== \"change\" && event !== \"add\") {\n return;\n }\n\n try {\n await this.handleFileChange(event, filePath);\n } catch (e) {\n console.error(e);\n }\n });\n }\n\n /*\n A function that automatically handles init and destroy when using Sonamu via scripts. \n */\n async runScript(fn: () => Promise<void>) {\n await this.init(true, false, undefined, false);\n try {\n await fn();\n } finally {\n await this.destroy();\n }\n }\n\n private registerPlugins(\n server: FastifyInstance,\n plugins: SonamuServerOptions[\"plugins\"]\n ) {\n if (!plugins) {\n return;\n }\n\n const pluginsModules = {\n cors: \"@fastify/cors\",\n formbody: \"@fastify/formbody\",\n multipart: \"@fastify/multipart\",\n qs: \"fastify-qs\",\n sse: \"fastify-sse-v2\",\n static: \"@fastify/static\",\n session: \"@fastify/secure-session\",\n } as const;\n\n const registerPlugin = <K extends keyof NonNullable<typeof plugins>>(\n key: K,\n pluginName: string\n ) => {\n const option = plugins[key];\n if (!option) return;\n\n if (option === true) {\n server.register(import(pluginName));\n } else {\n server.register(import(pluginName), option);\n }\n };\n\n Object.entries(pluginsModules).forEach(([key, pluginName]) => {\n registerPlugin(key as keyof typeof plugins, pluginName);\n });\n\n if (plugins.custom) {\n plugins.custom(server);\n }\n }\n\n private async registerAuth(\n server: FastifyInstance,\n options: NonNullable<SonamuServerOptions[\"auth\"]>\n ) {\n server.register(fastifyPassport.initialize());\n server.register(fastifyPassport.secureSession());\n\n if (typeof options === \"boolean\") {\n fastifyPassport.registerUserSerializer(async (user, _request) => user);\n fastifyPassport.registerUserDeserializer(\n async (serialized, _request) => serialized\n );\n } else {\n fastifyPassport.registerUserSerializer(options.userSerializer);\n fastifyPassport.registerUserDeserializer(options.userDeserializer);\n }\n }\n\n private async boot(server: FastifyInstance, options: SonamuServerOptions) {\n const port = options.listen?.port ?? 3000;\n const host = options.listen?.host ?? \"localhost\";\n\n server.addHook(\"onClose\", async () => {\n await options.lifecycle?.onShutdown?.(server);\n await this.destroy();\n });\n\n const shutdown = async () => {\n try {\n await server.close();\n process.exit(0);\n } catch (err) {\n console.error(\"Error during shutdown:\", err);\n process.exit(1);\n }\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n if (options.lifecycle?.onError) {\n server.setErrorHandler(options.lifecycle?.onError);\n }\n\n server\n .listen({ port, host })\n .then(async () => {\n await options.lifecycle?.onStart?.(server);\n })\n .catch(async (err) => {\n console.error(chalk.red(\"Failed to start server:\", err));\n await shutdown();\n });\n }\n\n private async handleFileChange(\n event: string,\n filePath: string\n ): Promise<void> {\n // 첫 번째 파일이면 HMR 시작 시간 기록\n if (this.pendingFiles.length === 0) {\n this.hmrStartTime = Date.now();\n }\n\n this.pendingFiles.push(filePath);\n\n const relativePath = filePath.replace(this.apiRootPath, \"api\");\n console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)}`));\n\n await this.syncer.syncFromWatcher([filePath]);\n\n // 처리 완료된 파일을 대기 목록에서 제거\n this.pendingFiles = this.pendingFiles.slice(1);\n\n // 모든 파일 처리가 완료되면 최종 메시지 출력\n if (this.pendingFiles.length === 0) {\n await this.finishHMR();\n }\n }\n\n private async finishHMR(): Promise<void> {\n await this.syncer.saveChecksums(await this.syncer.getCurrentChecksums());\n\n const endTime = Date.now();\n const totalTime = endTime - this.hmrStartTime;\n const msg = `HMR Done! ${chalk.bold.white(`${totalTime}ms`)}`;\n const margin = Math.max(0, (process.stdout.columns - msg.length) / 2);\n\n console.log(\n chalk.black.bgGreen(\" \".repeat(margin) + msg + \" \".repeat(margin))\n );\n }\n\n async destroy(): Promise<void> {\n const { BaseModel } = require(\"../database/base-model\");\n await BaseModel.destroy();\n await this.watcher?.close();\n this.storage?.destroy();\n }\n}\nexport const Sonamu = new SonamuClass();\n"],"names":["Sonamu","SonamuClass","isInitialized","asyncLocalStorage","AsyncLocalStorage","uploadStorage","_apiRootPath","_dbConfig","_syncer","_config","_secrets","_storage","watcher","pendingFiles","hmrStartTime","server","getContext","store","getStore","context","Error","getUploadContext","uploadContext","apiRootPath","appRootPath","split","path","sep","slice","join","dbConfig","syncer","config","secrets","storage","initForTesting","init","undefined","doSilent","enableSync","forTesting","configPath","secretsPath","EntityManager","Syncer","console","time","chalk","cyan","findApiRootPath","exists","JSON","parse","readFile","toString","DB","readKnexfile","log","green","attachOnDuplicateUpdate","autoload","autoloadModels","autoloadTypes","autoloadApis","isLocal","isTest","sync","startWatcher","syncUI","timeEnd","createServer","options","initOptions","fastify","plugins","registerPlugins","auth","session","registerAuth","withFastify","apiConfig","boot","timezone","DATE_FORMAT","ISO_DATE_REGEX","setReplySerializer","payload","stringify","_key","value","test","formatInTimeZone","Date","get","route","prefix","_request","_reply","apis","all","request","reply","found","find","api","url","httpMethod","method","toUpperCase","getApiHandler","NotFoundException","map","models","modelName","handler","ReqType","which","reqBody","messages","cacheKey","cacheTtl","cachedData","createSSE","model","guards","every","guard","guardHandler","getZodObjectFromApi","types","fastifyCaster","e","ZodError","humanizeZodError","issue","message","BadRequestException","zodError","type","contentType","cacheKeyRes","cache","resolveKey","key","ttl","error","_events","createSSEFactory","socket","bind","contextProvider","headers","user","passport","login","logout","run","result","methodName","apply","parameters","param","ApiParamType","isContext","name","put","watchPath","chokidar","require","watch","ignored","stats","isFile","endsWith","persistent","ignoreInitial","on","event","filePath","handleFileChange","runScript","fn","destroy","pluginsModules","cors","formbody","multipart","qs","sse","static","registerPlugin","pluginName","option","register","Object","entries","forEach","custom","fastifyPassport","initialize","secureSession","registerUserSerializer","registerUserDeserializer","serialized","userSerializer","userDeserializer","port","host","shutdown","listen","addHook","lifecycle","onShutdown","err","close","process","exit","onError","setErrorHandler","then","onStart","catch","red","relativePath","length","now","push","replace","bold","blue","syncFromWatcher","finishHMR","endTime","totalTime","msg","margin","saveChecksums","getCurrentChecksums","white","Math","max","stdout","columns","black","bgGreen","repeat","BaseModel"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/bin/build-config.ts"],"sourcesContent":["/**\n * 빌드 결과물이 담길 디렉토리 경로\n */\nexport const BUILD_DIR = \"dist\";\n\n/**\n * SWC 빌드 명령어\n */\nexport const SWC_BUILD_COMMAND = `swc src -d ${BUILD_DIR} --strip-leading-paths --source-maps -C module.type=commonjs -C jsc.parser.syntax=typescript -C jsc.parser.decorators=true -C jsc.target=es5`;\n\n/**\n * TSC 타입 체크 명령어\n */\nexport const TSC_TYPE_CHECK_COMMAND = `tsc --noEmit`;\n"],"names":["BUILD_DIR","SWC_BUILD_COMMAND","TSC_TYPE_CHECK_COMMAND"],"mappings":"mPAGaA,mBAAAA,eAKAC,2BAAAA,uBAKAC,gCAAAA,0BAVN,IAAMF,UAAY,OAKlB,IAAMC,kBAAoB,AAAC,cAAuB,OAAVD,UAAU,gJAKlD,IAAME,uBAAyB"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/bin/cli-wrapper.ts"],"sourcesContent":["#!/usr/bin/env ts-node\n\nimport { spawnSync, execSync } from \"child_process\";\nimport { resolve } from \"path\";\nimport { existsSync, rmSync } from \"fs\";\nimport chalk from \"chalk\";\nimport {\n BUILD_DIR,\n SWC_BUILD_COMMAND,\n TSC_TYPE_CHECK_COMMAND,\n} from \"./build-config\";\n\nconst scriptPath = resolve(__dirname, \"cli.js\");\nconst args = process.argv.slice(2);\n\n// build 명령어는 dist 없이도 실행 가능하도록 cli.ts 외부에서 처리(Sonamu.init에서 dist 필요)\nfunction build() {\n try {\n console.log(chalk.blue(\"Removing build directory...\"));\n if (existsSync(BUILD_DIR)) {\n rmSync(BUILD_DIR, { recursive: true, force: true });\n }\n } catch (error) {\n console.error(chalk.red(\"Remove build directory failed.\"), error);\n process.exit(1);\n }\n\n try {\n console.log(chalk.blue(\"Building with swc...\"));\n execSync(SWC_BUILD_COMMAND, { cwd: process.cwd(), stdio: \"inherit\" });\n } catch (error) {\n console.error(chalk.red(\"Build failed.\"), error);\n process.exit(1);\n }\n}\n\nfunction checkTypes() {\n try {\n console.log(chalk.blue(\"Checking types with tsc...\"));\n execSync(TSC_TYPE_CHECK_COMMAND, {\n cwd: process.cwd(),\n stdio: \"inherit\",\n });\n } catch (error) {\n console.error(chalk.red(\"Type check failed.\"), error);\n process.exit(1);\n }\n}\n\nif (args[0] === \"build\") {\n console.log(chalk.blue(\"Building the project...\"));\n build();\n checkTypes();\n console.log(chalk.green(\"Build completed successfully.\"));\n process.exit(0);\n}\n\nif (args[0] === \"dev:serve\") {\n build();\n}\n\nif (!existsSync(scriptPath)) {\n console.error(`Error: Script not found at ${scriptPath}`);\n process.exit(1);\n}\n\nconst result = spawnSync(\n process.execPath,\n [\"-r\", \"source-map-support/register\", \"--no-warnings\", scriptPath, ...args],\n {\n stdio: \"inherit\",\n }\n);\n\nprocess.exit(result.status ?? 1);\n"],"names":["scriptPath","resolve","__dirname","args","process","argv","slice","build","console","log","chalk","blue","existsSync","BUILD_DIR","rmSync","recursive","force","error","red","exit","execSync","SWC_BUILD_COMMAND","cwd","stdio","checkTypes","TSC_TYPE_CHECK_COMMAND","green","result","spawnSync","execPath","status"],"mappings":";iGAEoC,mCACZ,wBACW,+DACjB,mCAKX,6rCAEP,IAAMA,WAAaC,GAAAA,aAAO,EAACC,UAAW,UACtC,IAAMC,KAAOC,QAAQC,IAAI,CAACC,KAAK,CAAC,GAGhC,SAASC,QACP,GAAI,CACFC,QAAQC,GAAG,CAACC,cAAK,CAACC,IAAI,CAAC,gCACvB,GAAIC,GAAAA,cAAU,EAACC,sBAAS,EAAG,CACzBC,GAAAA,UAAM,EAACD,sBAAS,CAAE,CAAEE,UAAW,KAAMC,MAAO,IAAK,EACnD,CACF,CAAE,MAAOC,MAAO,CACdT,QAAQS,KAAK,CAACP,cAAK,CAACQ,GAAG,CAAC,kCAAmCD,OAC3Db,QAAQe,IAAI,CAAC,EACf,CAEA,GAAI,CACFX,QAAQC,GAAG,CAACC,cAAK,CAACC,IAAI,CAAC,yBACvBS,GAAAA,uBAAQ,EAACC,8BAAiB,CAAE,CAAEC,IAAKlB,QAAQkB,GAAG,GAAIC,MAAO,SAAU,EACrE,CAAE,MAAON,MAAO,CACdT,QAAQS,KAAK,CAACP,cAAK,CAACQ,GAAG,CAAC,iBAAkBD,OAC1Cb,QAAQe,IAAI,CAAC,EACf,CACF,CAEA,SAASK,aACP,GAAI,CACFhB,QAAQC,GAAG,CAACC,cAAK,CAACC,IAAI,CAAC,+BACvBS,GAAAA,uBAAQ,EAACK,mCAAsB,CAAE,CAC/BH,IAAKlB,QAAQkB,GAAG,GAChBC,MAAO,SACT,EACF,CAAE,MAAON,MAAO,CACdT,QAAQS,KAAK,CAACP,cAAK,CAACQ,GAAG,CAAC,sBAAuBD,OAC/Cb,QAAQe,IAAI,CAAC,EACf,CACF,CAEA,GAAIhB,IAAI,CAAC,EAAE,GAAK,QAAS,CACvBK,QAAQC,GAAG,CAACC,cAAK,CAACC,IAAI,CAAC,4BACvBJ,QACAiB,aACAhB,QAAQC,GAAG,CAACC,cAAK,CAACgB,KAAK,CAAC,kCACxBtB,QAAQe,IAAI,CAAC,EACf,CAEA,GAAIhB,IAAI,CAAC,EAAE,GAAK,YAAa,CAC3BI,OACF,CAEA,GAAI,CAACK,GAAAA,cAAU,EAACZ,YAAa,CAC3BQ,QAAQS,KAAK,CAAC,AAAC,8BAAwC,OAAXjB,aAC5CI,QAAQe,IAAI,CAAC,EACf,CAEA,IAAMQ,OAASC,GAAAA,wBAAS,EACtBxB,QAAQyB,QAAQ,CAChB,CAAC,KAAM,8BAA+B,gBAAiB7B,WAAoB,CAA3E,OAAmE,qBAAGG,OACtE,CACEoB,MAAO,SACT,OAGWI,eAAbvB,QAAQe,IAAI,CAACQ,CAAAA,eAAAA,OAAOG,MAAM,UAAbH,wBAAAA,eAAiB"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/bin/cli.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport dotenv from \"dotenv\";\ndotenv.config();\n\nimport path from \"path\";\nimport { tsicli } from \"tsicli\";\nimport { execSync } from \"child_process\";\nimport { mkdir, readdir, readFile, writeFile } from \"fs/promises\";\nimport { exists } from \"../utils/fs-utils\";\nimport process from \"process\";\nimport { Sonamu } from \"../api\";\nimport knex, { Knex } from \"knex\";\nimport { findApiRootPath } from \"../utils/utils\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport { Migrator } from \"../migration/migrator\";\nimport { FixtureManager } from \"../testing/fixture-manager\";\n// import { SWC_BUILD_COMMAND } from \"./build-config\";\nimport { NodemonSettings } from \"nodemon\";\n\nlet migrator: Migrator;\n\nasync function bootstrap() {\n // dev:serve 명령어가 아닌 경우에만 Sonamu 초기화\n if (process.argv[2] !== \"dev:serve\") {\n await Sonamu.init(false, false);\n }\n\n await tsicli(process.argv, {\n types: {\n \"#entityId\": {\n type: \"autocomplete\",\n name: \"#entityId\",\n message: \"Please input #entityId\",\n choices: EntityManager.getAllParentIds().map((entityId) => ({\n title: entityId,\n value: entityId,\n })),\n },\n \"#recordIds\": \"number[]\",\n \"#name\": \"string\",\n },\n args: [\n [\"fixture\", \"init\"],\n [\"fixture\", \"import\", \"#entityId\", \"#recordIds\"],\n [\"fixture\", \"sync\"],\n [\"migrate\", \"run\"],\n [\"migrate\", \"check\"],\n [\"migrate\", \"rollback\"],\n [\"migrate\", \"reset\"],\n [\"migrate\", \"clear\"],\n [\"migrate\", \"status\"],\n [\"stub\", \"practice\", \"#name\"],\n [\"stub\", \"entity\", \"#name\"],\n [\"scaffold\", \"model\", \"#entityId\"],\n [\"scaffold\", \"model_test\", \"#entityId\"],\n [\"scaffold\", \"view_list\", \"#entityId\"],\n [\"scaffold\", \"view_form\", \"#entityId\"],\n [\"ui\"],\n [\"dev:serve\"],\n [\"serve\"],\n ],\n runners: {\n migrate_run,\n migrate_check,\n migrate_rollback,\n migrate_clear,\n migrate_reset,\n migrate_status,\n fixture_init,\n fixture_import,\n fixture_sync,\n stub_practice,\n stub_entity,\n scaffold_model,\n scaffold_model_test,\n ui,\n // scaffold_view_list,\n // scaffold_view_form,\n \"dev:serve\": dev_serve,\n serve,\n },\n });\n}\nbootstrap().finally(async () => {\n if (migrator) {\n await migrator.destroy();\n }\n await FixtureManager.destroy();\n});\n\nasync function dev_serve() {\n const nodemon = await import(\"nodemon\");\n\n const nodemonConfig = await (async () => {\n const projectNodemonPath = path.join(findApiRootPath(), \"nodemon.json\");\n const hasProjectNodemon = await exists(projectNodemonPath);\n\n if (hasProjectNodemon) {\n return JSON.parse(await readFile(projectNodemonPath, \"utf8\"));\n }\n\n return {\n watch: [\"src/index.ts\"],\n ignore: [\"dist/**\", \"**/*.js\", \"**/*.d.ts\"],\n exec: [\n // SWC_BUILD_COMMAND,\n \"node --no-warnings -r source-map-support/register -r dotenv/config dist/index.js\",\n ].join(\" && \"),\n } as NodemonSettings;\n })();\n nodemon.default(nodemonConfig);\n\n // 프로세스 종료 처리\n const cleanup = async () => {\n await Sonamu.server?.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n process.on(\"SIGUSR2\", cleanup);\n}\n\nasync function serve() {\n const distIndexPath = path.join(Sonamu.apiRootPath, \"dist\", \"index.js\");\n\n if (!(await exists(distIndexPath))) {\n console.log(\n chalk.red(\"dist/index.js not found. Please build your project first.\")\n );\n console.log(chalk.blue(\"Run: yarn sonamu build\"));\n return;\n }\n\n const { spawn } = await import(\"child_process\");\n const serverProcess = spawn(\n \"node\",\n [\"-r\", \"source-map-support/register\", \"-r\", \"dotenv/config\", distIndexPath],\n {\n cwd: Sonamu.apiRootPath,\n stdio: \"inherit\",\n }\n );\n\n process.on(\"SIGINT\", () => {\n serverProcess.kill(\"SIGTERM\");\n process.exit(0);\n });\n}\n\nasync function setupMigrator() {\n // migrator\n migrator = new Migrator({\n mode: \"dev\",\n });\n}\n\nasync function setupFixtureManager() {\n FixtureManager.init();\n}\n\nasync function migrate_run() {\n await setupMigrator();\n\n await migrator.cleanUpDist();\n await migrator.run();\n}\n\nasync function migrate_check() {\n await setupMigrator();\n\n await migrator.cleanUpDist();\n await migrator.check();\n}\n\nasync function migrate_status() {\n await setupMigrator();\n\n const status = await migrator.getStatus();\n // status;\n console.log(status);\n}\n\nasync function migrate_rollback() {\n await setupMigrator();\n\n await migrator.rollback();\n}\n\nasync function migrate_clear() {\n await setupMigrator();\n\n await migrator.clearPendingList();\n}\n\nasync function migrate_reset() {\n await setupMigrator();\n\n await migrator.resetAll();\n}\n\nasync function fixture_init() {\n const srcConfig = Sonamu.dbConfig.development_master;\n const targets = [\n {\n label: \"(REMOTE) Fixture DB\",\n config: Sonamu.dbConfig.fixture_remote,\n },\n {\n label: \"(LOCAL) Fixture DB\",\n config: Sonamu.dbConfig.fixture_local,\n toSkip: (() => {\n const remoteConn = Sonamu.dbConfig.fixture_remote\n .connection as Knex.ConnectionConfig;\n const localConn = Sonamu.dbConfig.fixture_local\n .connection as Knex.ConnectionConfig;\n return (\n remoteConn.host === localConn.host &&\n remoteConn.database === localConn.database\n );\n })(),\n },\n {\n label: \"(LOCAL) Testing DB\",\n config: Sonamu.dbConfig.test,\n },\n ] as {\n label: string;\n config: Knex.Config;\n toSkip?: boolean;\n }[];\n\n // 1. 기준DB 스키마를 덤프\n console.log(\"DUMP...\");\n const dumpFilename = `/tmp/sonamu-fixture-init-${Date.now()}.sql`;\n const srcConn = srcConfig.connection as Knex.ConnectionConfig;\n const migrationsDump = `/tmp/sonamu-fixture-init-migrations-${Date.now()}.sql`;\n execSync(\n `mysqldump -h${srcConn.host} -u${srcConn.user} -p${srcConn.password} --single-transaction -d --no-create-db --triggers ${srcConn.database} > ${dumpFilename}`\n );\n const _db = knex(srcConfig);\n const [[migrations]] = await _db.raw(\n \"SELECT COUNT(*) as count FROM information_schema.tables WHERE table_schema = ? AND table_name = 'knex_migrations'\",\n [srcConn.database]\n );\n if (migrations.count > 0) {\n execSync(\n `mysqldump -h${srcConn.host} -u${srcConn.user} -p${srcConn.password} --single-transaction --no-create-db --triggers ${srcConn.database} knex_migrations knex_migrations_lock > ${migrationsDump}`\n );\n }\n\n // 2. 대상DB 각각에 대하여 존재여부 확인 후 붓기\n for await (const { label, config, toSkip } of targets) {\n const conn = config.connection as Knex.ConnectionConfig;\n\n if (toSkip === true) {\n console.log(chalk.red(`${label}: Skipped!`));\n continue;\n }\n\n const db = knex({\n ...config,\n connection: {\n ...((config.connection ?? {}) as Knex.ConnectionConfig),\n database: undefined,\n },\n });\n const [[row]] = await db.raw(`SHOW DATABASES LIKE \"${conn.database}\"`);\n if (row) {\n console.log(\n chalk.yellow(`${label}: Database \"${conn.database}\" Already exists`)\n );\n await db.destroy();\n continue;\n }\n\n console.log(`SYNC to ${label}...`);\n const mysqlCmd = `mysql -h${conn.host} -u${conn.user} -p${conn.password}`;\n execSync(`${mysqlCmd} -e 'DROP DATABASE IF EXISTS \\`${conn.database}\\`'`);\n execSync(`${mysqlCmd} -e 'CREATE DATABASE \\`${conn.database}\\`'`);\n execSync(`${mysqlCmd} ${conn.database} < ${dumpFilename}`);\n if (await exists(migrationsDump)) {\n execSync(`${mysqlCmd} ${conn.database} < ${migrationsDump}`);\n }\n\n await db.destroy();\n }\n\n await _db.destroy();\n}\n\nasync function fixture_import(entityId: string, recordIds: number[]) {\n await setupFixtureManager();\n\n await FixtureManager.importFixture(entityId, recordIds);\n await FixtureManager.sync();\n}\n\nasync function fixture_sync() {\n await setupFixtureManager();\n\n await FixtureManager.sync();\n}\n\nasync function stub_practice(name: string) {\n const practiceDir = path.join(Sonamu.apiRootPath, \"src\", \"practices\");\n const fileNames = await readdir(practiceDir);\n\n const maxSeqNo = await (async () => {\n if (!(await exists(practiceDir))) {\n await mkdir(practiceDir, { recursive: true });\n }\n\n const filteredSeqs = fileNames\n .filter(\n (fileName) => fileName.startsWith(\"p\") && fileName.endsWith(\".ts\")\n )\n .map((fileName) => {\n const [, seqNo] = fileName.match(/^p([0-9]+)\\-/) ?? [\"0\", \"0\"];\n return parseInt(seqNo);\n })\n .sort((a, b) => b - a);\n\n if (filteredSeqs.length > 0) {\n return filteredSeqs[0];\n }\n\n return 0;\n })();\n\n const currentSeqNo = maxSeqNo + 1;\n const fileName = `p${currentSeqNo}-${name}.ts`;\n const dstPath = path.join(practiceDir, fileName);\n\n const code = [\n `import { Sonamu } from \"sonamu\";`,\n \"\",\n `console.clear();`,\n `console.log(\"${fileName}\");`,\n \"\",\n `Sonamu.runScript(async () => {`,\n ` // TODO`,\n `});`,\n \"\",\n ].join(\"\\n\");\n await writeFile(dstPath, code);\n\n execSync(`code ${dstPath}`);\n\n const runCode = `yarn node -r dotenv/config -r source-map-support/register dist/practices/${fileName.replace(\n \".ts\",\n \".js\"\n )}`;\n console.log(`${chalk.blue(runCode)} copied to clipboard.`);\n execSync(`echo \"${runCode}\" | pbcopy`);\n}\n\nasync function stub_entity(entityId: string) {\n await Sonamu.syncer.createEntity({ entityId });\n}\n\nasync function scaffold_model(entityId: string) {\n await Sonamu.syncer.generateTemplate(\"model\", {\n entityId,\n });\n}\n\nasync function scaffold_model_test(entityId: string) {\n await Sonamu.syncer.generateTemplate(\"model_test\", {\n entityId,\n });\n}\n\nasync function ui() {\n try {\n type StartServersOptions = {\n projectName: string;\n apiRootPath: string;\n port: number;\n };\n const sonamuUI: {\n startServers: (options: StartServersOptions) => void;\n } = await import(\"@sonamu-kit/ui\" as string);\n sonamuUI.startServers({\n projectName:\n Sonamu.config.projectName ?? path.basename(Sonamu.apiRootPath),\n apiRootPath: Sonamu.apiRootPath,\n port: Sonamu.config.ui?.port ?? 57000,\n });\n } catch (e: unknown) {\n if (e instanceof Error && e.message.includes(\"isn't declared\")) {\n console.log(`You need to install ${chalk.blue(`@sonamu-kit/ui`)} first.`);\n return;\n }\n throw e;\n }\n}\n"],"names":["dotenv","config","migrator","bootstrap","process","argv","Sonamu","init","tsicli","types","type","name","message","choices","EntityManager","getAllParentIds","map","entityId","title","value","args","runners","migrate_run","migrate_check","migrate_rollback","migrate_clear","migrate_reset","migrate_status","fixture_init","fixture_import","fixture_sync","stub_practice","stub_entity","scaffold_model","scaffold_model_test","ui","dev_serve","serve","finally","destroy","FixtureManager","nodemon","nodemonConfig","cleanup","projectNodemonPath","hasProjectNodemon","path","join","findApiRootPath","exists","JSON","parse","readFile","watch","ignore","exec","default","server","close","exit","on","distIndexPath","spawn","serverProcess","apiRootPath","console","log","chalk","red","blue","cwd","stdio","kill","setupMigrator","Migrator","mode","setupFixtureManager","cleanUpDist","run","check","status","getStatus","rollback","clearPendingList","resetAll","srcConfig","targets","dumpFilename","srcConn","migrationsDump","_db","migrations","label","toSkip","conn","db","row","mysqlCmd","dbConfig","development_master","fixture_remote","fixture_local","remoteConn","connection","localConn","host","database","test","Date","now","execSync","user","password","knex","raw","count","undefined","yellow","recordIds","importFixture","sync","practiceDir","fileNames","maxSeqNo","currentSeqNo","fileName","dstPath","code","runCode","readdir","filteredSeqs","mkdir","recursive","filter","startsWith","endsWith","match","seqNo","parseInt","sort","a","b","length","writeFile","replace","syncer","createEntity","generateTemplate","sonamuUI","e","startServers","projectName","basename","port","Error","includes"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/database/_batch_update.ts"],"sourcesContent":["/*\n 아래의 링크에서 참고해서 가져온 소스코드\n https://github.com/knex/knex/issues/5716\n*/\n\nimport { Knex } from \"knex\";\n\nexport type RowWithId<Id extends string> = {\n [key in Id]: any;\n} & Record<string, any>;\n\n/**\n * Batch update rows in a table. Technically its a patch since it only updates the specified columns. Any omitted columns will not be affected\n * @param db\n * @param tableName\n * @param ids\n * @param rows\n * @param chunkSize\n * @param trx\n */\nexport async function batchUpdate<Id extends string>(\n knex: Knex,\n tableName: string,\n ids: Id[],\n rows: RowWithId<Id>[],\n chunkSize = 50,\n trx: Knex.Transaction | null = null\n) {\n const chunks: RowWithId<Id>[][] = [];\n for (let i = 0; i < rows.length; i += chunkSize) {\n chunks.push(rows.slice(i, i + chunkSize));\n }\n\n const executeUpdate = async (\n chunk: RowWithId<Id>[],\n transaction: Knex.Transaction\n ) => {\n const sql = generateBatchUpdateSQL(knex, tableName, chunk, ids);\n return knex.raw(sql).transacting(transaction);\n };\n\n if (trx) {\n for (const chunk of chunks) {\n await executeUpdate(chunk, trx);\n }\n } else {\n await knex.transaction(async (newTrx) => {\n for (const chunk of chunks) {\n await executeUpdate(chunk, newTrx);\n }\n });\n }\n}\n\n/**\n * Generate a set of unique keys in a data array\n *\n * Example:\n * [ { a: 1, b: 2 }, { a: 3, c: 4 } ] => Set([ \"a\", \"b\", \"c\" ])\n * @param data\n */\nfunction generateKeySetFromData(data: Record<string, any>[]) {\n const keySet: Set<string> = new Set();\n for (const row of data) {\n for (const key of Object.keys(row)) {\n keySet.add(key);\n }\n }\n return keySet;\n}\n\nfunction generateBatchUpdateSQL<Id extends string>(\n db: Knex,\n tableName: string,\n data: Record<string, any>[],\n identifiers: Id[]\n) {\n const keySet = generateKeySetFromData(data);\n const bindings = [];\n\n const invalidIdentifiers = identifiers.filter((id) => !keySet.has(id));\n if (invalidIdentifiers.length > 0) {\n throw new Error(\n `Invalid identifiers: ${invalidIdentifiers.join(\", \")}. Identifiers must exist in the data`\n );\n }\n\n const cases = [];\n for (const key of keySet) {\n if (identifiers.includes(key as Id)) continue;\n\n const rows = [];\n for (const row of data) {\n if (Object.hasOwnProperty.call(row, key)) {\n const whereClause = identifiers\n .map((id) => `\\`${id}\\` = ?`)\n .join(\" AND \");\n rows.push(`WHEN (${whereClause}) THEN ?`);\n bindings.push(...identifiers.map((i) => row[i]), row[key]);\n }\n }\n\n const whenThen = rows.join(\" \");\n cases.push(`\\`${key}\\` = CASE ${whenThen} ELSE \\`${key}\\` END`);\n }\n\n const whereInClauses = identifiers\n .map((col) => `${col} IN (${data.map(() => \"?\").join(\", \")})`)\n .join(\" AND \");\n\n const whereInBindings = identifiers.flatMap((col) =>\n data.map((row) => row[col])\n );\n\n const sql = db.raw(\n `UPDATE \\`${tableName}\\` SET ${cases.join(\", \")} WHERE ${whereInClauses}`,\n [...bindings, ...whereInBindings]\n );\n\n return sql.toQuery();\n}\n"],"names":["batchUpdate","knex","tableName","ids","rows","chunkSize","trx","chunks","i","executeUpdate","chunk","length","push","slice","transaction","sql","generateBatchUpdateSQL","raw","transacting","newTrx","generateKeySetFromData","data","keySet","Set","row","Object","keys","key","add","db","identifiers","bindings","invalidIdentifiers","filter","id","has","Error","join","cases","includes","hasOwnProperty","call","whereClause","map","whenThen","whereInClauses","col","whereInBindings","flatMap","toQuery"],"mappings":"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"}