sonamu 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (406) hide show
  1. package/.swcrc.project-default +18 -0
  2. package/bin/cli.js +24 -0
  3. package/dist/ai/agents/agent.d.ts +11 -0
  4. package/dist/ai/agents/agent.d.ts.map +1 -0
  5. package/dist/ai/agents/agent.js +65 -0
  6. package/dist/ai/agents/index.d.ts +3 -0
  7. package/dist/ai/agents/index.d.ts.map +1 -0
  8. package/dist/ai/agents/index.js +4 -0
  9. package/dist/ai/agents/types.d.ts +43 -0
  10. package/dist/ai/agents/types.d.ts.map +1 -0
  11. package/dist/ai/agents/types.js +3 -0
  12. package/dist/ai/index.d.ts +2 -0
  13. package/dist/ai/index.d.ts.map +1 -0
  14. package/dist/ai/index.js +3 -0
  15. package/dist/ai/providers/rtzr/api.d.ts +22 -0
  16. package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
  17. package/dist/ai/providers/rtzr/api.js +28 -0
  18. package/dist/ai/providers/rtzr/error.d.ts +18 -0
  19. package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
  20. package/dist/ai/providers/rtzr/error.js +29 -0
  21. package/dist/ai/providers/rtzr/index.d.ts +5 -0
  22. package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
  23. package/dist/ai/providers/rtzr/index.js +6 -0
  24. package/dist/ai/providers/rtzr/model.d.ts +52 -0
  25. package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
  26. package/dist/ai/providers/rtzr/model.js +137 -0
  27. package/dist/ai/providers/rtzr/options.d.ts +7 -0
  28. package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
  29. package/dist/ai/providers/rtzr/options.js +47 -0
  30. package/dist/ai/providers/rtzr/provider.d.ts +18 -0
  31. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
  32. package/dist/ai/providers/rtzr/provider.js +54 -0
  33. package/dist/ai/providers/rtzr/utils.d.ts +19 -0
  34. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
  35. package/dist/ai/providers/rtzr/utils.js +88 -0
  36. package/dist/api/base-frame.d.ts +2 -2
  37. package/dist/api/base-frame.d.ts.map +1 -1
  38. package/dist/api/base-frame.js +2 -1
  39. package/dist/api/caster.d.ts.map +1 -1
  40. package/dist/api/caster.js +6 -1
  41. package/dist/api/code-converters.d.ts +58 -14
  42. package/dist/api/code-converters.d.ts.map +1 -1
  43. package/dist/api/code-converters.js +178 -409
  44. package/dist/api/config.d.ts +27 -13
  45. package/dist/api/config.d.ts.map +1 -1
  46. package/dist/api/config.js +19 -26
  47. package/dist/api/context.d.ts +4 -3
  48. package/dist/api/context.d.ts.map +1 -1
  49. package/dist/api/context.js +1 -1
  50. package/dist/api/decorators.d.ts +20 -6
  51. package/dist/api/decorators.d.ts.map +1 -1
  52. package/dist/api/decorators.js +111 -18
  53. package/dist/api/index.d.ts +2 -2
  54. package/dist/api/index.d.ts.map +1 -1
  55. package/dist/api/index.js +3 -3
  56. package/dist/api/sonamu.d.ts +7 -7
  57. package/dist/api/sonamu.d.ts.map +1 -1
  58. package/dist/api/sonamu.js +83 -51
  59. package/dist/api/validator.d.ts +6 -0
  60. package/dist/api/validator.d.ts.map +1 -0
  61. package/dist/api/validator.js +81 -0
  62. package/dist/bin/build-config.d.ts +5 -1
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +5 -2
  65. package/dist/bin/cli.js +165 -64
  66. package/dist/bin/loader-register.d.ts +2 -0
  67. package/dist/bin/loader-register.d.ts.map +1 -0
  68. package/dist/bin/loader-register.js +34 -0
  69. package/dist/database/_batch_update.d.ts +5 -3
  70. package/dist/database/_batch_update.d.ts.map +1 -1
  71. package/dist/database/_batch_update.js +30 -13
  72. package/dist/database/base-model.d.ts +96 -10
  73. package/dist/database/base-model.d.ts.map +1 -1
  74. package/dist/database/base-model.js +232 -89
  75. package/dist/database/base-model.types.d.ts +93 -0
  76. package/dist/database/base-model.types.d.ts.map +1 -0
  77. package/dist/database/base-model.types.js +10 -0
  78. package/dist/database/code-generator.d.ts +1 -1
  79. package/dist/database/code-generator.d.ts.map +1 -1
  80. package/dist/database/code-generator.js +11 -10
  81. package/dist/database/db.d.ts +5 -6
  82. package/dist/database/db.d.ts.map +1 -1
  83. package/dist/database/db.js +22 -25
  84. package/dist/database/puri-subset.test-d.js +81 -0
  85. package/dist/database/puri-subset.types.d.ts +123 -0
  86. package/dist/database/puri-subset.types.d.ts.map +1 -0
  87. package/dist/database/puri-subset.types.js +16 -0
  88. package/dist/database/puri-wrapper.d.ts +13 -11
  89. package/dist/database/puri-wrapper.d.ts.map +1 -1
  90. package/dist/database/puri-wrapper.js +2 -2
  91. package/dist/database/puri.d.ts +25 -14
  92. package/dist/database/puri.d.ts.map +1 -1
  93. package/dist/database/puri.js +83 -21
  94. package/dist/database/puri.types.d.ts +21 -7
  95. package/dist/database/puri.types.d.ts.map +1 -1
  96. package/dist/database/puri.types.js +4 -1
  97. package/dist/database/transaction-context.d.ts +1 -1
  98. package/dist/database/transaction-context.d.ts.map +1 -1
  99. package/dist/database/transaction-context.js +1 -1
  100. package/dist/database/upsert-builder.d.ts +9 -3
  101. package/dist/database/upsert-builder.d.ts.map +1 -1
  102. package/dist/database/upsert-builder.js +227 -78
  103. package/dist/entity/entity-manager.d.ts +165 -2
  104. package/dist/entity/entity-manager.d.ts.map +1 -1
  105. package/dist/entity/entity-manager.js +26 -10
  106. package/dist/entity/entity.d.ts +5 -3
  107. package/dist/entity/entity.d.ts.map +1 -1
  108. package/dist/entity/entity.js +153 -54
  109. package/dist/exceptions/error-handler.d.ts +1 -1
  110. package/dist/exceptions/error-handler.d.ts.map +1 -1
  111. package/dist/exceptions/error-handler.js +1 -1
  112. package/dist/exceptions/so-exceptions.d.ts +1 -1
  113. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  114. package/dist/exceptions/so-exceptions.js +1 -1
  115. package/dist/file-storage/driver.d.ts +1 -1
  116. package/dist/file-storage/driver.d.ts.map +1 -1
  117. package/dist/file-storage/driver.js +1 -1
  118. package/dist/file-storage/file-storage.js +2 -2
  119. package/dist/index.d.ts +18 -11
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +19 -13
  122. package/dist/migration/code-generation.d.ts +1 -1
  123. package/dist/migration/code-generation.d.ts.map +1 -1
  124. package/dist/migration/code-generation.js +123 -67
  125. package/dist/migration/migration-set.d.ts +2 -10
  126. package/dist/migration/migration-set.d.ts.map +1 -1
  127. package/dist/migration/migration-set.js +67 -218
  128. package/dist/migration/migrator.d.ts +24 -73
  129. package/dist/migration/migrator.d.ts.map +1 -1
  130. package/dist/migration/migrator.js +121 -301
  131. package/dist/migration/postgresql-schema-reader.d.ts +51 -0
  132. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
  133. package/dist/migration/postgresql-schema-reader.js +245 -0
  134. package/dist/migration/types.d.ts +6 -38
  135. package/dist/migration/types.d.ts.map +1 -1
  136. package/dist/migration/types.js +1 -1
  137. package/dist/naite/messaging-types.d.ts +43 -0
  138. package/dist/naite/messaging-types.d.ts.map +1 -0
  139. package/dist/naite/messaging-types.js +7 -0
  140. package/dist/naite/naite-reporter.d.ts +41 -0
  141. package/dist/naite/naite-reporter.d.ts.map +1 -0
  142. package/dist/naite/naite-reporter.js +102 -0
  143. package/dist/naite/naite.d.ts +91 -8
  144. package/dist/naite/naite.d.ts.map +1 -1
  145. package/dist/naite/naite.js +285 -41
  146. package/dist/stream/sse.d.ts +2 -2
  147. package/dist/stream/sse.d.ts.map +1 -1
  148. package/dist/stream/sse.js +1 -1
  149. package/dist/syncer/api-parser.d.ts +3 -13
  150. package/dist/syncer/api-parser.d.ts.map +1 -1
  151. package/dist/syncer/api-parser.js +67 -56
  152. package/dist/syncer/checksum.d.ts +2 -2
  153. package/dist/syncer/checksum.d.ts.map +1 -1
  154. package/dist/syncer/checksum.js +11 -11
  155. package/dist/syncer/code-generator.d.ts +3 -3
  156. package/dist/syncer/code-generator.d.ts.map +1 -1
  157. package/dist/syncer/code-generator.js +37 -17
  158. package/dist/syncer/entity-operations.d.ts +2 -2
  159. package/dist/syncer/entity-operations.d.ts.map +1 -1
  160. package/dist/syncer/entity-operations.js +9 -8
  161. package/dist/syncer/file-patterns.d.ts +1 -1
  162. package/dist/syncer/file-patterns.d.ts.map +1 -1
  163. package/dist/syncer/file-patterns.js +1 -1
  164. package/dist/syncer/index.d.ts +4 -4
  165. package/dist/syncer/index.d.ts.map +1 -1
  166. package/dist/syncer/index.js +5 -5
  167. package/dist/syncer/module-loader.d.ts +4 -4
  168. package/dist/syncer/module-loader.d.ts.map +1 -1
  169. package/dist/syncer/module-loader.js +17 -12
  170. package/dist/syncer/syncer.d.ts +31 -24
  171. package/dist/syncer/syncer.d.ts.map +1 -1
  172. package/dist/syncer/syncer.js +92 -45
  173. package/dist/template/entity-converter.d.ts +1 -1
  174. package/dist/template/entity-converter.d.ts.map +1 -1
  175. package/dist/template/entity-converter.js +15 -8
  176. package/dist/template/helpers.d.ts +2 -2
  177. package/dist/template/helpers.d.ts.map +1 -1
  178. package/dist/template/helpers.js +3 -3
  179. package/dist/template/implementations/entity.template.d.ts +2 -2
  180. package/dist/template/implementations/entity.template.d.ts.map +1 -1
  181. package/dist/template/implementations/entity.template.js +4 -5
  182. package/dist/template/implementations/generated.template.d.ts +2 -3
  183. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  184. package/dist/template/implementations/generated.template.js +46 -29
  185. package/dist/template/implementations/generated_http.template.d.ts +2 -3
  186. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  187. package/dist/template/implementations/generated_http.template.js +9 -9
  188. package/dist/template/implementations/generated_sso.template.d.ts +3 -4
  189. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  190. package/dist/template/implementations/generated_sso.template.js +54 -25
  191. package/dist/template/implementations/init_types.template.d.ts +2 -2
  192. package/dist/template/implementations/init_types.template.d.ts.map +1 -1
  193. package/dist/template/implementations/init_types.template.js +2 -2
  194. package/dist/template/implementations/model.template.d.ts +2 -2
  195. package/dist/template/implementations/model.template.d.ts.map +1 -1
  196. package/dist/template/implementations/model.template.js +47 -37
  197. package/dist/template/implementations/model_test.template.d.ts +2 -2
  198. package/dist/template/implementations/model_test.template.d.ts.map +1 -1
  199. package/dist/template/implementations/model_test.template.js +2 -2
  200. package/dist/template/implementations/service.template.d.ts +4 -4
  201. package/dist/template/implementations/service.template.d.ts.map +1 -1
  202. package/dist/template/implementations/service.template.js +24 -16
  203. package/dist/template/implementations/view_enums_buttonset.template.d.ts +2 -2
  204. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -1
  205. package/dist/template/implementations/view_enums_buttonset.template.js +1 -1
  206. package/dist/template/implementations/view_enums_dropdown.template.d.ts +2 -2
  207. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -1
  208. package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
  209. package/dist/template/implementations/view_enums_select.template.d.ts +2 -2
  210. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -1
  211. package/dist/template/implementations/view_enums_select.template.js +2 -2
  212. package/dist/template/implementations/view_form.template.d.ts +2 -2
  213. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  214. package/dist/template/implementations/view_form.template.js +4 -4
  215. package/dist/template/implementations/view_id_all_select.template.d.ts +2 -2
  216. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
  217. package/dist/template/implementations/view_id_all_select.template.js +1 -1
  218. package/dist/template/implementations/view_id_async_select.template.d.ts +2 -2
  219. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -1
  220. package/dist/template/implementations/view_id_async_select.template.js +1 -1
  221. package/dist/template/implementations/view_list.template.d.ts +2 -2
  222. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  223. package/dist/template/implementations/view_list.template.js +29 -19
  224. package/dist/template/implementations/view_list_columns.template.d.ts +3 -3
  225. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -1
  226. package/dist/template/implementations/view_list_columns.template.js +1 -1
  227. package/dist/template/implementations/view_search_input.template.d.ts +2 -2
  228. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
  229. package/dist/template/implementations/view_search_input.template.js +1 -1
  230. package/dist/template/index.d.ts +4 -2
  231. package/dist/template/index.d.ts.map +1 -1
  232. package/dist/template/index.js +5 -3
  233. package/dist/template/template-manager.d.ts +56 -0
  234. package/dist/template/template-manager.d.ts.map +1 -0
  235. package/dist/template/template-manager.js +125 -0
  236. package/dist/template/template-types.d.ts +16 -0
  237. package/dist/template/template-types.d.ts.map +1 -0
  238. package/dist/template/template-types.js +7 -0
  239. package/dist/template/template.d.ts +12 -2
  240. package/dist/template/template.d.ts.map +1 -1
  241. package/dist/template/template.js +19 -6
  242. package/dist/template/zod-converter.d.ts +40 -7
  243. package/dist/template/zod-converter.d.ts.map +1 -1
  244. package/dist/template/zod-converter.js +386 -58
  245. package/dist/testing/_relation-graph.d.ts +1 -1
  246. package/dist/testing/_relation-graph.d.ts.map +1 -1
  247. package/dist/testing/_relation-graph.js +12 -3
  248. package/dist/testing/fixture-manager.d.ts +42 -11
  249. package/dist/testing/fixture-manager.d.ts.map +1 -1
  250. package/dist/testing/fixture-manager.js +338 -236
  251. package/dist/types/types.d.ts +709 -104
  252. package/dist/types/types.d.ts.map +1 -1
  253. package/dist/types/types.js +309 -52
  254. package/dist/typings/knex.d.js +2 -2
  255. package/dist/utils/async-utils.d.ts.map +1 -1
  256. package/dist/utils/async-utils.js +3 -3
  257. package/dist/utils/console-util.js +1 -1
  258. package/dist/utils/controller.d.ts +1 -0
  259. package/dist/utils/controller.d.ts.map +1 -1
  260. package/dist/utils/controller.js +4 -1
  261. package/dist/utils/esm-utils.d.ts +0 -6
  262. package/dist/utils/esm-utils.d.ts.map +1 -1
  263. package/dist/utils/esm-utils.js +2 -9
  264. package/dist/utils/formatter.d.ts +3 -0
  265. package/dist/utils/formatter.d.ts.map +1 -0
  266. package/dist/utils/formatter.js +110 -0
  267. package/dist/utils/fs-utils.d.ts +1 -1
  268. package/dist/utils/fs-utils.d.ts.map +1 -1
  269. package/dist/utils/fs-utils.js +1 -1
  270. package/dist/utils/lodash-able.d.ts.map +1 -1
  271. package/dist/utils/lodash-able.js +1 -1
  272. package/dist/utils/object-utils.d.ts +44 -0
  273. package/dist/utils/object-utils.d.ts.map +1 -0
  274. package/dist/utils/object-utils.js +191 -0
  275. package/dist/utils/path-utils.d.ts +1 -1
  276. package/dist/utils/path-utils.d.ts.map +1 -1
  277. package/dist/utils/path-utils.js +3 -3
  278. package/dist/utils/process-utils.js +1 -1
  279. package/dist/utils/sql-parser.d.ts +5 -1
  280. package/dist/utils/sql-parser.d.ts.map +1 -1
  281. package/dist/utils/sql-parser.js +14 -3
  282. package/dist/utils/type-utils.d.ts +23 -0
  283. package/dist/utils/type-utils.d.ts.map +1 -0
  284. package/dist/utils/type-utils.js +45 -0
  285. package/dist/utils/utils.d.ts +7 -1
  286. package/dist/utils/utils.d.ts.map +1 -1
  287. package/dist/utils/utils.js +44 -5
  288. package/dist/utils/zod-error.d.ts +1 -1
  289. package/dist/utils/zod-error.d.ts.map +1 -1
  290. package/dist/utils/zod-error.js +1 -1
  291. package/package.json +55 -30
  292. package/src/ai/agents/agent.ts +87 -0
  293. package/src/ai/agents/index.ts +2 -0
  294. package/src/ai/agents/types.ts +47 -0
  295. package/src/ai/index.ts +1 -0
  296. package/src/ai/providers/rtzr/api.ts +37 -0
  297. package/src/ai/providers/rtzr/error.ts +34 -0
  298. package/src/ai/providers/rtzr/index.ts +4 -0
  299. package/src/ai/providers/rtzr/model.ts +201 -0
  300. package/src/ai/providers/rtzr/options.ts +49 -0
  301. package/src/ai/providers/rtzr/provider.ts +91 -0
  302. package/src/ai/providers/rtzr/utils.ts +127 -0
  303. package/src/api/base-frame.ts +4 -2
  304. package/src/api/caster.ts +17 -23
  305. package/src/api/code-converters.ts +176 -533
  306. package/src/api/config.ts +39 -56
  307. package/src/api/context.ts +7 -18
  308. package/src/api/decorators.ts +175 -46
  309. package/src/api/index.ts +2 -2
  310. package/src/api/sonamu.ts +133 -124
  311. package/src/api/validator.ts +83 -0
  312. package/src/bin/build-config.ts +7 -1
  313. package/src/bin/cli.ts +192 -110
  314. package/src/bin/loader-register.ts +38 -0
  315. package/src/database/_batch_update.ts +46 -31
  316. package/src/database/base-model.ts +390 -182
  317. package/src/database/base-model.types.ts +155 -0
  318. package/src/database/code-generator.ts +13 -32
  319. package/src/database/db.ts +36 -50
  320. package/src/database/puri-subset.test-d.ts +471 -0
  321. package/src/database/puri-subset.types.ts +195 -0
  322. package/src/database/puri-wrapper.ts +58 -67
  323. package/src/database/puri.ts +182 -126
  324. package/src/database/puri.types.ts +64 -31
  325. package/src/database/transaction-context.ts +1 -1
  326. package/src/database/upsert-builder.ts +261 -132
  327. package/src/entity/entity-manager.ts +36 -28
  328. package/src/entity/entity.ts +330 -249
  329. package/src/exceptions/error-handler.ts +3 -3
  330. package/src/exceptions/so-exceptions.ts +11 -11
  331. package/src/file-storage/driver.ts +5 -5
  332. package/src/file-storage/file-storage.ts +2 -2
  333. package/src/index.ts +18 -12
  334. package/src/migration/code-generation.ts +185 -172
  335. package/src/migration/migration-set.ts +80 -293
  336. package/src/migration/migrator.ts +182 -425
  337. package/src/migration/mysql-schema-reader.ts.txt +272 -0
  338. package/src/migration/postgresql-schema-reader.ts +310 -0
  339. package/src/migration/types.ts +6 -39
  340. package/src/naite/messaging-types.ts +51 -0
  341. package/src/naite/naite-reporter.ts +128 -0
  342. package/src/naite/naite.ts +378 -33
  343. package/src/shared/web.shared.ts.txt +20 -24
  344. package/src/stream/sse.ts +5 -5
  345. package/src/syncer/api-parser.ts +52 -69
  346. package/src/syncer/checksum.ts +25 -37
  347. package/src/syncer/code-generator.ts +58 -62
  348. package/src/syncer/entity-operations.ts +12 -15
  349. package/src/syncer/file-patterns.ts +2 -2
  350. package/src/syncer/index.ts +4 -4
  351. package/src/syncer/module-loader.ts +28 -25
  352. package/src/syncer/syncer.ts +155 -162
  353. package/src/template/entity-converter.ts +18 -27
  354. package/src/template/helpers.ts +8 -11
  355. package/src/template/implementations/entity.template.ts +6 -6
  356. package/src/template/implementations/generated.template.ts +99 -99
  357. package/src/template/implementations/generated_http.template.ts +21 -54
  358. package/src/template/implementations/generated_sso.template.ts +78 -65
  359. package/src/template/implementations/init_types.template.ts +4 -6
  360. package/src/template/implementations/model.template.ts +47 -38
  361. package/src/template/implementations/model_test.template.ts +3 -3
  362. package/src/template/implementations/service.template.ts +56 -80
  363. package/src/template/implementations/view_enums_buttonset.template.ts +2 -2
  364. package/src/template/implementations/view_enums_dropdown.template.ts +4 -4
  365. package/src/template/implementations/view_enums_select.template.ts +3 -3
  366. package/src/template/implementations/view_form.template.ts +34 -75
  367. package/src/template/implementations/view_id_all_select.template.ts +2 -2
  368. package/src/template/implementations/view_id_async_select.template.ts +9 -23
  369. package/src/template/implementations/view_list.template.ts +54 -95
  370. package/src/template/implementations/view_list_columns.template.ts +4 -10
  371. package/src/template/implementations/view_search_input.template.ts +2 -2
  372. package/src/template/index.ts +4 -2
  373. package/src/template/template-manager.ts +166 -0
  374. package/src/template/template-types.ts +16 -0
  375. package/src/template/template.ts +29 -10
  376. package/src/template/zod-converter.ts +459 -101
  377. package/src/testing/_relation-graph.ts +18 -11
  378. package/src/testing/fixture-manager.ts +468 -362
  379. package/src/types/types.ts +516 -248
  380. package/src/typings/knex.d.ts +7 -9
  381. package/src/utils/async-utils.ts +8 -12
  382. package/src/utils/console-util.ts +1 -1
  383. package/src/utils/controller.ts +3 -0
  384. package/src/utils/esm-utils.ts +8 -18
  385. package/src/utils/formatter.ts +109 -0
  386. package/src/utils/fs-utils.ts +1 -1
  387. package/src/utils/lodash-able.ts +1 -4
  388. package/src/utils/object-utils.ts +217 -0
  389. package/src/utils/path-utils.ts +3 -6
  390. package/src/utils/process-utils.ts +1 -1
  391. package/src/utils/sql-parser.ts +23 -5
  392. package/src/utils/type-utils.ts +83 -0
  393. package/src/utils/utils.ts +58 -9
  394. package/src/utils/zod-error.ts +3 -3
  395. package/dist/bin/cli-wrapper.d.ts +0 -3
  396. package/dist/bin/cli-wrapper.d.ts.map +0 -1
  397. package/dist/bin/cli-wrapper.js +0 -72
  398. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
  399. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
  400. package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -39
  401. package/dist/entity/entity-utils.d.ts +0 -61
  402. package/dist/entity/entity-utils.d.ts.map +0 -1
  403. package/dist/entity/entity-utils.js +0 -210
  404. package/src/bin/cli-wrapper.ts +0 -82
  405. package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
  406. package/src/entity/entity-utils.ts +0 -291
@@ -1,31 +1,33 @@
1
- import * as _ from "lodash-es";
2
- import { createImportUrl } from "../utils/esm-utils";
3
- import { EntityManager as EntityManager } from "./entity-manager";
1
+ import assert from "assert";
2
+ import { writeFile } from "fs/promises";
3
+ import inflection from "inflection";
4
+ import path from "path";
5
+ import { group, unique } from "radashi";
6
+ import { z } from "zod";
7
+ import { Sonamu } from "../api/sonamu";
4
8
  import {
5
- EntityProp,
6
- RelationProp,
7
- isRelationProp,
8
- SubsetQuery,
9
- isVirtualProp,
9
+ type EntityIndex,
10
+ type EntityJson,
11
+ type EntityProp,
12
+ type EntityPropNode,
13
+ type EntitySubsetRow,
10
14
  isBelongsToOneRelationProp,
11
- isOneToOneRelationProp,
15
+ isEnumProp,
12
16
  isHasManyRelationProp,
13
17
  isManyToManyRelationProp,
14
- EntityPropNode,
15
- isEnumProp,
16
- StringProp,
17
- EntityIndex,
18
- EntityJson,
19
- EntitySubsetRow,
18
+ isOneToOneRelationProp,
19
+ isRelationProp,
20
+ isVirtualProp,
21
+ type RelationProp,
22
+ type StringProp,
23
+ type SubsetQuery,
20
24
  } from "../types/types";
21
- import inflection from "inflection";
22
- import path from "path";
23
- import { writeFile } from "fs/promises";
24
- import { z } from "zod";
25
- import { Sonamu } from "../api/sonamu";
26
- import prettier from "prettier";
27
- import { nonNullable } from "../utils/utils";
25
+ import { importMembers } from "../utils/esm-utils";
26
+ import { formatCode } from "../utils/formatter";
28
27
  import { exists } from "../utils/fs-utils";
28
+ import { runtimePath } from "../utils/path-utils";
29
+ import { assertDefined, nonNullable } from "../utils/utils";
30
+ import { EntityManager } from "./entity-manager";
29
31
 
30
32
  export class Entity {
31
33
  id: string;
@@ -52,7 +54,7 @@ export class Entity {
52
54
  [name: string]: z.ZodTypeAny;
53
55
  } = {};
54
56
  enums: {
55
- [enumId: string]: z.ZodEnum<any>;
57
+ [enumId: string]: z.ZodEnum<Readonly<Record<string, string>>>;
56
58
  } = {};
57
59
  enumLabels: {
58
60
  [enumId: string]: {
@@ -60,16 +62,7 @@ export class Entity {
60
62
  };
61
63
  } = {};
62
64
 
63
- constructor({
64
- id,
65
- parentId,
66
- table,
67
- title,
68
- props,
69
- indexes,
70
- subsets,
71
- enums,
72
- }: EntityJson) {
65
+ constructor({ id, parentId, table, title, props, indexes, subsets, enums }: EntityJson) {
73
66
  // id
74
67
  this.id = id;
75
68
  this.parentId = parentId;
@@ -86,22 +79,16 @@ export class Entity {
86
79
  }
87
80
  return prop;
88
81
  });
89
- this.propsDict = props.reduce((result, prop) => {
90
- return {
91
- ...result,
92
- [prop.name]: prop,
93
- };
94
- }, {});
82
+ this.propsDict = Object.fromEntries(
83
+ props.map((prop) => {
84
+ return [prop.name, prop];
85
+ }),
86
+ );
95
87
 
96
88
  // relations
97
- this.relations = props
98
- .filter((prop) => isRelationProp(prop))
99
- .reduce((result, prop) => {
100
- return {
101
- ...result,
102
- [prop.name]: prop,
103
- };
104
- }, {});
89
+ this.relations = Object.fromEntries(
90
+ props.filter((prop) => isRelationProp(prop)).map((prop) => [prop.name, prop]),
91
+ );
105
92
  } else {
106
93
  this.props = [];
107
94
  this.propsDict = {};
@@ -118,25 +105,180 @@ export class Entity {
118
105
  this.enumLabels = enums ?? {};
119
106
  this.enums = Object.fromEntries(
120
107
  Object.entries(this.enumLabels).map(([key, enumLabel]) => {
121
- return [
122
- key,
123
- z.enum(
124
- Object.keys(enumLabel) as unknown as readonly [string, ...string[]]
125
- ),
126
- ];
127
- })
108
+ return [key, z.enum(Object.keys(enumLabel) as unknown as readonly [string, ...string[]])];
109
+ }),
128
110
  );
129
111
 
130
112
  // names
131
113
  this.names = {
132
- parentFs: inflection
133
- .dasherize(inflection.underscore(parentId ?? id))
134
- .toLowerCase(),
114
+ parentFs: inflection.dasherize(inflection.underscore(parentId ?? id)).toLowerCase(),
135
115
  fs: inflection.dasherize(inflection.underscore(id)).toLowerCase(),
136
116
  module: id,
137
117
  };
138
118
  }
139
119
 
120
+ /*
121
+ subset을 Puri 코드로 변환
122
+ */
123
+ getPuriSubsetQuery(subsetKey: string): string {
124
+ const subset = this.subsets[subsetKey];
125
+ const subsetQuery = this.resolveSubsetQuery("", subset);
126
+
127
+ const lines: string[] = [];
128
+
129
+ // from
130
+ lines.push(`return qbWrapper`);
131
+ lines.push(`.from("${this.table}")`);
132
+
133
+ // join
134
+ for (const join of subsetQuery.joins) {
135
+ const joinMethod = join.join === "inner" ? "join" : "leftJoin";
136
+
137
+ if ("custom" in join) {
138
+ // custom join clause는 raw 사용
139
+ lines.push(
140
+ `.${joinMethod}({ ${join.as}: "${join.table}" }, qbWrapper.knex.raw(\`${join.custom}\`))`,
141
+ );
142
+ } else {
143
+ lines.push(`.${joinMethod}({ ${join.as}: "${join.table}" }, "${join.from}", "${join.to}")`);
144
+ }
145
+ }
146
+
147
+ // select
148
+ const selectObj: Record<string, string> = {};
149
+ for (const selectItem of subsetQuery.select) {
150
+ // "users.id" 또는 "users.id as user__id" 형태
151
+ const match = selectItem.match(/^(.+?)(?: as (.+))?$/);
152
+ if (match) {
153
+ const [, column, alias] = match;
154
+ const key = alias ?? assertDefined(column.split(".").pop());
155
+ selectObj[key] = `"${column.trim()}"`;
156
+ }
157
+ }
158
+
159
+ lines.push(`.select({`);
160
+ Object.entries(selectObj).forEach(([key, value]) => {
161
+ lines.push(`${key}: ${value},`);
162
+ });
163
+ lines.push(`});`);
164
+
165
+ return lines.join("\n");
166
+ }
167
+
168
+ getPuriLoaderQuery(subsetKey: string): string {
169
+ const subset = this.subsets[subsetKey];
170
+ const { loaders } = this.resolveSubsetQuery("", subset);
171
+
172
+ const lines: string[] = [`[`];
173
+
174
+ const parseSelect = (select: string, table: string) => {
175
+ const tablePrefix = `${table}.`;
176
+ if (select.startsWith(tablePrefix)) {
177
+ return `${select.replace(tablePrefix, "")}: "${select}"`;
178
+ }
179
+
180
+ if (select.includes(" as ")) {
181
+ const [column, alias] = select.split(" as ");
182
+ return `${alias}: "${column}"`;
183
+ }
184
+ return `${select}: "${select}"`;
185
+ };
186
+
187
+ // 재귀적으로 loader 생성하는 헬퍼 함수
188
+ const generateLoaderCode = (loaders: SubsetQuery["loaders"]): string[] => {
189
+ const loaderLines: string[] = [];
190
+
191
+ for (const loader of loaders) {
192
+ const { toTable, toCol, through } = loader.manyJoin;
193
+ loaderLines.push(
194
+ "{",
195
+ `as: "${loader.as}",`,
196
+ `refId: "${loader.manyJoin.idField}",`,
197
+ `qb: (qbWrapper: PuriWrapper<DatabaseSchemaExtend>, fromIds: number[]) => {`,
198
+ );
199
+
200
+ if (through === undefined) {
201
+ // HasMany
202
+ loaderLines.push(
203
+ //
204
+ "return qbWrapper",
205
+ `.from("${toTable}")`,
206
+ );
207
+
208
+ loader.oneJoins.forEach((join: SubsetQuery["joins"][number]) => {
209
+ const joinType = join.join === "inner" ? "join" : "leftJoin";
210
+ if ("custom" in join) {
211
+ // FIXME: 검증 필요
212
+ loaderLines.push(
213
+ `.${joinType}({ ${join.as}: "${join.table}" }, (j) => {`,
214
+ `j.on(Puri.rawString("${join.custom}"));`,
215
+ "})",
216
+ );
217
+ } else {
218
+ loaderLines.push(
219
+ `.${joinType}({ ${join.as}: "${join.table}" }, "${join.from}", "${join.to}")`,
220
+ );
221
+ }
222
+ });
223
+
224
+ loaderLines.push(
225
+ `.whereIn("${toTable}.${toCol}", fromIds)`,
226
+ `.select({`,
227
+ `${loader.select.map((select: string) => parseSelect(select, toTable)).join(",")},`,
228
+ `refId: "${toTable}.${toCol}",`,
229
+ `});`,
230
+ );
231
+ } else {
232
+ // ManyToMany
233
+ loaderLines.push(
234
+ "return qbWrapper",
235
+ `.from("${through.table}")`,
236
+ `.join("${toTable}", "${through.table}.${through.toCol}", "${toTable}.${toCol}")`,
237
+ );
238
+
239
+ loader.oneJoins.forEach((join: SubsetQuery["joins"][number]) => {
240
+ const joinType = join.join === "inner" ? "join" : "leftJoin";
241
+ if ("custom" in join) {
242
+ // FIXME: 검증 필요
243
+ loaderLines.push(
244
+ `.${joinType}({ ${join.as}: "${join.table}" }, (j) => {`,
245
+ `j.on(Puri.rawString("${join.custom}"));`,
246
+ "})",
247
+ );
248
+ } else {
249
+ loaderLines.push(
250
+ `.${joinType}({ ${join.as}: "${join.table}" }, "${join.from}", "${join.to}")`,
251
+ );
252
+ }
253
+ });
254
+ loaderLines.push(
255
+ `.whereIn("${through.table}.${through.fromCol}", fromIds)`,
256
+ `.select({`,
257
+ `${loader.select.map((select: string) => parseSelect(select, toTable)).join(",")},`,
258
+ `refId: "${through.table}.${through.fromCol}",`,
259
+ `});`,
260
+ );
261
+ }
262
+
263
+ loaderLines.push(`},`);
264
+
265
+ // 중첩 loaders 처리
266
+ if (loader.loaders && loader.loaders.length > 0) {
267
+ loaderLines.push("loaders: [", ...generateLoaderCode(loader.loaders), "],");
268
+ }
269
+
270
+ loaderLines.push("},");
271
+ }
272
+
273
+ return loaderLines;
274
+ };
275
+
276
+ lines.push(...generateLoaderCode(loaders));
277
+ lines.push(`]`);
278
+
279
+ return lines.join("\n");
280
+ }
281
+
140
282
  /*
141
283
  subset SELECT/JOIN/LOADER 결과 리턴
142
284
  */
@@ -152,13 +294,13 @@ export class Entity {
152
294
  resolveSubsetQuery(
153
295
  prefix: string,
154
296
  fields: string[],
155
- isAlreadyOuterJoined: boolean = false
297
+ isAlreadyOuterJoined: boolean = false,
156
298
  ): SubsetQuery {
157
299
  // prefix 치환 (prefix는 ToOneRelation이 복수로 붙은 경우 모두 __로 변경됨)
158
300
  prefix = prefix.replace(/\./g, "__");
159
301
 
160
302
  // 서브셋을 1뎁스만 분리하여 그룹핑
161
- const subsetGroup = _.groupBy(fields, (field) => {
303
+ const subsetGroup = group(fields, (field) => {
162
304
  if (field.includes(".")) {
163
305
  const [rel] = field.split(".");
164
306
  return rel;
@@ -170,27 +312,21 @@ export class Entity {
170
312
  const result = Object.keys(subsetGroup).reduce(
171
313
  (r, groupKey) => {
172
314
  const fields = subsetGroup[groupKey];
315
+ assert(fields !== undefined, "fields is undefined");
316
+
173
317
  // 현재 테이블 필드셋은 select, virtual에 추가하고 리턴
174
318
  if (groupKey === "") {
175
- const realFields = fields.filter(
176
- (field) => !isVirtualProp(this.propsDict[field])
177
- );
178
- const virtualFields = fields.filter((field) =>
179
- isVirtualProp(this.propsDict[field])
180
- );
319
+ const realFields = fields.filter((field) => !isVirtualProp(this.propsDict[field]));
320
+ const virtualFields = fields.filter((field) => isVirtualProp(this.propsDict[field]));
181
321
 
182
322
  if (prefix === "") {
183
323
  // 현재 테이블인 경우
184
- r.select = r.select.concat(
185
- realFields.map((field) => `${this.table}.${field}`)
186
- );
324
+ r.select = r.select.concat(realFields.map((field) => `${this.table}.${field}`));
187
325
  r.virtual = r.virtual.concat(virtualFields);
188
326
  } else {
189
327
  // 넘어온 테이블인 경우
190
328
  r.select = r.select.concat(
191
- realFields.map(
192
- (field) => `${prefix}.${field} as ${prefix}__${field}`
193
- )
329
+ realFields.map((field) => `${prefix}.${field} as ${prefix}__${field}`),
194
330
  );
195
331
  }
196
332
 
@@ -203,23 +339,16 @@ export class Entity {
203
339
  }
204
340
  const relEntity = EntityManager.get(relation.with);
205
341
 
206
- if (
207
- isOneToOneRelationProp(relation) ||
208
- isBelongsToOneRelationProp(relation)
209
- ) {
342
+ if (isOneToOneRelationProp(relation) || isBelongsToOneRelationProp(relation)) {
210
343
  // -One Relation: JOIN 으로 처리
211
- const relFields = fields.map((field) =>
212
- field.split(".").slice(1).join(".")
213
- );
344
+ const relFields = fields.map((field) => field.split(".").slice(1).join("."));
214
345
 
215
346
  // -One Relation에서 id 필드만 참조하는 경우 릴레이션 넘기지 않고 리턴
216
347
  if (relFields.length === 1 && relFields[0] === "id") {
217
348
  if (prefix === "") {
218
349
  r.select = r.select.concat(`${this.table}.${groupKey}_id`);
219
350
  } else {
220
- r.select = r.select.concat(
221
- `${prefix}.${groupKey}_id as ${prefix}__${groupKey}_id`
222
- );
351
+ r.select = r.select.concat(`${prefix}.${groupKey}_id as ${prefix}__${groupKey}_id`);
223
352
  }
224
353
  return r;
225
354
  }
@@ -231,10 +360,7 @@ export class Entity {
231
360
  }
232
361
 
233
362
  if (isOneToOneRelationProp(relation)) {
234
- if (
235
- relation.hasJoinColumn === true &&
236
- (relation.nullable ?? false) === false
237
- ) {
363
+ if (relation.hasJoinColumn === true && (relation.nullable ?? false) === false) {
238
364
  return "inner";
239
365
  } else {
240
366
  return "outer";
@@ -248,32 +374,37 @@ export class Entity {
248
374
  }
249
375
  })();
250
376
  const relSubsetQuery = relEntity.resolveSubsetQuery(
251
- `${prefix !== "" ? prefix + "." : ""}${groupKey}`,
377
+ `${prefix !== "" ? `${prefix}.` : ""}${groupKey}`,
252
378
  relFields,
253
- innerOrOuter === "outer"
379
+ innerOrOuter === "outer",
254
380
  );
255
381
  r.select = r.select.concat(relSubsetQuery.select);
256
382
  r.virtual = r.virtual.concat(relSubsetQuery.virtual);
257
383
 
258
- const joinAs = prefix === "" ? groupKey : prefix + "__" + groupKey;
384
+ const joinAs = prefix === "" ? groupKey : `${prefix}__${groupKey}`;
259
385
  const fromTable = prefix === "" ? this.table : prefix;
260
386
 
261
- let joinClause;
387
+ let joinClause:
388
+ | {
389
+ from: string;
390
+ to: string;
391
+ }
392
+ | {
393
+ custom: string;
394
+ };
262
395
  if (relation.customJoinClause) {
263
396
  joinClause = {
264
397
  custom: relation.customJoinClause,
265
398
  };
266
399
  } else {
267
- let from, to;
400
+ let from: string, to: string;
268
401
  if (isOneToOneRelationProp(relation)) {
269
402
  if (relation.hasJoinColumn) {
270
403
  from = `${fromTable}.${relation.name}_id`;
271
404
  to = `${joinAs}.id`;
272
405
  } else {
273
406
  from = `${fromTable}.id`;
274
- to = `${joinAs}.${inflection.underscore(
275
- this.names.fs.replace(/\-/g, "_")
276
- )}_id`;
407
+ to = `${joinAs}.${inflection.underscore(this.names.fs.replace(/-/g, "_"))}_id`;
277
408
  }
278
409
  } else {
279
410
  from = `${fromTable}.${relation.name}_id`;
@@ -310,14 +441,9 @@ export class Entity {
310
441
  }
311
442
 
312
443
  r.joins = r.joins.concat(relSubsetQuery.joins);
313
- } else if (
314
- isHasManyRelationProp(relation) ||
315
- isManyToManyRelationProp(relation)
316
- ) {
444
+ } else if (isHasManyRelationProp(relation) || isManyToManyRelationProp(relation)) {
317
445
  // -Many Relation: Loader 로 처리
318
- const relFields = fields.map((field) =>
319
- field.split(".").slice(1).join(".")
320
- );
446
+ const relFields = fields.map((field) => field.split(".").slice(1).join("."));
321
447
  const relSubsetQuery = relEntity.resolveSubsetQuery("", relFields);
322
448
 
323
449
  let manyJoin: SubsetQuery["loaders"][number]["manyJoin"];
@@ -364,7 +490,7 @@ export class Entity {
364
490
  virtual: [],
365
491
  joins: [],
366
492
  loaders: [],
367
- } as SubsetQuery
493
+ } as SubsetQuery,
368
494
  );
369
495
  return result;
370
496
  }
@@ -372,13 +498,10 @@ export class Entity {
372
498
  /*
373
499
  FieldExpr[] 을 EntityPropNode[] 로 변환
374
500
  */
375
- fieldExprsToPropNodes(
376
- fieldExprs: string[],
377
- entity: Entity = this
378
- ): EntityPropNode[] {
501
+ fieldExprsToPropNodes(fieldExprs: string[], entity: Entity = this): EntityPropNode[] {
379
502
  const groups = fieldExprs.reduce(
380
503
  (result, fieldExpr) => {
381
- let key, value, elseExpr;
504
+ let key: string, value: string, elseExpr: string[];
382
505
  if (fieldExpr.includes(".")) {
383
506
  [key, ...elseExpr] = fieldExpr.split(".");
384
507
  value = elseExpr.join(".");
@@ -392,91 +515,85 @@ export class Entity {
392
515
  },
393
516
  {} as {
394
517
  [k: string]: string[];
395
- }
518
+ },
396
519
  );
397
520
 
398
- return Object.keys(groups)
399
- .map((key) => {
400
- const group = groups[key];
401
-
402
- // 일반 prop 처리
403
- if (key === "") {
404
- return group.map((propName) => {
405
- // uuid 개별 처리
406
- if (propName === "uuid") {
407
- return {
408
- nodeType: "plain" as const,
409
- prop: {
410
- type: "string",
411
- name: "uuid",
412
- length: 128,
413
- } as StringProp,
414
- children: [],
415
- };
416
- }
417
-
418
- const prop = entity.props.find((p) => p.name === propName);
419
- if (prop === undefined) {
420
- console.log({ propName, groups });
421
- throw new Error(`${entity.id} -- 잘못된 FieldExpr ${propName}`);
422
- }
423
- return {
424
- nodeType: "plain" as const,
425
- prop,
426
- children: [],
427
- };
428
- });
429
- }
430
-
431
- // relation prop 처리
432
- const prop = entity.propsDict[key];
433
- if (!isRelationProp(prop)) {
434
- throw new Error(`잘못된 FieldExpr ${key}.${group[0]}`);
435
- }
436
- const relEntity = EntityManager.get(prop.with);
521
+ return Object.keys(groups).flatMap((key) => {
522
+ const group = groups[key];
437
523
 
438
- // relation -One 에 id 필드 하나인 경우
439
- if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)) {
440
- if (group.length == 1 && (group[0] === "id" || group[0] == "id?")) {
441
- // id 하나만 있는지 체크해서, 하나만 있으면 상위 prop으로 id를 리턴
442
- const idProp = relEntity.propsDict.id;
524
+ // 일반 prop 처리
525
+ if (key === "") {
526
+ return group.map((propName) => {
527
+ // uuid 개별 처리
528
+ if (propName === "uuid") {
443
529
  return {
444
530
  nodeType: "plain" as const,
445
531
  prop: {
446
- ...idProp,
447
- name: key + "_id",
448
- nullable: prop.nullable,
449
- },
532
+ type: "string",
533
+ name: "uuid",
534
+ length: 128,
535
+ } as StringProp,
450
536
  children: [],
451
- };
537
+ } as EntityPropNode;
452
538
  }
539
+
540
+ const prop = entity.props.find((p) => p.name === propName);
541
+ if (prop === undefined) {
542
+ console.log({ propName, groups });
543
+ throw new Error(`${entity.id} -- 잘못된 FieldExpr ${propName}`);
544
+ }
545
+ return {
546
+ nodeType: "plain" as const,
547
+ prop,
548
+ children: [],
549
+ };
550
+ });
551
+ }
552
+
553
+ // relation prop 처리
554
+ const prop = entity.propsDict[key];
555
+ if (!isRelationProp(prop)) {
556
+ throw new Error(`잘못된 FieldExpr ${key}.${group[0]}`);
557
+ }
558
+ const relEntity = EntityManager.get(prop.with);
559
+
560
+ // relation -One 에 id 필드 하나인 경우
561
+ if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)) {
562
+ if (group.length === 1 && (group[0] === "id" || group[0] === "id?")) {
563
+ // id 하나만 있는지 체크해서, 하나만 있으면 상위 prop으로 id를 리턴
564
+ const idProp = relEntity.propsDict.id;
565
+ return {
566
+ nodeType: "plain" as const,
567
+ prop: {
568
+ ...idProp,
569
+ name: `${key}_id`,
570
+ nullable: prop.nullable,
571
+ },
572
+ children: [],
573
+ };
453
574
  }
575
+ }
454
576
 
455
- // -One 그외의 경우 object로 리턴
456
- // -Many의 경우 array로 리턴
457
- // Recursive 로 뎁스 처리
458
- const children = this.fieldExprsToPropNodes(group, relEntity);
459
- const nodeType =
460
- isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)
461
- ? ("object" as const)
462
- : ("array" as const);
577
+ // -One 그외의 경우 object로 리턴
578
+ // -Many의 경우 array로 리턴
579
+ // Recursive 로 뎁스 처리
580
+ const children = this.fieldExprsToPropNodes(group, relEntity);
581
+ const nodeType =
582
+ isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)
583
+ ? ("object" as const)
584
+ : ("array" as const);
463
585
 
464
- return {
465
- prop,
466
- children,
467
- nodeType,
468
- };
469
- })
470
- .flat();
586
+ return {
587
+ prop,
588
+ children,
589
+ nodeType,
590
+ };
591
+ });
471
592
  }
472
593
 
473
- getFieldExprs(
474
- prefix = "",
475
- maxDepth: number = 3,
476
- froms: string[] = []
477
- ): string[] {
594
+ getFieldExprs(prefix = "", maxDepth: number = 3, froms: string[] = []): string[] {
478
595
  return this.props
479
- .map((prop) => {
596
+ .flatMap((prop) => {
480
597
  const propName = [prefix, prop.name].filter((v) => v !== "").join(".");
481
598
  if (propName === prefix) {
482
599
  return null;
@@ -491,14 +608,10 @@ export class Entity {
491
608
  }
492
609
  // 정방향 relation인 경우 recursive 콜
493
610
  const relMd = EntityManager.get(prop.with);
494
- return relMd.getFieldExprs(propName, maxDepth - 1, [
495
- ...froms,
496
- this.id,
497
- ]);
611
+ return relMd.getFieldExprs(propName, maxDepth - 1, [...froms, this.id]);
498
612
  }
499
613
  return propName;
500
614
  })
501
- .flat()
502
615
  .filter((f) => f !== null) as string[];
503
616
  }
504
617
 
@@ -529,40 +642,35 @@ export class Entity {
529
642
  // subset
530
643
  if (Object.keys(this.subsets).length > 0) {
531
644
  EntityManager.setModulePath(`${this.id}SubsetKey`, `sonamu.generated`);
532
- EntityManager.setModulePath(
533
- `${this.id}SubsetMapping`,
534
- `sonamu.generated`
535
- );
536
- Object.keys(this.subsets).map((subsetKey) => {
645
+ EntityManager.setModulePath(`${this.id}SubsetMapping`, `sonamu.generated`);
646
+ for (const subsetKey of Object.keys(this.subsets)) {
537
647
  EntityManager.setModulePath(
538
648
  `${this.id}Subset${subsetKey.toUpperCase()}`,
539
- `sonamu.generated`
649
+ `sonamu.generated`,
540
650
  );
541
- });
651
+ }
542
652
  }
543
653
 
544
654
  // enums
545
- Object.keys(this.enumLabels).map((enumId) => {
655
+ for (const enumId of Object.keys(this.enumLabels)) {
546
656
  EntityManager.setModulePath(enumId, `sonamu.generated`);
547
- });
657
+ }
548
658
 
549
659
  // types
550
660
  const typesModulePath = `${basePath}/${this.names.parentFs}.types`;
551
- const typesFileDistPath = path.join(
661
+ const typesFilePath = path.join(
552
662
  Sonamu.apiRootPath,
553
- `dist/application/${typesModulePath}.js`
663
+ runtimePath(`dist/application/${typesModulePath}.js`),
554
664
  );
555
665
 
556
- if (await exists(typesFileDistPath)) {
557
- const importUrl = createImportUrl(typesFileDistPath);
558
- const t = await import(importUrl);
559
- this.types = Object.keys(t).reduce((result, key) => {
560
- EntityManager.setModulePath(key, typesModulePath);
561
- return {
562
- ...result,
563
- [key]: t[key],
564
- };
565
- }, {});
666
+ if (await exists(typesFilePath)) {
667
+ const importedMembers = await importMembers<z.ZodTypeAny>(typesFilePath);
668
+ this.types = Object.fromEntries(
669
+ importedMembers.map(({ name, value }) => {
670
+ EntityManager.setModulePath(name, typesModulePath);
671
+ return [name, value];
672
+ }),
673
+ ) as { [name: string]: z.ZodTypeAny };
566
674
  }
567
675
  }
568
676
 
@@ -593,25 +701,17 @@ export class Entity {
593
701
  const subsetRows = this.getSubsetRows();
594
702
  this.subsets = Object.fromEntries(
595
703
  Object.entries(this.subsets).map(([subsetKey]) => {
596
- return [
597
- subsetKey,
598
- this.subsetRowsToSubsetFields(subsetRows, subsetKey),
599
- ];
600
- })
704
+ return [subsetKey, this.subsetRowsToSubsetFields(subsetRows, subsetKey)];
705
+ }),
601
706
  );
602
707
 
603
708
  // save
604
709
  const jsonPath = path.join(
605
710
  Sonamu.apiRootPath,
606
- `src/application/${this.names.parentFs}/${this.names.fs}.entity.json`
711
+ `src/application/${this.names.parentFs}/${this.names.fs}.entity.json`,
607
712
  );
608
713
  const json = this.toJson();
609
- await writeFile(
610
- jsonPath,
611
- await prettier.format(JSON.stringify(json), {
612
- parser: "json",
613
- })
614
- );
714
+ await writeFile(jsonPath, formatCode(JSON.stringify(json), "json", jsonPath));
615
715
 
616
716
  // reload
617
717
  await EntityManager.register(json);
@@ -619,7 +719,7 @@ export class Entity {
619
719
 
620
720
  getSubsetRows(
621
721
  _subsets?: { [key: string]: string[] },
622
- prefixes: string[] = []
722
+ prefixes: string[] = [],
623
723
  ): EntitySubsetRow[] {
624
724
  if (prefixes.length > 10) {
625
725
  return [];
@@ -627,20 +727,15 @@ export class Entity {
627
727
 
628
728
  const subsets = _subsets ?? this.subsets;
629
729
  const subsetKeys = Object.keys(subsets);
630
- const allFields = _.uniq(subsetKeys.map((key) => subsets[key]).flat());
730
+ const allFields = unique(subsetKeys.flatMap((key) => subsets[key]));
631
731
 
632
732
  return this.props.map((prop) => {
633
733
  if (
634
734
  prop.type === "relation" &&
635
- allFields.find((f) =>
636
- f.startsWith([...prefixes, prop.name].join(".") + ".")
637
- )
735
+ allFields.find((f) => f.startsWith(`${[...prefixes, prop.name].join(".")}.`))
638
736
  ) {
639
737
  const relEntity = EntityManager.get(prop.with);
640
- const children = relEntity.getSubsetRows(subsets, [
641
- ...prefixes,
642
- `${prop.name}`,
643
- ]);
738
+ const children = relEntity.getSubsetRows(subsets, [...prefixes, `${prop.name}`]);
644
739
 
645
740
  return {
646
741
  field: prop.name,
@@ -650,11 +745,8 @@ export class Entity {
650
745
  isOpen: children.length > 0,
651
746
  has: Object.fromEntries(
652
747
  subsetKeys.map((subsetKey) => {
653
- return [
654
- subsetKey,
655
- children.every((child) => child.has[subsetKey] === true),
656
- ];
657
- })
748
+ return [subsetKey, children.every((child) => child.has[subsetKey] === true)];
749
+ }),
658
750
  ),
659
751
  };
660
752
  }
@@ -669,19 +761,16 @@ export class Entity {
669
761
  const subsetFields = subsets[subsetKey];
670
762
  const has = subsetFields.some((f) => {
671
763
  const field = [...prefixes, prop.name].join(".");
672
- return f === field || f.startsWith(field + ".");
764
+ return f === field || f.startsWith(`${field}.`);
673
765
  });
674
766
  return [subsetKey, has];
675
- })
767
+ }),
676
768
  ),
677
769
  };
678
770
  });
679
771
  }
680
772
 
681
- subsetRowsToSubsetFields(
682
- subsetRows: EntitySubsetRow[],
683
- subsetKey: string
684
- ): string[] {
773
+ subsetRowsToSubsetFields(subsetRows: EntitySubsetRow[], subsetKey: string): string[] {
685
774
  return subsetRows
686
775
  .map((subsetRow) => {
687
776
  if (subsetRow.children.length > 0) {
@@ -723,9 +812,7 @@ export class Entity {
723
812
  propName,
724
813
  });
725
814
 
726
- const prop = EntityManager.get(entityId).props.find(
727
- (p) => p.name === propName
728
- );
815
+ const prop = EntityManager.get(entityId).props.find((p) => p.name === propName);
729
816
  if (!prop) {
730
817
  throw new Error(`${entityId}의 잘못된 서브셋키 ${subsetField}`);
731
818
  }
@@ -762,7 +849,7 @@ export class Entity {
762
849
  ...a,
763
850
  propName: newProp.name,
764
851
  }
765
- : a
852
+ : a,
766
853
  );
767
854
  // 분석한 필드를 다시 서브셋 필드로 복구
768
855
  return modified.map((a) => a.propName).join(".");
@@ -800,11 +887,7 @@ export class Entity {
800
887
  const modifiedSubsetFields = subset
801
888
  .map((subsetField) => {
802
889
  const analyzed = relEntity.analyzeSubsetField(subsetField);
803
- if (
804
- analyzed.find(
805
- (a) => a.propName === oldName && a.entityId === this.id
806
- )
807
- ) {
890
+ if (analyzed.find((a) => a.propName === oldName && a.entityId === this.id)) {
808
891
  return null;
809
892
  } else {
810
893
  return subsetField;
@@ -820,9 +903,9 @@ export class Entity {
820
903
  }
821
904
 
822
905
  // 현재 엔티티의 인덱스에서 제외
823
- EntityManager.get(this.id).indexes.map((index) => {
906
+ for (const index of EntityManager.get(this.id).indexes) {
824
907
  index.columns = index.columns.filter((col) => col !== oldName);
825
- });
908
+ }
826
909
 
827
910
  // 프롭 삭제
828
911
  this.props.splice(at, 1);
@@ -840,9 +923,7 @@ export class Entity {
840
923
 
841
924
  // 서브셋 필드를 내려가면서 마지막으로 relation된 엔티티를 찾음
842
925
  const lastEntityId = arr.reduce((entityId, field) => {
843
- const relProp = EntityManager.get(entityId).props.find(
844
- (p) => p.name === field
845
- );
926
+ const relProp = EntityManager.get(entityId).props.find((p) => p.name === field);
846
927
  if (!relProp || relProp.type !== "relation") {
847
928
  console.debug({ arr, thisId: this.id, entityId, field });
848
929
  throw new Error(`잘못된 서브셋키 ${subsetField}`);