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
@@ -0,0 +1,114 @@
1
+ import assert from "assert";
2
+ import z from "zod";
3
+ import { EntityManager } from "../entity/entity-manager";
4
+ import { ServiceUnavailableException } from "../exceptions/so-exceptions";
5
+ import type { EntityPropNode, RenderingNode } from "../types/types";
6
+ import { propToZodType, zodTypeToRenderingNode } from "./zod-converter";
7
+
8
+ /**
9
+ * 엔티티의 특정 subset을 RenderingNode로 변환합니다.
10
+ * subset의 필드들을 Zod 타입으로 변환한 후 UI 렌더링용 노드로 만듭니다.
11
+ * object와 array의 경우 적절한 pick 필드를 자동으로 선택합니다.
12
+ */
13
+ export async function getColumnsNode(entityId: string, subsetKey: string): Promise<RenderingNode> {
14
+ const entity = EntityManager.get(entityId);
15
+ const subset = entity.subsets[subsetKey];
16
+ if (subset === undefined) {
17
+ throw new ServiceUnavailableException(`Subset ${subsetKey} 가 없습니다.`);
18
+ }
19
+ const propNodes = entity.fieldExprsToPropNodes(subset);
20
+ const rootPropNode: EntityPropNode = {
21
+ nodeType: "object",
22
+ children: propNodes,
23
+ };
24
+
25
+ // biome-ignore lint/suspicious/noExplicitAny: zod 스키마를 로드할 때 사용하는 타입
26
+ const columnsZodType = (await propNodeToZodType(rootPropNode)) as z.ZodObject<any>;
27
+
28
+ const columnsNode = zodTypeToRenderingNode(columnsZodType);
29
+ assert(columnsNode.children !== undefined, "columnsNode.children is undefined");
30
+ columnsNode.children = columnsNode.children.map((child) => {
31
+ if (child.renderType === "object") {
32
+ assert(child.children !== undefined, "child.children is undefined");
33
+ const pickedCol = child.children.find((cc) => ["title", "name"].includes(cc.name));
34
+ if (pickedCol) {
35
+ return {
36
+ ...child,
37
+ renderType: "object-pick",
38
+ config: {
39
+ picked: pickedCol.name,
40
+ },
41
+ };
42
+ } else {
43
+ return child;
44
+ }
45
+ } else if (
46
+ child.renderType === "array" &&
47
+ child.element &&
48
+ child.element.renderType === "object"
49
+ ) {
50
+ const pickedCol = child.element?.children?.find((cc) => ["title", "name"].includes(cc.name));
51
+ if (pickedCol) {
52
+ return {
53
+ ...child,
54
+ element: {
55
+ ...child.element,
56
+ renderType: "object-pick",
57
+ config: {
58
+ picked: pickedCol.name,
59
+ },
60
+ },
61
+ };
62
+ } else {
63
+ return child;
64
+ }
65
+ }
66
+ return child;
67
+ });
68
+
69
+ return columnsNode;
70
+ }
71
+
72
+ /**
73
+ * EntityPropNode를 Zod 타입으로 변환합니다.
74
+ * plain, array, object 세 가지 nodeType을 재귀적으로 처리합니다.
75
+ */
76
+ export async function propNodeToZodType(propNode: EntityPropNode): Promise<z.ZodTypeAny> {
77
+ if (propNode.nodeType === "plain") {
78
+ return propToZodType(propNode.prop);
79
+ } else if (propNode.nodeType === "array") {
80
+ if (propNode.prop === undefined) {
81
+ throw new Error();
82
+ } else if (propNode.children.length > 0) {
83
+ return (
84
+ await propNodeToZodType({
85
+ ...propNode,
86
+ nodeType: "object",
87
+ })
88
+ ).array();
89
+ } else {
90
+ const innerType = await propToZodType(propNode.prop);
91
+ if (propNode.prop.nullable === true) {
92
+ return z.array(innerType).nullable();
93
+ } else {
94
+ return z.array(innerType);
95
+ }
96
+ }
97
+ } else if (propNode.nodeType === "object") {
98
+ const entries = await Promise.all(
99
+ propNode.children.map(async (childPropNode) => {
100
+ assert(childPropNode.prop?.name !== undefined, "childPropNode.prop.name is undefined");
101
+ return [childPropNode.prop.name, await propNodeToZodType(childPropNode)] as const;
102
+ }),
103
+ );
104
+ const obj = Object.fromEntries(entries);
105
+
106
+ if (propNode.prop?.nullable === true) {
107
+ return z.object(obj).nullable();
108
+ } else {
109
+ return z.object(obj);
110
+ }
111
+ } else {
112
+ throw Error;
113
+ }
114
+ }
@@ -0,0 +1,81 @@
1
+ import inflection from "inflection";
2
+ import { EntityManager, type EntityNamesRecord } from "../entity/entity-manager";
3
+ import { isEnumProp, isRelationProp, type RelationProp } from "../types/types";
4
+
5
+ /**
6
+ * Enum의 표시용 라벨을 가져옵니다.
7
+ * OrderBy, SearchField 등 특수한 경우와 일반 Enum을 구분하여 처리합니다.
8
+ */
9
+ export function getLabel(entityId: string, enumId: string): string {
10
+ if (enumId.endsWith("OrderBy")) {
11
+ return "정렬";
12
+ } else if (enumId.endsWith("SearchField")) {
13
+ return "검색";
14
+ } else {
15
+ const enumProp = EntityManager.get(entityId).props.find(
16
+ (prop) => `${entityId}${inflection.camelize(prop.name)}` === enumId,
17
+ );
18
+ if (enumProp?.desc) {
19
+ return enumProp.desc;
20
+ }
21
+ return enumId;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * 컬럼 이름으로부터 Enum 정보를 추출합니다.
27
+ * Entity의 prop 중 enum 타입인 것을 찾아 관련 정보를 반환합니다.
28
+ */
29
+ export function getEnumInfoFromColName(
30
+ entityId: string,
31
+ colName: string,
32
+ ): {
33
+ id: string;
34
+ targetEntityNames: EntityNamesRecord;
35
+ targetEntityId: string;
36
+ title: string;
37
+ } {
38
+ const baseEntity = EntityManager.get(entityId);
39
+ const prop = baseEntity.props.find((p) => p.name === colName);
40
+ if (prop && isEnumProp(prop)) {
41
+ return {
42
+ id: prop.id,
43
+ targetEntityId: entityId,
44
+ targetEntityNames: EntityManager.getNamesFromId(entityId),
45
+ title: prop.desc ?? prop.id,
46
+ };
47
+ } else {
48
+ const idCandidate = inflection.camelize(
49
+ `${inflection.underscore(entityId)}_${inflection.underscore(colName)}`,
50
+ false,
51
+ );
52
+ try {
53
+ const targetEntityNames = EntityManager.getNamesFromId(entityId);
54
+ return {
55
+ id: idCandidate,
56
+ targetEntityId: entityId,
57
+ targetEntityNames: targetEntityNames,
58
+ title: idCandidate,
59
+ };
60
+ } catch {}
61
+ throw new Error(`찾을 수 없는 EnumProp ${colName}`);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 컬럼 이름으로부터 Relation prop 정보를 가져옵니다.
67
+ * 관계형 prop이 아닌 경우 에러를 발생시킵니다.
68
+ */
69
+ export function getRelationPropFromColName(entityId: string, colName: string): RelationProp {
70
+ const baseEntity = EntityManager.get(entityId);
71
+ const relProp = baseEntity.props.find((prop) => prop.name === colName);
72
+ if (isRelationProp(relProp)) {
73
+ const relEntity = EntityManager.get(relProp.with);
74
+ if (relEntity.parentId !== undefined) {
75
+ throw new Error("Only parent entities can be used as relation props");
76
+ }
77
+ return relProp;
78
+ } else {
79
+ throw new Error(`찾을 수 없는 Relation ${colName}`);
80
+ }
81
+ }
@@ -1,7 +1,7 @@
1
- import { TemplateOptions } from "../types/types";
2
- import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
- import { Template } from "./base-template";
4
- import { Sonamu } from "../api";
1
+ import { Sonamu } from "../../api";
2
+ import { EntityManager, type EntityNamesRecord } from "../../entity/entity-manager";
3
+ import type { TemplateOptions } from "../../types/types";
4
+ import { Template } from "../template";
5
5
 
6
6
  export class Template__entity extends Template {
7
7
  constructor() {
@@ -38,11 +38,11 @@ export class Template__entity extends Template {
38
38
  id: entityId,
39
39
  title: title ?? entityId,
40
40
  parentId,
41
- table: table ?? names.fsPlural.replace(/\-/g, "_"),
41
+ table: table ?? names.fsPlural.replace(/-/g, "_"),
42
42
  props: options.props?.length
43
43
  ? options.props
44
44
  : [
45
- { name: "id", type: "integer", unsigned: true, desc: "ID" },
45
+ { name: "id", type: "integer", desc: "ID" },
46
46
  ...(parent
47
47
  ? [
48
48
  {
@@ -58,7 +58,7 @@ export class Template__entity extends Template {
58
58
  : []),
59
59
  {
60
60
  name: "created_at",
61
- type: "timestamp",
61
+ type: "date",
62
62
  desc: "등록일시",
63
63
  dbDefault: "CURRENT_TIMESTAMP",
64
64
  },
@@ -1,12 +1,13 @@
1
- import _ from "lodash";
2
- import { TemplateOptions } from "../types/types";
3
- import { EntityManager } from "../entity/entity-manager";
4
- import { Entity } from "../entity/entity";
5
- import { EntityPropNode } from "../types/types";
6
- import { propNodeToZodTypeDef, zodTypeToZodCode } from "../api/code-converters";
7
- import { Template } from "./base-template";
8
- import { nonNullable } from "../utils/utils";
9
- import { Sonamu } from "../api";
1
+ import assert from "assert";
2
+ import { unique } from "radashi";
3
+ import { Sonamu } from "../../api";
4
+ import type { Entity } from "../../entity/entity";
5
+ import { EntityManager } from "../../entity/entity-manager";
6
+ import { Naite } from "../../naite/naite";
7
+ import { type EntityPropNode, isVirtualProp } from "../../types/types";
8
+ import { nonNullable } from "../../utils/utils";
9
+ import { Template } from "../template";
10
+ import { propNodeToZodTypeDef, zodTypeToZodCode } from "../zod-converter";
10
11
 
11
12
  export type SourceCode = {
12
13
  label: string;
@@ -20,37 +21,28 @@ export class Template__generated extends Template {
20
21
 
21
22
  getTargetAndPath() {
22
23
  const { dir } = Sonamu.config.api;
23
-
24
24
  return {
25
25
  target: `${dir}/src/application`,
26
26
  path: `sonamu.generated.ts`,
27
27
  };
28
28
  }
29
-
30
- render({}: TemplateOptions["generated"]) {
29
+ render() {
31
30
  const entityIds = EntityManager.getAllIds();
32
31
  const entities = entityIds.map((id) => EntityManager.get(id));
33
32
 
34
33
  // 전체 SourceCode 생성
35
- const sourceCodes = entities
36
- .map((entity) => {
37
- return [
38
- this.getEnumsSourceCode(entity),
39
- this.getBaseSchemaSourceCode(entity),
40
- this.getBaseListParamsSourceCode(entity),
41
- this.getSubsetSourceCode(entity),
42
- ].filter(nonNullable);
43
- })
44
- .flat();
34
+ const sourceCodes = entities.flatMap((entity) => {
35
+ return [
36
+ this.getEnumsSourceCode(entity),
37
+ this.getBaseSchemaSourceCode(entity),
38
+ this.getBaseListParamsSourceCode(entity),
39
+ this.getSubsetSourceCode(entity),
40
+ ].filter(nonNullable);
41
+ });
42
+ Naite.t("Template__generated:sourceCodes", sourceCodes);
45
43
 
46
44
  // Sort
47
- const LABEL_KEY_ORDER = [
48
- "Enums",
49
- "BaseSchema",
50
- "BaseListParams",
51
- "Subsets",
52
- "SubsetQueries",
53
- ];
45
+ const LABEL_KEY_ORDER = ["Enums", "BaseSchema", "BaseListParams", "Subsets", "SubsetQueries"];
54
46
  sourceCodes.sort((a, b) => {
55
47
  const [aKey] = a.label.split(":");
56
48
  const [bKey] = b.label.split(":");
@@ -71,47 +63,45 @@ export class Template__generated extends Template {
71
63
  return result;
72
64
  }
73
65
  return {
74
- lines: [...result!.lines, `// ${ts.label}`, ...ts.lines, ""],
75
- importKeys: _.uniq([...result!.importKeys, ...ts.importKeys].sort()),
66
+ lines: [...result.lines, `// ${ts.label}`, ...ts.lines, ""],
67
+ importKeys: unique([...result.importKeys, ...ts.importKeys].sort()),
76
68
  };
77
69
  },
78
70
  {
79
71
  lines: [],
80
72
  importKeys: [],
81
- } as Omit<SourceCode, "label">
73
+ } as Omit<SourceCode, "label">,
82
74
  );
83
75
 
84
76
  // .types.ts의 타입을 참조하는 경우 순환참조(상호참조)가 발생하므로 타입을 가져와 인라인 처리
85
- const allTypeKeys = entities
86
- .map((entity) => Object.keys(entity.types))
87
- .flat();
77
+ const allTypeKeys = entities.flatMap((entity) => Object.keys(entity.types));
88
78
  const cdImportKeys = sourceCode.importKeys.filter((importKey) =>
89
- allTypeKeys.includes(importKey)
79
+ allTypeKeys.includes(importKey),
90
80
  );
91
81
  if (cdImportKeys.length > 0) {
92
- const customScalarLines = cdImportKeys
93
- .map((importKey) => {
94
- const entity = entities.find((entity) => entity.types[importKey]);
95
- if (!entity) {
96
- throw new Error(`ZodType not found ${importKey}`);
97
- }
98
- const zodType = entity.types[importKey]!;
99
-
100
- return [
101
- `// CustomScalar: ${importKey}`,
102
- `const ${importKey} = ${zodTypeToZodCode(zodType)};`,
103
- `type ${importKey} = z.infer<typeof ${importKey}>`,
104
- "",
105
- ];
106
- })
107
- .flat();
82
+ const customScalarLines = cdImportKeys.flatMap((importKey) => {
83
+ const entity = entities.find((entity) => entity.types[importKey]);
84
+ if (!entity) {
85
+ throw new Error(`ZodType not found ${importKey}`);
86
+ }
87
+ const zodType = entity.types[importKey];
88
+ assert(zodType);
89
+
90
+ return [
91
+ `// CustomScalar: ${importKey}`,
92
+ `const ${importKey} = ${zodTypeToZodCode(zodType)};`,
93
+ `type ${importKey} = z.infer<typeof ${importKey}>`,
94
+ "",
95
+ ];
96
+ });
108
97
  sourceCode.lines = [...customScalarLines, ...sourceCode.lines];
109
98
  sourceCode.importKeys = sourceCode.importKeys.filter(
110
- (importKey) => !cdImportKeys.includes(importKey)
99
+ (importKey) => !cdImportKeys.includes(importKey),
111
100
  );
112
101
  }
113
102
 
114
103
  const body = sourceCode.lines.join("\n");
104
+ Naite.t("Template__generated:body", body);
115
105
 
116
106
  // import
117
107
  const sonamuImports = [
@@ -126,6 +116,9 @@ export class Template__generated extends Template {
126
116
  body,
127
117
  importKeys: sourceCode.importKeys,
128
118
  customHeaders: [
119
+ "/** biome-ignore-all lint: generated는 무시 */",
120
+ "/** biome-ignore-all assist: generated는 무시 */",
121
+ "",
129
122
  `import { z } from 'zod';`,
130
123
  `import { ${sonamuImports.join(",")} } from "sonamu";`,
131
124
  ],
@@ -141,23 +134,19 @@ export class Template__generated extends Template {
141
134
  lines: [
142
135
  ...Object.entries(entity.enumLabels)
143
136
  .filter(([_, enumLabel]) => Object.keys(enumLabel).length > 0)
144
- .map(([enumId, enumLabel]) => [
137
+ .flatMap(([enumId, enumLabel]) => [
145
138
  `export const ${enumId} = z.enum([${Object.keys(enumLabel).map(
146
- (el) => `"${el}"`
139
+ (el) => `"${el}"`,
147
140
  )}]).describe("${enumId}");`,
148
- `export type ${enumId} = z.infer<typeof ${enumId}>`,
149
- `export const ${enumId}Label = ${JSON.stringify(enumLabel)}`,
150
- ])
151
- .flat(),
141
+ `export type ${enumId} = z.infer<typeof ${enumId}>;`,
142
+ `export const ${enumId}Label = ${JSON.stringify(enumLabel)};`,
143
+ ]),
152
144
  ],
153
145
  importKeys: [],
154
146
  };
155
147
  }
156
148
 
157
- getBaseSchemaSourceCode(
158
- entity: Entity,
159
- importKeys: string[] = []
160
- ): SourceCode {
149
+ getBaseSchemaSourceCode(entity: Entity, importKeys: string[] = []): SourceCode {
161
150
  const schemaName = `${entity.names.module}BaseSchema`;
162
151
  const propNode: EntityPropNode = {
163
152
  nodeType: "object",
@@ -169,23 +158,39 @@ export class Template__generated extends Template {
169
158
  }),
170
159
  };
171
160
 
172
- const schemaBody = propNodeToZodTypeDef(propNode, importKeys);
161
+ const schemaBody = (() => {
162
+ const result = propNodeToZodTypeDef(propNode, importKeys);
163
+ if (result.endsWith(",")) {
164
+ return result.slice(0, -1);
165
+ }
166
+
167
+ return result;
168
+ })();
173
169
 
174
170
  // fulltext index에 포함된 컬럼들 추출
175
- const fulltextColumns = _.uniq(
176
- entity.indexes
177
- .filter((index) => index.type === "fulltext")
178
- .flatMap((index) => index.columns)
171
+ const fulltextColumns = unique(
172
+ entity.indexes.filter((index) => index.type === "fulltext").flatMap((index) => index.columns),
179
173
  );
180
174
 
175
+ // virtual props
176
+ const virtualProps = entity.props
177
+ .filter((prop) => isVirtualProp(prop))
178
+ .map((prop) => prop.name);
179
+
181
180
  const lines = [
182
- `export const ${schemaName} = ${schemaBody}`,
181
+ `export const ${schemaName} = ${schemaBody};`,
183
182
  `export type ${schemaName} = z.infer<typeof ${schemaName}>` +
184
183
  (fulltextColumns.length > 0
185
184
  ? ` & { readonly __fulltext__: readonly [${fulltextColumns
186
185
  .map((col) => `"${col}"`)
187
186
  .join(", ")}] }`
188
- : ""),
187
+ : "") +
188
+ (virtualProps.length > 0
189
+ ? ` & { readonly __virtual__: readonly [${virtualProps
190
+ .map((prop) => `"${prop}"`)
191
+ .join(", ")}] }`
192
+ : "") +
193
+ ";",
189
194
  ];
190
195
 
191
196
  return {
@@ -234,7 +239,7 @@ z.object({
234
239
 
235
240
  const lines = [
236
241
  `export const ${schemaName} = ${schemaBody}`,
237
- `export type ${schemaName} = z.infer<typeof ${schemaName}>`,
242
+ `export type ${schemaName} = z.infer<typeof ${schemaName}>;`,
238
243
  ];
239
244
 
240
245
  return {
@@ -245,7 +250,7 @@ z.object({
245
250
  }
246
251
 
247
252
  getSubsetSourceCode(entity: Entity): SourceCode | null {
248
- if (Object.keys(entity.subsets).length == 0) {
253
+ if (Object.keys(entity.subsets).length === 0) {
249
254
  return null;
250
255
  } else if (entity.parentId !== undefined) {
251
256
  return null;
@@ -254,45 +259,40 @@ z.object({
254
259
  const subsetKeys = Object.keys(entity.subsets);
255
260
  const importKeys: string[] = [];
256
261
  const lines: string[] = [
257
- ...subsetKeys
258
- .map((subsetKey) => {
259
- // 서브셋에서 FieldExpr[] 가져옴
260
- const fieldExprs = entity.subsets[subsetKey];
261
-
262
- // FieldExpr[]로 EntityPropNode[] 가져옴
263
- const propNodes = entity.fieldExprsToPropNodes(fieldExprs);
264
- const schemaName = `${entity.names.module}Subset${subsetKey}`;
265
- const propNode: EntityPropNode = {
266
- nodeType: "object",
267
- children: propNodes,
268
- };
269
-
270
- // EntityPropNode[]로 ZodTypeDef(string)을 가져옴
271
- const body = propNodeToZodTypeDef(propNode, importKeys);
272
-
273
- return [
274
- `export const ${schemaName} = ${body}`,
275
- `export type ${schemaName} = z.infer<typeof ${schemaName}>`,
276
- ];
277
- })
278
- .flat(),
262
+ ...subsetKeys.flatMap((subsetKey) => {
263
+ // 서브셋에서 FieldExpr[] 가져옴
264
+ const fieldExprs = entity.subsets[subsetKey];
265
+
266
+ // FieldExpr[]로 EntityPropNode[] 가져옴
267
+ const propNodes = entity.fieldExprsToPropNodes(fieldExprs);
268
+ const schemaName = `${entity.names.module}Subset${subsetKey}`;
269
+ const propNode: EntityPropNode = {
270
+ nodeType: "object",
271
+ children: propNodes,
272
+ };
273
+
274
+ // EntityPropNode[]로 ZodTypeDef(string)을 가져옴
275
+ const body = propNodeToZodTypeDef(propNode, importKeys);
276
+
277
+ return [
278
+ `export const ${schemaName} = ${body.replace(/,$/, "")};`,
279
+ `export type ${schemaName} = z.infer<typeof ${schemaName}>;`,
280
+ ];
281
+ }),
279
282
  `export type ${entity.names.module}SubsetMapping = {`,
280
- ...subsetKeys.map(
281
- (subsetKey) =>
282
- ` ${subsetKey}: ${entity.names.module}Subset${subsetKey};`
283
- ),
284
- "}",
283
+ ...subsetKeys.map((subsetKey) => ` ${subsetKey}: ${entity.names.module}Subset${subsetKey};`),
284
+ "};",
285
285
  `export const ${entity.names.module}SubsetKey = z.enum([${subsetKeys
286
286
  .map((k) => `"${k}"`)
287
287
  .join(",")}]);`,
288
- `export type ${entity.names.module}SubsetKey = z.infer<typeof ${entity.names.module}SubsetKey>`,
288
+ `export type ${entity.names.module}SubsetKey = z.infer<typeof ${entity.names.module}SubsetKey>;`,
289
289
  "",
290
290
  ];
291
291
 
292
292
  return {
293
293
  label: `Subsets: ${entity.id}`,
294
294
  lines,
295
- importKeys: _.uniq(importKeys),
295
+ importKeys: unique(importKeys),
296
296
  };
297
297
  }
298
298
  }