sonamu 0.6.0 → 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 (406) hide show
  1. package/.swcrc.project-default +18 -0
  2. package/bin/cli.js +24 -0
  3. package/dist/ai/agents/agent.d.ts +11 -0
  4. package/dist/ai/agents/agent.d.ts.map +1 -0
  5. package/dist/ai/agents/agent.js +65 -0
  6. package/dist/ai/agents/index.d.ts +3 -0
  7. package/dist/ai/agents/index.d.ts.map +1 -0
  8. package/dist/ai/agents/index.js +4 -0
  9. package/dist/ai/agents/types.d.ts +43 -0
  10. package/dist/ai/agents/types.d.ts.map +1 -0
  11. package/dist/ai/agents/types.js +3 -0
  12. package/dist/ai/index.d.ts +2 -0
  13. package/dist/ai/index.d.ts.map +1 -0
  14. package/dist/ai/index.js +3 -0
  15. package/dist/ai/providers/rtzr/api.d.ts +22 -0
  16. package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
  17. package/dist/ai/providers/rtzr/api.js +28 -0
  18. package/dist/ai/providers/rtzr/error.d.ts +18 -0
  19. package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
  20. package/dist/ai/providers/rtzr/error.js +29 -0
  21. package/dist/ai/providers/rtzr/index.d.ts +5 -0
  22. package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
  23. package/dist/ai/providers/rtzr/index.js +6 -0
  24. package/dist/ai/providers/rtzr/model.d.ts +52 -0
  25. package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
  26. package/dist/ai/providers/rtzr/model.js +137 -0
  27. package/dist/ai/providers/rtzr/options.d.ts +7 -0
  28. package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
  29. package/dist/ai/providers/rtzr/options.js +47 -0
  30. package/dist/ai/providers/rtzr/provider.d.ts +18 -0
  31. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
  32. package/dist/ai/providers/rtzr/provider.js +54 -0
  33. package/dist/ai/providers/rtzr/utils.d.ts +19 -0
  34. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
  35. package/dist/ai/providers/rtzr/utils.js +88 -0
  36. package/dist/api/base-frame.d.ts +2 -2
  37. package/dist/api/base-frame.d.ts.map +1 -1
  38. package/dist/api/base-frame.js +2 -1
  39. package/dist/api/caster.d.ts.map +1 -1
  40. package/dist/api/caster.js +6 -1
  41. package/dist/api/code-converters.d.ts +58 -14
  42. package/dist/api/code-converters.d.ts.map +1 -1
  43. package/dist/api/code-converters.js +178 -409
  44. package/dist/api/config.d.ts +27 -13
  45. package/dist/api/config.d.ts.map +1 -1
  46. package/dist/api/config.js +19 -26
  47. package/dist/api/context.d.ts +4 -3
  48. package/dist/api/context.d.ts.map +1 -1
  49. package/dist/api/context.js +1 -1
  50. package/dist/api/decorators.d.ts +20 -6
  51. package/dist/api/decorators.d.ts.map +1 -1
  52. package/dist/api/decorators.js +111 -18
  53. package/dist/api/index.d.ts +2 -2
  54. package/dist/api/index.d.ts.map +1 -1
  55. package/dist/api/index.js +3 -3
  56. package/dist/api/sonamu.d.ts +7 -7
  57. package/dist/api/sonamu.d.ts.map +1 -1
  58. package/dist/api/sonamu.js +83 -51
  59. package/dist/api/validator.d.ts +6 -0
  60. package/dist/api/validator.d.ts.map +1 -0
  61. package/dist/api/validator.js +81 -0
  62. package/dist/bin/build-config.d.ts +5 -1
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +5 -2
  65. package/dist/bin/cli.js +165 -64
  66. package/dist/bin/loader-register.d.ts +2 -0
  67. package/dist/bin/loader-register.d.ts.map +1 -0
  68. package/dist/bin/loader-register.js +34 -0
  69. package/dist/database/_batch_update.d.ts +5 -3
  70. package/dist/database/_batch_update.d.ts.map +1 -1
  71. package/dist/database/_batch_update.js +30 -13
  72. package/dist/database/base-model.d.ts +96 -10
  73. package/dist/database/base-model.d.ts.map +1 -1
  74. package/dist/database/base-model.js +232 -89
  75. package/dist/database/base-model.types.d.ts +93 -0
  76. package/dist/database/base-model.types.d.ts.map +1 -0
  77. package/dist/database/base-model.types.js +10 -0
  78. package/dist/database/code-generator.d.ts +1 -1
  79. package/dist/database/code-generator.d.ts.map +1 -1
  80. package/dist/database/code-generator.js +11 -10
  81. package/dist/database/db.d.ts +5 -6
  82. package/dist/database/db.d.ts.map +1 -1
  83. package/dist/database/db.js +22 -25
  84. package/dist/database/puri-subset.test-d.js +81 -0
  85. package/dist/database/puri-subset.types.d.ts +123 -0
  86. package/dist/database/puri-subset.types.d.ts.map +1 -0
  87. package/dist/database/puri-subset.types.js +16 -0
  88. package/dist/database/puri-wrapper.d.ts +13 -11
  89. package/dist/database/puri-wrapper.d.ts.map +1 -1
  90. package/dist/database/puri-wrapper.js +2 -2
  91. package/dist/database/puri.d.ts +25 -14
  92. package/dist/database/puri.d.ts.map +1 -1
  93. package/dist/database/puri.js +83 -21
  94. package/dist/database/puri.types.d.ts +21 -7
  95. package/dist/database/puri.types.d.ts.map +1 -1
  96. package/dist/database/puri.types.js +4 -1
  97. package/dist/database/transaction-context.d.ts +1 -1
  98. package/dist/database/transaction-context.d.ts.map +1 -1
  99. package/dist/database/transaction-context.js +1 -1
  100. package/dist/database/upsert-builder.d.ts +9 -3
  101. package/dist/database/upsert-builder.d.ts.map +1 -1
  102. package/dist/database/upsert-builder.js +228 -78
  103. package/dist/entity/entity-manager.d.ts +165 -2
  104. package/dist/entity/entity-manager.d.ts.map +1 -1
  105. package/dist/entity/entity-manager.js +26 -10
  106. package/dist/entity/entity.d.ts +5 -3
  107. package/dist/entity/entity.d.ts.map +1 -1
  108. package/dist/entity/entity.js +153 -54
  109. package/dist/exceptions/error-handler.d.ts +1 -1
  110. package/dist/exceptions/error-handler.d.ts.map +1 -1
  111. package/dist/exceptions/error-handler.js +1 -1
  112. package/dist/exceptions/so-exceptions.d.ts +1 -1
  113. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  114. package/dist/exceptions/so-exceptions.js +1 -1
  115. package/dist/file-storage/driver.d.ts +1 -1
  116. package/dist/file-storage/driver.d.ts.map +1 -1
  117. package/dist/file-storage/driver.js +1 -1
  118. package/dist/file-storage/file-storage.js +2 -2
  119. package/dist/index.d.ts +18 -11
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +19 -13
  122. package/dist/migration/code-generation.d.ts +1 -1
  123. package/dist/migration/code-generation.d.ts.map +1 -1
  124. package/dist/migration/code-generation.js +123 -67
  125. package/dist/migration/migration-set.d.ts +2 -10
  126. package/dist/migration/migration-set.d.ts.map +1 -1
  127. package/dist/migration/migration-set.js +67 -218
  128. package/dist/migration/migrator.d.ts +24 -73
  129. package/dist/migration/migrator.d.ts.map +1 -1
  130. package/dist/migration/migrator.js +121 -301
  131. package/dist/migration/postgresql-schema-reader.d.ts +51 -0
  132. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
  133. package/dist/migration/postgresql-schema-reader.js +245 -0
  134. package/dist/migration/types.d.ts +6 -38
  135. package/dist/migration/types.d.ts.map +1 -1
  136. package/dist/migration/types.js +1 -1
  137. package/dist/naite/messaging-types.d.ts +43 -0
  138. package/dist/naite/messaging-types.d.ts.map +1 -0
  139. package/dist/naite/messaging-types.js +7 -0
  140. package/dist/naite/naite-reporter.d.ts +41 -0
  141. package/dist/naite/naite-reporter.d.ts.map +1 -0
  142. package/dist/naite/naite-reporter.js +102 -0
  143. package/dist/naite/naite.d.ts +91 -8
  144. package/dist/naite/naite.d.ts.map +1 -1
  145. package/dist/naite/naite.js +285 -41
  146. package/dist/stream/sse.d.ts +2 -2
  147. package/dist/stream/sse.d.ts.map +1 -1
  148. package/dist/stream/sse.js +1 -1
  149. package/dist/syncer/api-parser.d.ts +3 -13
  150. package/dist/syncer/api-parser.d.ts.map +1 -1
  151. package/dist/syncer/api-parser.js +67 -56
  152. package/dist/syncer/checksum.d.ts +2 -2
  153. package/dist/syncer/checksum.d.ts.map +1 -1
  154. package/dist/syncer/checksum.js +11 -11
  155. package/dist/syncer/code-generator.d.ts +3 -3
  156. package/dist/syncer/code-generator.d.ts.map +1 -1
  157. package/dist/syncer/code-generator.js +37 -17
  158. package/dist/syncer/entity-operations.d.ts +2 -2
  159. package/dist/syncer/entity-operations.d.ts.map +1 -1
  160. package/dist/syncer/entity-operations.js +9 -8
  161. package/dist/syncer/file-patterns.d.ts +1 -1
  162. package/dist/syncer/file-patterns.d.ts.map +1 -1
  163. package/dist/syncer/file-patterns.js +1 -1
  164. package/dist/syncer/index.d.ts +4 -4
  165. package/dist/syncer/index.d.ts.map +1 -1
  166. package/dist/syncer/index.js +5 -5
  167. package/dist/syncer/module-loader.d.ts +4 -4
  168. package/dist/syncer/module-loader.d.ts.map +1 -1
  169. package/dist/syncer/module-loader.js +17 -12
  170. package/dist/syncer/syncer.d.ts +31 -24
  171. package/dist/syncer/syncer.d.ts.map +1 -1
  172. package/dist/syncer/syncer.js +92 -45
  173. package/dist/template/entity-converter.d.ts +1 -1
  174. package/dist/template/entity-converter.d.ts.map +1 -1
  175. package/dist/template/entity-converter.js +15 -8
  176. package/dist/template/helpers.d.ts +2 -2
  177. package/dist/template/helpers.d.ts.map +1 -1
  178. package/dist/template/helpers.js +3 -3
  179. package/dist/template/implementations/entity.template.d.ts +2 -2
  180. package/dist/template/implementations/entity.template.d.ts.map +1 -1
  181. package/dist/template/implementations/entity.template.js +4 -5
  182. package/dist/template/implementations/generated.template.d.ts +2 -3
  183. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  184. package/dist/template/implementations/generated.template.js +46 -29
  185. package/dist/template/implementations/generated_http.template.d.ts +2 -3
  186. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  187. package/dist/template/implementations/generated_http.template.js +9 -9
  188. package/dist/template/implementations/generated_sso.template.d.ts +3 -4
  189. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  190. package/dist/template/implementations/generated_sso.template.js +54 -25
  191. package/dist/template/implementations/init_types.template.d.ts +2 -2
  192. package/dist/template/implementations/init_types.template.d.ts.map +1 -1
  193. package/dist/template/implementations/init_types.template.js +2 -2
  194. package/dist/template/implementations/model.template.d.ts +2 -2
  195. package/dist/template/implementations/model.template.d.ts.map +1 -1
  196. package/dist/template/implementations/model.template.js +47 -37
  197. package/dist/template/implementations/model_test.template.d.ts +2 -2
  198. package/dist/template/implementations/model_test.template.d.ts.map +1 -1
  199. package/dist/template/implementations/model_test.template.js +2 -2
  200. package/dist/template/implementations/service.template.d.ts +4 -4
  201. package/dist/template/implementations/service.template.d.ts.map +1 -1
  202. package/dist/template/implementations/service.template.js +24 -16
  203. package/dist/template/implementations/view_enums_buttonset.template.d.ts +2 -2
  204. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -1
  205. package/dist/template/implementations/view_enums_buttonset.template.js +1 -1
  206. package/dist/template/implementations/view_enums_dropdown.template.d.ts +2 -2
  207. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -1
  208. package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
  209. package/dist/template/implementations/view_enums_select.template.d.ts +2 -2
  210. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -1
  211. package/dist/template/implementations/view_enums_select.template.js +2 -2
  212. package/dist/template/implementations/view_form.template.d.ts +2 -2
  213. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  214. package/dist/template/implementations/view_form.template.js +4 -4
  215. package/dist/template/implementations/view_id_all_select.template.d.ts +2 -2
  216. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
  217. package/dist/template/implementations/view_id_all_select.template.js +1 -1
  218. package/dist/template/implementations/view_id_async_select.template.d.ts +2 -2
  219. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -1
  220. package/dist/template/implementations/view_id_async_select.template.js +1 -1
  221. package/dist/template/implementations/view_list.template.d.ts +2 -2
  222. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  223. package/dist/template/implementations/view_list.template.js +29 -19
  224. package/dist/template/implementations/view_list_columns.template.d.ts +3 -3
  225. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -1
  226. package/dist/template/implementations/view_list_columns.template.js +1 -1
  227. package/dist/template/implementations/view_search_input.template.d.ts +2 -2
  228. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
  229. package/dist/template/implementations/view_search_input.template.js +1 -1
  230. package/dist/template/index.d.ts +4 -2
  231. package/dist/template/index.d.ts.map +1 -1
  232. package/dist/template/index.js +5 -3
  233. package/dist/template/template-manager.d.ts +56 -0
  234. package/dist/template/template-manager.d.ts.map +1 -0
  235. package/dist/template/template-manager.js +125 -0
  236. package/dist/template/template-types.d.ts +16 -0
  237. package/dist/template/template-types.d.ts.map +1 -0
  238. package/dist/template/template-types.js +7 -0
  239. package/dist/template/template.d.ts +12 -2
  240. package/dist/template/template.d.ts.map +1 -1
  241. package/dist/template/template.js +19 -6
  242. package/dist/template/zod-converter.d.ts +40 -7
  243. package/dist/template/zod-converter.d.ts.map +1 -1
  244. package/dist/template/zod-converter.js +341 -58
  245. package/dist/testing/_relation-graph.d.ts +1 -1
  246. package/dist/testing/_relation-graph.d.ts.map +1 -1
  247. package/dist/testing/_relation-graph.js +12 -3
  248. package/dist/testing/fixture-manager.d.ts +42 -11
  249. package/dist/testing/fixture-manager.d.ts.map +1 -1
  250. package/dist/testing/fixture-manager.js +338 -236
  251. package/dist/types/types.d.ts +709 -104
  252. package/dist/types/types.d.ts.map +1 -1
  253. package/dist/types/types.js +309 -52
  254. package/dist/typings/knex.d.js +2 -2
  255. package/dist/utils/async-utils.d.ts.map +1 -1
  256. package/dist/utils/async-utils.js +3 -3
  257. package/dist/utils/console-util.js +1 -1
  258. package/dist/utils/controller.d.ts +1 -0
  259. package/dist/utils/controller.d.ts.map +1 -1
  260. package/dist/utils/controller.js +4 -1
  261. package/dist/utils/esm-utils.d.ts +0 -6
  262. package/dist/utils/esm-utils.d.ts.map +1 -1
  263. package/dist/utils/esm-utils.js +2 -9
  264. package/dist/utils/formatter.d.ts +3 -0
  265. package/dist/utils/formatter.d.ts.map +1 -0
  266. package/dist/utils/formatter.js +110 -0
  267. package/dist/utils/fs-utils.d.ts +1 -1
  268. package/dist/utils/fs-utils.d.ts.map +1 -1
  269. package/dist/utils/fs-utils.js +1 -1
  270. package/dist/utils/lodash-able.d.ts.map +1 -1
  271. package/dist/utils/lodash-able.js +1 -1
  272. package/dist/utils/object-utils.d.ts +44 -0
  273. package/dist/utils/object-utils.d.ts.map +1 -0
  274. package/dist/utils/object-utils.js +191 -0
  275. package/dist/utils/path-utils.d.ts +1 -1
  276. package/dist/utils/path-utils.d.ts.map +1 -1
  277. package/dist/utils/path-utils.js +3 -3
  278. package/dist/utils/process-utils.js +1 -1
  279. package/dist/utils/sql-parser.d.ts +5 -1
  280. package/dist/utils/sql-parser.d.ts.map +1 -1
  281. package/dist/utils/sql-parser.js +14 -3
  282. package/dist/utils/type-utils.d.ts +23 -0
  283. package/dist/utils/type-utils.d.ts.map +1 -0
  284. package/dist/utils/type-utils.js +45 -0
  285. package/dist/utils/utils.d.ts +7 -1
  286. package/dist/utils/utils.d.ts.map +1 -1
  287. package/dist/utils/utils.js +44 -5
  288. package/dist/utils/zod-error.d.ts +1 -1
  289. package/dist/utils/zod-error.d.ts.map +1 -1
  290. package/dist/utils/zod-error.js +1 -1
  291. package/package.json +54 -29
  292. package/src/ai/agents/agent.ts +87 -0
  293. package/src/ai/agents/index.ts +2 -0
  294. package/src/ai/agents/types.ts +47 -0
  295. package/src/ai/index.ts +1 -0
  296. package/src/ai/providers/rtzr/api.ts +37 -0
  297. package/src/ai/providers/rtzr/error.ts +34 -0
  298. package/src/ai/providers/rtzr/index.ts +4 -0
  299. package/src/ai/providers/rtzr/model.ts +201 -0
  300. package/src/ai/providers/rtzr/options.ts +49 -0
  301. package/src/ai/providers/rtzr/provider.ts +91 -0
  302. package/src/ai/providers/rtzr/utils.ts +127 -0
  303. package/src/api/base-frame.ts +4 -2
  304. package/src/api/caster.ts +17 -23
  305. package/src/api/code-converters.ts +176 -533
  306. package/src/api/config.ts +39 -56
  307. package/src/api/context.ts +7 -18
  308. package/src/api/decorators.ts +175 -46
  309. package/src/api/index.ts +2 -2
  310. package/src/api/sonamu.ts +133 -124
  311. package/src/api/validator.ts +83 -0
  312. package/src/bin/build-config.ts +7 -1
  313. package/src/bin/cli.ts +192 -110
  314. package/src/bin/loader-register.ts +38 -0
  315. package/src/database/_batch_update.ts +46 -31
  316. package/src/database/base-model.ts +390 -182
  317. package/src/database/base-model.types.ts +155 -0
  318. package/src/database/code-generator.ts +13 -32
  319. package/src/database/db.ts +36 -50
  320. package/src/database/puri-subset.test-d.ts +471 -0
  321. package/src/database/puri-subset.types.ts +195 -0
  322. package/src/database/puri-wrapper.ts +58 -67
  323. package/src/database/puri.ts +182 -126
  324. package/src/database/puri.types.ts +64 -31
  325. package/src/database/transaction-context.ts +1 -1
  326. package/src/database/upsert-builder.ts +262 -132
  327. package/src/entity/entity-manager.ts +36 -28
  328. package/src/entity/entity.ts +330 -249
  329. package/src/exceptions/error-handler.ts +3 -3
  330. package/src/exceptions/so-exceptions.ts +11 -11
  331. package/src/file-storage/driver.ts +5 -5
  332. package/src/file-storage/file-storage.ts +2 -2
  333. package/src/index.ts +18 -12
  334. package/src/migration/code-generation.ts +185 -172
  335. package/src/migration/migration-set.ts +80 -293
  336. package/src/migration/migrator.ts +182 -425
  337. package/src/migration/mysql-schema-reader.ts.txt +272 -0
  338. package/src/migration/postgresql-schema-reader.ts +310 -0
  339. package/src/migration/types.ts +6 -39
  340. package/src/naite/messaging-types.ts +51 -0
  341. package/src/naite/naite-reporter.ts +128 -0
  342. package/src/naite/naite.ts +378 -33
  343. package/src/shared/web.shared.ts.txt +20 -24
  344. package/src/stream/sse.ts +5 -5
  345. package/src/syncer/api-parser.ts +52 -69
  346. package/src/syncer/checksum.ts +25 -37
  347. package/src/syncer/code-generator.ts +58 -62
  348. package/src/syncer/entity-operations.ts +12 -15
  349. package/src/syncer/file-patterns.ts +2 -2
  350. package/src/syncer/index.ts +4 -4
  351. package/src/syncer/module-loader.ts +28 -25
  352. package/src/syncer/syncer.ts +155 -162
  353. package/src/template/entity-converter.ts +18 -27
  354. package/src/template/helpers.ts +8 -11
  355. package/src/template/implementations/entity.template.ts +6 -6
  356. package/src/template/implementations/generated.template.ts +99 -99
  357. package/src/template/implementations/generated_http.template.ts +21 -54
  358. package/src/template/implementations/generated_sso.template.ts +78 -65
  359. package/src/template/implementations/init_types.template.ts +4 -6
  360. package/src/template/implementations/model.template.ts +47 -38
  361. package/src/template/implementations/model_test.template.ts +3 -3
  362. package/src/template/implementations/service.template.ts +56 -80
  363. package/src/template/implementations/view_enums_buttonset.template.ts +2 -2
  364. package/src/template/implementations/view_enums_dropdown.template.ts +4 -4
  365. package/src/template/implementations/view_enums_select.template.ts +3 -3
  366. package/src/template/implementations/view_form.template.ts +34 -75
  367. package/src/template/implementations/view_id_all_select.template.ts +2 -2
  368. package/src/template/implementations/view_id_async_select.template.ts +9 -23
  369. package/src/template/implementations/view_list.template.ts +54 -95
  370. package/src/template/implementations/view_list_columns.template.ts +4 -10
  371. package/src/template/implementations/view_search_input.template.ts +2 -2
  372. package/src/template/index.ts +4 -2
  373. package/src/template/template-manager.ts +166 -0
  374. package/src/template/template-types.ts +16 -0
  375. package/src/template/template.ts +29 -10
  376. package/src/template/zod-converter.ts +407 -101
  377. package/src/testing/_relation-graph.ts +18 -11
  378. package/src/testing/fixture-manager.ts +468 -362
  379. package/src/types/types.ts +516 -248
  380. package/src/typings/knex.d.ts +7 -9
  381. package/src/utils/async-utils.ts +8 -12
  382. package/src/utils/console-util.ts +1 -1
  383. package/src/utils/controller.ts +3 -0
  384. package/src/utils/esm-utils.ts +8 -18
  385. package/src/utils/formatter.ts +109 -0
  386. package/src/utils/fs-utils.ts +1 -1
  387. package/src/utils/lodash-able.ts +1 -4
  388. package/src/utils/object-utils.ts +217 -0
  389. package/src/utils/path-utils.ts +3 -6
  390. package/src/utils/process-utils.ts +1 -1
  391. package/src/utils/sql-parser.ts +23 -5
  392. package/src/utils/type-utils.ts +83 -0
  393. package/src/utils/utils.ts +58 -9
  394. package/src/utils/zod-error.ts +3 -3
  395. package/dist/bin/cli-wrapper.d.ts +0 -3
  396. package/dist/bin/cli-wrapper.d.ts.map +0 -1
  397. package/dist/bin/cli-wrapper.js +0 -72
  398. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
  399. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
  400. package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -39
  401. package/dist/entity/entity-utils.d.ts +0 -61
  402. package/dist/entity/entity-utils.d.ts.map +0 -1
  403. package/dist/entity/entity-utils.js +0 -210
  404. package/src/bin/cli-wrapper.ts +0 -82
  405. package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
  406. package/src/entity/entity-utils.ts +0 -291
package/src/api/sonamu.ts CHANGED
@@ -1,42 +1,22 @@
1
+ import assert from "assert";
1
2
  import { AsyncLocalStorage } from "async_hooks";
2
- import chalk from "chalk";
3
- import fastify from "fastify";
4
- import { readFile } from "fs/promises";
5
- import path from "path";
6
- import { exists } from "../utils/fs-utils";
7
- import chokidar, { type FSWatcher } from "chokidar";
8
- import { formatInTimeZone } from "date-fns-tz";
3
+ import type { FSWatcher } from "chokidar";
9
4
  import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
10
5
  import type { IncomingMessage, Server, ServerResponse } from "http";
11
- import { ZodError, ZodObject } from "zod";
12
- import { DB, SonamuDBConfig } from "../database/db";
13
- import { attachOnDuplicateUpdate } from "../database/knex-plugins/knex-on-duplicate-update";
14
- import {
15
- BadRequestException,
16
- NotFoundException,
17
- } from "../exceptions/so-exceptions";
6
+ import path from "path";
7
+ import type { ZodObject } from "zod";
8
+ import type { SonamuDBConfig } from "../database/db";
18
9
  import type { Driver } from "../file-storage/driver";
19
- import { createSSEFactory } from "../stream/sse";
10
+ import { Naite } from "../naite/naite";
20
11
  import type { Syncer } from "../syncer/syncer";
21
- import { ApiParamType, SonamuFastifyConfig } from "../types/types";
22
- import { isLocal, isTest } from "../utils/controller";
23
- import { findApiRootPath } from "../utils/utils";
24
- import { humanizeZodError } from "../utils/zod-error";
25
- import { fastifyCaster } from "./caster";
26
- import { getZodObjectFromApi } from "./code-converters";
12
+ import type { SonamuFastifyConfig } from "../types/types";
13
+ import type { AbsolutePath } from "../utils/path-utils";
14
+ import type { SonamuConfig, SonamuServerOptions } from "./config";
27
15
  import type { AuthContext, Context, UploadContext } from "./context";
28
16
  import type { ExtendedApi } from "./decorators";
29
- import fastifyPassport from "@fastify/passport";
30
- import { loadConfig, SonamuConfig, SonamuServerOptions } from "./config";
31
- import { AbsolutePath } from "../utils/path-utils";
32
- import { isHotReloadServer } from "../utils/esm-utils";
33
- import { Template } from "../template";
34
- import assert from "assert";
35
- import { centerText } from "../utils/console-util";
36
- import { BaseModel } from "../database/base-model";
37
17
 
38
18
  export type SonamuSecrets = {
39
- [key: string]: string;
19
+ anthropic_api_key?: string;
40
20
  };
41
21
  class SonamuClass {
42
22
  public isInitialized: boolean = false;
@@ -61,6 +41,7 @@ class SonamuClass {
61
41
  reply: null,
62
42
  headers: {},
63
43
  createSSE: () => {},
44
+ // biome-ignore lint/suspicious/noExplicitAny: 테스팅 환경에서 컨텍스트가 주입되지 않은 경우 빈 컨텍스트 리턴
64
45
  naiteStore: new Map<string, any>(),
65
46
  } as unknown as Context;
66
47
  } else {
@@ -73,9 +54,7 @@ class SonamuClass {
73
54
  if (store?.uploadContext) {
74
55
  return store.uploadContext;
75
56
  }
76
- throw new Error(
77
- "Sonamu cannot find upload context. Did you use @upload decorator?"
78
- );
57
+ throw new Error("Sonamu cannot find upload context. Did you use @upload decorator?");
79
58
  }
80
59
 
81
60
  private _apiRootPath: AbsolutePath | null = null;
@@ -86,7 +65,7 @@ class SonamuClass {
86
65
  if (this._apiRootPath === null) {
87
66
  throw new Error("Sonamu has not been initialized");
88
67
  }
89
- return this._apiRootPath!;
68
+ return this._apiRootPath;
90
69
  }
91
70
  get appRootPath(): string {
92
71
  return this.apiRootPath.split(path.sep).slice(0, -1).join(path.sep);
@@ -100,7 +79,7 @@ class SonamuClass {
100
79
  if (this._dbConfig === null) {
101
80
  throw new Error("Sonamu has not been initialized");
102
81
  }
103
- return this._dbConfig!;
82
+ return this._dbConfig;
104
83
  }
105
84
 
106
85
  private _syncer: Syncer | null = null;
@@ -111,7 +90,7 @@ class SonamuClass {
111
90
  if (this._syncer === null) {
112
91
  throw new Error("Sonamu has not been initialized");
113
92
  }
114
- return this._syncer!;
93
+ return this._syncer;
115
94
  }
116
95
 
117
96
  private _config: SonamuConfig | null = null;
@@ -156,30 +135,39 @@ class SonamuClass {
156
135
  doSilent: boolean = false,
157
136
  enableSync: boolean = true,
158
137
  apiRootPath?: AbsolutePath,
159
- forTesting: boolean = false
138
+ forTesting: boolean = false,
160
139
  ) {
161
140
  if (this.isInitialized) {
162
141
  return;
163
142
  }
164
- !doSilent &&
165
- console.time(
166
- chalk.cyan(`Sonamu.init${forTesting ? " for testing" : ""}`)
167
- );
143
+
144
+ if (!doSilent) {
145
+ const chalk = (await import("chalk")).default;
146
+ console.time(chalk.cyan(`Sonamu.init${forTesting ? " for testing" : ""}`));
147
+ }
168
148
 
169
149
  // API 루트 패스
150
+ const { findApiRootPath } = await import("../utils/utils");
170
151
  this.apiRootPath = apiRootPath ?? findApiRootPath();
152
+
153
+ const { loadConfig } = await import("./config");
171
154
  this.config = await loadConfig(this.apiRootPath);
172
- const secretsPath = path.join(this.apiRootPath, "sonamu.secrets.json");
173
- if (await exists(secretsPath)) {
174
- this.secrets = JSON.parse(
175
- (await readFile(secretsPath)).toString()
176
- ) as SonamuSecrets;
155
+ // sonamu.config.ts 기본값 설정
156
+ this.config.database.database = this.config.database.database ?? "postgresql";
157
+
158
+ if (process.env.ANTHROPIC_API_KEY) {
159
+ this.secrets = {
160
+ anthropic_api_key: process.env.ANTHROPIC_API_KEY,
161
+ };
177
162
  }
178
163
 
179
164
  // DB 로드
165
+ const { DB } = await import("../database/db");
180
166
  this.dbConfig = DB.generateDBConfig(this.config.database);
181
- !doSilent && console.log(chalk.green("DB Config Loaded!"));
182
- attachOnDuplicateUpdate();
167
+ if (!doSilent) {
168
+ const chalk = (await import("chalk")).default;
169
+ console.log(chalk.green("DB Config Loaded!"));
170
+ }
183
171
 
184
172
  // 테스팅인 경우 엔티티 로드 & 싱크 없이 중단
185
173
  if (forTesting) {
@@ -200,29 +188,38 @@ class SonamuClass {
200
188
  await this.syncer.autoloadModels();
201
189
  await this.syncer.autoloadApis();
202
190
 
203
- await Template.autoload();
191
+ const { TemplateManager } = await import("../template");
192
+ await TemplateManager.autoload();
204
193
 
194
+ const { isLocal, isTest } = await import("../utils/controller");
195
+ if (isLocal()) {
196
+ // 로컬에서는 코드 생성을 위해 Biome 셋업이 필요함 (현재 apiRootPath 전달하여 실행)
197
+ (await import("../utils/formatter")).setupBiome(this.apiRootPath);
198
+ }
199
+
200
+ const { isHotReloadServer } = await import("../utils/controller");
205
201
  if (isLocal() && !isTest() && isHotReloadServer() && enableSync) {
206
202
  await this.syncer.sync();
207
203
 
208
- this.startWatcher();
204
+ await this.startWatcher();
209
205
 
210
206
  this.syncer.syncUI();
211
207
  }
212
208
 
213
209
  this.isInitialized = true;
214
- !doSilent && console.timeEnd(chalk.cyan("Sonamu.init"));
210
+ if (!doSilent) {
211
+ const chalk = (await import("chalk")).default;
212
+ console.timeEnd(chalk.cyan("Sonamu.init"));
213
+ }
215
214
  }
216
215
 
217
- async createServer(initOptions?: {
218
- enableSync?: boolean;
219
- doSilent?: boolean;
220
- }) {
216
+ async createServer(initOptions?: { enableSync?: boolean; doSilent?: boolean }) {
221
217
  if (this.isInitialized === false) {
222
218
  await this.init(initOptions?.doSilent, initOptions?.enableSync);
223
219
  }
224
220
 
225
221
  const options = this.config.server;
222
+ const fastify = (await import("fastify")).default;
226
223
  const server = fastify(options.fastify);
227
224
  this.server = server;
228
225
 
@@ -233,17 +230,15 @@ class SonamuClass {
233
230
 
234
231
  // 플러그인 등록
235
232
  if (options.plugins) {
236
- this.registerPlugins(server, options.plugins);
233
+ await this.registerPlugins(server, options.plugins);
237
234
  }
238
235
 
239
236
  if (options.auth) {
240
237
  if (!options.plugins?.session) {
241
- throw new Error(
242
- "Auth requires session plugin. Please add plugins.session configuration."
243
- );
238
+ throw new Error("Auth requires session plugin. Please add plugins.session configuration.");
244
239
  }
245
240
 
246
- this.registerAuth(server, options.auth);
241
+ await this.registerAuth(server, options.auth);
247
242
  }
248
243
 
249
244
  // API 라우팅 설정
@@ -264,7 +259,7 @@ class SonamuClass {
264
259
  options?: {
265
260
  enableSync?: boolean;
266
261
  doSilent?: boolean;
267
- }
262
+ },
268
263
  ) {
269
264
  if (this.isInitialized === false) {
270
265
  await this.init(options?.doSilent, options?.enableSync);
@@ -275,28 +270,43 @@ class SonamuClass {
275
270
  // timezone 설정
276
271
  const timezone = this.config.api.timezone;
277
272
  if (timezone) {
278
- const DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
273
+ // 타임존에 맞게 응답 날짜 스트링을 변환해주어야 합니다.
274
+ // 가령 timezone이 "Asia/Seoul" 이면
275
+ // "2025-11-21T00:00:00.000Z" 를 "2025-11-21T09:00:00+09:00" 으로 변환해주어야 합니다.
276
+ const { formatInTimeZone } = await import("date-fns-tz");
277
+
279
278
  // ISO 8601 날짜 형식 정규식 (예: 2024-01-15T09:30:00.000Z)
280
279
  const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;
281
280
 
281
+ // T를 둘러싼 작은따옴표가 없다면 "2025-11-19176354618900018:56:29+09:00"와 같은 결과가 나옵니다.
282
+ // 이는 date-fns 특입니다.
283
+ // 이렇게 해도 괜찮습니다. "2025-11-19T18:56:29+09:00" 모양으로 잘 나옵니다.
284
+ const DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
285
+
282
286
  server.setReplySerializer((payload) => {
283
287
  return JSON.stringify(payload, (_key, value) => {
284
288
  if (typeof value === "string" && ISO_DATE_REGEX.test(value)) {
285
- return formatInTimeZone(new Date(value), timezone, DATE_FORMAT);
289
+ return formatInTimeZone(
290
+ new Date(value),
291
+ timezone as `${string}/${string}`,
292
+ DATE_FORMAT,
293
+ );
286
294
  }
287
295
  return value;
288
296
  });
289
297
  });
290
- !options?.doSilent &&
298
+ if (!options?.doSilent) {
299
+ const chalk = (await import("chalk")).default;
291
300
  console.log(chalk.green(`Timezone set to ${timezone}`));
301
+ }
292
302
  }
293
303
 
294
304
  // 전체 라우팅 리스트
295
305
  server.get(
296
306
  `${this.config.api.route.prefix}/routes`,
297
- async (_request, _reply): Promise<any> => {
307
+ async (_request, _reply): Promise<typeof this.syncer.apis> => {
298
308
  return this.syncer.apis;
299
- }
309
+ },
300
310
  );
301
311
 
302
312
  // Healthcheck API
@@ -304,25 +314,26 @@ class SonamuClass {
304
314
  `${this.config.api.route.prefix}/healthcheck`,
305
315
  async (_request, _reply): Promise<string> => {
306
316
  return "ok";
307
- }
317
+ },
308
318
  );
309
319
 
310
320
  // API 라우팅 (로컬HMR 상태와 구분)
321
+ const { isLocal } = await import("../utils/controller");
311
322
  if (isLocal()) {
312
- server.all("*", (request, reply) => {
323
+ server.all("*", async (request, reply) => {
313
324
  const found = this.syncer.apis.find(
314
325
  (api) =>
315
- this.config.api.route.prefix + api.path ===
316
- request.url.split("?")[0] &&
317
- (api.options.httpMethod ?? "GET") === request.method.toUpperCase()
326
+ this.config.api.route.prefix + api.path === request.url.split("?")[0] &&
327
+ (api.options.httpMethod ?? "GET") === request.method.toUpperCase(),
318
328
  );
319
329
  if (found) {
320
330
  return this.getApiHandler(found, config)(request, reply);
321
331
  }
332
+ const { NotFoundException } = await import("../exceptions/so-exceptions");
322
333
  throw new NotFoundException("존재하지 않는 API 접근입니다.");
323
334
  });
324
335
  } else {
325
- this.syncer.apis.map((api) => {
336
+ for (const api of this.syncer.apis) {
326
337
  // model
327
338
  if (this.syncer.models[api.modelName] === undefined) {
328
339
  throw new Error(`정의되지 않은 모델에 접근 ${api.modelName}`);
@@ -330,24 +341,23 @@ class SonamuClass {
330
341
 
331
342
  // route
332
343
  server.route({
333
- method: api.options.httpMethod!,
344
+ method: api.options.httpMethod ?? "GET",
334
345
  url: this.config.api.route.prefix + api.path,
335
346
  handler: this.getApiHandler(api, config),
336
347
  }); // END server.route
337
- });
348
+ }
338
349
  }
339
350
  }
340
351
 
341
- getApiHandler(api: ExtendedApi, config: SonamuFastifyConfig) {
342
- return async (
343
- request: FastifyRequest,
344
- reply: FastifyReply
345
- ): Promise<unknown> => {
346
- (api.options.guards ?? []).every((guard) =>
347
- config.guardHandler(guard, request, api)
348
- );
352
+ getApiHandler(
353
+ api: ExtendedApi,
354
+ config: SonamuFastifyConfig,
355
+ ): (request: FastifyRequest, reply: FastifyReply) => Promise<unknown> {
356
+ return async (request: FastifyRequest, reply: FastifyReply): Promise<unknown> => {
357
+ (api.options.guards ?? []).every((guard) => config.guardHandler(guard, request, api));
349
358
 
350
359
  // 파라미터 정보로 zod 스키마 빌드
360
+ const { getZodObjectFromApi } = await import("./code-converters");
351
361
  const ReqType = getZodObjectFromApi(api, this.syncer.types);
352
362
 
353
363
  // request 파싱
@@ -356,12 +366,16 @@ class SonamuClass {
356
366
  [key: string]: unknown;
357
367
  };
358
368
  try {
369
+ const { fastifyCaster } = await import("./caster");
359
370
  reqBody = fastifyCaster(ReqType).parse(request[which] ?? {});
360
371
  } catch (e) {
372
+ const { ZodError } = await import("zod");
361
373
  if (e instanceof ZodError) {
374
+ const { humanizeZodError } = await import("../utils/zod-error");
362
375
  const messages = humanizeZodError(e)
363
376
  .map((issue) => issue.message)
364
377
  .join(" ");
378
+ const { BadRequestException } = await import("../exceptions/so-exceptions");
365
379
  throw new BadRequestException(messages, {
366
380
  zodError: e,
367
381
  });
@@ -398,15 +412,12 @@ class SonamuClass {
398
412
  }
399
413
 
400
414
  // createSSEFactory 함수에 미리 request의 socket과 reply를 바인딩.
415
+ const { createSSEFactory } = await import("../stream/sse");
401
416
  const createSSE = (<T extends ZodObject>(
402
417
  _request: FastifyRequest,
403
418
  _reply: FastifyReply,
404
- _events: T
405
- ) => createSSEFactory(_request.socket, _reply, _events)).bind(
406
- null,
407
- request,
408
- reply
409
- );
419
+ _events: T,
420
+ ) => createSSEFactory(_request.socket, _reply, _events)).bind(null, request, reply);
410
421
 
411
422
  const context: Context = {
412
423
  ...(await Promise.resolve(
@@ -416,26 +427,24 @@ class SonamuClass {
416
427
  reply,
417
428
  headers: request.headers,
418
429
  createSSE,
419
- naiteStore: new Map<string, any>(),
430
+ naiteStore: Naite.createStore(),
420
431
  // auth
421
432
  user: request.user ?? null,
422
433
  passport: {
423
- login: request.login.bind(
424
- request
425
- ) as AuthContext["passport"]["login"],
426
- logout: request.logout.bind(
427
- request
428
- ) as AuthContext["passport"]["logout"],
434
+ login: request.login.bind(request) as AuthContext["passport"]["login"],
435
+ logout: request.logout.bind(request) as AuthContext["passport"]["logout"],
429
436
  },
430
437
  },
431
438
  request,
432
- reply
433
- )
439
+ reply,
440
+ ),
434
441
  )),
435
442
  };
436
443
 
437
444
  const model = this.syncer.models[api.modelName];
438
445
  return this.asyncLocalStorage.run({ context }, async () => {
446
+ const { ApiParamType } = await import("../types/types");
447
+ // biome-ignore lint/suspicious/noExplicitAny: model은 모델 인스턴스이므로 메서드 호출 가능
439
448
  const result = await (model as any)[api.methodName].apply(
440
449
  model,
441
450
  api.parameters.map((param) => {
@@ -445,7 +454,7 @@ class SonamuClass {
445
454
  } else {
446
455
  return reqBody[param.name];
447
456
  }
448
- })
457
+ }),
449
458
  );
450
459
  reply.type(api.options.contentType ?? "application/json");
451
460
 
@@ -458,12 +467,13 @@ class SonamuClass {
458
467
  };
459
468
  }
460
469
 
461
- startWatcher(): void {
470
+ async startWatcher(): Promise<void> {
462
471
  const watchPath = [
463
472
  path.join(this.apiRootPath, "src"),
464
473
  path.join(this.apiRootPath, "sonamu.config.ts"),
465
474
  ];
466
475
 
476
+ const chokidar = (await import("chokidar")).default;
467
477
  this.watcher = chokidar.watch(watchPath, {
468
478
  ignored: (path, stats) =>
469
479
  !!stats?.isFile() && !path.endsWith(".ts") && !path.endsWith(".json"),
@@ -475,7 +485,7 @@ class SonamuClass {
475
485
  const absolutePath = filePath as AbsolutePath;
476
486
  assert(
477
487
  absolutePath.startsWith(this.apiRootPath),
478
- "File path is not within the API root path"
488
+ "File path is not within the API root path",
479
489
  );
480
490
 
481
491
  if (event !== "change" && event !== "add") {
@@ -484,15 +494,13 @@ class SonamuClass {
484
494
 
485
495
  try {
486
496
  // sonamu.config.ts 변경 시 재시작
487
- const isConfigTs =
488
- filePath === path.join(this.apiRootPath, "sonamu.config.ts");
497
+ const isConfigTs = filePath === path.join(this.apiRootPath, "sonamu.config.ts");
489
498
 
490
499
  if (isConfigTs) {
491
500
  const relativePath = filePath.replace(this.apiRootPath, "api");
501
+ const chalk = (await import("chalk")).default;
492
502
  console.log(
493
- chalk.bold(
494
- `Detected(${event}): ${chalk.blue(relativePath)} - Restarting...`
495
- )
503
+ chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)} - Restarting...`),
496
504
  );
497
505
  process.kill(process.pid, "SIGUSR2");
498
506
  return;
@@ -517,10 +525,7 @@ class SonamuClass {
517
525
  }
518
526
  }
519
527
 
520
- private registerPlugins(
521
- server: FastifyInstance,
522
- plugins: SonamuServerOptions["plugins"]
523
- ) {
528
+ private async registerPlugins(server: FastifyInstance, plugins: SonamuServerOptions["plugins"]) {
524
529
  if (!plugins) {
525
530
  return;
526
531
  }
@@ -535,23 +540,23 @@ class SonamuClass {
535
540
  session: "@fastify/secure-session",
536
541
  } as const;
537
542
 
538
- const registerPlugin = <K extends keyof NonNullable<typeof plugins>>(
543
+ const registerPlugin = async <K extends keyof NonNullable<typeof plugins>>(
539
544
  key: K,
540
- pluginName: string
545
+ pluginName: string,
541
546
  ) => {
542
547
  const option = plugins[key];
543
548
  if (!option) return;
544
549
 
545
550
  if (option === true) {
546
- server.register(import(pluginName));
551
+ server.register((await import(pluginName)).default);
547
552
  } else {
548
- server.register(import(pluginName), option);
553
+ server.register((await import(pluginName)).default, option);
549
554
  }
550
555
  };
551
556
 
552
- Object.entries(pluginsModules).forEach(([key, pluginName]) => {
553
- registerPlugin(key as keyof typeof plugins, pluginName);
554
- });
557
+ for (const [key, pluginName] of Object.entries(pluginsModules)) {
558
+ await registerPlugin(key as keyof typeof plugins, pluginName);
559
+ }
555
560
 
556
561
  if (plugins.custom) {
557
562
  plugins.custom(server);
@@ -560,16 +565,16 @@ class SonamuClass {
560
565
 
561
566
  private async registerAuth(
562
567
  server: FastifyInstance,
563
- options: NonNullable<SonamuServerOptions["auth"]>
568
+ options: NonNullable<SonamuServerOptions["auth"]>,
564
569
  ) {
570
+ // await import("fastify");
571
+ const fastifyPassport = (await import("@fastify/passport")).default;
565
572
  server.register(fastifyPassport.initialize());
566
573
  server.register(fastifyPassport.secureSession());
567
574
 
568
575
  if (typeof options === "boolean") {
569
576
  fastifyPassport.registerUserSerializer(async (user, _request) => user);
570
- fastifyPassport.registerUserDeserializer(
571
- async (serialized, _request) => serialized
572
- );
577
+ fastifyPassport.registerUserDeserializer(async (serialized, _request) => serialized);
573
578
  } else {
574
579
  fastifyPassport.registerUserSerializer(options.userSerializer);
575
580
  fastifyPassport.registerUserDeserializer(options.userDeserializer);
@@ -608,15 +613,13 @@ class SonamuClass {
608
613
  await options.lifecycle?.onStart?.(server);
609
614
  })
610
615
  .catch(async (err) => {
616
+ const chalk = (await import("chalk")).default;
611
617
  console.error(chalk.red("Failed to start server:", err));
612
618
  await shutdown();
613
619
  });
614
620
  }
615
621
 
616
- private async handleFileChange(
617
- event: string,
618
- filePath: AbsolutePath
619
- ): Promise<void> {
622
+ private async handleFileChange(event: string, filePath: AbsolutePath): Promise<void> {
620
623
  // 첫 번째 파일이면 HMR 시작 시간 기록
621
624
  if (this.pendingFiles.length === 0) {
622
625
  this.hmrStartTime = Date.now();
@@ -624,6 +627,7 @@ class SonamuClass {
624
627
  this.pendingFiles.push(filePath);
625
628
 
626
629
  const relativePath = path.relative(this.apiRootPath, filePath);
630
+ const chalk = (await import("chalk")).default;
627
631
  console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)}`));
628
632
 
629
633
  await this.syncer.syncFromWatcher(event, filePath);
@@ -642,12 +646,17 @@ class SonamuClass {
642
646
 
643
647
  const endTime = Date.now();
644
648
  const totalTime = endTime - this.hmrStartTime;
649
+ const [chalk, { centerText }] = await Promise.all([
650
+ (await import("chalk")).default,
651
+ import("../utils/console-util"),
652
+ ]);
645
653
  const msg = `HMR Done! ${chalk.bold.white(`${totalTime}ms`)}`;
646
654
 
647
655
  console.log(chalk.black.bgGreen(centerText(msg)));
648
656
  }
649
657
 
650
658
  async destroy(): Promise<void> {
659
+ const { BaseModel } = await import("../database/base-model");
651
660
  await BaseModel.destroy();
652
661
  await this.watcher?.close();
653
662
  this.storage?.destroy();
@@ -0,0 +1,83 @@
1
+ export const RESERVED_KEYWORDS = new Set([
2
+ "abstract",
3
+ "arguments",
4
+ "async",
5
+ "await",
6
+ "boolean",
7
+ "break",
8
+ "byte",
9
+ "case",
10
+ "catch",
11
+ "char",
12
+ "class",
13
+ "const",
14
+ "continue",
15
+ "debugger",
16
+ "default",
17
+ "delete",
18
+ "do",
19
+ "double",
20
+ "else",
21
+ "enum",
22
+ "eval",
23
+ "export",
24
+ "extends",
25
+ "false",
26
+ "final",
27
+ "finally",
28
+ "float",
29
+ "for",
30
+ "function",
31
+ "goto",
32
+ "if",
33
+ "implements",
34
+ "import",
35
+ "in",
36
+ "instanceof",
37
+ "int",
38
+ "interface",
39
+ "let",
40
+ "long",
41
+ "native",
42
+ "new",
43
+ "null",
44
+ "package",
45
+ "private",
46
+ "protected",
47
+ "public",
48
+ "return",
49
+ "short",
50
+ "static",
51
+ "super",
52
+ "switch",
53
+ "synchronized",
54
+ "this",
55
+ "throw",
56
+ "throws",
57
+ "transient",
58
+ "true",
59
+ "try",
60
+ "typeof",
61
+ "using",
62
+ "var",
63
+ "void",
64
+ "volatile",
65
+ "while",
66
+ "with",
67
+ "yield",
68
+ ]);
69
+
70
+ export class ApiValidationError extends Error {
71
+ constructor(message: string) {
72
+ super(`[Sonamu API Validation] ${message}`);
73
+ this.name = "ApiValidationError";
74
+ }
75
+ }
76
+
77
+ export function validateMethodName(methodName: string) {
78
+ if (RESERVED_KEYWORDS.has(methodName)) {
79
+ throw new ApiValidationError(
80
+ `Method name ${methodName} is a reserved keyword. Please choose a different name.`,
81
+ );
82
+ }
83
+ }
@@ -1,3 +1,8 @@
1
+ /**
2
+ * 소스 코드가 담길 디렉토리 경로
3
+ */
4
+ export const SRC_DIR = "src";
5
+
1
6
  /**
2
7
  * 빌드 결과물이 담길 디렉토리 경로
3
8
  */
@@ -7,7 +12,8 @@ export const BUILD_DIR = "dist";
7
12
  * SWC 빌드 명령어
8
13
  * .swcrc 설정 사용
9
14
  */
10
- export const SWC_BUILD_COMMAND = `swc src -d ${BUILD_DIR} --strip-leading-paths`;
15
+ export const SWC_BUILD_COMMAND = (configFilePath: string) =>
16
+ `swc ${SRC_DIR} -d ${BUILD_DIR} --config-file ${configFilePath} --strip-leading-paths`;
11
17
 
12
18
  /**
13
19
  * TSC 타입 체크 명령어