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,30 +1,33 @@
1
- import _ from "lodash";
2
- 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";
3
8
  import {
4
- EntityProp,
5
- RelationProp,
6
- isRelationProp,
7
- SubsetQuery,
8
- isVirtualProp,
9
+ type EntityIndex,
10
+ type EntityJson,
11
+ type EntityProp,
12
+ type EntityPropNode,
13
+ type EntitySubsetRow,
9
14
  isBelongsToOneRelationProp,
10
- isOneToOneRelationProp,
15
+ isEnumProp,
11
16
  isHasManyRelationProp,
12
17
  isManyToManyRelationProp,
13
- EntityPropNode,
14
- isEnumProp,
15
- StringProp,
16
- EntityIndex,
17
- EntityJson,
18
- EntitySubsetRow,
18
+ isOneToOneRelationProp,
19
+ isRelationProp,
20
+ isVirtualProp,
21
+ type RelationProp,
22
+ type StringProp,
23
+ type SubsetQuery,
19
24
  } from "../types/types";
20
- import inflection from "inflection";
21
- import path from "path";
22
- import { writeFile } from "fs/promises";
23
- import { z } from "zod";
24
- import { Sonamu } from "../api/sonamu";
25
- import prettier from "prettier";
26
- import { nonNullable } from "../utils/utils";
25
+ import { importMembers } from "../utils/esm-utils";
26
+ import { formatCode } from "../utils/formatter";
27
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";
28
31
 
29
32
  export class Entity {
30
33
  id: string;
@@ -51,7 +54,7 @@ export class Entity {
51
54
  [name: string]: z.ZodTypeAny;
52
55
  } = {};
53
56
  enums: {
54
- [enumId: string]: z.ZodEnum<any>;
57
+ [enumId: string]: z.ZodEnum<Readonly<Record<string, string>>>;
55
58
  } = {};
56
59
  enumLabels: {
57
60
  [enumId: string]: {
@@ -59,16 +62,7 @@ export class Entity {
59
62
  };
60
63
  } = {};
61
64
 
62
- constructor({
63
- id,
64
- parentId,
65
- table,
66
- title,
67
- props,
68
- indexes,
69
- subsets,
70
- enums,
71
- }: EntityJson) {
65
+ constructor({ id, parentId, table, title, props, indexes, subsets, enums }: EntityJson) {
72
66
  // id
73
67
  this.id = id;
74
68
  this.parentId = parentId;
@@ -85,22 +79,16 @@ export class Entity {
85
79
  }
86
80
  return prop;
87
81
  });
88
- this.propsDict = props.reduce((result, prop) => {
89
- return {
90
- ...result,
91
- [prop.name]: prop,
92
- };
93
- }, {});
82
+ this.propsDict = Object.fromEntries(
83
+ props.map((prop) => {
84
+ return [prop.name, prop];
85
+ }),
86
+ );
94
87
 
95
88
  // relations
96
- this.relations = props
97
- .filter((prop) => isRelationProp(prop))
98
- .reduce((result, prop) => {
99
- return {
100
- ...result,
101
- [prop.name]: prop,
102
- };
103
- }, {});
89
+ this.relations = Object.fromEntries(
90
+ props.filter((prop) => isRelationProp(prop)).map((prop) => [prop.name, prop]),
91
+ );
104
92
  } else {
105
93
  this.props = [];
106
94
  this.propsDict = {};
@@ -117,25 +105,180 @@ export class Entity {
117
105
  this.enumLabels = enums ?? {};
118
106
  this.enums = Object.fromEntries(
119
107
  Object.entries(this.enumLabels).map(([key, enumLabel]) => {
120
- return [
121
- key,
122
- z.enum(
123
- Object.keys(enumLabel) as unknown as readonly [string, ...string[]]
124
- ),
125
- ];
126
- })
108
+ return [key, z.enum(Object.keys(enumLabel) as unknown as readonly [string, ...string[]])];
109
+ }),
127
110
  );
128
111
 
129
112
  // names
130
113
  this.names = {
131
- parentFs: inflection
132
- .dasherize(inflection.underscore(parentId ?? id))
133
- .toLowerCase(),
114
+ parentFs: inflection.dasherize(inflection.underscore(parentId ?? id)).toLowerCase(),
134
115
  fs: inflection.dasherize(inflection.underscore(id)).toLowerCase(),
135
116
  module: id,
136
117
  };
137
118
  }
138
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
+
139
282
  /*
140
283
  subset SELECT/JOIN/LOADER 결과 리턴
141
284
  */
@@ -151,13 +294,13 @@ export class Entity {
151
294
  resolveSubsetQuery(
152
295
  prefix: string,
153
296
  fields: string[],
154
- isAlreadyOuterJoined: boolean = false
297
+ isAlreadyOuterJoined: boolean = false,
155
298
  ): SubsetQuery {
156
299
  // prefix 치환 (prefix는 ToOneRelation이 복수로 붙은 경우 모두 __로 변경됨)
157
300
  prefix = prefix.replace(/\./g, "__");
158
301
 
159
302
  // 서브셋을 1뎁스만 분리하여 그룹핑
160
- const subsetGroup = _.groupBy(fields, (field) => {
303
+ const subsetGroup = group(fields, (field) => {
161
304
  if (field.includes(".")) {
162
305
  const [rel] = field.split(".");
163
306
  return rel;
@@ -169,27 +312,21 @@ export class Entity {
169
312
  const result = Object.keys(subsetGroup).reduce(
170
313
  (r, groupKey) => {
171
314
  const fields = subsetGroup[groupKey];
315
+ assert(fields !== undefined, "fields is undefined");
316
+
172
317
  // 현재 테이블 필드셋은 select, virtual에 추가하고 리턴
173
318
  if (groupKey === "") {
174
- const realFields = fields.filter(
175
- (field) => !isVirtualProp(this.propsDict[field])
176
- );
177
- const virtualFields = fields.filter((field) =>
178
- isVirtualProp(this.propsDict[field])
179
- );
319
+ const realFields = fields.filter((field) => !isVirtualProp(this.propsDict[field]));
320
+ const virtualFields = fields.filter((field) => isVirtualProp(this.propsDict[field]));
180
321
 
181
322
  if (prefix === "") {
182
323
  // 현재 테이블인 경우
183
- r.select = r.select.concat(
184
- realFields.map((field) => `${this.table}.${field}`)
185
- );
324
+ r.select = r.select.concat(realFields.map((field) => `${this.table}.${field}`));
186
325
  r.virtual = r.virtual.concat(virtualFields);
187
326
  } else {
188
327
  // 넘어온 테이블인 경우
189
328
  r.select = r.select.concat(
190
- realFields.map(
191
- (field) => `${prefix}.${field} as ${prefix}__${field}`
192
- )
329
+ realFields.map((field) => `${prefix}.${field} as ${prefix}__${field}`),
193
330
  );
194
331
  }
195
332
 
@@ -202,23 +339,16 @@ export class Entity {
202
339
  }
203
340
  const relEntity = EntityManager.get(relation.with);
204
341
 
205
- if (
206
- isOneToOneRelationProp(relation) ||
207
- isBelongsToOneRelationProp(relation)
208
- ) {
342
+ if (isOneToOneRelationProp(relation) || isBelongsToOneRelationProp(relation)) {
209
343
  // -One Relation: JOIN 으로 처리
210
- const relFields = fields.map((field) =>
211
- field.split(".").slice(1).join(".")
212
- );
344
+ const relFields = fields.map((field) => field.split(".").slice(1).join("."));
213
345
 
214
346
  // -One Relation에서 id 필드만 참조하는 경우 릴레이션 넘기지 않고 리턴
215
347
  if (relFields.length === 1 && relFields[0] === "id") {
216
348
  if (prefix === "") {
217
349
  r.select = r.select.concat(`${this.table}.${groupKey}_id`);
218
350
  } else {
219
- r.select = r.select.concat(
220
- `${prefix}.${groupKey}_id as ${prefix}__${groupKey}_id`
221
- );
351
+ r.select = r.select.concat(`${prefix}.${groupKey}_id as ${prefix}__${groupKey}_id`);
222
352
  }
223
353
  return r;
224
354
  }
@@ -230,10 +360,7 @@ export class Entity {
230
360
  }
231
361
 
232
362
  if (isOneToOneRelationProp(relation)) {
233
- if (
234
- relation.hasJoinColumn === true &&
235
- (relation.nullable ?? false) === false
236
- ) {
363
+ if (relation.hasJoinColumn === true && (relation.nullable ?? false) === false) {
237
364
  return "inner";
238
365
  } else {
239
366
  return "outer";
@@ -247,32 +374,37 @@ export class Entity {
247
374
  }
248
375
  })();
249
376
  const relSubsetQuery = relEntity.resolveSubsetQuery(
250
- `${prefix !== "" ? prefix + "." : ""}${groupKey}`,
377
+ `${prefix !== "" ? `${prefix}.` : ""}${groupKey}`,
251
378
  relFields,
252
- innerOrOuter === "outer"
379
+ innerOrOuter === "outer",
253
380
  );
254
381
  r.select = r.select.concat(relSubsetQuery.select);
255
382
  r.virtual = r.virtual.concat(relSubsetQuery.virtual);
256
383
 
257
- const joinAs = prefix === "" ? groupKey : prefix + "__" + groupKey;
384
+ const joinAs = prefix === "" ? groupKey : `${prefix}__${groupKey}`;
258
385
  const fromTable = prefix === "" ? this.table : prefix;
259
386
 
260
- let joinClause;
387
+ let joinClause:
388
+ | {
389
+ from: string;
390
+ to: string;
391
+ }
392
+ | {
393
+ custom: string;
394
+ };
261
395
  if (relation.customJoinClause) {
262
396
  joinClause = {
263
397
  custom: relation.customJoinClause,
264
398
  };
265
399
  } else {
266
- let from, to;
400
+ let from: string, to: string;
267
401
  if (isOneToOneRelationProp(relation)) {
268
402
  if (relation.hasJoinColumn) {
269
403
  from = `${fromTable}.${relation.name}_id`;
270
404
  to = `${joinAs}.id`;
271
405
  } else {
272
406
  from = `${fromTable}.id`;
273
- to = `${joinAs}.${inflection.underscore(
274
- this.names.fs.replace(/\-/g, "_")
275
- )}_id`;
407
+ to = `${joinAs}.${inflection.underscore(this.names.fs.replace(/-/g, "_"))}_id`;
276
408
  }
277
409
  } else {
278
410
  from = `${fromTable}.${relation.name}_id`;
@@ -309,14 +441,9 @@ export class Entity {
309
441
  }
310
442
 
311
443
  r.joins = r.joins.concat(relSubsetQuery.joins);
312
- } else if (
313
- isHasManyRelationProp(relation) ||
314
- isManyToManyRelationProp(relation)
315
- ) {
444
+ } else if (isHasManyRelationProp(relation) || isManyToManyRelationProp(relation)) {
316
445
  // -Many Relation: Loader 로 처리
317
- const relFields = fields.map((field) =>
318
- field.split(".").slice(1).join(".")
319
- );
446
+ const relFields = fields.map((field) => field.split(".").slice(1).join("."));
320
447
  const relSubsetQuery = relEntity.resolveSubsetQuery("", relFields);
321
448
 
322
449
  let manyJoin: SubsetQuery["loaders"][number]["manyJoin"];
@@ -363,7 +490,7 @@ export class Entity {
363
490
  virtual: [],
364
491
  joins: [],
365
492
  loaders: [],
366
- } as SubsetQuery
493
+ } as SubsetQuery,
367
494
  );
368
495
  return result;
369
496
  }
@@ -371,13 +498,10 @@ export class Entity {
371
498
  /*
372
499
  FieldExpr[] 을 EntityPropNode[] 로 변환
373
500
  */
374
- fieldExprsToPropNodes(
375
- fieldExprs: string[],
376
- entity: Entity = this
377
- ): EntityPropNode[] {
501
+ fieldExprsToPropNodes(fieldExprs: string[], entity: Entity = this): EntityPropNode[] {
378
502
  const groups = fieldExprs.reduce(
379
503
  (result, fieldExpr) => {
380
- let key, value, elseExpr;
504
+ let key: string, value: string, elseExpr: string[];
381
505
  if (fieldExpr.includes(".")) {
382
506
  [key, ...elseExpr] = fieldExpr.split(".");
383
507
  value = elseExpr.join(".");
@@ -391,91 +515,85 @@ export class Entity {
391
515
  },
392
516
  {} as {
393
517
  [k: string]: string[];
394
- }
518
+ },
395
519
  );
396
520
 
397
- return Object.keys(groups)
398
- .map((key) => {
399
- const group = groups[key];
400
-
401
- // 일반 prop 처리
402
- if (key === "") {
403
- return group.map((propName) => {
404
- // uuid 개별 처리
405
- if (propName === "uuid") {
406
- return {
407
- nodeType: "plain" as const,
408
- prop: {
409
- type: "string",
410
- name: "uuid",
411
- length: 128,
412
- } as StringProp,
413
- children: [],
414
- };
415
- }
416
-
417
- const prop = entity.props.find((p) => p.name === propName);
418
- if (prop === undefined) {
419
- console.log({ propName, groups });
420
- throw new Error(`${entity.id} -- 잘못된 FieldExpr ${propName}`);
421
- }
422
- return {
423
- nodeType: "plain" as const,
424
- prop,
425
- children: [],
426
- };
427
- });
428
- }
429
-
430
- // relation prop 처리
431
- const prop = entity.propsDict[key];
432
- if (!isRelationProp(prop)) {
433
- throw new Error(`잘못된 FieldExpr ${key}.${group[0]}`);
434
- }
435
- const relEntity = EntityManager.get(prop.with);
521
+ return Object.keys(groups).flatMap((key) => {
522
+ const group = groups[key];
436
523
 
437
- // relation -One 에 id 필드 하나인 경우
438
- if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)) {
439
- if (group.length == 1 && (group[0] === "id" || group[0] == "id?")) {
440
- // id 하나만 있는지 체크해서, 하나만 있으면 상위 prop으로 id를 리턴
441
- const idProp = relEntity.propsDict.id;
524
+ // 일반 prop 처리
525
+ if (key === "") {
526
+ return group.map((propName) => {
527
+ // uuid 개별 처리
528
+ if (propName === "uuid") {
442
529
  return {
443
530
  nodeType: "plain" as const,
444
531
  prop: {
445
- ...idProp,
446
- name: key + "_id",
447
- nullable: prop.nullable,
448
- },
532
+ type: "string",
533
+ name: "uuid",
534
+ length: 128,
535
+ } as StringProp,
449
536
  children: [],
450
- };
537
+ } as EntityPropNode;
451
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
+ };
452
574
  }
575
+ }
453
576
 
454
- // -One 그외의 경우 object로 리턴
455
- // -Many의 경우 array로 리턴
456
- // Recursive 로 뎁스 처리
457
- const children = this.fieldExprsToPropNodes(group, relEntity);
458
- const nodeType =
459
- isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)
460
- ? ("object" as const)
461
- : ("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);
462
585
 
463
- return {
464
- prop,
465
- children,
466
- nodeType,
467
- };
468
- })
469
- .flat();
586
+ return {
587
+ prop,
588
+ children,
589
+ nodeType,
590
+ };
591
+ });
470
592
  }
471
593
 
472
- getFieldExprs(
473
- prefix = "",
474
- maxDepth: number = 3,
475
- froms: string[] = []
476
- ): string[] {
594
+ getFieldExprs(prefix = "", maxDepth: number = 3, froms: string[] = []): string[] {
477
595
  return this.props
478
- .map((prop) => {
596
+ .flatMap((prop) => {
479
597
  const propName = [prefix, prop.name].filter((v) => v !== "").join(".");
480
598
  if (propName === prefix) {
481
599
  return null;
@@ -490,14 +608,10 @@ export class Entity {
490
608
  }
491
609
  // 정방향 relation인 경우 recursive 콜
492
610
  const relMd = EntityManager.get(prop.with);
493
- return relMd.getFieldExprs(propName, maxDepth - 1, [
494
- ...froms,
495
- this.id,
496
- ]);
611
+ return relMd.getFieldExprs(propName, maxDepth - 1, [...froms, this.id]);
497
612
  }
498
613
  return propName;
499
614
  })
500
- .flat()
501
615
  .filter((f) => f !== null) as string[];
502
616
  }
503
617
 
@@ -528,40 +642,35 @@ export class Entity {
528
642
  // subset
529
643
  if (Object.keys(this.subsets).length > 0) {
530
644
  EntityManager.setModulePath(`${this.id}SubsetKey`, `sonamu.generated`);
531
- EntityManager.setModulePath(
532
- `${this.id}SubsetMapping`,
533
- `sonamu.generated`
534
- );
535
- Object.keys(this.subsets).map((subsetKey) => {
645
+ EntityManager.setModulePath(`${this.id}SubsetMapping`, `sonamu.generated`);
646
+ for (const subsetKey of Object.keys(this.subsets)) {
536
647
  EntityManager.setModulePath(
537
648
  `${this.id}Subset${subsetKey.toUpperCase()}`,
538
- `sonamu.generated`
649
+ `sonamu.generated`,
539
650
  );
540
- });
651
+ }
541
652
  }
542
653
 
543
654
  // enums
544
- Object.keys(this.enumLabels).map((enumId) => {
655
+ for (const enumId of Object.keys(this.enumLabels)) {
545
656
  EntityManager.setModulePath(enumId, `sonamu.generated`);
546
- });
657
+ }
547
658
 
548
659
  // types
549
660
  const typesModulePath = `${basePath}/${this.names.parentFs}.types`;
550
- const typesFileDistPath = path.join(
661
+ const typesFilePath = path.join(
551
662
  Sonamu.apiRootPath,
552
- `dist/application/${typesModulePath}.js`
663
+ runtimePath(`dist/application/${typesModulePath}.js`),
553
664
  );
554
665
 
555
- if (await exists(typesFileDistPath)) {
556
- const importPath = path.relative(__dirname, typesFileDistPath);
557
- const t = await import(importPath);
558
- this.types = Object.keys(t).reduce((result, key) => {
559
- EntityManager.setModulePath(key, typesModulePath);
560
- return {
561
- ...result,
562
- [key]: t[key],
563
- };
564
- }, {});
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 };
565
674
  }
566
675
  }
567
676
 
@@ -592,25 +701,17 @@ export class Entity {
592
701
  const subsetRows = this.getSubsetRows();
593
702
  this.subsets = Object.fromEntries(
594
703
  Object.entries(this.subsets).map(([subsetKey]) => {
595
- return [
596
- subsetKey,
597
- this.subsetRowsToSubsetFields(subsetRows, subsetKey),
598
- ];
599
- })
704
+ return [subsetKey, this.subsetRowsToSubsetFields(subsetRows, subsetKey)];
705
+ }),
600
706
  );
601
707
 
602
708
  // save
603
709
  const jsonPath = path.join(
604
710
  Sonamu.apiRootPath,
605
- `src/application/${this.names.parentFs}/${this.names.fs}.entity.json`
711
+ `src/application/${this.names.parentFs}/${this.names.fs}.entity.json`,
606
712
  );
607
713
  const json = this.toJson();
608
- await writeFile(
609
- jsonPath,
610
- await prettier.format(JSON.stringify(json), {
611
- parser: "json",
612
- })
613
- );
714
+ await writeFile(jsonPath, formatCode(JSON.stringify(json), "json", jsonPath));
614
715
 
615
716
  // reload
616
717
  await EntityManager.register(json);
@@ -618,7 +719,7 @@ export class Entity {
618
719
 
619
720
  getSubsetRows(
620
721
  _subsets?: { [key: string]: string[] },
621
- prefixes: string[] = []
722
+ prefixes: string[] = [],
622
723
  ): EntitySubsetRow[] {
623
724
  if (prefixes.length > 10) {
624
725
  return [];
@@ -626,20 +727,15 @@ export class Entity {
626
727
 
627
728
  const subsets = _subsets ?? this.subsets;
628
729
  const subsetKeys = Object.keys(subsets);
629
- const allFields = _.uniq(subsetKeys.map((key) => subsets[key]).flat());
730
+ const allFields = unique(subsetKeys.flatMap((key) => subsets[key]));
630
731
 
631
732
  return this.props.map((prop) => {
632
733
  if (
633
734
  prop.type === "relation" &&
634
- allFields.find((f) =>
635
- f.startsWith([...prefixes, prop.name].join(".") + ".")
636
- )
735
+ allFields.find((f) => f.startsWith(`${[...prefixes, prop.name].join(".")}.`))
637
736
  ) {
638
737
  const relEntity = EntityManager.get(prop.with);
639
- const children = relEntity.getSubsetRows(subsets, [
640
- ...prefixes,
641
- `${prop.name}`,
642
- ]);
738
+ const children = relEntity.getSubsetRows(subsets, [...prefixes, `${prop.name}`]);
643
739
 
644
740
  return {
645
741
  field: prop.name,
@@ -649,11 +745,8 @@ export class Entity {
649
745
  isOpen: children.length > 0,
650
746
  has: Object.fromEntries(
651
747
  subsetKeys.map((subsetKey) => {
652
- return [
653
- subsetKey,
654
- children.every((child) => child.has[subsetKey] === true),
655
- ];
656
- })
748
+ return [subsetKey, children.every((child) => child.has[subsetKey] === true)];
749
+ }),
657
750
  ),
658
751
  };
659
752
  }
@@ -668,19 +761,16 @@ export class Entity {
668
761
  const subsetFields = subsets[subsetKey];
669
762
  const has = subsetFields.some((f) => {
670
763
  const field = [...prefixes, prop.name].join(".");
671
- return f === field || f.startsWith(field + ".");
764
+ return f === field || f.startsWith(`${field}.`);
672
765
  });
673
766
  return [subsetKey, has];
674
- })
767
+ }),
675
768
  ),
676
769
  };
677
770
  });
678
771
  }
679
772
 
680
- subsetRowsToSubsetFields(
681
- subsetRows: EntitySubsetRow[],
682
- subsetKey: string
683
- ): string[] {
773
+ subsetRowsToSubsetFields(subsetRows: EntitySubsetRow[], subsetKey: string): string[] {
684
774
  return subsetRows
685
775
  .map((subsetRow) => {
686
776
  if (subsetRow.children.length > 0) {
@@ -722,9 +812,7 @@ export class Entity {
722
812
  propName,
723
813
  });
724
814
 
725
- const prop = EntityManager.get(entityId).props.find(
726
- (p) => p.name === propName
727
- );
815
+ const prop = EntityManager.get(entityId).props.find((p) => p.name === propName);
728
816
  if (!prop) {
729
817
  throw new Error(`${entityId}의 잘못된 서브셋키 ${subsetField}`);
730
818
  }
@@ -761,7 +849,7 @@ export class Entity {
761
849
  ...a,
762
850
  propName: newProp.name,
763
851
  }
764
- : a
852
+ : a,
765
853
  );
766
854
  // 분석한 필드를 다시 서브셋 필드로 복구
767
855
  return modified.map((a) => a.propName).join(".");
@@ -799,11 +887,7 @@ export class Entity {
799
887
  const modifiedSubsetFields = subset
800
888
  .map((subsetField) => {
801
889
  const analyzed = relEntity.analyzeSubsetField(subsetField);
802
- if (
803
- analyzed.find(
804
- (a) => a.propName === oldName && a.entityId === this.id
805
- )
806
- ) {
890
+ if (analyzed.find((a) => a.propName === oldName && a.entityId === this.id)) {
807
891
  return null;
808
892
  } else {
809
893
  return subsetField;
@@ -819,9 +903,9 @@ export class Entity {
819
903
  }
820
904
 
821
905
  // 현재 엔티티의 인덱스에서 제외
822
- EntityManager.get(this.id).indexes.map((index) => {
906
+ for (const index of EntityManager.get(this.id).indexes) {
823
907
  index.columns = index.columns.filter((col) => col !== oldName);
824
- });
908
+ }
825
909
 
826
910
  // 프롭 삭제
827
911
  this.props.splice(at, 1);
@@ -839,9 +923,7 @@ export class Entity {
839
923
 
840
924
  // 서브셋 필드를 내려가면서 마지막으로 relation된 엔티티를 찾음
841
925
  const lastEntityId = arr.reduce((entityId, field) => {
842
- const relProp = EntityManager.get(entityId).props.find(
843
- (p) => p.name === field
844
- );
926
+ const relProp = EntityManager.get(entityId).props.find((p) => p.name === field);
845
927
  if (!relProp || relProp.type !== "relation") {
846
928
  console.debug({ arr, thisId: this.id, entityId, field });
847
929
  throw new Error(`잘못된 서브셋키 ${subsetField}`);