sonamu 0.5.7 → 0.7.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 (529) hide show
  1. package/.swcrc.project-default +18 -0
  2. package/bin/cli.js +24 -0
  3. package/dist/ai/agents/agent.d.ts +11 -0
  4. package/dist/ai/agents/agent.d.ts.map +1 -0
  5. package/dist/ai/agents/agent.js +65 -0
  6. package/dist/ai/agents/index.d.ts +3 -0
  7. package/dist/ai/agents/index.d.ts.map +1 -0
  8. package/dist/ai/agents/index.js +4 -0
  9. package/dist/ai/agents/types.d.ts +43 -0
  10. package/dist/ai/agents/types.d.ts.map +1 -0
  11. package/dist/ai/agents/types.js +3 -0
  12. package/dist/ai/index.d.ts +2 -0
  13. package/dist/ai/index.d.ts.map +1 -0
  14. package/dist/ai/index.js +3 -0
  15. package/dist/ai/providers/rtzr/api.d.ts +22 -0
  16. package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
  17. package/dist/ai/providers/rtzr/api.js +28 -0
  18. package/dist/ai/providers/rtzr/error.d.ts +18 -0
  19. package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
  20. package/dist/ai/providers/rtzr/error.js +29 -0
  21. package/dist/ai/providers/rtzr/index.d.ts +5 -0
  22. package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
  23. package/dist/ai/providers/rtzr/index.js +6 -0
  24. package/dist/ai/providers/rtzr/model.d.ts +52 -0
  25. package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
  26. package/dist/ai/providers/rtzr/model.js +137 -0
  27. package/dist/ai/providers/rtzr/options.d.ts +7 -0
  28. package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
  29. package/dist/ai/providers/rtzr/options.js +47 -0
  30. package/dist/ai/providers/rtzr/provider.d.ts +18 -0
  31. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
  32. package/dist/ai/providers/rtzr/provider.js +54 -0
  33. package/dist/ai/providers/rtzr/utils.d.ts +19 -0
  34. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
  35. package/dist/ai/providers/rtzr/utils.js +88 -0
  36. package/dist/api/base-frame.d.ts +2 -2
  37. package/dist/api/base-frame.d.ts.map +1 -1
  38. package/dist/api/base-frame.js +13 -2
  39. package/dist/api/caster.d.ts.map +1 -1
  40. package/dist/api/caster.js +71 -2
  41. package/dist/api/code-converters.d.ts +58 -14
  42. package/dist/api/code-converters.d.ts.map +1 -1
  43. package/dist/api/code-converters.js +258 -2
  44. package/dist/api/config.d.ts +90 -0
  45. package/dist/api/config.d.ts.map +1 -0
  46. package/dist/api/config.js +25 -0
  47. package/dist/api/context.d.ts +4 -2
  48. package/dist/api/context.d.ts.map +1 -1
  49. package/dist/api/context.js +3 -2
  50. package/dist/api/decorators.d.ts +20 -6
  51. package/dist/api/decorators.d.ts.map +1 -1
  52. package/dist/api/decorators.js +235 -2
  53. package/dist/api/index.d.ts +2 -2
  54. package/dist/api/index.d.ts.map +1 -1
  55. package/dist/api/index.js +9 -2
  56. package/dist/api/sonamu.d.ts +10 -24
  57. package/dist/api/sonamu.d.ts.map +1 -1
  58. package/dist/api/sonamu.js +514 -2
  59. package/dist/api/validator.d.ts +6 -0
  60. package/dist/api/validator.d.ts.map +1 -0
  61. package/dist/api/validator.js +81 -0
  62. package/dist/bin/build-config.d.ts +6 -1
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +15 -2
  65. package/dist/bin/cli.js +519 -2
  66. package/dist/bin/hot-hook-register.d.ts +11 -0
  67. package/dist/bin/hot-hook-register.d.ts.map +1 -0
  68. package/dist/bin/hot-hook-register.js +21 -0
  69. package/dist/bin/loader-register.d.ts +2 -0
  70. package/dist/bin/loader-register.d.ts.map +1 -0
  71. package/dist/bin/loader-register.js +34 -0
  72. package/dist/database/_batch_update.d.ts +5 -3
  73. package/dist/database/_batch_update.d.ts.map +1 -1
  74. package/dist/database/_batch_update.js +95 -2
  75. package/dist/database/base-model.d.ts +96 -10
  76. package/dist/database/base-model.d.ts.map +1 -1
  77. package/dist/database/base-model.js +390 -2
  78. package/dist/database/base-model.types.d.ts +93 -0
  79. package/dist/database/base-model.types.d.ts.map +1 -0
  80. package/dist/database/base-model.types.js +10 -0
  81. package/dist/database/code-generator.d.ts +1 -1
  82. package/dist/database/code-generator.d.ts.map +1 -1
  83. package/dist/database/code-generator.js +54 -2
  84. package/dist/database/db.d.ts +6 -21
  85. package/dist/database/db.d.ts.map +1 -1
  86. package/dist/database/db.js +129 -2
  87. package/dist/database/puri-subset.test-d.js +81 -0
  88. package/dist/database/puri-subset.types.d.ts +123 -0
  89. package/dist/database/puri-subset.types.d.ts.map +1 -0
  90. package/dist/database/puri-subset.types.js +16 -0
  91. package/dist/database/puri-wrapper.d.ts +13 -11
  92. package/dist/database/puri-wrapper.d.ts.map +1 -1
  93. package/dist/database/puri-wrapper.js +109 -2
  94. package/dist/database/puri.d.ts +41 -23
  95. package/dist/database/puri.d.ts.map +1 -1
  96. package/dist/database/puri.js +601 -2
  97. package/dist/database/puri.types.d.ts +25 -6
  98. package/dist/database/puri.types.d.ts.map +1 -1
  99. package/dist/database/puri.types.js +6 -2
  100. package/dist/database/transaction-context.d.ts +1 -1
  101. package/dist/database/transaction-context.d.ts.map +1 -1
  102. package/dist/database/transaction-context.js +14 -2
  103. package/dist/database/upsert-builder.d.ts +9 -3
  104. package/dist/database/upsert-builder.d.ts.map +1 -1
  105. package/dist/database/upsert-builder.js +365 -2
  106. package/dist/entity/entity-manager.d.ts +167 -2
  107. package/dist/entity/entity-manager.d.ts.map +1 -1
  108. package/dist/entity/entity-manager.js +130 -2
  109. package/dist/entity/entity.d.ts +5 -3
  110. package/dist/entity/entity.d.ts.map +1 -1
  111. package/dist/entity/entity.js +750 -2
  112. package/dist/exceptions/error-handler.d.ts +1 -1
  113. package/dist/exceptions/error-handler.d.ts.map +1 -1
  114. package/dist/exceptions/error-handler.js +29 -2
  115. package/dist/exceptions/so-exceptions.d.ts +1 -1
  116. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  117. package/dist/exceptions/so-exceptions.js +85 -2
  118. package/dist/file-storage/driver.d.ts +1 -1
  119. package/dist/file-storage/driver.d.ts.map +1 -1
  120. package/dist/file-storage/driver.js +79 -2
  121. package/dist/file-storage/file-storage.js +75 -2
  122. package/dist/index.d.ts +18 -9
  123. package/dist/index.d.ts.map +1 -1
  124. package/dist/index.js +34 -2
  125. package/dist/migration/code-generation.d.ts +1 -1
  126. package/dist/migration/code-generation.d.ts.map +1 -1
  127. package/dist/migration/code-generation.js +614 -2
  128. package/dist/migration/migration-set.d.ts +2 -10
  129. package/dist/migration/migration-set.d.ts.map +1 -1
  130. package/dist/migration/migration-set.js +213 -2
  131. package/dist/migration/migrator.d.ts +24 -82
  132. package/dist/migration/migrator.d.ts.map +1 -1
  133. package/dist/migration/migrator.js +330 -2
  134. package/dist/migration/postgresql-schema-reader.d.ts +51 -0
  135. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
  136. package/dist/migration/postgresql-schema-reader.js +245 -0
  137. package/dist/migration/types.d.ts +6 -38
  138. package/dist/migration/types.d.ts.map +1 -1
  139. package/dist/migration/types.js +3 -2
  140. package/dist/naite/messaging-types.d.ts +43 -0
  141. package/dist/naite/messaging-types.d.ts.map +1 -0
  142. package/dist/naite/messaging-types.js +7 -0
  143. package/dist/naite/naite-reporter.d.ts +41 -0
  144. package/dist/naite/naite-reporter.d.ts.map +1 -0
  145. package/dist/naite/naite-reporter.js +102 -0
  146. package/dist/naite/naite.d.ts +95 -0
  147. package/dist/naite/naite.d.ts.map +1 -0
  148. package/dist/naite/naite.js +316 -0
  149. package/dist/stream/index.js +3 -2
  150. package/dist/stream/sse.d.ts +2 -2
  151. package/dist/stream/sse.d.ts.map +1 -1
  152. package/dist/stream/sse.js +38 -2
  153. package/dist/syncer/api-parser.d.ts +10 -0
  154. package/dist/syncer/api-parser.d.ts.map +1 -0
  155. package/dist/syncer/api-parser.js +240 -0
  156. package/dist/syncer/checksum.d.ts +21 -0
  157. package/dist/syncer/checksum.d.ts.map +1 -0
  158. package/dist/syncer/checksum.js +98 -0
  159. package/dist/syncer/code-generator.d.ts +20 -0
  160. package/dist/syncer/code-generator.d.ts.map +1 -0
  161. package/dist/syncer/code-generator.js +161 -0
  162. package/dist/syncer/entity-operations.d.ts +17 -0
  163. package/dist/syncer/entity-operations.d.ts.map +1 -0
  164. package/dist/syncer/entity-operations.js +59 -0
  165. package/dist/syncer/file-patterns.d.ts +29 -0
  166. package/dist/syncer/file-patterns.d.ts.map +1 -0
  167. package/dist/syncer/file-patterns.js +38 -0
  168. package/dist/syncer/index.d.ts +6 -0
  169. package/dist/syncer/index.d.ts.map +1 -1
  170. package/dist/syncer/index.js +9 -2
  171. package/dist/syncer/module-loader.d.ts +35 -0
  172. package/dist/syncer/module-loader.d.ts.map +1 -0
  173. package/dist/syncer/module-loader.js +87 -0
  174. package/dist/syncer/syncer.d.ts +98 -106
  175. package/dist/syncer/syncer.d.ts.map +1 -1
  176. package/dist/syncer/syncer.js +422 -2
  177. package/dist/template/entity-converter.d.ts +14 -0
  178. package/dist/template/entity-converter.d.ts.map +1 -0
  179. package/dist/template/entity-converter.js +108 -0
  180. package/dist/template/helpers.d.ts +23 -0
  181. package/dist/template/helpers.d.ts.map +1 -0
  182. package/dist/template/helpers.js +64 -0
  183. package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
  184. package/dist/template/implementations/entity.template.d.ts.map +1 -0
  185. package/dist/template/implementations/entity.template.js +86 -0
  186. package/dist/{templates → template/implementations}/generated.template.d.ts +3 -4
  187. package/dist/template/implementations/generated.template.d.ts.map +1 -0
  188. package/dist/template/implementations/generated.template.js +249 -0
  189. package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -4
  190. package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
  191. package/dist/template/implementations/generated_http.template.js +131 -0
  192. package/dist/{templates → template/implementations}/generated_sso.template.d.ts +4 -5
  193. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
  194. package/dist/template/implementations/generated_sso.template.js +134 -0
  195. package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
  196. package/dist/template/implementations/init_types.template.d.ts.map +1 -0
  197. package/dist/template/implementations/init_types.template.js +38 -0
  198. package/dist/template/implementations/model.template.d.ts +17 -0
  199. package/dist/template/implementations/model.template.d.ts.map +1 -0
  200. package/dist/template/implementations/model.template.js +181 -0
  201. package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
  202. package/dist/template/implementations/model_test.template.d.ts.map +1 -0
  203. package/dist/template/implementations/model_test.template.js +35 -0
  204. package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
  205. package/dist/template/implementations/service.template.d.ts.map +1 -0
  206. package/dist/template/implementations/service.template.js +201 -0
  207. package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
  208. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
  209. package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
  210. package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
  211. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
  212. package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
  213. package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
  214. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
  215. package/dist/template/implementations/view_enums_select.template.js +55 -0
  216. package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
  217. package/dist/template/implementations/view_form.template.d.ts.map +1 -0
  218. package/dist/template/implementations/view_form.template.js +337 -0
  219. package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
  220. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
  221. package/dist/template/implementations/view_id_all_select.template.js +31 -0
  222. package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
  223. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
  224. package/dist/template/implementations/view_id_async_select.template.js +105 -0
  225. package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
  226. package/dist/template/implementations/view_list.template.d.ts.map +1 -0
  227. package/dist/template/implementations/view_list.template.js +475 -0
  228. package/dist/template/implementations/view_list_columns.template.d.ts +17 -0
  229. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
  230. package/dist/template/implementations/view_list_columns.template.js +49 -0
  231. package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
  232. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
  233. package/dist/template/implementations/view_search_input.template.js +64 -0
  234. package/dist/template/index.d.ts +7 -0
  235. package/dist/template/index.d.ts.map +1 -0
  236. package/dist/template/index.js +8 -0
  237. package/dist/template/template-manager.d.ts +56 -0
  238. package/dist/template/template-manager.d.ts.map +1 -0
  239. package/dist/template/template-manager.js +125 -0
  240. package/dist/template/template-types.d.ts +16 -0
  241. package/dist/template/template-types.d.ts.map +1 -0
  242. package/dist/template/template-types.js +7 -0
  243. package/dist/template/template.d.ts +49 -0
  244. package/dist/template/template.d.ts.map +1 -0
  245. package/dist/template/template.js +60 -0
  246. package/dist/template/zod-converter.d.ts +51 -0
  247. package/dist/template/zod-converter.d.ts.map +1 -0
  248. package/dist/template/zod-converter.js +449 -0
  249. package/dist/testing/_relation-graph.d.ts +1 -1
  250. package/dist/testing/_relation-graph.d.ts.map +1 -1
  251. package/dist/testing/_relation-graph.js +89 -2
  252. package/dist/testing/fixture-manager.d.ts +42 -11
  253. package/dist/testing/fixture-manager.d.ts.map +1 -1
  254. package/dist/testing/fixture-manager.js +623 -2
  255. package/dist/types/types.d.ts +747 -143
  256. package/dist/types/types.d.ts.map +1 -1
  257. package/dist/types/types.js +546 -2
  258. package/dist/typings/knex.d.js +3 -2
  259. package/dist/utils/async-utils.d.ts +7 -0
  260. package/dist/utils/async-utils.d.ts.map +1 -1
  261. package/dist/utils/async-utils.js +57 -2
  262. package/dist/utils/console-util.d.ts +2 -0
  263. package/dist/utils/console-util.d.ts.map +1 -0
  264. package/dist/utils/console-util.js +6 -0
  265. package/dist/utils/controller.d.ts +1 -0
  266. package/dist/utils/controller.d.ts.map +1 -1
  267. package/dist/utils/controller.js +29 -2
  268. package/dist/utils/esm-utils.d.ts +39 -0
  269. package/dist/utils/esm-utils.d.ts.map +1 -0
  270. package/dist/utils/esm-utils.js +49 -0
  271. package/dist/utils/formatter.d.ts +3 -0
  272. package/dist/utils/formatter.d.ts.map +1 -0
  273. package/dist/utils/formatter.js +110 -0
  274. package/dist/utils/fs-utils.d.ts +1 -1
  275. package/dist/utils/fs-utils.d.ts.map +1 -1
  276. package/dist/utils/fs-utils.js +17 -2
  277. package/dist/utils/lodash-able.d.ts.map +1 -1
  278. package/dist/utils/lodash-able.js +6 -2
  279. package/dist/utils/model.js +22 -2
  280. package/dist/utils/object-utils.d.ts +44 -0
  281. package/dist/utils/object-utils.d.ts.map +1 -0
  282. package/dist/utils/object-utils.js +191 -0
  283. package/dist/utils/path-utils.d.ts +89 -0
  284. package/dist/utils/path-utils.d.ts.map +1 -0
  285. package/dist/utils/path-utils.js +60 -0
  286. package/dist/utils/process-utils.d.ts +13 -0
  287. package/dist/utils/process-utils.d.ts.map +1 -0
  288. package/dist/utils/process-utils.js +36 -0
  289. package/dist/utils/sql-parser.d.ts +5 -1
  290. package/dist/utils/sql-parser.d.ts.map +1 -1
  291. package/dist/utils/sql-parser.js +46 -2
  292. package/dist/utils/type-utils.d.ts +23 -0
  293. package/dist/utils/type-utils.d.ts.map +1 -0
  294. package/dist/utils/type-utils.js +45 -0
  295. package/dist/utils/utils.d.ts +10 -7
  296. package/dist/utils/utils.d.ts.map +1 -1
  297. package/dist/utils/utils.js +72 -2
  298. package/dist/utils/zod-error.d.ts +1 -1
  299. package/dist/utils/zod-error.d.ts.map +1 -1
  300. package/dist/utils/zod-error.js +19 -2
  301. package/package.json +65 -27
  302. package/src/ai/agents/agent.ts +87 -0
  303. package/src/ai/agents/index.ts +2 -0
  304. package/src/ai/agents/types.ts +47 -0
  305. package/src/ai/index.ts +1 -0
  306. package/src/ai/providers/rtzr/api.ts +37 -0
  307. package/src/ai/providers/rtzr/error.ts +34 -0
  308. package/src/ai/providers/rtzr/index.ts +4 -0
  309. package/src/ai/providers/rtzr/model.ts +201 -0
  310. package/src/ai/providers/rtzr/options.ts +49 -0
  311. package/src/ai/providers/rtzr/provider.ts +91 -0
  312. package/src/ai/providers/rtzr/utils.ts +127 -0
  313. package/src/api/base-frame.ts +4 -2
  314. package/src/api/caster.ts +17 -23
  315. package/src/api/code-converters.ts +178 -535
  316. package/src/api/config.ts +125 -0
  317. package/src/api/context.ts +7 -17
  318. package/src/api/decorators.ts +176 -46
  319. package/src/api/index.ts +2 -2
  320. package/src/api/sonamu.ts +190 -167
  321. package/src/api/validator.ts +83 -0
  322. package/src/bin/build-config.ts +8 -1
  323. package/src/bin/cli.ts +258 -124
  324. package/src/bin/hot-hook-register.ts +22 -0
  325. package/src/bin/loader-register.ts +38 -0
  326. package/src/database/_batch_update.ts +46 -31
  327. package/src/database/base-model.ts +390 -182
  328. package/src/database/base-model.types.ts +155 -0
  329. package/src/database/code-generator.ts +13 -32
  330. package/src/database/db.ts +40 -96
  331. package/src/database/puri-subset.test-d.ts +471 -0
  332. package/src/database/puri-subset.types.ts +195 -0
  333. package/src/database/puri-wrapper.ts +58 -67
  334. package/src/database/puri.ts +229 -148
  335. package/src/database/puri.types.ts +76 -30
  336. package/src/database/transaction-context.ts +1 -1
  337. package/src/database/upsert-builder.ts +262 -132
  338. package/src/entity/entity-manager.ts +48 -36
  339. package/src/entity/entity.ts +330 -248
  340. package/src/exceptions/error-handler.ts +3 -3
  341. package/src/exceptions/so-exceptions.ts +11 -11
  342. package/src/file-storage/driver.ts +5 -5
  343. package/src/file-storage/file-storage.ts +2 -2
  344. package/src/index.ts +18 -10
  345. package/src/migration/code-generation.ts +185 -172
  346. package/src/migration/migration-set.ts +80 -293
  347. package/src/migration/migrator.ts +199 -571
  348. package/src/migration/mysql-schema-reader.ts.txt +272 -0
  349. package/src/migration/postgresql-schema-reader.ts +310 -0
  350. package/src/migration/types.ts +6 -39
  351. package/src/naite/messaging-types.ts +51 -0
  352. package/src/naite/naite-reporter.ts +128 -0
  353. package/src/naite/naite.ts +415 -0
  354. package/src/shared/web.shared.ts.txt +20 -24
  355. package/src/stream/sse.ts +5 -5
  356. package/src/syncer/api-parser.ts +282 -0
  357. package/src/syncer/checksum.ts +140 -0
  358. package/src/syncer/code-generator.ts +198 -0
  359. package/src/syncer/entity-operations.ts +65 -0
  360. package/src/syncer/file-patterns.ts +56 -0
  361. package/src/syncer/index.ts +6 -0
  362. package/src/syncer/module-loader.ts +128 -0
  363. package/src/syncer/syncer.ts +389 -1453
  364. package/src/template/entity-converter.ts +114 -0
  365. package/src/template/helpers.ts +81 -0
  366. package/src/{templates → template/implementations}/entity.template.ts +7 -7
  367. package/src/{templates → template/implementations}/generated.template.ts +101 -101
  368. package/src/{templates → template/implementations}/generated_http.template.ts +27 -57
  369. package/src/template/implementations/generated_sso.template.ts +151 -0
  370. package/src/{templates → template/implementations}/init_types.template.ts +5 -7
  371. package/src/{templates → template/implementations}/model.template.ts +52 -43
  372. package/src/{templates → template/implementations}/model_test.template.ts +5 -5
  373. package/src/{templates → template/implementations}/service.template.ts +66 -82
  374. package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
  375. package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +4 -20
  376. package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
  377. package/src/{templates → template/implementations}/view_form.template.ts +40 -83
  378. package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
  379. package/src/{templates → template/implementations}/view_id_async_select.template.ts +10 -24
  380. package/src/{templates → template/implementations}/view_list.template.ts +60 -152
  381. package/src/{templates → template/implementations}/view_list_columns.template.ts +5 -11
  382. package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
  383. package/src/template/index.ts +6 -0
  384. package/src/template/template-manager.ts +166 -0
  385. package/src/template/template-types.ts +16 -0
  386. package/src/template/template.ts +105 -0
  387. package/src/template/zod-converter.ts +525 -0
  388. package/src/testing/_relation-graph.ts +18 -11
  389. package/src/testing/fixture-manager.ts +472 -359
  390. package/src/types/types.ts +553 -308
  391. package/src/typings/knex.d.ts +7 -9
  392. package/src/utils/async-utils.ts +23 -10
  393. package/src/utils/console-util.ts +4 -0
  394. package/src/utils/controller.ts +3 -0
  395. package/src/utils/esm-utils.ts +59 -0
  396. package/src/utils/formatter.ts +109 -0
  397. package/src/utils/fs-utils.ts +1 -1
  398. package/src/utils/lodash-able.ts +1 -4
  399. package/src/utils/object-utils.ts +217 -0
  400. package/src/utils/path-utils.ts +99 -0
  401. package/src/utils/process-utils.ts +46 -0
  402. package/src/utils/sql-parser.ts +23 -5
  403. package/src/utils/type-utils.ts +83 -0
  404. package/src/utils/utils.ts +66 -43
  405. package/src/utils/zod-error.ts +3 -4
  406. package/dist/api/base-frame.js.map +0 -1
  407. package/dist/api/caster.js.map +0 -1
  408. package/dist/api/code-converters.js.map +0 -1
  409. package/dist/api/context.js.map +0 -1
  410. package/dist/api/decorators.js.map +0 -1
  411. package/dist/api/index.js.map +0 -1
  412. package/dist/api/sonamu.js.map +0 -1
  413. package/dist/bin/build-config.js.map +0 -1
  414. package/dist/bin/cli-wrapper.d.ts +0 -3
  415. package/dist/bin/cli-wrapper.d.ts.map +0 -1
  416. package/dist/bin/cli-wrapper.js +0 -3
  417. package/dist/bin/cli-wrapper.js.map +0 -1
  418. package/dist/bin/cli.js.map +0 -1
  419. package/dist/database/_batch_update.js.map +0 -1
  420. package/dist/database/base-model.js.map +0 -1
  421. package/dist/database/code-generator.js.map +0 -1
  422. package/dist/database/db.js.map +0 -1
  423. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
  424. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
  425. package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -2
  426. package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
  427. package/dist/database/puri-wrapper.js.map +0 -1
  428. package/dist/database/puri.js.map +0 -1
  429. package/dist/database/puri.types.js.map +0 -1
  430. package/dist/database/transaction-context.js.map +0 -1
  431. package/dist/database/upsert-builder.js.map +0 -1
  432. package/dist/entity/entity-manager.js.map +0 -1
  433. package/dist/entity/entity-utils.d.ts +0 -61
  434. package/dist/entity/entity-utils.d.ts.map +0 -1
  435. package/dist/entity/entity-utils.js +0 -2
  436. package/dist/entity/entity-utils.js.map +0 -1
  437. package/dist/entity/entity.js.map +0 -1
  438. package/dist/exceptions/error-handler.js.map +0 -1
  439. package/dist/exceptions/so-exceptions.js.map +0 -1
  440. package/dist/file-storage/driver.js.map +0 -1
  441. package/dist/file-storage/file-storage.js.map +0 -1
  442. package/dist/index.js.map +0 -1
  443. package/dist/migration/code-generation.js.map +0 -1
  444. package/dist/migration/migration-set.js.map +0 -1
  445. package/dist/migration/migrator.js.map +0 -1
  446. package/dist/migration/types.js.map +0 -1
  447. package/dist/stream/index.js.map +0 -1
  448. package/dist/stream/sse.js.map +0 -1
  449. package/dist/syncer/index.js.map +0 -1
  450. package/dist/syncer/syncer.js.map +0 -1
  451. package/dist/templates/base-template.d.ts +0 -13
  452. package/dist/templates/base-template.d.ts.map +0 -1
  453. package/dist/templates/base-template.js +0 -2
  454. package/dist/templates/base-template.js.map +0 -1
  455. package/dist/templates/entity.template.d.ts.map +0 -1
  456. package/dist/templates/entity.template.js +0 -2
  457. package/dist/templates/entity.template.js.map +0 -1
  458. package/dist/templates/generated.template.d.ts.map +0 -1
  459. package/dist/templates/generated.template.js +0 -2
  460. package/dist/templates/generated.template.js.map +0 -1
  461. package/dist/templates/generated_http.template.d.ts.map +0 -1
  462. package/dist/templates/generated_http.template.js +0 -2
  463. package/dist/templates/generated_http.template.js.map +0 -1
  464. package/dist/templates/generated_sso.template.d.ts.map +0 -1
  465. package/dist/templates/generated_sso.template.js +0 -2
  466. package/dist/templates/generated_sso.template.js.map +0 -1
  467. package/dist/templates/index.d.ts +0 -2
  468. package/dist/templates/index.d.ts.map +0 -1
  469. package/dist/templates/index.js +0 -2
  470. package/dist/templates/index.js.map +0 -1
  471. package/dist/templates/init_types.template.d.ts.map +0 -1
  472. package/dist/templates/init_types.template.js +0 -2
  473. package/dist/templates/init_types.template.js.map +0 -1
  474. package/dist/templates/model.template.d.ts +0 -17
  475. package/dist/templates/model.template.d.ts.map +0 -1
  476. package/dist/templates/model.template.js +0 -2
  477. package/dist/templates/model.template.js.map +0 -1
  478. package/dist/templates/model_test.template.d.ts.map +0 -1
  479. package/dist/templates/model_test.template.js +0 -2
  480. package/dist/templates/model_test.template.js.map +0 -1
  481. package/dist/templates/service.template.d.ts.map +0 -1
  482. package/dist/templates/service.template.js +0 -2
  483. package/dist/templates/service.template.js.map +0 -1
  484. package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
  485. package/dist/templates/view_enums_buttonset.template.js +0 -2
  486. package/dist/templates/view_enums_buttonset.template.js.map +0 -1
  487. package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
  488. package/dist/templates/view_enums_dropdown.template.js +0 -2
  489. package/dist/templates/view_enums_dropdown.template.js.map +0 -1
  490. package/dist/templates/view_enums_select.template.d.ts.map +0 -1
  491. package/dist/templates/view_enums_select.template.js +0 -2
  492. package/dist/templates/view_enums_select.template.js.map +0 -1
  493. package/dist/templates/view_form.template.d.ts.map +0 -1
  494. package/dist/templates/view_form.template.js +0 -2
  495. package/dist/templates/view_form.template.js.map +0 -1
  496. package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
  497. package/dist/templates/view_id_all_select.template.js +0 -2
  498. package/dist/templates/view_id_all_select.template.js.map +0 -1
  499. package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
  500. package/dist/templates/view_id_async_select.template.js +0 -2
  501. package/dist/templates/view_id_async_select.template.js.map +0 -1
  502. package/dist/templates/view_list.template.d.ts.map +0 -1
  503. package/dist/templates/view_list.template.js +0 -2
  504. package/dist/templates/view_list.template.js.map +0 -1
  505. package/dist/templates/view_list_columns.template.d.ts +0 -17
  506. package/dist/templates/view_list_columns.template.d.ts.map +0 -1
  507. package/dist/templates/view_list_columns.template.js +0 -2
  508. package/dist/templates/view_list_columns.template.js.map +0 -1
  509. package/dist/templates/view_search_input.template.d.ts.map +0 -1
  510. package/dist/templates/view_search_input.template.js +0 -2
  511. package/dist/templates/view_search_input.template.js.map +0 -1
  512. package/dist/testing/_relation-graph.js.map +0 -1
  513. package/dist/testing/fixture-manager.js.map +0 -1
  514. package/dist/types/types.js.map +0 -1
  515. package/dist/typings/knex.d.js.map +0 -1
  516. package/dist/utils/async-utils.js.map +0 -1
  517. package/dist/utils/controller.js.map +0 -1
  518. package/dist/utils/fs-utils.js.map +0 -1
  519. package/dist/utils/lodash-able.js.map +0 -1
  520. package/dist/utils/model.js.map +0 -1
  521. package/dist/utils/sql-parser.js.map +0 -1
  522. package/dist/utils/utils.js.map +0 -1
  523. package/dist/utils/zod-error.js.map +0 -1
  524. package/src/bin/cli-wrapper.ts +0 -75
  525. package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
  526. package/src/entity/entity-utils.ts +0 -291
  527. package/src/templates/base-template.ts +0 -19
  528. package/src/templates/generated_sso.template.ts +0 -138
  529. package/src/templates/index.ts +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/entity/entity.ts"],"sourcesContent":["import _ from \"lodash\";\nimport { EntityManager as EntityManager } from \"./entity-manager\";\nimport {\n EntityProp,\n RelationProp,\n isRelationProp,\n SubsetQuery,\n isVirtualProp,\n isBelongsToOneRelationProp,\n isOneToOneRelationProp,\n isHasManyRelationProp,\n isManyToManyRelationProp,\n EntityPropNode,\n isEnumProp,\n StringProp,\n EntityIndex,\n EntityJson,\n EntitySubsetRow,\n} from \"../types/types\";\nimport inflection from \"inflection\";\nimport path from \"path\";\nimport { writeFile } from \"fs/promises\";\nimport { z } from \"zod\";\nimport { Sonamu } from \"../api/sonamu\";\nimport prettier from \"prettier\";\nimport { nonNullable } from \"../utils/utils\";\nimport { exists } from \"../utils/fs-utils\";\n\nexport class Entity {\n id: string;\n parentId?: string;\n table: string;\n title: string;\n names: {\n parentFs: string;\n fs: string;\n module: string;\n };\n props: EntityProp[];\n propsDict: {\n [key: string]: EntityProp;\n };\n relations: {\n [key: string]: RelationProp;\n };\n indexes: EntityIndex[];\n subsets: {\n [key: string]: string[];\n };\n types: {\n [name: string]: z.ZodTypeAny;\n } = {};\n enums: {\n [enumId: string]: z.ZodEnum<any>;\n } = {};\n enumLabels: {\n [enumId: string]: {\n [key: string]: string;\n };\n } = {};\n\n constructor({\n id,\n parentId,\n table,\n title,\n props,\n indexes,\n subsets,\n enums,\n }: EntityJson) {\n // id\n this.id = id;\n this.parentId = parentId;\n this.title = title ?? this.id;\n this.table = table ?? inflection.underscore(inflection.pluralize(id));\n\n // props\n if (props) {\n this.props = props.map((prop) => {\n if (isEnumProp(prop)) {\n if (prop.id.includes(\"$Model\")) {\n prop.id = prop.id.replace(\"$Model\", id);\n }\n }\n return prop;\n });\n this.propsDict = props.reduce((result, prop) => {\n return {\n ...result,\n [prop.name]: prop,\n };\n }, {});\n\n // relations\n this.relations = props\n .filter((prop) => isRelationProp(prop))\n .reduce((result, prop) => {\n return {\n ...result,\n [prop.name]: prop,\n };\n }, {});\n } else {\n this.props = [];\n this.propsDict = {};\n this.relations = {};\n }\n\n // indexes\n this.indexes = indexes ?? [];\n\n // subsets\n this.subsets = subsets ?? {};\n\n // enums\n this.enumLabels = enums ?? {};\n this.enums = Object.fromEntries(\n Object.entries(this.enumLabels).map(([key, enumLabel]) => {\n return [\n key,\n z.enum(\n Object.keys(enumLabel) as unknown as readonly [string, ...string[]]\n ),\n ];\n })\n );\n\n // names\n this.names = {\n parentFs: inflection\n .dasherize(inflection.underscore(parentId ?? id))\n .toLowerCase(),\n fs: inflection.dasherize(inflection.underscore(id)).toLowerCase(),\n module: id,\n };\n }\n\n /*\n subset SELECT/JOIN/LOADER 결과 리턴\n */\n getSubsetQuery(subsetKey: string): SubsetQuery {\n const subset = this.subsets[subsetKey];\n\n const result: SubsetQuery = this.resolveSubsetQuery(\"\", subset);\n return result;\n }\n\n /*\n */\n resolveSubsetQuery(\n prefix: string,\n fields: string[],\n isAlreadyOuterJoined: boolean = false\n ): SubsetQuery {\n // prefix 치환 (prefix는 ToOneRelation이 복수로 붙은 경우 모두 __로 변경됨)\n prefix = prefix.replace(/\\./g, \"__\");\n\n // 서브셋을 1뎁스만 분리하여 그룹핑\n const subsetGroup = _.groupBy(fields, (field) => {\n if (field.includes(\".\")) {\n const [rel] = field.split(\".\");\n return rel;\n } else {\n return \"\";\n }\n });\n\n const result = Object.keys(subsetGroup).reduce(\n (r, groupKey) => {\n const fields = subsetGroup[groupKey];\n // 현재 테이블 필드셋은 select, virtual에 추가하고 리턴\n if (groupKey === \"\") {\n const realFields = fields.filter(\n (field) => !isVirtualProp(this.propsDict[field])\n );\n const virtualFields = fields.filter((field) =>\n isVirtualProp(this.propsDict[field])\n );\n\n if (prefix === \"\") {\n // 현재 테이블인 경우\n r.select = r.select.concat(\n realFields.map((field) => `${this.table}.${field}`)\n );\n r.virtual = r.virtual.concat(virtualFields);\n } else {\n // 넘어온 테이블인 경우\n r.select = r.select.concat(\n realFields.map(\n (field) => `${prefix}.${field} as ${prefix}__${field}`\n )\n );\n }\n\n return r;\n }\n\n const relation = this.relations[groupKey];\n if (relation === undefined) {\n throw new Error(`존재하지 않는 relation 참조 ${groupKey}`);\n }\n const relEntity = EntityManager.get(relation.with);\n\n if (\n isOneToOneRelationProp(relation) ||\n isBelongsToOneRelationProp(relation)\n ) {\n // -One Relation: JOIN 으로 처리\n const relFields = fields.map((field) =>\n field.split(\".\").slice(1).join(\".\")\n );\n\n // -One Relation에서 id 필드만 참조하는 경우 릴레이션 넘기지 않고 리턴\n if (relFields.length === 1 && relFields[0] === \"id\") {\n if (prefix === \"\") {\n r.select = r.select.concat(`${this.table}.${groupKey}_id`);\n } else {\n r.select = r.select.concat(\n `${prefix}.${groupKey}_id as ${prefix}__${groupKey}_id`\n );\n }\n return r;\n }\n\n // innerOrOuter\n const innerOrOuter = (() => {\n if (isAlreadyOuterJoined) {\n return \"outer\";\n }\n\n if (isOneToOneRelationProp(relation)) {\n if (\n relation.hasJoinColumn === true &&\n (relation.nullable ?? false) === false\n ) {\n return \"inner\";\n } else {\n return \"outer\";\n }\n } else {\n if (relation.nullable) {\n return \"outer\";\n } else {\n return \"inner\";\n }\n }\n })();\n const relSubsetQuery = relEntity.resolveSubsetQuery(\n `${prefix !== \"\" ? prefix + \".\" : \"\"}${groupKey}`,\n relFields,\n innerOrOuter === \"outer\"\n );\n r.select = r.select.concat(relSubsetQuery.select);\n r.virtual = r.virtual.concat(relSubsetQuery.virtual);\n\n const joinAs = prefix === \"\" ? groupKey : prefix + \"__\" + groupKey;\n const fromTable = prefix === \"\" ? this.table : prefix;\n\n let joinClause;\n if (relation.customJoinClause) {\n joinClause = {\n custom: relation.customJoinClause,\n };\n } else {\n let from, to;\n if (isOneToOneRelationProp(relation)) {\n if (relation.hasJoinColumn) {\n from = `${fromTable}.${relation.name}_id`;\n to = `${joinAs}.id`;\n } else {\n from = `${fromTable}.id`;\n to = `${joinAs}.${inflection.underscore(\n this.names.fs.replace(/\\-/g, \"_\")\n )}_id`;\n }\n } else {\n from = `${fromTable}.${relation.name}_id`;\n to = `${joinAs}.id`;\n }\n joinClause = {\n from,\n to,\n };\n }\n\n r.joins.push({\n as: joinAs,\n join: innerOrOuter,\n table: relEntity.table,\n ...joinClause,\n });\n\n // BelongsToOne 밑에 HasMany가 붙은 경우\n if (relSubsetQuery.loaders.length > 0) {\n const convertedLoaders = relSubsetQuery.loaders.map((loader) => {\n const newAs = [groupKey, loader.as].join(\"__\");\n return {\n as: newAs,\n table: loader.table,\n manyJoin: loader.manyJoin,\n oneJoins: loader.oneJoins,\n select: loader.select,\n loaders: loader.loaders,\n };\n });\n\n r.loaders = [...r.loaders, ...convertedLoaders];\n }\n\n r.joins = r.joins.concat(relSubsetQuery.joins);\n } else if (\n isHasManyRelationProp(relation) ||\n isManyToManyRelationProp(relation)\n ) {\n // -Many Relation: Loader 로 처리\n const relFields = fields.map((field) =>\n field.split(\".\").slice(1).join(\".\")\n );\n const relSubsetQuery = relEntity.resolveSubsetQuery(\"\", relFields);\n\n let manyJoin: SubsetQuery[\"loaders\"][number][\"manyJoin\"];\n if (isHasManyRelationProp(relation)) {\n const fromCol = relation?.fromColumn ?? \"id\";\n manyJoin = {\n fromTable: this.table,\n fromCol,\n idField: prefix === \"\" ? `${fromCol}` : `${prefix}__${fromCol}`,\n toTable: relEntity.table,\n toCol: relation.joinColumn,\n };\n } else if (isManyToManyRelationProp(relation)) {\n manyJoin = {\n fromTable: this.table,\n fromCol: \"id\",\n idField: prefix === \"\" ? `id` : `${prefix}__id`,\n through: {\n table: relation.joinTable,\n fromCol: `${inflection.singularize(this.table)}_id`,\n toCol: `${inflection.singularize(relEntity.table)}_id`,\n },\n toTable: relEntity.table,\n toCol: \"id\",\n };\n } else {\n throw new Error();\n }\n\n r.loaders.push({\n as: groupKey,\n table: relEntity.table,\n manyJoin,\n oneJoins: relSubsetQuery.joins,\n select: relSubsetQuery.select,\n loaders: relSubsetQuery.loaders,\n });\n }\n\n return r;\n },\n {\n select: [],\n virtual: [],\n joins: [],\n loaders: [],\n } as SubsetQuery\n );\n return result;\n }\n\n /*\n FieldExpr[] 을 EntityPropNode[] 로 변환\n */\n fieldExprsToPropNodes(\n fieldExprs: string[],\n entity: Entity = this\n ): EntityPropNode[] {\n const groups = fieldExprs.reduce(\n (result, fieldExpr) => {\n let key, value, elseExpr;\n if (fieldExpr.includes(\".\")) {\n [key, ...elseExpr] = fieldExpr.split(\".\");\n value = elseExpr.join(\".\");\n } else {\n key = \"\";\n value = fieldExpr;\n }\n result[key] = (result[key] ?? []).concat(value);\n\n return result;\n },\n {} as {\n [k: string]: string[];\n }\n );\n\n return Object.keys(groups)\n .map((key) => {\n const group = groups[key];\n\n // 일반 prop 처리\n if (key === \"\") {\n return group.map((propName) => {\n // uuid 개별 처리\n if (propName === \"uuid\") {\n return {\n nodeType: \"plain\" as const,\n prop: {\n type: \"string\",\n name: \"uuid\",\n length: 128,\n } as StringProp,\n children: [],\n };\n }\n\n const prop = entity.props.find((p) => p.name === propName);\n if (prop === undefined) {\n console.log({ propName, groups });\n throw new Error(`${entity.id} -- 잘못된 FieldExpr ${propName}`);\n }\n return {\n nodeType: \"plain\" as const,\n prop,\n children: [],\n };\n });\n }\n\n // relation prop 처리\n const prop = entity.propsDict[key];\n if (!isRelationProp(prop)) {\n throw new Error(`잘못된 FieldExpr ${key}.${group[0]}`);\n }\n const relEntity = EntityManager.get(prop.with);\n\n // relation -One 에 id 필드 하나인 경우\n if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)) {\n if (group.length == 1 && (group[0] === \"id\" || group[0] == \"id?\")) {\n // id 하나만 있는지 체크해서, 하나만 있으면 상위 prop으로 id를 리턴\n const idProp = relEntity.propsDict.id;\n return {\n nodeType: \"plain\" as const,\n prop: {\n ...idProp,\n name: key + \"_id\",\n nullable: prop.nullable,\n },\n children: [],\n };\n }\n }\n\n // -One 그외의 경우 object로 리턴\n // -Many의 경우 array로 리턴\n // Recursive 로 뎁스 처리\n const children = this.fieldExprsToPropNodes(group, relEntity);\n const nodeType =\n isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)\n ? (\"object\" as const)\n : (\"array\" as const);\n\n return {\n prop,\n children,\n nodeType,\n };\n })\n .flat();\n }\n\n getFieldExprs(\n prefix = \"\",\n maxDepth: number = 3,\n froms: string[] = []\n ): string[] {\n return this.props\n .map((prop) => {\n const propName = [prefix, prop.name].filter((v) => v !== \"\").join(\".\");\n if (propName === prefix) {\n return null;\n }\n if (isRelationProp(prop)) {\n if (maxDepth < 0) {\n return null;\n }\n if (froms.includes(prop.with)) {\n // 역방향 relation인 경우 제외\n return null;\n }\n // 정방향 relation인 경우 recursive 콜\n const relMd = EntityManager.get(prop.with);\n return relMd.getFieldExprs(propName, maxDepth - 1, [\n ...froms,\n this.id,\n ]);\n }\n return propName;\n })\n .flat()\n .filter((f) => f !== null) as string[];\n }\n\n getTableColumns(): { name: string; type: string }[] {\n return this.props\n .map((prop) => {\n if (prop.type === \"relation\") {\n if (\n prop.relationType === \"BelongsToOne\" ||\n (prop.relationType === \"OneToOne\" && prop.hasJoinColumn === true)\n ) {\n return { name: `${prop.name}_id`, type: \"int_unsigned\" };\n } else {\n return null;\n }\n }\n return { name: prop.name, type: prop.type };\n })\n .filter(nonNullable);\n }\n\n async registerModulePaths() {\n const basePath = `${this.names.parentFs}`;\n\n // base-scheme\n EntityManager.setModulePath(`${this.id}BaseSchema`, `sonamu.generated`);\n\n // subset\n if (Object.keys(this.subsets).length > 0) {\n EntityManager.setModulePath(`${this.id}SubsetKey`, `sonamu.generated`);\n EntityManager.setModulePath(\n `${this.id}SubsetMapping`,\n `sonamu.generated`\n );\n Object.keys(this.subsets).map((subsetKey) => {\n EntityManager.setModulePath(\n `${this.id}Subset${subsetKey.toUpperCase()}`,\n `sonamu.generated`\n );\n });\n }\n\n // enums\n Object.keys(this.enumLabels).map((enumId) => {\n EntityManager.setModulePath(enumId, `sonamu.generated`);\n });\n\n // types\n const typesModulePath = `${basePath}/${this.names.parentFs}.types`;\n const typesFileDistPath = path.join(\n Sonamu.apiRootPath,\n `dist/application/${typesModulePath}.js`\n );\n\n if (await exists(typesFileDistPath)) {\n const importPath = path.relative(__dirname, typesFileDistPath);\n const t = await import(importPath);\n this.types = Object.keys(t).reduce((result, key) => {\n EntityManager.setModulePath(key, typesModulePath);\n return {\n ...result,\n [key]: t[key],\n };\n }, {});\n }\n }\n\n registerTableSpecs(): void {\n const uniqueIndexes = this.indexes.filter((idx) => idx.type === \"unique\");\n\n EntityManager.setTableSpec({\n name: this.table,\n uniqueIndexes,\n });\n }\n\n toJson(): EntityJson {\n return {\n id: this.id,\n parentId: this.parentId,\n table: this.table,\n title: this.title,\n props: this.props,\n indexes: this.indexes,\n subsets: this.subsets,\n enums: this.enumLabels,\n };\n }\n\n async save(): Promise<void> {\n // sort: subsets\n const subsetRows = this.getSubsetRows();\n this.subsets = Object.fromEntries(\n Object.entries(this.subsets).map(([subsetKey]) => {\n return [\n subsetKey,\n this.subsetRowsToSubsetFields(subsetRows, subsetKey),\n ];\n })\n );\n\n // save\n const jsonPath = path.join(\n Sonamu.apiRootPath,\n `src/application/${this.names.parentFs}/${this.names.fs}.entity.json`\n );\n const json = this.toJson();\n await writeFile(\n jsonPath,\n await prettier.format(JSON.stringify(json), {\n parser: \"json\",\n })\n );\n\n // reload\n await EntityManager.register(json);\n }\n\n getSubsetRows(\n _subsets?: { [key: string]: string[] },\n prefixes: string[] = []\n ): EntitySubsetRow[] {\n if (prefixes.length > 10) {\n return [];\n }\n\n const subsets = _subsets ?? this.subsets;\n const subsetKeys = Object.keys(subsets);\n const allFields = _.uniq(subsetKeys.map((key) => subsets[key]).flat());\n\n return this.props.map((prop) => {\n if (\n prop.type === \"relation\" &&\n allFields.find((f) =>\n f.startsWith([...prefixes, prop.name].join(\".\") + \".\")\n )\n ) {\n const relEntity = EntityManager.get(prop.with);\n const children = relEntity.getSubsetRows(subsets, [\n ...prefixes,\n `${prop.name}`,\n ]);\n\n return {\n field: prop.name,\n children,\n relationEntity: prop.with,\n prefixes,\n isOpen: children.length > 0,\n has: Object.fromEntries(\n subsetKeys.map((subsetKey) => {\n return [\n subsetKey,\n children.every((child) => child.has[subsetKey] === true),\n ];\n })\n ),\n };\n }\n\n return {\n field: prop.name,\n children: [],\n relationEntity: prop.type === \"relation\" ? prop.with : undefined,\n prefixes,\n has: Object.fromEntries(\n subsetKeys.map((subsetKey) => {\n const subsetFields = subsets[subsetKey];\n const has = subsetFields.some((f) => {\n const field = [...prefixes, prop.name].join(\".\");\n return f === field || f.startsWith(field + \".\");\n });\n return [subsetKey, has];\n })\n ),\n };\n });\n }\n\n subsetRowsToSubsetFields(\n subsetRows: EntitySubsetRow[],\n subsetKey: string\n ): string[] {\n return subsetRows\n .map((subsetRow) => {\n if (subsetRow.children.length > 0) {\n return this.subsetRowsToSubsetFields(subsetRow.children, subsetKey);\n } else if (subsetRow.has[subsetKey]) {\n return subsetRow.prefixes.concat(subsetRow.field).join(\".\");\n } else {\n return null;\n }\n })\n .filter(nonNullable)\n .flat();\n }\n\n async createProp(prop: EntityProp, at?: number): Promise<void> {\n if (!at) {\n this.props.push(prop);\n } else {\n this.props.splice(at, 0, prop);\n }\n await this.save();\n }\n\n analyzeSubsetField(subsetField: string): {\n entityId: string;\n propName: string;\n }[] {\n const arr = subsetField.split(\".\");\n\n let entityId = this.id;\n const result: {\n entityId: string;\n propName: string;\n }[] = [];\n for (let i = 0; i < arr.length; i++) {\n const propName = arr[i];\n result.push({\n entityId,\n propName,\n });\n\n const prop = EntityManager.get(entityId).props.find(\n (p) => p.name === propName\n );\n if (!prop) {\n throw new Error(`${entityId}의 잘못된 서브셋키 ${subsetField}`);\n }\n if (isRelationProp(prop)) {\n entityId = prop.with;\n }\n }\n return result;\n }\n\n async modifyProp(newProp: EntityProp, at: number): Promise<void> {\n // 이전 프롭 이름 저장\n const oldName = this.props[at].name;\n\n // 저장할 엔티티\n const entities: Entity[] = [this];\n\n // 이름이 바뀐 경우\n if (oldName !== newProp.name) {\n // 전체 엔티티에서 현재 수정된 프롭을 참조하고 있는 모든 서브셋필드 찾아서 수정\n const allEntityIds = EntityManager.getAllIds();\n for (const relEntityId of allEntityIds) {\n const relEntity = EntityManager.get(relEntityId);\n const relEntitySubsetKeys = Object.keys(relEntity.subsets);\n for (const subsetKey of relEntitySubsetKeys) {\n const subset = relEntity.subsets[subsetKey];\n\n // 서브셋 필드를 순회하며, 엔티티-프롭 단위로 분석한 후 현재 엔티티-프롭과 일치하는 경우 수정 처리\n const modifiedSubsetFields = subset.map((subsetField) => {\n const analyzed = relEntity.analyzeSubsetField(subsetField);\n const modified = analyzed.map((a) =>\n a.propName === oldName && a.entityId === this.id\n ? {\n ...a,\n propName: newProp.name,\n }\n : a\n );\n // 분석한 필드를 다시 서브셋 필드로 복구\n return modified.map((a) => a.propName).join(\".\");\n });\n\n if (subset.join(\",\") !== modifiedSubsetFields.join(\",\")) {\n relEntity.subsets[subsetKey] = modifiedSubsetFields;\n entities.push(relEntity);\n }\n }\n }\n }\n\n // 프롭 수정\n this.props[at] = newProp;\n\n await Promise.all(entities.map(async (entity) => entity.save()));\n }\n\n async delProp(at: number): Promise<void> {\n // 이전 프롭 이름 저장\n const oldName = this.props[at].name;\n\n // 저장할 엔티티\n const entities: Entity[] = [this];\n\n // 전체 엔티티에서 현재 삭제된 프롭을 참조하고 있는 모든 서브셋필드 찾아서 제외\n const allEntityIds = EntityManager.getAllIds();\n for (const relEntityId of allEntityIds) {\n const relEntity = EntityManager.get(relEntityId);\n const relEntitySubsetKeys = Object.keys(relEntity.subsets);\n for (const subsetKey of relEntitySubsetKeys) {\n const subset = relEntity.subsets[subsetKey];\n // 서브셋 필드를 순회하며, 엔티티-프롭 단위로 분석한 후 현재 엔티티-프롭과 일치하는 경우 이후의 필드를 제외\n const modifiedSubsetFields = subset\n .map((subsetField) => {\n const analyzed = relEntity.analyzeSubsetField(subsetField);\n if (\n analyzed.find(\n (a) => a.propName === oldName && a.entityId === this.id\n )\n ) {\n return null;\n } else {\n return subsetField;\n }\n })\n .filter(nonNullable);\n\n if (subset.join(\",\") !== modifiedSubsetFields.join(\",\")) {\n relEntity.subsets[subsetKey] = modifiedSubsetFields;\n entities.push(relEntity);\n }\n }\n }\n\n // 현재 엔티티의 인덱스에서 제외\n EntityManager.get(this.id).indexes.map((index) => {\n index.columns = index.columns.filter((col) => col !== oldName);\n });\n\n // 프롭 삭제\n this.props.splice(at, 1);\n\n await Promise.all(entities.map(async (entity) => entity.save()));\n }\n\n getEntityIdFromSubsetField(subsetField: string): string {\n if (subsetField.includes(\".\") === false) {\n return this.id;\n }\n\n // 서브셋 필드의 마지막은 프롭이므로 제외\n const arr = subsetField.split(\".\").slice(0, -1);\n\n // 서브셋 필드를 내려가면서 마지막으로 relation된 엔티티를 찾음\n const lastEntityId = arr.reduce((entityId, field) => {\n const relProp = EntityManager.get(entityId).props.find(\n (p) => p.name === field\n );\n if (!relProp || relProp.type !== \"relation\") {\n console.debug({ arr, thisId: this.id, entityId, field });\n throw new Error(`잘못된 서브셋키 ${subsetField}`);\n }\n return relProp.with;\n }, this.id);\n return lastEntityId;\n }\n\n async moveProp(at: number, to: number): Promise<void> {\n const prop = this.props[at];\n const newProps = [...this.props];\n newProps.splice(to, 0, prop);\n newProps.splice(at < to ? at : at + 1, 1);\n this.props = newProps;\n\n await this.save();\n }\n}\n"],"names":["Entity","id","parentId","table","title","props","indexes","subsets","enums","names","propsDict","relations","types","enumLabels","inflection","underscore","pluralize","map","prop","isEnumProp","includes","replace","reduce","result","name","filter","isRelationProp","Object","fromEntries","entries","key","enumLabel","z","enum","keys","parentFs","dasherize","toLowerCase","fs","module","getSubsetQuery","subsetKey","subset","resolveSubsetQuery","prefix","fields","isAlreadyOuterJoined","subsetGroup","_","groupBy","field","split","rel","r","groupKey","realFields","isVirtualProp","virtualFields","select","concat","virtual","relation","undefined","Error","relEntity","EntityManager","get","with","isOneToOneRelationProp","isBelongsToOneRelationProp","relFields","slice","join","length","innerOrOuter","hasJoinColumn","nullable","relSubsetQuery","joinAs","fromTable","joinClause","customJoinClause","custom","from","to","joins","push","as","loaders","convertedLoaders","loader","newAs","manyJoin","oneJoins","isHasManyRelationProp","isManyToManyRelationProp","fromCol","fromColumn","idField","toTable","toCol","joinColumn","through","joinTable","singularize","fieldExprsToPropNodes","fieldExprs","entity","groups","fieldExpr","value","elseExpr","group","propName","nodeType","type","children","find","p","console","log","idProp","flat","getFieldExprs","maxDepth","froms","v","relMd","f","getTableColumns","relationType","nonNullable","registerModulePaths","basePath","typesModulePath","typesFileDistPath","importPath","t","setModulePath","toUpperCase","enumId","path","Sonamu","apiRootPath","exists","relative","__dirname","registerTableSpecs","uniqueIndexes","idx","setTableSpec","toJson","save","subsetRows","jsonPath","json","getSubsetRows","subsetRowsToSubsetFields","prettier","format","JSON","stringify","parser","writeFile","register","_subsets","prefixes","subsetKeys","allFields","uniq","startsWith","relationEntity","isOpen","has","every","child","subsetFields","some","subsetRow","createProp","at","splice","analyzeSubsetField","subsetField","arr","i","entityId","modifyProp","newProp","oldName","entities","allEntityIds","getAllIds","relEntityId","relEntitySubsetKeys","modifiedSubsetFields","analyzed","modified","a","Promise","all","delProp","index","columns","col","getEntityIdFromSubsetField","lastEntityId","relProp","debug","thisId","moveProp","newProps"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/exceptions/error-handler.ts"],"sourcesContent":["import { FastifyInstance } from \"fastify\";\nimport { ZodIssue } from \"zod\";\nimport { isSoException } from \"./so-exceptions\";\n\nexport function setupErrorHandler(server: FastifyInstance) {\n server.setErrorHandler((error, request, reply) => {\n error.statusCode ??= 400;\n\n if (isSoException(error) && error.payload && Array.isArray(error.payload)) {\n const issues = error.payload as ZodIssue[];\n const [issue] = issues;\n const message = `${issue.message} (${issue.path.join(\"/\")})`;\n\n request.log.error(`${error.statusCode} ${message}`);\n reply.status(error.statusCode <= 501 ? error.statusCode : 501).send({\n name: error.name,\n code: error.code,\n message: message,\n validationErrors: error.validation,\n issues,\n });\n } else {\n request.log.error(`${error.statusCode} ${error.message}`);\n reply.status(error.statusCode <= 501 ? error.statusCode : 501).send({\n name: error.name,\n code: error.code,\n message: error.message,\n validationErrors: error.validation,\n });\n }\n });\n}\n"],"names":["setupErrorHandler","server","setErrorHandler","error","request","reply","statusCode","isSoException","payload","Array","isArray","issues","issue","message","path","join","log","status","send","name","code","validationErrors","validation"],"mappings":"oGAIgBA,2DAAAA,+CAFc,62CAEvB,SAASA,kBAAkBC,MAAuB,EACvDA,OAAOC,eAAe,CAAC,SAACC,MAAOC,QAASC,WACtCF,sBAAAA,eAAAA,OAAAA,OAAMG,qDAANH,OAAMG,WAAe,IAErB,GAAIC,GAAAA,2BAAa,EAACJ,QAAUA,MAAMK,OAAO,EAAIC,MAAMC,OAAO,CAACP,MAAMK,OAAO,EAAG,CACzE,IAAMG,OAASR,MAAMK,OAAO,CAC5B,IAAgBG,yBAAAA,UAATC,MAASD,WAChB,IAAME,QAAU,AAAC,GAAoBD,OAAlBA,MAAMC,OAAO,CAAC,MAAyB,OAArBD,MAAME,IAAI,CAACC,IAAI,CAAC,KAAK,KAE1DX,QAAQY,GAAG,CAACb,KAAK,CAAC,AAAC,GAAsBU,OAApBV,MAAMG,UAAU,CAAC,KAAW,OAARO,UACzCR,MAAMY,MAAM,CAACd,MAAMG,UAAU,EAAI,IAAMH,MAAMG,UAAU,CAAG,KAAKY,IAAI,CAAC,CAClEC,KAAMhB,MAAMgB,IAAI,CAChBC,KAAMjB,MAAMiB,IAAI,CAChBP,QAASA,QACTQ,iBAAkBlB,MAAMmB,UAAU,CAClCX,OAAAA,MACF,EACF,KAAO,CACLP,QAAQY,GAAG,CAACb,KAAK,CAAC,AAAC,GAAsBA,OAApBA,MAAMG,UAAU,CAAC,KAAiB,OAAdH,MAAMU,OAAO,GACtDR,MAAMY,MAAM,CAACd,MAAMG,UAAU,EAAI,IAAMH,MAAMG,UAAU,CAAG,KAAKY,IAAI,CAAC,CAClEC,KAAMhB,MAAMgB,IAAI,CAChBC,KAAMjB,MAAMiB,IAAI,CAChBP,QAASV,MAAMU,OAAO,CACtBQ,iBAAkBlB,MAAMmB,UAAU,AACpC,EACF,CACF,EACF"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/exceptions/so-exceptions.ts"],"sourcesContent":["export abstract class SoException extends Error {\n constructor(\n public readonly statusCode: number,\n public message: string,\n public payload?: unknown\n ) {\n super(message);\n }\n}\n\nexport function isSoException(err: any): err is SoException {\n return err.statusCode !== undefined;\n}\n\n/*\n\t잘못된 매개변수 등 요청사항에 문제가 있는 경우\n*/\nexport class BadRequestException extends SoException {\n constructor(\n public message = \"Bad Request\",\n public payload?: unknown\n ) {\n super(400, message, payload);\n }\n}\n\n/*\n\t로그인이 반드시 필요한 케이스에 로그아웃 상태인 경우 / 접근 권한이 없는 요청시\n*/\nexport class UnauthorizedException extends SoException {\n constructor(\n public message = \"Unauthorized\",\n public payload?: unknown\n ) {\n super(401, message, payload);\n }\n}\n\n/*\n\t존재하지 않는 레코드에 접근시\n*/\nexport class NotFoundException extends SoException {\n constructor(\n public message = \"Not Found\",\n public payload?: unknown\n ) {\n super(404, message, payload);\n }\n}\n\n/*\n\t현재 상태에서 처리가 불가능한 케이스\n*/\nexport class ServiceUnavailableException extends SoException {\n constructor(\n public message = \"Service Unavailable\",\n public payload?: unknown\n ) {\n super(503, message, payload);\n }\n}\n\n/*\n\t내부 처리 로직 (외부 API 콜 포함) 오류 발생시\n*/\nexport class InternalServerErrorException extends SoException {\n constructor(\n public message = \"Internal Server Error\",\n public payload?: unknown\n ) {\n super(500, message, payload);\n }\n}\n\n/*\n\t이미 처리함\n*/\nexport class AlreadyProcessedException extends SoException {\n constructor(\n public message = \"Already Processed\",\n public payload?: unknown\n ) {\n super(541, message, payload);\n }\n}\n\n/*\n\t중복 허용하지 않는 케이스에 중복 요청\n*/\nexport class DuplicateRowException extends SoException {\n constructor(\n public message = \"Duplicate Row\",\n public payload?: unknown\n ) {\n super(542, message, payload);\n }\n}\n\n/*\n\t뭔가를 하려고 했으나 대상이 없음\n*/\nexport class TargetNotFoundException extends SoException {\n constructor(\n public message = \"Target Not Found\",\n public payload?: unknown\n ) {\n super(520, message, payload);\n }\n}\n"],"names":["AlreadyProcessedException","BadRequestException","DuplicateRowException","InternalServerErrorException","NotFoundException","ServiceUnavailableException","SoException","TargetNotFoundException","UnauthorizedException","isSoException","statusCode","message","payload","Error","err","undefined"],"mappings":"mPA6EaA,mCAAAA,+BA5DAC,6BAAAA,yBAwEAC,+BAAAA,2BAxBAC,sCAAAA,kCAxBAC,2BAAAA,uBAYAC,qCAAAA,iCArDSC,qBAAAA,iBAqGTC,iCAAAA,6BAxEAC,+BAAAA,2BAnBGC,uBAAAA,ijGAVT,IAAA,AAAeH,yBAAf,wCAAeA,6BAAAA,YAElB,AAAgBI,UAAkB,CAClC,AAAOC,OAAe,CACtB,AAAOC,OAAiB,yBAJNN,6BAMlB,iBANkBA,aAMZK,8IAJUD,WAAAA,iBACTC,QAAAA,cACAC,QAAAA,4BAJWN,gCAAoBO,QAUnC,SAASJ,cAAcK,GAAQ,EACpC,OAAOA,IAAIJ,UAAU,GAAKK,SAC5B,CAKO,IAAA,AAAMd,iCAAN,6CAAMA,0CAAAA,0BAET,AAAOU,QAAP,uDAAiB,cACjB,AAAOC,sEAHEX,qCAKT,iBALSA,qBAKH,IAAKU,QAASC,kGAHbD,QAAAA,cACAC,QAAAA,4BAHEX,qBAA4BK,aAYlC,IAAA,AAAME,mCAAN,6CAAMA,4CAAAA,4BAET,AAAOG,QAAP,uDAAiB,eACjB,AAAOC,sEAHEJ,uCAKT,iBALSA,uBAKH,IAAKG,QAASC,kGAHbD,QAAAA,cACAC,QAAAA,4BAHEJ,uBAA8BF,aAYpC,IAAA,AAAMF,+BAAN,6CAAMA,wCAAAA,wBAET,AAAOO,QAAP,uDAAiB,YACjB,AAAOC,sEAHER,mCAKT,iBALSA,mBAKH,IAAKO,QAASC,kGAHbD,QAAAA,cACAC,QAAAA,4BAHER,mBAA0BE,aAYhC,IAAA,AAAMD,yCAAN,6CAAMA,kDAAAA,kCAET,AAAOM,QAAP,uDAAiB,sBACjB,AAAOC,sEAHEP,6CAKT,iBALSA,6BAKH,IAAKM,QAASC,kGAHbD,QAAAA,cACAC,QAAAA,4BAHEP,6BAAoCC,aAY1C,IAAA,AAAMH,0CAAN,6CAAMA,mDAAAA,mCAET,AAAOQ,QAAP,uDAAiB,wBACjB,AAAOC,sEAHET,8CAKT,iBALSA,8BAKH,IAAKQ,QAASC,kGAHbD,QAAAA,cACAC,QAAAA,4BAHET,8BAAqCG,aAY3C,IAAA,AAAMN,uCAAN,6CAAMA,gDAAAA,gCAET,AAAOW,QAAP,uDAAiB,oBACjB,AAAOC,sEAHEZ,2CAKT,iBALSA,2BAKH,IAAKW,QAASC,kGAHbD,QAAAA,cACAC,QAAAA,4BAHEZ,2BAAkCM,aAYxC,IAAA,AAAMJ,mCAAN,6CAAMA,4CAAAA,4BAET,AAAOS,QAAP,uDAAiB,gBACjB,AAAOC,sEAHEV,uCAKT,iBALSA,uBAKH,IAAKS,QAASC,kGAHbD,QAAAA,cACAC,QAAAA,4BAHEV,uBAA8BI,aAYpC,IAAA,AAAMC,qCAAN,6CAAMA,8CAAAA,8BAET,AAAOI,QAAP,uDAAiB,mBACjB,AAAOC,sEAHEL,yCAKT,iBALSA,yBAKH,IAAKI,QAASC,kGAHbD,QAAAA,cACAC,QAAAA,4BAHEL,yBAAgCD"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/file-storage/driver.ts"],"sourcesContent":["import {\n DeleteObjectCommand,\n GetObjectCommand,\n PutObjectCommand,\n S3Client,\n S3ClientConfig,\n} from \"@aws-sdk/client-s3\";\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\n\n/**\n * 파일 저장소의 공통 인터페이스\n */\nexport interface Driver {\n put(\n key: string,\n contents: Buffer,\n options?: { contentType?: string; visibility?: \"public\" | \"private\" }\n ): Promise<void>;\n\n del(key: string): Promise<void>;\n\n getUrl(key: string): string;\n\n getSignedUrl(key: string, expiresIn?: number): Promise<string>;\n\n destroy(): void;\n}\n\nexport type FSDriverConfig = {\n location: string;\n urlPrefix: string;\n};\n\n/**\n * 로컬 파일시스템\n */\nexport class FSDriver implements Driver {\n constructor(private config: FSDriverConfig) {}\n\n async put(key: string, contents: Buffer): Promise<void> {\n const filePath = path.join(this.config.location, key);\n const dir = path.dirname(filePath);\n\n await fs.mkdir(dir, { recursive: true });\n\n await fs.writeFile(filePath, contents);\n }\n\n async del(key: string) {\n await fs.rm(path.join(this.config.location, key));\n }\n\n getUrl(key: string): string {\n return `${this.config.urlPrefix}/${key}`;\n }\n\n // 로컬 파일시스템은 signed URL을 지원하지 않으므로 일반 URL 반환\n async getSignedUrl(key: string, _expiresIn?: number): Promise<string> {\n return this.getUrl(key);\n }\n\n destroy() {\n // 아무것도 하지 않음\n }\n}\n\nexport type S3DriverConfig = S3ClientConfig & {\n bucket: string;\n};\n\nexport class S3Driver implements Driver {\n s3: S3Client;\n\n constructor(private config: S3DriverConfig) {\n this.s3 = new S3Client(config);\n }\n\n async put(\n key: string,\n contents: Buffer,\n options?: { contentType?: string; visibility?: \"public\" | \"private\" }\n ): Promise<void> {\n await this.s3.send(\n new PutObjectCommand({\n Bucket: this.config.bucket,\n Key: key,\n Body: contents,\n ContentType: options?.contentType,\n ACL: this.getAcl(options?.visibility),\n })\n );\n }\n\n async del(key: string): Promise<void> {\n await this.s3.send(\n new DeleteObjectCommand({\n Bucket: this.config.bucket,\n Key: key,\n })\n );\n }\n\n getUrl(key: string): string {\n return `https://${this.config.bucket}.s3.${this.config.region}.amazonaws.com/${key}`;\n }\n\n async getSignedUrl(key: string, expiresIn?: number): Promise<string> {\n const command = new GetObjectCommand({\n Bucket: this.config.bucket,\n Key: key,\n });\n\n return getSignedUrl(this.s3, command, {\n expiresIn: expiresIn ?? 60 * 60 * 24 * 7,\n });\n }\n\n private getAcl(visibility?: \"public\" | \"private\") {\n if (visibility === \"public\") {\n return \"public-read\";\n }\n\n return visibility;\n }\n\n destroy() {\n this.s3.destroy();\n }\n}\n"],"names":["FSDriver","S3Driver","config","put","key","contents","filePath","dir","path","join","location","dirname","fs","mkdir","recursive","writeFile","del","rm","getUrl","urlPrefix","getSignedUrl","_expiresIn","destroy","s3","S3Client","options","send","PutObjectCommand","Bucket","bucket","Key","Body","ContentType","contentType","ACL","getAcl","visibility","DeleteObjectCommand","region","expiresIn","command","GetObjectCommand"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/file-storage/file-storage.ts"],"sourcesContent":["import type { MultipartFile } from \"@fastify/multipart\";\nimport mime from \"mime-types\";\nimport { createHash } from \"crypto\";\nimport type { Driver } from \"./driver\";\n\n/**\n * @fastify/multipart의 MultipartFile 래퍼\n */\nexport class FileStorage {\n private _file: MultipartFile;\n private _buffer?: Buffer;\n private _driver: Driver;\n\n constructor(file: MultipartFile, driver: Driver) {\n this._file = file;\n this._driver = driver;\n }\n\n /**\n * 사용자 컴퓨터의 원본 파일명\n */\n get clientName(): string {\n return this._file.filename;\n }\n\n /**\n * 파일명 (clientName의 별칭)\n */\n get filename(): string {\n return this._file.filename;\n }\n\n /**\n * HTML input 필드명\n */\n get fieldName(): string {\n return this._file.fieldname;\n }\n\n /**\n * 파일 크기 (바이트)\n */\n get size(): number {\n return this._file.file.bytesRead;\n }\n\n /**\n * 파일 확장자 (점 제외)\n */\n get extname(): string | false {\n return mime.extension(this._file.mimetype);\n }\n\n get mimetype(): string {\n return this._file.mimetype;\n }\n\n get encoding(): string {\n return this._file.encoding;\n }\n\n async toBuffer(): Promise<Buffer> {\n if (!this._buffer) {\n this._buffer = await this._file.toBuffer();\n }\n return this._buffer;\n }\n\n async md5(): Promise<string> {\n const buffer = await this.toBuffer();\n return createHash(\"md5\").update(buffer).digest(\"hex\");\n }\n\n /**\n * 파일을 저장소에 저장\n *\n * @example\n * ```typescript\n * const { file } = Sonamu.getUploadContext();\n * const url = await file.saveToDisk('uploads/avatar.png');\n * ```\n */\n async saveToDisk(\n key: string,\n options?: { contentType?: string; visibility?: \"public\" | \"private\" }\n ): Promise<string> {\n const buffer = await this.toBuffer();\n\n await this._driver.put(key, buffer, {\n contentType: options?.contentType ?? this.mimetype,\n visibility: options?.visibility,\n });\n\n return this._driver.getSignedUrl(key);\n }\n\n get raw(): MultipartFile {\n return this._file;\n }\n}\n"],"names":["FileStorage","file","driver","_file","_buffer","_driver","clientName","filename","fieldName","fieldname","size","bytesRead","extname","mime","extension","mimetype","encoding","toBuffer","md5","buffer","createHash","update","digest","saveToDisk","key","options","put","contentType","visibility","getSignedUrl","raw"],"mappings":"oGAQaA,qDAAAA,4EAPI,mCACU,+qFAMpB,IAAA,AAAMA,yBAAN,iCAAMA,YAKCC,IAAmB,CAAEC,MAAc,yBALpCF,aACX,sBAAQG,QAAR,KAAA,GACA,sBAAQC,UAAR,KAAA,GACA,sBAAQC,UAAR,KAAA,EAGE,CAAA,IAAI,CAACF,KAAK,CAAGF,IACb,CAAA,IAAI,CAACI,OAAO,CAAGH,qBAPNF,cAaPM,IAAAA,iBAAJ,eACE,OAAO,IAAI,CAACH,KAAK,CAACI,QAAQ,AAC5B,IAKIA,IAAAA,eAAJ,eACE,OAAO,IAAI,CAACJ,KAAK,CAACI,QAAQ,AAC5B,IAKIC,IAAAA,gBAAJ,eACE,OAAO,IAAI,CAACL,KAAK,CAACM,SAAS,AAC7B,IAKIC,IAAAA,WAAJ,eACE,OAAO,IAAI,CAACP,KAAK,CAACF,IAAI,CAACU,SAAS,AAClC,IAKIC,IAAAA,cAAJ,eACE,OAAOC,kBAAI,CAACC,SAAS,CAAC,IAAI,CAACX,KAAK,CAACY,QAAQ,CAC3C,IAEIA,IAAAA,eAAJ,eACE,OAAO,IAAI,CAACZ,KAAK,CAACY,QAAQ,AAC5B,IAEIC,IAAAA,eAAJ,eACE,OAAO,IAAI,CAACb,KAAK,CAACa,QAAQ,AAC5B,IAEMC,IAAAA,iBAAN,SAAMA,kIACA,CAAC,IAAI,CAACb,OAAO,CAAb,cACF,IAAI,CAAW,SAAM,IAAI,CAACD,KAAK,CAACc,QAAQ,WAAxC,EAAKb,OAAO,CAAG,oCAEjB,SAAO,IAAI,CAACA,OAAO,IACrB,iBAEMc,IAAAA,YAAN,SAAMA,gDACEC,8EAAS,SAAM,IAAI,CAACF,QAAQ,WAA5BE,OAAS,cACf,SAAOC,GAAAA,kBAAU,EAAC,OAAOC,MAAM,CAACF,QAAQG,MAAM,CAAC,UACjD,iBAWMC,IAAAA,mBAAN,SAAMA,WACJC,GAAW,CACXC,OAAqE,4CAE/DN,OAGSM,4FAHA,SAAM,IAAI,CAACR,QAAQ,WAA5BE,OAAS,cAEf,SAAM,IAAI,CAACd,OAAO,CAACqB,GAAG,CAACF,IAAKL,OAAQ,CAClCQ,YAAaF,CAAAA,qBAAAA,gBAAAA,wBAAAA,QAASE,WAAW,UAApBF,8BAAAA,qBAAwB,IAAI,CAACV,QAAQ,CAClDa,UAAU,CAAEH,gBAAAA,wBAAAA,QAASG,UAAU,AACjC,WAHA,cAKA,SAAO,IAAI,CAACvB,OAAO,CAACwB,YAAY,CAACL,QACnC,iBAEIM,IAAAA,UAAJ,eACE,OAAO,IAAI,CAAC3B,KAAK,AACnB,YA1FWH"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type * from \"./api/context\";\nexport * from \"./api/decorators\";\nexport * from \"./api/sonamu\";\nexport * from \"./database/base-model\";\nexport * from \"./api/base-frame\";\nexport * from \"./database/db\";\nexport * from \"./database/upsert-builder\";\nexport * from \"./database/puri\";\nexport * from \"./database/puri-wrapper\";\nexport * from \"./database/puri.types\";\nexport * from \"./exceptions/error-handler\";\nexport * from \"./exceptions/so-exceptions\";\nexport * from \"./stream/sse\";\nexport * from \"./types/types\";\nexport * from \"./utils/controller\";\nexport * from \"./utils/model\";\nexport * from \"./utils/utils\";\nexport * from \"./testing/fixture-manager\";\nexport * from \"./entity/entity-manager\";\nexport * from \"./entity/entity\";\nexport * from \"./migration/migrator\";\nexport * from \"./migration/types\";\nexport * from \"./file-storage/driver\";\n\n// export * from \"./api/code-converters\";\n// export * from \"./entity/entity-utils\";\n// export * from \"./syncer/syncer\";\n"],"names":[],"mappings":"2FACc,kDACA,8CACA,uDACA,kDACA,+CACA,2DACA,iDACA,yDACA,uDACA,4DACA,4DACA,8CACA,+CACA,oDACA,+CACA,+CACA,2DACA,yDACA,iDACA,sDACA,mDACA"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/migration/code-generation.ts"],"sourcesContent":["import _ from \"lodash\";\nimport prettier from \"prettier\";\nimport equal from \"fast-deep-equal\";\nimport {\n GenMigrationCode,\n MigrationColumn,\n MigrationForeign,\n MigrationIndex,\n MigrationSet,\n} from \"../types/types\";\n\n/**\n * 테이블 생성하는 케이스 - 컬럼/인덱스 생성\n */\nasync function generateCreateCode_ColumnAndIndexes(\n table: string,\n columns: MigrationColumn[],\n indexes: MigrationIndex[]\n): Promise<GenMigrationCode> {\n // fulltext index 분리\n const [ngramIndexes, standardIndexes] = _.partition(\n indexes,\n (i) => i.type === \"fulltext\" && i.parser === \"ngram\"\n );\n\n // 컬럼, 인덱스 처리\n const lines: string[] = [\n 'import { Knex } from \"knex\";',\n \"\",\n \"export async function up(knex: Knex): Promise<void> {\",\n `await knex.schema.createTable(\"${table}\", (table) => {`,\n \"// columns\",\n ...genColumnDefinitions(columns),\n \"\",\n \"// indexes\",\n ...standardIndexes.map((index) => genIndexDefinition(index, table)),\n \"});\",\n // ngram은 knex.raw로 처리하므로 createTable 밖에서 실행\n ...ngramIndexes.map((index) => genIndexDefinition(index, table)),\n \"}\",\n \"\",\n \"export async function down(knex: Knex): Promise<void> {\",\n ` return knex.schema.dropTable(\"${table}\");`,\n \"}\",\n ];\n return {\n table,\n type: \"normal\",\n title: `create__${table}`,\n formatted: await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n }),\n };\n}\n\n/**\n * MigrationColumn[] 읽어서 컬럼 정의하는 구문 생성\n */\nfunction genColumnDefinitions(columns: MigrationColumn[]): string[] {\n return columns.map((column) => {\n const chains: string[] = [];\n if (column.name === \"id\") {\n return `table.increments().primary();`;\n }\n\n // FIXME: float(M,D) deprecated -> decimal(M,D) 이용하도록 하고, float/double 처리 추가\n if (column.type === \"float\" || column.type === \"decimal\") {\n chains.push(\n `${column.type}('${column.name}', ${column.precision}, ${column.scale})`\n );\n } else {\n // type, length\n let columnType = column.type;\n let extraType: string | undefined;\n if (columnType.includes(\"text\") && columnType !== \"text\") {\n extraType = columnType;\n columnType = \"text\";\n }\n chains.push(\n `${columnType}('${column.name}'${\n column.length ? `, ${column.length}` : \"\"\n }${extraType ? `, '${extraType}'` : \"\"})`\n );\n }\n if (column.unsigned) {\n chains.push(\"unsigned()\");\n }\n\n // nullable\n chains.push(column.nullable ? \"nullable()\" : \"notNullable()\");\n\n // defaultTo\n if (column.defaultTo !== undefined) {\n if (\n typeof column.defaultTo === \"string\" &&\n column.defaultTo.startsWith(`\"`)\n ) {\n chains.push(`defaultTo(${column.defaultTo})`);\n } else {\n chains.push(`defaultTo(knex.raw('${column.defaultTo}'))`);\n }\n }\n\n return `table.${chains.join(\".\")};`;\n });\n}\n\n/**\n * 개별 인덱스 정의 생성\n */\nfunction genIndexDefinition(index: MigrationIndex, table: string) {\n const methodMap = {\n index: \"index\",\n fulltext: \"index\",\n unique: \"unique\",\n };\n\n if (index.type === \"fulltext\" && index.parser === \"ngram\") {\n const indexName = `${table}_${index.columns.join(\"_\")}_index`;\n return `await knex.raw(\\`ALTER TABLE ${table} ADD FULLTEXT INDEX ${indexName} (${index.columns.join(\n \", \"\n )}) WITH PARSER ngram\\`);`;\n }\n\n return `table.${methodMap[index.type]}([${index.columns\n .map((col) => `'${col}'`)\n .join(\",\")}]${index.type === \"fulltext\" ? \", undefined, 'FULLTEXT'\" : \"\"})`;\n}\n\n/**\n * 테이블 생성하는 케이스 - FK 생성\n */\nasync function generateCreateCode_Foreign(\n table: string,\n foreigns: MigrationForeign[]\n): Promise<GenMigrationCode[]> {\n if (foreigns.length === 0) {\n return [];\n }\n\n const { up, down } = genForeignDefinitions(table, foreigns);\n if (up.length === 0 && down.length === 0) {\n console.log(\"fk 가 뭔가 다릅니다\");\n return [];\n }\n\n const lines: string[] = [\n 'import { Knex } from \"knex\";',\n \"\",\n \"export async function up(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n \"// create fk\",\n ...up,\n \"});\",\n \"}\",\n \"\",\n \"export async function down(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n \"// drop fk\",\n ...down,\n \"});\",\n \"}\",\n ];\n\n const foreignKeysString = foreigns\n .map((foreign) => foreign.columns.join(\"_\"))\n .join(\"_\");\n return [\n {\n table,\n type: \"foreign\",\n title: `foreign__${table}__${foreignKeysString}`,\n formatted: await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n }),\n },\n ];\n}\n\n/**\n * MigrationForeign[] 읽어서 외부키 constraint 정의하는 구문 생성\n */\nfunction genForeignDefinitions(\n table: string,\n foreigns: MigrationForeign[]\n): { up: string[]; down: string[] } {\n return foreigns.reduce(\n (r, foreign) => {\n const columnsStringQuote = foreign.columns\n .map((col) => `'${col.replace(`${table}.`, \"\")}'`)\n .join(\",\");\n r.up.push(\n `table.foreign('${foreign.columns.join(\",\")}')\n .references('${foreign.to}')\n .onUpdate('${foreign.onUpdate}')\n .onDelete('${foreign.onDelete}')`\n );\n r.down.push(`table.dropForeign([${columnsStringQuote}])`);\n return r;\n },\n {\n up: [] as string[],\n down: [] as string[],\n }\n );\n}\n\n/**\n * 테이블 변경 케이스 - 컬럼/인덱스 변경\n */\nasync function generateAlterCode_ColumnAndIndexes(\n table: string,\n entityColumns: MigrationColumn[],\n entityIndexes: MigrationIndex[],\n dbColumns: MigrationColumn[],\n dbIndexes: MigrationIndex[],\n dbForeigns: MigrationForeign[]\n): Promise<GenMigrationCode[]> {\n /*\n 세부 비교 후 다른점 찾아서 코드 생성\n\n 1. 컬럼갯수 다름: MD에 있으나, DB에 없다면 추가\n 2. 컬럼갯수 다름: MD에 없으나, DB에 있다면 삭제\n 3. 그외 컬럼(컬럼 갯수가 동일하거나, 다른 경우 동일한 컬럼끼리) => alter\n 4. 다른거 다 동일하고 index만 변경되는 경우\n\n ** 컬럼명을 변경하는 경우는 따로 핸들링하지 않음\n => drop/add 형태의 마이그레이션 코드가 생성되는데, 수동으로 rename 코드로 수정하여 처리\n */\n\n // 각 컬럼 이름 기준으로 add, drop, alter 여부 확인\n const alterColumnsTo = getAlterColumnsTo(entityColumns, dbColumns);\n\n // 추출된 컬럼들을 기준으로 각각 라인 생성\n const alterColumnLinesTo = getAlterColumnLinesTo(\n alterColumnsTo,\n entityColumns,\n table,\n dbForeigns\n );\n\n // 인덱스의 add, drop 여부 확인\n const alterIndexesTo = getAlterIndexesTo(entityIndexes, dbIndexes);\n\n // fulltext index 분리\n const [ngramIndexes, standardIndexes] = _.partition(\n alterIndexesTo.add,\n (i) => i.type === \"fulltext\" && i.parser === \"ngram\"\n );\n\n // 인덱스가 삭제되는 경우, 컬럼과 같이 삭제된 케이스에는 drop에서 제외해야함!\n const indexNeedsToDrop = alterIndexesTo.drop.filter(\n (index) =>\n index.columns.every((colName) =>\n alterColumnsTo.drop.map((col) => col.name).includes(colName)\n ) === false\n );\n\n const lines: string[] = [\n 'import { Knex } from \"knex\";',\n \"\",\n \"export async function up(knex: Knex): Promise<void> {\",\n `await knex.schema.alterTable(\"${table}\", (table) => {`,\n // 1. add column\n ...(alterColumnsTo.add.length > 0 ? alterColumnLinesTo.add.up : []),\n // 2. drop column\n ...(alterColumnsTo.drop.length > 0 ? alterColumnLinesTo.drop.up : []),\n // 3. alter column\n ...(alterColumnsTo.alter.length > 0 ? alterColumnLinesTo.alter.up : []),\n // 4. add index\n ...standardIndexes.map((index) => genIndexDefinition(index, table)),\n // 5. drop index\n ...indexNeedsToDrop.map(genIndexDropDefinition),\n \"});\",\n // ngram은 knex.raw로 처리하므로 alterTable 밖에서 실행\n ...ngramIndexes.map((index) => genIndexDefinition(index, table)),\n \"}\",\n \"\",\n \"export async function down(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n ...(alterColumnsTo.add.length > 0 ? alterColumnLinesTo.add.down : []),\n ...(alterColumnsTo.drop.length > 0 ? alterColumnLinesTo.drop.down : []),\n ...(alterColumnsTo.alter.length > 0 ? alterColumnLinesTo.alter.down : []),\n ...alterIndexesTo.add\n .filter(\n (index) =>\n index.columns.every((colName) =>\n alterColumnsTo.add.map((col) => col.name).includes(colName)\n ) === false\n )\n .map(genIndexDropDefinition),\n ...indexNeedsToDrop.map((index) => genIndexDefinition(index, table)),\n \"});\",\n \"}\",\n ];\n\n const formatted = await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n });\n\n const title = [\n \"alter\",\n table,\n ...([\"add\", \"drop\", \"alter\"] as const)\n .map((action) => {\n const len = alterColumnsTo[action].length;\n if (len > 0) {\n return action + len;\n }\n return null;\n })\n .filter((part) => part !== null),\n ].join(\"_\");\n\n return [\n {\n table,\n title,\n formatted,\n type: \"normal\",\n },\n ];\n}\n\n/**\n * 각 컬럼 이름 기준으로 add, drop, alter 여부 확인\n */\nfunction getAlterColumnsTo(\n entityColumns: MigrationColumn[],\n dbColumns: MigrationColumn[]\n) {\n const columnsTo = {\n add: [] as MigrationColumn[],\n drop: [] as MigrationColumn[],\n alter: [] as MigrationColumn[],\n };\n\n // 컬럼명 기준 비교\n const extraColumns = {\n db: _.differenceBy(dbColumns, entityColumns, (col) => col.name),\n entity: _.differenceBy(entityColumns, dbColumns, (col) => col.name),\n };\n if (extraColumns.entity.length > 0) {\n columnsTo.add = columnsTo.add.concat(extraColumns.entity);\n }\n if (extraColumns.db.length > 0) {\n columnsTo.drop = columnsTo.drop.concat(extraColumns.db);\n }\n\n // 동일 컬럼명의 세부 필드 비교\n const sameDbColumns = _.intersectionBy(\n dbColumns,\n entityColumns,\n (col) => col.name\n );\n const sameMdColumns = _.intersectionBy(\n entityColumns,\n dbColumns,\n (col) => col.name\n );\n columnsTo.alter = _.differenceWith(sameDbColumns, sameMdColumns, (a, b) =>\n equal(a, b)\n );\n\n return columnsTo;\n}\n\n/**\n * 추출된 컬럼들을 기준으로 각각 라인 생성\n */\nfunction getAlterColumnLinesTo(\n columnsTo: ReturnType<typeof getAlterColumnsTo>,\n entityColumns: MigrationColumn[],\n table: string,\n dbForeigns: MigrationForeign[]\n) {\n let linesTo = {\n add: {\n up: [] as string[],\n down: [] as string[],\n },\n drop: {\n up: [] as string[],\n down: [] as string[],\n },\n alter: {\n up: [] as string[],\n down: [] as string[],\n },\n };\n\n linesTo.add = {\n up: [\"// add\", ...genColumnDefinitions(columnsTo.add)],\n down: [\n \"// rollback - add\",\n `table.dropColumns(${columnsTo.add\n .map((col) => `'${col.name}'`)\n .join(\", \")})`,\n ],\n };\n\n // drop할 컬럼에 걸린 FK 찾기\n const dropColumnNames = columnsTo.drop.map((col) => col.name);\n const fkToDropBeforeColumn = dbForeigns.filter((fk) =>\n fk.columns.some((col) => dropColumnNames.includes(col))\n );\n\n const dropFkLines = fkToDropBeforeColumn.map((fk) => {\n const columnsStringQuote = fk.columns.map((col) => `'${col}'`).join(\",\");\n return `table.dropForeign([${columnsStringQuote}])`;\n });\n\n const restoreFkLines = genForeignDefinitions(table, fkToDropBeforeColumn).up;\n\n linesTo.drop = {\n up: [\n ...(dropFkLines.length > 0\n ? [\"// drop foreign keys on columns to be dropped\", ...dropFkLines]\n : []),\n \"// drop columns\",\n `table.dropColumns(${columnsTo.drop\n .map((col) => `'${col.name}'`)\n .join(\", \")})`,\n ],\n down: [\n \"// rollback - drop columns\",\n ...genColumnDefinitions(columnsTo.drop),\n ...(restoreFkLines.length > 0\n ? [\"// restore foreign keys\", ...restoreFkLines]\n : []),\n ],\n };\n linesTo.alter = columnsTo.alter.reduce(\n (r, dbColumn) => {\n const entityColumn = entityColumns.find(\n (col) => col.name == dbColumn.name\n );\n if (entityColumn === undefined) {\n return r;\n }\n\n // 컬럼 변경사항\n const columnDiffUp = _.difference(\n genColumnDefinitions([entityColumn]),\n genColumnDefinitions([dbColumn])\n );\n const columnDiffDown = _.difference(\n genColumnDefinitions([dbColumn]),\n genColumnDefinitions([entityColumn])\n );\n if (columnDiffUp.length > 0) {\n r.up = [\n ...r.up,\n \"// alter column\",\n ...columnDiffUp.map((l) => l.replace(\";\", \"\") + \".alter();\"),\n ];\n r.down = [\n ...r.down,\n \"// rollback - alter column\",\n ...columnDiffDown.map((l) => l.replace(\";\", \"\") + \".alter();\"),\n ];\n }\n\n return r;\n },\n {\n up: [] as string[],\n down: [] as string[],\n }\n );\n\n return linesTo;\n}\n\n/**\n * 인덱스의 add, drop 여부 확인\n */\nfunction getAlterIndexesTo(\n entityIndexes: MigrationIndex[],\n dbIndexes: MigrationIndex[]\n) {\n // 인덱스 비교\n let indexesTo = {\n add: [] as MigrationIndex[],\n drop: [] as MigrationIndex[],\n };\n const extraIndexes = {\n db: _.differenceBy(dbIndexes, entityIndexes, (col) =>\n [col.type, col.columns.join(\"-\")].join(\"//\")\n ),\n entity: _.differenceBy(entityIndexes, dbIndexes, (col) =>\n [col.type, col.columns.join(\"-\")].join(\"//\")\n ),\n };\n if (extraIndexes.entity.length > 0) {\n indexesTo.add = indexesTo.add.concat(extraIndexes.entity);\n }\n if (extraIndexes.db.length > 0) {\n indexesTo.drop = indexesTo.drop.concat(extraIndexes.db);\n }\n\n return indexesTo;\n}\n\n/**\n * 인덱스 삭제 정의 생성\n */\nfunction genIndexDropDefinition(index: MigrationIndex) {\n const methodMap = {\n index: \"Index\",\n fulltext: \"Index\",\n unique: \"Unique\",\n };\n\n return `table.drop${methodMap[index.type]}([${index.columns\n .map((columnName) => `'${columnName}'`)\n .join(\",\")}])`;\n}\n\n/**\n * 테이블 변경 케이스 - Foreign Key 변경\n */\nasync function generateAlterCode_Foreigns(\n table: string,\n entityForeigns: MigrationForeign[],\n dbForeigns: MigrationForeign[],\n droppingColumns: MigrationColumn[] = []\n): Promise<GenMigrationCode[]> {\n // console.log({ entityForeigns, dbForeigns });\n\n const getKey = (mf: MigrationForeign): string => {\n return [mf.columns.join(\"-\"), mf.to].join(\"///\");\n };\n\n // 삭제될 컬럼명 목록\n const droppingColumnNames = droppingColumns.map((col) => col.name);\n\n const fkTo = entityForeigns.reduce(\n (result, entityF) => {\n const matchingDbF = dbForeigns.find(\n (dbF) => getKey(entityF) === getKey(dbF)\n );\n if (!matchingDbF) {\n result.add.push(entityF);\n return result;\n }\n\n if (equal(entityF, matchingDbF) === false) {\n result.alterSrc.push(matchingDbF);\n result.alterDst.push(entityF);\n return result;\n }\n return result;\n },\n {\n add: [] as MigrationForeign[],\n drop: [] as MigrationForeign[],\n alterSrc: [] as MigrationForeign[],\n alterDst: [] as MigrationForeign[],\n }\n );\n\n // dbForeigns에는 있지만 entityForeigns에는 없는 경우 (삭제된 FK)\n // 단, 삭제될 컬럼의 FK는 제외 (generateAlterCode_ColumnAndIndexes에서 처리)\n dbForeigns.forEach((dbF) => {\n const matchingEntityF = entityForeigns.find(\n (entityF) => getKey(entityF) === getKey(dbF)\n );\n if (!matchingEntityF) {\n // 이 FK의 컬럼이 삭제될 컬럼 목록에 있는지 확인\n const isColumnDropping = dbF.columns.some((col) =>\n droppingColumnNames.includes(col)\n );\n // 컬럼이 삭제되지 않는 경우에만 FK drop 목록에 추가\n if (!isColumnDropping) {\n fkTo.drop.push(dbF);\n }\n }\n });\n\n const linesTo = {\n add: genForeignDefinitions(table, fkTo.add),\n drop: genForeignDefinitions(table, fkTo.drop),\n alterSrc: genForeignDefinitions(table, fkTo.alterSrc),\n alterDst: genForeignDefinitions(table, fkTo.alterDst),\n };\n\n // drop fk columns인 경우(생성될 코드 없는 경우) 패스\n const hasLines = Object.values(linesTo).some(\n (l) => l.up.length > 0 || l.down.length > 0\n );\n if (!hasLines) {\n return [];\n }\n\n const lines: string[] = [\n 'import { Knex } from \"knex\";',\n \"\",\n \"export async function up(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n ...linesTo.drop.down,\n ...linesTo.add.up,\n ...linesTo.alterSrc.down,\n ...linesTo.alterDst.up,\n \"})\",\n \"}\",\n \"\",\n \"export async function down(knex: Knex): Promise<void> {\",\n `return knex.schema.alterTable(\"${table}\", (table) => {`,\n ...linesTo.add.down,\n ...linesTo.alterDst.down,\n ...linesTo.alterSrc.up,\n ...linesTo.drop.up,\n \"})\",\n \"}\",\n ];\n\n const formatted = await prettier.format(lines.join(\"\\n\"), {\n parser: \"typescript\",\n });\n\n const title = [\n \"alter\",\n table,\n \"foreigns\",\n // TODO 바뀌는 부분\n ].join(\"_\");\n\n return [\n {\n table,\n title,\n formatted,\n type: \"normal\",\n },\n ];\n}\n\n/**\n * 주어진 EntitySet을 기반으로 테이블 CREATE 마이그레이션 코드를 생성합니다.\n * @param entitySet\n * @returns CREATE 마이그레이션 코드\n */\nexport async function generateCreateCode(\n entitySet: MigrationSet\n): Promise<GenMigrationCode[]> {\n return [\n await generateCreateCode_ColumnAndIndexes(\n entitySet.table,\n entitySet.columns,\n entitySet.indexes\n ),\n ...(await generateCreateCode_Foreign(entitySet.table, entitySet.foreigns)),\n ];\n}\n\n/**\n * 주어진 entitySet을 목표로, dbSet을 현 상황으로 하여 테이블 ALTER 마이그레이션 코드를 생성합니다.\n * @param entitySet 현 상황의 MigrationSet\n * @param dbSet 목표 상황의 MigrationSet\n * @returns ALTER 마이그레이션 코드\n */\nexport async function generateAlterCode(\n entitySet: MigrationSet,\n dbSet: MigrationSet\n): Promise<GenMigrationCode[]> {\n const replaceColumnDefaultTo = (col: MigrationColumn) => {\n // float인 경우 기본값을 0으로 지정하는 경우 \"0.00\"으로 변환되는 케이스 대응\n if (\n col.type === \"float\" &&\n col.defaultTo &&\n String(col.defaultTo).includes('\"') === false\n ) {\n col.defaultTo = `\"${Number(col.defaultTo).toFixed(col.scale ?? 2)}\"`;\n }\n // string인 경우 기본값이 빈 스트링인 경우 대응\n if (col.type === \"string\" && col.defaultTo === \"\") {\n col.defaultTo = '\"\"';\n }\n // boolean인 경우 기본값 정규화 (MySQL에서는 TINYINT(1)로 저장되므로 0 또는 1로 정규화)\n // TODO: db.ts에 typeCase 설정 확인하여 처리하도록 수정 필요\n if (col.type === \"boolean\" && col.defaultTo !== undefined) {\n if (col.defaultTo === \"0\" || col.defaultTo.toLowerCase() === \"false\") {\n col.defaultTo = \"0\";\n } else if (col.defaultTo === \"1\" || col.defaultTo.toLowerCase() === \"true\") {\n col.defaultTo = \"1\";\n }\n }\n return col;\n };\n const entityColumns = _.sortBy(entitySet.columns, (a) => a.name).map(\n replaceColumnDefaultTo\n );\n const dbColumns = _.sortBy(dbSet.columns, (a) => a.name).map(\n replaceColumnDefaultTo\n );\n\n /* 디버깅용 코드, 특정 컬럼에서 불일치 발생할 때 확인\n const entityColumn = entitySet.columns.find(\n (col) => col.name === \"price_krw\"\n );\n const dbColumn = dbSet.columns.find(\n (col) => col.name === \"price_krw\"\n );\n console.debug({ entityColumn, dbColumn });\n */\n\n const entityIndexes = _.sortBy(entitySet.indexes, (a) =>\n [a.type, ...a.columns.sort((c1, c2) => (c1 > c2 ? 1 : -1))].join(\"-\")\n );\n const dbIndexes = _.sortBy(dbSet.indexes, (a) =>\n [a.type, ...a.columns.sort((c1, c2) => (c1 > c2 ? 1 : -1))].join(\"-\")\n );\n\n const replaceNoActionOnMySQL = (f: MigrationForeign) => {\n // MySQL에서 RESTRICT와 NO ACTION은 동일함\n const { onDelete, onUpdate } = f;\n return {\n ...f,\n onUpdate: onUpdate === \"RESTRICT\" ? \"NO ACTION\" : onUpdate,\n onDelete: onDelete === \"RESTRICT\" ? \"NO ACTION\" : onDelete,\n };\n };\n\n const entityForeigns = _.sortBy(entitySet.foreigns, (a) =>\n [a.to, ...a.columns].join(\"-\")\n ).map((f) => replaceNoActionOnMySQL(f));\n const dbForeigns = _.sortBy(dbSet.foreigns, (a) =>\n [a.to, ...a.columns].join(\"-\")\n ).map((f) => replaceNoActionOnMySQL(f));\n\n // 삭제될 컬럼 목록 계산\n const droppingColumns = _.differenceBy(\n dbColumns,\n entityColumns,\n (col) => col.name\n );\n\n const alterCodes: (GenMigrationCode | GenMigrationCode[] | null)[] = [];\n\n // 1. columnsAndIndexes 처리\n const isEqualColumns = equal(entityColumns, dbColumns);\n const isEqualIndexes = equal(\n entityIndexes.map((index) => _.omit(index, [\"parser\"])),\n dbIndexes\n );\n if (!isEqualColumns || !isEqualIndexes) {\n alterCodes.push(\n await generateAlterCode_ColumnAndIndexes(\n entitySet.table,\n entityColumns,\n entityIndexes,\n dbColumns,\n dbIndexes,\n dbSet.foreigns\n )\n );\n }\n\n // 2. foreigns 처리 (삭제될 컬럼 정보 전달)\n if (equal(entityForeigns, dbForeigns) === false) {\n alterCodes.push(\n await generateAlterCode_Foreigns(\n entitySet.table,\n entityForeigns,\n dbForeigns,\n droppingColumns\n )\n );\n }\n\n if (alterCodes.every((alterCode) => alterCode === null)) {\n return [];\n }\n\n return alterCodes.filter((alterCode) => alterCode !== null).flat();\n}\n"],"names":["generateAlterCode","generateCreateCode","generateCreateCode_ColumnAndIndexes","table","columns","indexes","_","ngramIndexes","standardIndexes","lines","partition","i","type","parser","genColumnDefinitions","map","index","genIndexDefinition","title","prettier","format","join","formatted","column","chains","name","push","precision","scale","columnType","extraType","includes","length","unsigned","nullable","defaultTo","undefined","startsWith","methodMap","fulltext","unique","indexName","col","generateCreateCode_Foreign","foreigns","genForeignDefinitions","up","down","foreignKeysString","console","log","foreign","reduce","r","columnsStringQuote","replace","to","onUpdate","onDelete","generateAlterCode_ColumnAndIndexes","entityColumns","entityIndexes","dbColumns","dbIndexes","dbForeigns","alterColumnsTo","alterColumnLinesTo","alterIndexesTo","indexNeedsToDrop","getAlterColumnsTo","getAlterColumnLinesTo","getAlterIndexesTo","add","drop","filter","every","colName","alter","genIndexDropDefinition","action","len","part","columnsTo","extraColumns","db","differenceBy","entity","concat","sameDbColumns","intersectionBy","sameMdColumns","differenceWith","a","b","equal","linesTo","dropColumnNames","fkToDropBeforeColumn","fk","some","dropFkLines","restoreFkLines","dbColumn","entityColumn","find","columnDiffUp","difference","columnDiffDown","l","indexesTo","extraIndexes","columnName","generateAlterCode_Foreigns","entityForeigns","droppingColumns","getKey","droppingColumnNames","fkTo","hasLines","mf","result","entityF","matchingDbF","dbF","alterSrc","alterDst","forEach","matchingEntityF","isColumnDropping","Object","values","entitySet","dbSet","replaceColumnDefaultTo","replaceNoActionOnMySQL","alterCodes","isEqualColumns","isEqualIndexes","String","Number","toFixed","toLowerCase","sortBy","sort","c1","c2","f","omit","alterCode","flat"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/migration/migration-set.ts"],"sourcesContent":["import { Knex } from \"knex\";\nimport { DBColumn, DBForeign, DBIndex } from \"./types\";\nimport _ from \"lodash\";\nimport inflection from \"inflection\";\nimport { Entity } from \"../entity/entity\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport {\n isKnexError,\n MigrationSet,\n RelationOn,\n isBelongsToOneRelationProp,\n isDecimalProp,\n isEnumProp,\n isFloatProp,\n isHasManyRelationProp,\n isIntegerProp,\n isManyToManyRelationProp,\n isOneToOneRelationProp,\n isRelationProp,\n isStringProp,\n isTextProp,\n isVirtualProp,\n KnexColumnType,\n MigrationColumn,\n MigrationForeign,\n MigrationIndex,\n MigrationJoinTable,\n MigrationSetAndJoinTable,\n} from \"../types/types\";\n\n/**\n * DB에서 테이블 정보를 읽어서 MigrationSet을 만들어옵니다.\n * @param compareDB Knex 인스턴스\n * @param table 테이블 이름\n * @returns MigrationSet 객체\n */\nexport async function getMigrationSetFromDB(\n compareDB: Knex,\n table: string\n): Promise<MigrationSet | null> {\n let dbColumns: DBColumn[], dbIndexes: DBIndex[], dbForeigns: DBForeign[];\n try {\n [dbColumns, dbIndexes, dbForeigns] = await readTable(compareDB, table);\n } catch (e: unknown) {\n if (isKnexError(e) && e.code === \"ER_NO_SUCH_TABLE\") {\n return null;\n }\n console.error(e);\n return null;\n }\n\n const columns: MigrationColumn[] = dbColumns.map((dbColumn) => {\n const dbColType = resolveDBColType(dbColumn.Type, dbColumn.Field);\n return {\n name: dbColumn.Field,\n nullable: dbColumn.Null !== \"NO\",\n ...dbColType,\n ...(() => {\n if (dbColumn.Default !== null) {\n return {\n defaultTo: dbColumn.Default,\n };\n }\n return {};\n })(),\n };\n });\n\n const dbIndexesGroup = _.groupBy(\n dbIndexes.filter(\n (dbIndex) =>\n dbIndex.Key_name !== \"PRIMARY\" &&\n !dbForeigns.find((dbForeign) => dbForeign.keyName === dbIndex.Key_name)\n ),\n (dbIndex) => dbIndex.Key_name\n );\n\n const parseIndexType = (index: DBIndex) => {\n if (index.Index_type === \"FULLTEXT\") {\n return \"fulltext\";\n }\n return index.Non_unique === 1 ? \"index\" : \"unique\";\n };\n\n // indexes 처리\n const indexes: MigrationIndex[] = Object.keys(dbIndexesGroup).map(\n (keyName) => {\n const currentIndexes = dbIndexesGroup[keyName];\n return {\n type: parseIndexType(currentIndexes[0]),\n columns: currentIndexes.map((currentIndex) => currentIndex.Column_name),\n };\n }\n );\n // console.log(table);\n // console.table(dbIndexes);\n // console.table(dbForeigns);\n\n // foreigns 처리\n const foreigns: MigrationForeign[] = dbForeigns.map((dbForeign) => {\n return {\n columns: [dbForeign.from],\n to: `${dbForeign.referencesTable}.${dbForeign.referencesField}`,\n onUpdate: dbForeign.onUpdate as RelationOn,\n onDelete: dbForeign.onDelete as RelationOn,\n };\n });\n\n return {\n table,\n columns,\n indexes,\n foreigns,\n };\n}\n\n/*\n * 기존 테이블 읽어서 cols, indexes 반환\n */\nasync function readTable(\n compareDB: Knex,\n tableName: string\n): Promise<[DBColumn[], DBIndex[], DBForeign[]]> {\n // 테이블 정보\n try {\n const [_cols] = (await compareDB.raw(`SHOW FIELDS FROM ${tableName}`)) as [\n DBColumn[],\n ];\n const cols = _cols.map((col) => ({\n ...col,\n // Default 값은 숫자나 MySQL Expression이 아닌 경우 \"\"로 감싸줌\n ...(col.Default !== null && {\n Default:\n col.Default.replace(/[0-9]+/g, \"\").length > 0 &&\n col.Extra !== \"DEFAULT_GENERATED\"\n ? `\"${col.Default}\"`\n : col.Default,\n }),\n }));\n\n const [indexes] = await compareDB.raw(`SHOW INDEX FROM ${tableName}`);\n const [[row]] = await compareDB.raw(`SHOW CREATE TABLE ${tableName}`);\n const ddl = row[\"Create Table\"];\n const matched = ddl.match(/CONSTRAINT .+/g);\n const foreignKeys = (matched ?? []).map((line: string) => {\n // 해당 라인을 정규식으로 파싱\n const matched = line.match(\n /CONSTRAINT `(.+)` FOREIGN KEY \\(`(.+)`\\) REFERENCES `(.+)` \\(`(.+)`\\)( ON [A-Z ]+)*/\n );\n if (!matched) {\n throw new Error(`인식할 수 없는 FOREIGN KEY CONSTRAINT ${line}`);\n }\n const [, keyName, from, referencesTable, referencesField, onClause] =\n matched;\n // console.debug({ tableName, line, onClause });\n\n const [onUpdateFull, _onUpdate] =\n (onClause ?? \"\").match(/ON UPDATE ([A-Z ]+)$/) ?? [];\n const onUpdate = _onUpdate ?? \"NO ACTION\";\n\n const onDelete =\n (onClause ?? \"\")\n .replace(onUpdateFull ?? \"\", \"\")\n .match(/ON DELETE ([A-Z ]+)/)?.[1]\n ?.trim() ?? \"NO ACTION\";\n\n return {\n keyName,\n from,\n referencesTable,\n referencesField,\n onDelete,\n onUpdate,\n };\n });\n return [cols, indexes, foreignKeys];\n } catch (e) {\n throw e;\n }\n}\n\nfunction resolveDBColType(\n colType: string,\n colField: string\n): Pick<\n MigrationColumn,\n \"type\" | \"unsigned\" | \"length\" | \"precision\" | \"scale\"\n> {\n let [rawType, unsigned] = colType.split(\" \");\n const matched = rawType.match(/\\(([0-9]+)\\)/);\n let length;\n if (matched !== null && matched[1]) {\n rawType = rawType.replace(/\\(([0-9]+)\\)/, \"\");\n length = parseInt(matched[1]);\n }\n\n if (rawType === \"char\" && colField === \"uuid\") {\n return {\n type: \"uuid\",\n };\n }\n\n switch (rawType) {\n case \"int\":\n return {\n type: \"integer\",\n unsigned: unsigned === \"unsigned\",\n };\n case \"varchar\":\n // case \"char\":\n return {\n type: \"string\",\n ...(length !== undefined && {\n length,\n }),\n };\n case \"text\":\n case \"mediumtext\":\n case \"longtext\":\n case \"timestamp\":\n case \"json\":\n case \"date\":\n case \"time\":\n return {\n type: rawType,\n };\n case \"datetime\":\n return {\n type: \"datetime\",\n };\n case \"tinyint\":\n return {\n type: \"boolean\",\n };\n default:\n // decimal 처리\n if (rawType.startsWith(\"decimal\")) {\n const [, precision, scale] =\n rawType.match(/decimal\\(([0-9]+),([0-9]+)\\)/) ?? [];\n return {\n type: \"decimal\",\n precision: parseInt(precision),\n scale: parseInt(scale),\n ...(unsigned === \"unsigned\" && {\n unsigned: true,\n }),\n };\n } else if (rawType.startsWith(\"float\")) {\n const [, precision, scale] =\n rawType.match(/float\\(([0-9]+),([0-9]+)\\)/) ?? [];\n return {\n type: \"float\",\n precision: parseInt(precision),\n scale: parseInt(scale),\n ...(unsigned === \"unsigned\" && {\n unsigned: true,\n }),\n };\n }\n throw new Error(`resolve 불가능한 DB컬럼 타입 ${colType} ${rawType}`);\n }\n}\n\n/**\n * Entity를 읽어서 MigrationSetAndJoinTable을 만들어옵니다.\n * @param entity Entity 객체\n * @returns MigrationSetAndJoinTable 객체\n */\nexport function getMigrationSetFromEntity(\n entity: Entity\n): MigrationSetAndJoinTable {\n const migrationSet: MigrationSetAndJoinTable = entity.props.reduce(\n (r, prop) => {\n // virtual 필드 제외\n if (isVirtualProp(prop)) {\n return r;\n }\n // HasMany 케이스는 아무 처리도 하지 않음\n if (isHasManyRelationProp(prop)) {\n return r;\n }\n\n // 일반 컬럼\n if (!isRelationProp(prop)) {\n // type resolve\n let type: KnexColumnType;\n if (isTextProp(prop)) {\n type = prop.textType;\n } else if (isEnumProp(prop)) {\n type = \"string\";\n } else {\n type = prop.type as KnexColumnType;\n }\n\n const column = {\n name: prop.name,\n type,\n ...(isIntegerProp(prop) && { unsigned: prop.unsigned === true }),\n ...((isStringProp(prop) || isEnumProp(prop)) && {\n length: prop.length,\n }),\n nullable: prop.nullable === true,\n ...(() => {\n if (prop.dbDefault !== undefined) {\n return {\n defaultTo: prop.dbDefault,\n };\n }\n return {};\n })(),\n // FIXME: float(N, M) deprecated\n // Decimal, Float 타입의 경우 precision, scale 추가\n ...((isDecimalProp(prop) || isFloatProp(prop)) && {\n precision: prop.precision ?? 8,\n scale: prop.scale ?? 2,\n }),\n };\n\n r.columns.push(column);\n }\n\n if (isManyToManyRelationProp(prop)) {\n // ManyToMany 케이스\n const relMd = EntityManager.get(prop.with);\n const table1 = entity.table;\n const table2 = relMd.table;\n const join = {\n from: `${entity.table}.id`,\n through: {\n from: `${prop.joinTable}.${inflection.singularize(table1)}_id`,\n to: `${prop.joinTable}.${inflection.singularize(table2)}_id`,\n onUpdate: prop.onUpdate,\n onDelete: prop.onDelete,\n },\n to: `${relMd.table}.id`,\n };\n const through = join.through;\n const fields = [through.from, through.to];\n r.joinTables.push({\n table: through.from.split(\".\")[0],\n indexes: [\n {\n type: \"unique\",\n columns: [\"uuid\"],\n },\n // 조인 테이블에 걸린 인덱스 찾아와서 연결\n ...entity.indexes\n .filter((index) =>\n index.columns.find((col) => col.includes(prop.joinTable + \".\"))\n )\n .map((index) => ({\n ...index,\n columns: index.columns.map((col) =>\n col.replace(prop.joinTable + \".\", \"\")\n ),\n })),\n ],\n columns: [\n {\n name: \"id\",\n type: \"integer\",\n nullable: false,\n unsigned: true,\n },\n ...fields.map((field) => {\n return {\n name: field.split(\".\")[1],\n type: \"integer\",\n nullable: false,\n unsigned: true,\n } as MigrationColumn;\n }),\n {\n name: \"uuid\",\n nullable: true,\n type: \"uuid\",\n },\n ],\n foreigns: fields.map((field) => {\n // 현재 필드가 어떤 테이블에 속하는지 판단\n const col = field.split(\".\")[1];\n const to = (() => {\n if (\n inflection.singularize(join.to.split(\".\")[0]) + \"_id\" ===\n col\n ) {\n return join.to;\n } else {\n return join.from;\n }\n })();\n return {\n columns: [col],\n to,\n onUpdate: through.onUpdate,\n onDelete: through.onDelete,\n };\n }),\n });\n return r;\n } else if (\n isBelongsToOneRelationProp(prop) ||\n (isOneToOneRelationProp(prop) && prop.hasJoinColumn)\n ) {\n // -OneRelation 케이스\n const idColumnName = prop.name + \"_id\";\n r.columns.push({\n name: idColumnName,\n type: \"integer\",\n unsigned: true,\n nullable: prop.nullable ?? false,\n });\n if ((prop.useConstraint ?? true) === true) {\n r.foreigns.push({\n columns: [idColumnName],\n to: `${inflection\n .underscore(inflection.pluralize(prop.with))\n .toLowerCase()}.id`,\n onUpdate: prop.onUpdate ?? \"RESTRICT\",\n onDelete: prop.onDelete ?? \"RESTRICT\",\n });\n }\n }\n\n return r;\n },\n {\n table: entity.table,\n columns: [] as MigrationColumn[],\n indexes: [] as MigrationIndex[],\n foreigns: [] as MigrationForeign[],\n joinTables: [] as MigrationJoinTable[],\n }\n );\n\n // indexes\n migrationSet.indexes = entity.indexes.filter((index) =>\n index.columns.find((col) => col.includes(\".\") === false)\n );\n\n // uuid\n migrationSet.columns = migrationSet.columns.concat({\n name: \"uuid\",\n nullable: true,\n type: \"uuid\",\n } as MigrationColumn);\n migrationSet.indexes = migrationSet.indexes.concat({\n type: \"unique\",\n columns: [\"uuid\"],\n } as MigrationIndex);\n\n return migrationSet;\n}\n"],"names":["getMigrationSetFromDB","getMigrationSetFromEntity","compareDB","table","dbColumns","dbIndexes","dbForeigns","e","columns","dbIndexesGroup","parseIndexType","indexes","foreigns","readTable","isKnexError","code","console","error","map","dbColumn","dbColType","resolveDBColType","Type","Field","name","nullable","Null","Default","defaultTo","_","groupBy","filter","dbIndex","Key_name","find","dbForeign","keyName","index","Index_type","Non_unique","Object","keys","currentIndexes","type","currentIndex","Column_name","from","to","referencesTable","referencesField","onUpdate","onDelete","tableName","_cols","cols","row","ddl","matched","foreignKeys","raw","col","replace","length","Extra","match","line","Error","onClause","onUpdateFull","_onUpdate","trim","colType","colField","split","rawType","unsigned","parseInt","undefined","startsWith","precision","scale","entity","migrationSet","props","reduce","r","prop","isVirtualProp","isHasManyRelationProp","isRelationProp","isTextProp","textType","isEnumProp","column","isIntegerProp","isStringProp","dbDefault","isDecimalProp","isFloatProp","push","isManyToManyRelationProp","relMd","EntityManager","get","with","table1","table2","join","through","inflection","joinTable","singularize","fields","joinTables","includes","field","isBelongsToOneRelationProp","isOneToOneRelationProp","hasJoinColumn","idColumnName","useConstraint","underscore","pluralize","toLowerCase","concat"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/migration/migrator.ts"],"sourcesContent":["import _ from \"lodash\";\nimport knex, { Knex } from \"knex\";\nimport chalk from \"chalk\";\nimport { DateTime } from \"luxon\";\nimport { mkdir, readdir, unlink, writeFile } from \"fs/promises\";\nimport { exists } from \"../utils/fs-utils\";\nimport prompts from \"prompts\";\nimport { execSync } from \"child_process\";\nimport path from \"path\";\nimport { GenMigrationCode, MigrationSet } from \"../types/types\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport { Sonamu } from \"../api\";\nimport { ServiceUnavailableException } from \"../exceptions/so-exceptions\";\nimport { SonamuDBConfig } from \"../database/db\";\nimport { generateCreateCode, generateAlterCode } from \"./code-generation\";\nimport { MigrationStatus, MigrationCode, ConnString } from \"./types\";\nimport { getMigrationSetFromDB } from \"./migration-set\";\nimport { getMigrationSetFromEntity } from \"./migration-set\";\n\ntype MigratorMode = \"dev\" | \"deploy\";\nexport type MigratorOptions = {\n readonly mode: MigratorMode;\n};\n\nexport class Migrator {\n targets: {\n compare?: Knex;\n pending: Knex;\n shadow: Knex;\n apply: Knex[];\n };\n\n constructor(private readonly options: MigratorOptions) {\n const { dbConfig } = Sonamu;\n\n if (this.options.mode === \"dev\") {\n const devDB = knex(dbConfig.development_master);\n const testDB = knex(dbConfig.test);\n const fixtureLocalDB = knex(dbConfig.fixture_local);\n\n const applyDBs = [devDB, testDB, fixtureLocalDB];\n if (\n (dbConfig.fixture_local.connection as Knex.MySql2ConnectionConfig)\n .host !==\n (dbConfig.fixture_remote.connection as Knex.MySql2ConnectionConfig)\n .host ||\n (dbConfig.fixture_local.connection as Knex.MySql2ConnectionConfig)\n .database !==\n (dbConfig.fixture_remote.connection as Knex.MySql2ConnectionConfig)\n .database\n ) {\n const fixtureRemoteDB = knex(dbConfig.fixture_remote);\n applyDBs.push(fixtureRemoteDB);\n }\n\n this.targets = {\n compare: devDB,\n pending: devDB,\n shadow: testDB,\n apply: applyDBs,\n };\n } else if (this.options.mode === \"deploy\") {\n const productionDB = knex(dbConfig.production_master);\n const testDB = knex(dbConfig.test);\n\n this.targets = {\n pending: productionDB,\n shadow: testDB,\n apply: [productionDB],\n };\n } else {\n throw new Error(`잘못된 모드 ${this.options.mode} 입력`);\n }\n }\n\n private async getMigrationCodes(): Promise<{\n normal: MigrationCode[];\n onlyTs: MigrationCode[];\n onlyJs: MigrationCode[];\n }> {\n const srcMigrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n const distMigrationsDir = `${Sonamu.apiRootPath}/dist/migrations`;\n\n if (!(await exists(srcMigrationsDir))) {\n await mkdir(srcMigrationsDir, {\n recursive: true,\n });\n }\n if (!(await exists(distMigrationsDir))) {\n await mkdir(distMigrationsDir, {\n recursive: true,\n });\n }\n const srcMigrations = (await readdir(srcMigrationsDir))\n .filter((f) => f.endsWith(\".ts\"))\n .map((f) => f.split(\".\")[0]);\n const distMigrations = (await readdir(distMigrationsDir))\n .filter((f) => f.endsWith(\".js\"))\n .map((f) => f.split(\".\")[0]);\n\n const normal = _.intersection(srcMigrations, distMigrations)\n .map((filename) => {\n return {\n name: filename,\n path: path.join(srcMigrationsDir, filename) + \".ts\",\n };\n })\n .sort((a, b) => (a > b ? 1 : -1));\n\n const onlyTs = _.difference(srcMigrations, distMigrations).map(\n (filename) => {\n return {\n name: filename,\n path: path.join(srcMigrationsDir, filename) + \".ts\",\n };\n }\n );\n\n const onlyJs = _.difference(distMigrations, srcMigrations).map(\n (filename) => {\n return {\n name: filename,\n path: path.join(distMigrationsDir, filename) + \".js\",\n };\n }\n );\n\n return {\n normal,\n onlyTs,\n onlyJs,\n };\n }\n\n /**\n * 타겟별 마이그레이션 상태와 코드 생성/준비 상태를 구해옵니다.\n * 실제로 DB에 접근도 하고 마이그레이션 코드 파일도 확인하고,\n * 필요하다면 적용할 수 있는 코드를 생성까지 해옵니다.\n *\n * CLI와 Sonamu UI에서 사용됩니다.\n *\n * @returns\n */\n async getStatus(): Promise<MigrationStatus> {\n const { normal, onlyTs, onlyJs } = await this.getMigrationCodes();\n if (onlyTs.length > 0) {\n console.debug({ onlyTs });\n throw new ServiceUnavailableException(\n `There are un-compiled TS migration files.\\nPlease compile them first. You might want to run a development server with HMR.\\n\\n${onlyTs\n .map((f) => f.name)\n .join(\"\\n\")}`\n );\n }\n if (onlyJs.length > 0) {\n console.debug({ onlyJs });\n await Promise.all(\n onlyJs.map(async (f) => {\n execSync(\n `rm -f ${f.path.replace(\"/src/\", \"/dist/\").replace(\".ts\", \".js\")}`\n );\n })\n );\n }\n\n const connKeys = Object.keys(Sonamu.dbConfig).filter(\n (key) => key.endsWith(\"_slave\") === false\n ) as (keyof typeof Sonamu.dbConfig)[];\n\n const statuses = await Promise.all(\n connKeys.map(async (connKey) => {\n const knexOptions = Sonamu.dbConfig[connKey];\n const tConn = knex(knexOptions);\n\n const status = await (async () => {\n try {\n return await tConn.migrate.status();\n } catch (err) {\n console.warn(\n chalk.yellow(\n `${connKey}의 마이그레이션 상태를 가져오는 데에 실패하였습니다. 데이터베이스가 올바르게 구성되지 않은 것 같습니다. 확인하시고 다시 시도해주세요.\\n시도한 연결 설정:\\n${JSON.stringify(knexOptions.connection, null, 2)}\\n발생한 에러:\\n${err}\\n`\n )\n );\n return \"error\" /*클라이언트에서 에러 체크에 사용하는 리터럴입니다.*/;\n }\n })();\n const pending = await (async () => {\n try {\n const [, fdList] = await tConn.migrate.list();\n return fdList.map((fd: { file: string }) =>\n fd.file.replace(\".js\", \"\")\n );\n } catch (err) {\n return [];\n }\n })();\n const currentVersion = await (async () => {\n try {\n return await tConn.migrate.currentVersion();\n } catch (err) {\n return \"error\";\n }\n })();\n\n const connection =\n knexOptions.connection as Knex.MySql2ConnectionConfig;\n\n await tConn.destroy();\n\n return {\n name: connKey.replace(\"_master\", \"\"),\n connKey,\n connString: `mysql2://${connection.user ?? \"\"}@${connection.host}:${\n connection.port\n }/${connection.database}` as ConnString,\n currentVersion,\n status,\n pending,\n };\n })\n );\n\n const preparedCodes: GenMigrationCode[] = await (async () => {\n const status0conn = statuses.find((status) => status.status === 0);\n if (status0conn === undefined) {\n return [];\n }\n\n const compareDBconn = knex(Sonamu.dbConfig[status0conn.connKey]);\n const genCodes = await this.compareMigrations(compareDBconn);\n\n await compareDBconn.destroy();\n\n return genCodes;\n })();\n\n return {\n conns: statuses,\n codes: normal,\n preparedCodes,\n };\n /*\n TS/JS 코드 컴파일 상태 확인\n 1. 원본 파일 없는 JS파일이 존재하는 경우: 삭제\n 2. 컴파일 되지 않은 TS파일이 존재하는 경우: throw 쳐서 데브 서버 오픈 요청\n \n DB 마이그레이션 상태 확인\n 1. 전체 DB설정에 대해서 현재 마이그레이션 상태 확인\n - connKey: string\n - status: number\n - currentVersion: string\n - list: { file: string; directory: string }[]\n \n */\n }\n\n /**\n * 마이그레이션을 적용하거나 롤백합니다.\n * Sonamu UI에서 마이그레이션 작업을 수행할 때 사용됩니다.\n *\n * CLI와 Sonamu UI에서 사용됩니다.\n *\n * @param action 작업 유형 (apply/rollback)\n * @param targets 작업 대상 DB 설정 키 (keyof SonamuDBConfig)\n * @returns 작업 결과\n */\n async runAction(\n action: \"apply\" | \"rollback\",\n targets: (keyof SonamuDBConfig)[]\n ): Promise<\n {\n connKey: string;\n batchNo: number;\n applied: string[];\n }[]\n > {\n // get uniq knex configs\n const configs = _.uniqBy(\n targets\n .map((target) => ({\n connKey: target,\n options: Sonamu.dbConfig[target as keyof typeof Sonamu.dbConfig],\n }))\n .filter((c) => c.options !== undefined),\n ({ options }) =>\n `${(options.connection as Knex.MySql2ConnectionConfig).host}:${\n (options.connection as Knex.MySql2ConnectionConfig).port ?? 3306\n }/${(options.connection as Knex.MySql2ConnectionConfig).database}`\n );\n\n // get connections\n const conns = await Promise.all(\n configs.map(async (config) => ({\n connKey: config.connKey,\n knex: knex(config.options),\n }))\n );\n\n // action\n const result = await (async () => {\n switch (action) {\n case \"apply\":\n return Promise.all(\n conns.map(async ({ connKey, knex }) => {\n const [batchNo, applied] = await knex.migrate.latest();\n return {\n connKey,\n batchNo,\n applied,\n };\n })\n );\n case \"rollback\":\n return Promise.all(\n conns.map(async ({ connKey, knex }) => {\n const [batchNo, applied] = await knex.migrate.rollback();\n return {\n connKey,\n batchNo,\n applied,\n };\n })\n );\n }\n })();\n\n // destroy\n await Promise.all(\n conns.map(({ knex }) => {\n return knex.destroy();\n })\n );\n\n return result;\n }\n\n /**\n * 마이그레이션 코드 파일을 삭제합니다.\n *\n * Sonamu UI에서 사용됩니다.\n *\n * @param codeNames 삭제할 마이그레이션 코드 파일 이름 배열\n * @returns 삭제된 마이그레이션 코드 파일 개수\n */\n async delCodes(codeNames: string[]): Promise<number> {\n const { conns } = await this.getStatus();\n if (\n conns.some((conn) => {\n return codeNames.some(\n (codeName) => conn.pending.includes(codeName) === false\n );\n })\n ) {\n throw new Error(\n \"You cannot delete a migration file if there is already applied.\"\n );\n }\n\n const delFiles = codeNames\n .map((codeName) => [\n `${Sonamu.apiRootPath}/src/migrations/${codeName}.ts`,\n `${Sonamu.apiRootPath}/dist/migrations/${codeName}.js`,\n ])\n .flat();\n\n const res = await Promise.all(\n delFiles.map(async (delFile) => {\n if (await exists(delFile)) {\n console.log(chalk.red(`DELETE: ${delFile}`));\n await unlink(delFile);\n return delFiles.includes(\".ts\") ? 1 : 0;\n }\n return 0;\n })\n );\n return _.sum(res);\n }\n\n /**\n * 마이그레이션 코드 파일을 생성합니다.\n *\n * Sonamu UI에서 사용됩니다.\n *\n * @returns 생성된 마이그레이션 코드 파일 개수\n */\n async generatePreparedCodes(): Promise<number> {\n const { preparedCodes } = await this.getStatus();\n if (preparedCodes.length === 0) {\n console.log(chalk.green(\"\\n현재 모두 싱크된 상태입니다.\"));\n return 0;\n }\n\n // 실제 코드 생성\n const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n\n for (const [index, pcode] of preparedCodes.entries()) {\n if (pcode.formatted) {\n const dateTag = DateTime.local()\n .plus({ seconds: index })\n .toFormat(\"yyyyMMddHHmmss\");\n const filePath = `${migrationsDir}/${dateTag}_${pcode.title}.ts`;\n await writeFile(filePath, pcode.formatted!);\n console.log(chalk.green(`MIGRTAION CREATED ${filePath}`));\n }\n }\n\n return preparedCodes.length;\n }\n\n /**\n * pending 마이그레이션 목록을 삭제합니다.\n *\n * CLI에서 사용됩니다.\n */\n async clearPendingList(): Promise<void> {\n const [, pendingList] = (await this.targets.pending.migrate.list()) as [\n unknown,\n {\n file: string;\n directory: string;\n }[],\n ];\n const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n const delList = pendingList.map((df) => {\n return path.join(migrationsDir, df.file).replace(\".js\", \".ts\");\n });\n for (let p of delList) {\n if (await exists(p)) {\n await unlink(p);\n }\n }\n await this.cleanUpDist(true);\n }\n\n /**\n * 마이그레이션 코드 파일을 확인합니다.\n *\n * CLI에서 사용됩니다.\n */\n async check(): Promise<void> {\n const codes = await this.compareMigrations(this.targets.compare!);\n if (codes.length === 0) {\n console.log(chalk.green(\"\\n현재 모두 싱크된 상태입니다.\"));\n return;\n }\n\n // 현재 생성된 코드 표기\n console.table(codes, [\"type\", \"title\"]);\n console.log(codes[0]);\n }\n\n /**\n * 마이그레이션을 수행합니다.\n *\n * runAction이 인자로 들어온 타겟들에 대해 주어진 동작(apply/rollback)을 수행한다면,\n * 이 함수는 생성자로 들어온 connection(knex)들에 대해 마이그레이션을 수행합니다.\n *\n * CLI에서 사용됩니다.\n */\n async run(): Promise<void> {\n // pending 마이그레이션 확인\n const [, pendingList] = await this.targets.pending.migrate.list();\n if (pendingList.length > 0) {\n console.log(\n chalk.red(\"pending 된 마이그레이션이 존재합니다.\"),\n pendingList.map((pending: any) => pending.file)\n );\n\n // pending이 있는 경우 Shadow DB 테스트 진행 여부 컨펌\n const answer = await prompts({\n type: \"confirm\",\n name: \"value\",\n message: \"Shadow DB 테스트를 진행하시겠습니까?\",\n initial: true,\n });\n if (answer.value === false) {\n return;\n }\n\n console.time(chalk.blue(\"Migrator - runShadowTest\"));\n await this.runShadowTest();\n console.timeEnd(chalk.blue(\"Migrator - runShadowTest\"));\n await Promise.all(\n this.targets.apply.map(async (applyDb) => {\n const label = chalk.green(\n `APPLIED ${\n applyDb.client.connectionSettings.host\n } ${applyDb.client.database()}`\n );\n console.time(label);\n const [,] = await applyDb.migrate.latest();\n console.timeEnd(label);\n })\n );\n }\n\n // Entity-DB간 비교하여 코드 생성 리턴\n const codes = await this.compareMigrations(this.targets.compare!);\n if (codes.length === 0) {\n console.log(chalk.green(\"\\n현재 모두 싱크된 상태입니다.\"));\n return;\n }\n\n // 현재 생성된 코드 표기\n console.table(codes, [\"type\", \"title\"]);\n\n /* DEBUG: 디버깅용 코드\n codes.map((code) => console.log(code.formatted));\n process.exit();\n */\n\n // 실제 파일 생성 프롬프트\n const answer = await prompts({\n type: \"confirm\",\n name: \"value\",\n message: \"마이그레이션 코드를 생성하시겠습니까?\",\n initial: false,\n });\n if (answer.value === false) {\n return;\n }\n\n // 실제 코드 생성\n const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n\n for (const [index, code] of codes.entries()) {\n if (code.formatted) {\n const dateTag = DateTime.local()\n .plus({ seconds: index })\n .toFormat(\"yyyyMMddHHmmss\");\n const filePath = `${migrationsDir}/${dateTag}_${code.title}.ts`;\n await writeFile(filePath, code.formatted!);\n console.log(chalk.green(`MIGRTAION CREATED ${filePath}`));\n }\n }\n }\n\n /**\n * 타겟으로 지정된 DB를 롤백합니다.\n *\n * runAction이 인자로 들어온 타겟들에 대해 주어진 동작(apply/rollback)을 수행한다면,\n * 이 함수는 생성자로 들어온 connection(knex)들에 대해 롤백을 수행합니다.\n *\n * CLI에서 사용됩니다.\n */\n async rollback() {\n console.time(chalk.red(\"rollback:\"));\n const rollbackAllResult = await Promise.all(\n this.targets.apply.map(async (db) => {\n await db.migrate.forceFreeMigrationsLock();\n return db.migrate.rollback(undefined, false);\n })\n );\n console.dir({ rollbackAllResult }, { depth: null });\n console.timeEnd(chalk.red(\"rollback:\"));\n }\n\n /**\n * 빌드된 마이그레이션 파일을 삭제합니다.\n *\n * CLI에서 사용됩니다.\n *\n * @param force 강제 삭제 여부\n * @returns\n */\n async cleanUpDist(force: boolean = false): Promise<void> {\n async function getFilesUnder(dir: string): Promise<string[]> {\n const migrationPath = path.join(Sonamu.apiRootPath, dir, \"migrations\");\n if (!(await exists(migrationPath))) {\n await mkdir(migrationPath, {\n recursive: true,\n });\n }\n return (await readdir(migrationPath)).filter(\n (filename) => filename.startsWith(\".\") === false\n );\n }\n\n const files = {\n src: await getFilesUnder(\"src\"),\n dist: await getFilesUnder(\"dist\"),\n };\n\n const diffOnSrc = _.differenceBy(\n files.src,\n files.dist,\n (filename) => filename.split(\".\")[0]\n );\n if (diffOnSrc.length > 0) {\n throw new Error(\n \"컴파일 되지 않은 파일이 있습니다.\\n\" + diffOnSrc.join(\"\\n\")\n );\n }\n\n const diffOnDist = _.differenceBy(\n files.dist,\n files.src,\n (filename) => filename.split(\".\")[0]\n );\n if (diffOnDist.length > 0) {\n console.log(chalk.red(\"원본 ts파일을 찾을 수 없는 js파일이 있습니다.\"));\n console.log(diffOnDist);\n\n if (!force) {\n const answer = await prompts({\n type: \"confirm\",\n name: \"value\",\n message: \"삭제를 진행하시겠습니까?\",\n initial: true,\n });\n if (answer.value === false) {\n return;\n }\n }\n\n const filesToRm = diffOnDist.map((filename) => {\n return path.join(Sonamu.apiRootPath, \"dist\", \"migrations\", filename);\n });\n for (const filePath of filesToRm) {\n await unlink(filePath);\n }\n console.log(chalk.green(`${filesToRm.length}건 삭제되었습니다!`));\n }\n }\n\n /**\n * Shadow DB 테스트를 진행합니다.\n *\n * Sonamu UI에서 사용됩니다.\n *\n * @returns Shadow DB 테스트 결과\n */\n async runShadowTest(): Promise<\n {\n connKey: string;\n batchNo: number;\n applied: string[];\n }[]\n > {\n // ShadowDB 생성 후 테스트 진행\n const tdb = knex(Sonamu.dbConfig.test);\n const tdbConn = Sonamu.dbConfig.test\n .connection as Knex.MySql2ConnectionConfig;\n const shadowDatabase = tdbConn.database + \"__migration_shadow\";\n const tmpSqlPath = `/tmp/${shadowDatabase}.sql`;\n\n // 테스트DB 덤프 후 Database명 치환\n console.log(\n chalk.magenta(`${tdbConn.database}의 데이터 ${tmpSqlPath}로 덤프`)\n );\n execSync(\n `mysqldump -h${tdbConn.host} -P${tdbConn.port ?? 3306} -u${tdbConn.user} -p'${tdbConn.password}' ${tdbConn.database} --single-transaction --no-create-db --triggers > ${tmpSqlPath};`\n );\n execSync(\n `sed -i'' -e 's/\\`${tdbConn.database}\\`/\\`${shadowDatabase}\\`/g' ${tmpSqlPath};`\n );\n\n // 기존 ShadowDB 리셋\n console.log(chalk.magenta(`${shadowDatabase} 리셋`));\n await tdb.raw(`DROP DATABASE IF EXISTS \\`${shadowDatabase}\\`;`);\n await tdb.raw(`CREATE DATABASE \\`${shadowDatabase}\\`;`);\n\n // ShadowDB 테이블 + 데이터 생성\n console.log(chalk.magenta(`${shadowDatabase} 데이터베이스 생성`));\n execSync(\n `mysql -h${tdbConn.host} -P${tdbConn.port ?? 3306} -u${tdbConn.user} -p'${tdbConn.password}' ${shadowDatabase} < ${tmpSqlPath};`\n );\n\n // shadow db 테스트 진행\n const sdb = knex({\n ...Sonamu.dbConfig.test,\n connection: {\n ...tdbConn,\n database: shadowDatabase,\n password: tdbConn.password,\n },\n });\n\n // shadow db 테스트 진행\n try {\n const [batchNo, applied] = await sdb.migrate.latest();\n console.log(chalk.green(\"Shadow DB 테스트에 성공했습니다!\"), {\n batchNo,\n applied,\n });\n\n // 생성한 Shadow DB 삭제\n console.log(chalk.magenta(`${shadowDatabase} 삭제`));\n await tdb.raw(`DROP DATABASE IF EXISTS \\`${shadowDatabase}\\`;`);\n\n return [\n {\n connKey: \"shadow\",\n batchNo,\n applied,\n },\n ];\n } catch (e) {\n console.error(e);\n throw new ServiceUnavailableException(\"Shadow DB 테스트 진행 중 에러\");\n } finally {\n await tdb.destroy();\n }\n }\n\n /**\n * 모든 DB를 롤백하고 전체 마이그레이션 파일을 삭제합니다.\n *\n * CLI에서 사용됩니다.\n *\n * @returns\n */\n async resetAll() {\n const answer = await prompts({\n type: \"confirm\",\n name: \"value\",\n message: \"모든 DB를 롤백하고 전체 마이그레이션 파일을 삭제하시겠습니까?\",\n initial: false,\n });\n if (answer.value === false) {\n return;\n }\n\n console.time(chalk.red(\"rollback-all:\"));\n const rollbackAllResult = await Promise.all(\n this.targets.apply.map(async (db) => {\n await db.migrate.forceFreeMigrationsLock();\n return db.migrate.rollback(undefined, true);\n })\n );\n console.log({ rollbackAllResult });\n console.timeEnd(chalk.red(\"rollback-all:\"));\n\n const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n console.time(chalk.red(\"delete migration files\"));\n execSync(`rm -f ${migrationsDir}/*`);\n execSync(`rm -f ${migrationsDir.replace(\"/src/\", \"/dist/\")}/*`);\n console.timeEnd(chalk.red(\"delete migration files\"));\n }\n\n private async compareMigrations(\n compareDB: Knex\n ): Promise<GenMigrationCode[]> {\n // Entity 순회하여 싱크\n const entityIds = EntityManager.getAllIds();\n\n // 조인테이블 포함하여 Entity에서 MigrationSet 추출\n const entitySetsWithJoinTable = entityIds\n .filter((entityId) => EntityManager.get(entityId).props.length > 0)\n .map((entityId) =>\n getMigrationSetFromEntity(EntityManager.get(entityId))\n );\n\n // 조인테이블만 추출\n const joinTablesWithDup = entitySetsWithJoinTable\n .map((entitySet) => entitySet.joinTables)\n .flat();\n // 중복 제거 (중복인 경우 indexes를 병합)\n const joinTables = Object.values(\n _.groupBy(joinTablesWithDup, (jt) => jt.table)\n ).map((tables) => {\n if (tables.length === 1) {\n return tables[0];\n }\n return {\n ...tables[0],\n indexes: _.uniqBy(\n tables.flatMap((t) => t.indexes),\n (index) => [index.type, ...index.columns.sort()].join(\"-\")\n ),\n };\n });\n\n // 조인테이블 포함하여 MigrationSet 배열\n const entitySets: MigrationSet[] = [\n ...entitySetsWithJoinTable,\n ...joinTables,\n ];\n\n const codes: GenMigrationCode[] = (\n await Promise.all(\n entitySets.map(async (entitySet) => {\n const dbSet = await getMigrationSetFromDB(compareDB, entitySet.table);\n\n if (dbSet === null) {\n // 기존 테이블 없음, 새로 테이블 생성\n return await generateCreateCode(entitySet);\n } else {\n // 기존 테이블 존재하는 케이스\n return await generateAlterCode(entitySet, dbSet);\n }\n })\n )\n ).flat();\n\n // normal 타입이 앞으로, foreign이 뒤로\n codes.sort((codeA, codeB) => {\n if (codeA.type === \"foreign\" && codeB.type == \"normal\") {\n return 1;\n } else if (codeA.type === \"normal\" && codeB.type === \"foreign\") {\n return -1;\n } else {\n return 0;\n }\n });\n\n return codes;\n }\n\n /**\n * 마이그레이션 대상 커넥션을 종료합니다.\n *\n * CLI에서 사용됩니다.\n *\n * @returns {Promise<void>} 종료 결과\n */\n async destroy(): Promise<void> {\n await Promise.all(\n this.targets.apply.map((db) => {\n return db.destroy();\n })\n );\n }\n}\n"],"names":["Migrator","options","targets","dbConfig","Sonamu","mode","devDB","knex","development_master","testDB","test","fixtureLocalDB","fixture_local","applyDBs","connection","host","fixture_remote","database","fixtureRemoteDB","push","compare","pending","shadow","apply","productionDB","production_master","Error","getMigrationCodes","srcMigrationsDir","distMigrationsDir","srcMigrations","distMigrations","normal","onlyTs","onlyJs","apiRootPath","exists","mkdir","recursive","readdir","filter","f","endsWith","map","split","_","intersection","filename","name","path","join","sort","a","b","difference","getStatus","connKeys","statuses","preparedCodes","length","console","debug","ServiceUnavailableException","Promise","all","execSync","replace","Object","keys","key","connKey","knexOptions","tConn","status","currentVersion","err","migrate","warn","chalk","yellow","JSON","stringify","fdList","list","fd","file","destroy","connString","user","port","status0conn","compareDBconn","genCodes","find","undefined","compareMigrations","conns","codes","runAction","action","configs","result","uniqBy","target","c","config","batchNo","applied","latest","rollback","delCodes","codeNames","delFiles","res","some","conn","codeName","includes","flat","delFile","log","red","unlink","sum","generatePreparedCodes","migrationsDir","index","pcode","dateTag","filePath","green","entries","formatted","DateTime","local","plus","seconds","toFormat","title","writeFile","clearPendingList","pendingList","delList","p","df","cleanUpDist","check","table","run","answer","code","prompts","type","message","initial","value","time","blue","runShadowTest","timeEnd","applyDb","label","client","connectionSettings","rollbackAllResult","db","forceFreeMigrationsLock","dir","depth","force","files","diffOnSrc","diffOnDist","filesToRm","getFilesUnder","migrationPath","startsWith","src","dist","differenceBy","tdb","tdbConn","shadowDatabase","tmpSqlPath","sdb","e","magenta","password","raw","error","resetAll","compareDB","entityIds","entitySetsWithJoinTable","joinTablesWithDup","joinTables","entitySets","EntityManager","getAllIds","entityId","get","props","getMigrationSetFromEntity","entitySet","values","groupBy","jt","tables","indexes","flatMap","t","columns","dbSet","getMigrationSetFromDB","generateCreateCode","generateAlterCode","codeA","codeB"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/migration/types.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/stream/index.ts"],"sourcesContent":["export * from \"./sse\";\n"],"names":[],"mappings":"2FAAc"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/stream/sse.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type { FastifyRequest, FastifyReply } from \"fastify\";\n\n// NOTE(Haze, 251106): context provider에서 인자를 채워주면 createSSE(events)만으로 사용 가능\nexport function createSSEFactory<T extends z.ZodObject>(\n socket: FastifyRequest[\"socket\"],\n reply: FastifyReply,\n _events: T\n) {\n return new SSEConnection<T>(socket, reply);\n}\n\nclass SSEConnection<T extends z.ZodObject> {\n private _closed = false;\n\n constructor(\n private readonly socket: FastifyRequest[\"socket\"],\n private readonly reply: FastifyReply\n ) {\n this.socket.on(\"close\", () => {\n this._closed = true;\n });\n }\n\n publish<K extends keyof z.infer<T>>(event: K, data: z.infer<T>[K]): void {\n if (this._closed) {\n return;\n }\n\n this.reply.sse({\n event: event as string,\n data: JSON.stringify(data),\n });\n }\n\n async end(): Promise<void> {\n if (this._closed) {\n return;\n }\n\n this.reply.sse({\n event: \"end\",\n data: \"END\",\n });\n \n await new Promise((resolve) => setTimeout(resolve, 200));\n this.reply.raw.end();\n }\n}\n"],"names":["createSSEFactory","socket","reply","_events","SSEConnection","_closed","on","publish","event","data","sse","JSON","stringify","end","Promise","resolve","setTimeout","raw"],"mappings":"oGAIgBA,0DAAAA,qmFAAT,SAASA,iBACdC,MAAgC,CAChCC,KAAmB,CACnBC,OAAU,EAEV,OAAO,IAAIC,cAAiBH,OAAQC,MACtC,CAEA,IAAA,AAAME,2BAAN,iCAAMA,cAIF,AAAiBH,MAAgC,CACjD,AAAiBC,KAAmB,wCALlCE,4FACJ,sBAAQC,UAAR,KAAA,QAGmBJ,OAAAA,YACAC,MAAAA,WAJXG,QAAU,MAMhB,IAAI,CAACJ,MAAM,CAACK,EAAE,CAAC,QAAS,WACtB,MAAKD,OAAO,CAAG,IACjB,iBATED,gBAYJG,IAAAA,gBAAAA,SAAAA,QAAoCC,KAAQ,CAAEC,IAAmB,EAC/D,GAAI,IAAI,CAACJ,OAAO,CAAE,CAChB,MACF,CAEA,IAAI,CAACH,KAAK,CAACQ,GAAG,CAAC,CACbF,MAAOA,MACPC,KAAME,KAAKC,SAAS,CAACH,KACvB,EACF,IAEMI,IAAAA,YAAN,SAAMA,mHACJ,GAAI,IAAI,CAACR,OAAO,CAAE,CAChB,SACF,CAEA,IAAI,CAACH,KAAK,CAACQ,GAAG,CAAC,CACbF,MAAO,MACPC,KAAM,KACR,GAEA,SAAM,IAAIK,QAAQ,SAACC,gBAAYC,WAAWD,QAAS,eAAnD,cACA,IAAI,CAACb,KAAK,CAACe,GAAG,CAACJ,GAAG,eACpB,yBAnCIT"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/syncer/index.ts"],"sourcesContent":["export * from \"./syncer\";\n"],"names":[],"mappings":"2FAAc"}