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,128 @@
1
+ /**
2
+ * NaiteReporter
3
+ *
4
+ * 테스트 결과와 Trace 정보를 Unix Socket으로 VS Code extension에 전달합니다.
5
+ * extension이 ~/.sonamu/naite.sock에 소켓 서버를 열어둡니다.
6
+ *
7
+ * fs mock 충돌을 피하기 위해 net 모듈만 사용합니다.
8
+ */
9
+ /** biome-ignore-all lint/suspicious/noExplicitAny: Naite는 expect와 호응하도록 any를 허용함 */
10
+
11
+ import { connect, type Socket } from "net";
12
+ import { homedir } from "os";
13
+ import { join } from "path";
14
+ import type { NaiteMessagingTypes } from "./messaging-types";
15
+
16
+ // 소켓 경로
17
+ const SOCKET_PATH =
18
+ process.platform === "win32" ? "\\\\.\\pipe\\naite" : join(homedir(), ".sonamu", "naite.sock");
19
+
20
+ class NaiteReporterClass {
21
+ private socket: Socket | null = null;
22
+ private connected = false;
23
+ private buffer: string[] = [];
24
+
25
+ /**
26
+ * 소켓 연결 시도
27
+ */
28
+ private ensureConnection(): void {
29
+ if (this.connected || this.socket) return;
30
+
31
+ try {
32
+ this.socket = connect(SOCKET_PATH);
33
+
34
+ this.socket.on("connect", () => {
35
+ this.connected = true;
36
+ // 버퍼에 쌓인 메시지 전송
37
+ for (const msg of this.buffer) {
38
+ this.socket?.write(msg);
39
+ }
40
+ this.buffer = [];
41
+ });
42
+
43
+ this.socket.on("error", () => {
44
+ // 연결 실패 무시 (extension이 꺼져있을 수 있음)
45
+ this.connected = false;
46
+ this.socket = null;
47
+ });
48
+
49
+ this.socket.on("close", () => {
50
+ this.connected = false;
51
+ this.socket = null;
52
+ });
53
+ } catch {
54
+ // 연결 실패 무시
55
+ }
56
+ }
57
+
58
+ /**
59
+ * 메시지 전송 (줄바꿈으로 구분)
60
+ */
61
+ private send(data: NaiteMessagingTypes.NaiteMessage): void {
62
+ const msg = `${JSON.stringify(data)}\n`;
63
+
64
+ this.ensureConnection();
65
+
66
+ if (this.connected && this.socket) {
67
+ this.socket.write(msg);
68
+ } else {
69
+ // 연결 대기 중이면 버퍼에 저장
70
+ this.buffer.push(msg);
71
+ }
72
+ }
73
+
74
+ /**
75
+ * beforeAll에서 호출합니다.
76
+ * 테스트 run 시작을 알립니다 (데이터 클리어 신호).
77
+ */
78
+ startTestRun(): void {
79
+ if (process.env.CI) {
80
+ return;
81
+ }
82
+
83
+ this.send({
84
+ type: "run/start",
85
+ startedAt: new Date().toISOString(),
86
+ });
87
+ }
88
+
89
+ /**
90
+ * afterEach에서 호출합니다.
91
+ * 테스트 케이스 결과를 traces와 함께 전송합니다.
92
+ */
93
+ reportTestResult(result: Omit<NaiteMessagingTypes.TestResult, "receivedAt">): void {
94
+ if (process.env.CI) {
95
+ return;
96
+ }
97
+
98
+ this.send({
99
+ type: "test/result",
100
+ receivedAt: new Date().toISOString(),
101
+ ...result,
102
+ });
103
+ }
104
+
105
+ /**
106
+ * afterAll에서 호출합니다.
107
+ * 테스트 run 종료를 알립니다.
108
+ */
109
+ endTestRun(): void {
110
+ if (process.env.CI) {
111
+ return;
112
+ }
113
+
114
+ this.send({
115
+ type: "run/end",
116
+ endedAt: new Date().toISOString(),
117
+ });
118
+
119
+ // 연결 종료
120
+ if (this.socket) {
121
+ this.socket.end();
122
+ this.socket = null;
123
+ this.connected = false;
124
+ }
125
+ }
126
+ }
127
+
128
+ export const NaiteReporter = new NaiteReporterClass();
@@ -0,0 +1,415 @@
1
+ /** biome-ignore-all lint/suspicious/noExplicitAny: Naite는 expect와 호응하도록 any를 허용함 */
2
+
3
+ import { get } from "radashi";
4
+ import { Sonamu } from "../api/sonamu";
5
+ import type { ComparisonOperator } from "../database/puri.types";
6
+ import { isSerializable } from "../utils/object-utils";
7
+
8
+ // StackFrame 타입
9
+ interface StackFrame {
10
+ functionName: string | null;
11
+ filePath: string; // "/Users/.../syncer.ts" 또는 "node:internal/..."
12
+ lineNumber: number; // TS 파일 기준 라인 번호
13
+ }
14
+
15
+ // NaiteTrace 타입
16
+ interface NaiteTrace {
17
+ key: string;
18
+ data: any;
19
+ stack: StackFrame[]; // 콜스택 정보
20
+ at: Date;
21
+ }
22
+
23
+ // Naite.t가 저장되는 타입 (항상 배열로 통일)
24
+ export type NaiteStore = Map<string, NaiteTrace[]>;
25
+
26
+ /**
27
+ * 콜스택을 파싱하여 StackFrame 배열로 반환
28
+ * - extractCallStack 자신과 Naite.t는 제외
29
+ * - runWithContext/runWithMockContext 발견 시 거기서 종료
30
+ * - node: 내부 경로는 포함하되, lineNumber는 path에 : 포함 시 붙이지 않음
31
+ */
32
+ function extractCallStack(): StackFrame[] {
33
+ const stack = new Error().stack;
34
+ if (!stack) return [];
35
+
36
+ const lines = stack.split("\n");
37
+
38
+ // 콜스택 구조:
39
+ // [0]: "Error"
40
+ // [1]: "at extractCallStack"
41
+ // [2]: "at Naite.t"
42
+ // [3]: 실제 호출 위치부터 시작
43
+ const frames = lines
44
+ .slice(3)
45
+ .map(parseStackFrame)
46
+ .filter((frame): frame is StackFrame => frame !== null);
47
+
48
+ // runWithContext 계열 함수 발견 시 거기서 자르기
49
+ const contextIndex = frames.findIndex(
50
+ (f) =>
51
+ f.functionName?.includes("runWithContext") || f.functionName?.includes("runWithMockContext"),
52
+ );
53
+
54
+ return contextIndex >= 0 ? frames.slice(0, contextIndex + 1) : frames;
55
+ }
56
+
57
+ /**
58
+ * 콜스택 한 줄을 파싱
59
+ * 형식1: "at FunctionName (filePath:lineNumber:columnNumber)"
60
+ * 형식2: "at filePath:lineNumber:columnNumber" (익명 함수/모듈 레벨)
61
+ */
62
+ function parseStackFrame(line: string): StackFrame | null {
63
+ // 패턴1: "at FunctionName (filePath:lineNumber:columnNumber)"
64
+ const matchWithFunc = line.match(/at\s+(.+?)\s+\((.+?):(\d+):\d+\)/);
65
+ if (matchWithFunc) {
66
+ const functionName = matchWithFunc[1];
67
+ const filePath = matchWithFunc[2];
68
+ const lineNumberStr = matchWithFunc[3];
69
+
70
+ // filePath에 이미 :가 포함되어 있으면 (예: "node:internal/...")
71
+ if (filePath.includes(":")) {
72
+ return { functionName, filePath, lineNumber: 0 };
73
+ }
74
+
75
+ return {
76
+ functionName,
77
+ filePath,
78
+ lineNumber: Number.parseInt(lineNumberStr, 10),
79
+ };
80
+ }
81
+
82
+ // 패턴2: "at filePath:lineNumber:columnNumber" (함수명 없음)
83
+ const matchNoFunc = line.match(/at\s+(.+?):(\d+):\d+$/);
84
+ if (matchNoFunc) {
85
+ const filePath = matchNoFunc[1];
86
+ const lineNumberStr = matchNoFunc[2];
87
+
88
+ return {
89
+ functionName: null,
90
+ filePath,
91
+ lineNumber: Number.parseInt(lineNumberStr, 10),
92
+ };
93
+ }
94
+
95
+ return null;
96
+ }
97
+
98
+ /**
99
+ * wildcard 패턴 매칭
100
+ * 예시:
101
+ * - "syncer:*" → "syncer:a", "syncer:a:b" 모두 매칭
102
+ * - "syncer:*:user" → "syncer:renderTemplate:user" 매칭
103
+ * - "syncer:renderTemplate:*" → "syncer:renderTemplate:service" 매칭
104
+ */
105
+ function matchesPattern(key: string, pattern: string): boolean {
106
+ const keyParts = key.split(":");
107
+ const patternParts = pattern.split(":");
108
+
109
+ // 마지막이 * → prefix 매칭 (길이 무관)
110
+ // 예: "syncer:*"는 "syncer:a", "syncer:a:b" 모두 매칭
111
+ if (patternParts[patternParts.length - 1] === "*") {
112
+ const prefixParts = patternParts.slice(0, -1);
113
+ // prefix가 모두 일치하는지 확인
114
+ return prefixParts.every((part, i) => part === keyParts[i]);
115
+ }
116
+
117
+ // 길이가 같아야 함
118
+ if (patternParts.length !== keyParts.length) {
119
+ return false;
120
+ }
121
+
122
+ // 각 파트가 * 또는 정확히 일치
123
+ return patternParts.every((part, i) => part === "*" || part === keyParts[i]);
124
+ }
125
+
126
+ /**
127
+ * NaiteQuery 클래스
128
+ * 체이닝을 통한 trace 필터링 및 조회
129
+ */
130
+ export class NaiteQuery {
131
+ constructor(private traces: NaiteTrace[]) {}
132
+
133
+ /**
134
+ * 파일명으로 필터링
135
+ * @param fileName 파일명 (예: "syncer.test.ts")
136
+ */
137
+ fromFile(fileName: string): NaiteQuery {
138
+ const filtered = this.traces.filter((t) =>
139
+ t.stack.some((frame) => frame.filePath.endsWith(`/${fileName}`)),
140
+ );
141
+ return new NaiteQuery(filtered);
142
+ }
143
+
144
+ /**
145
+ * 함수명으로 필터링
146
+ * @param funcName 함수명 (includes 체크)
147
+ * @param options.from 'direct' = 직접 호출만, 'indirect' = 간접 호출만, 'both' = 모두
148
+ */
149
+ fromFunction(
150
+ funcName: string,
151
+ options: { from: "direct" | "indirect" | "both" } = { from: "both" },
152
+ ): NaiteQuery {
153
+ const filtered = this.traces.filter((t) => {
154
+ if (options.from === "direct") {
155
+ // stack[0]만 확인 (직접 호출)
156
+ return t.stack[0]?.functionName?.includes(funcName);
157
+ }
158
+ if (options.from === "indirect") {
159
+ // stack[1+]에서 확인 (간접 호출)
160
+ return t.stack.slice(1).some((f) => f.functionName?.includes(funcName));
161
+ }
162
+ // 전체 스택에서 확인
163
+ return t.stack.some((f) => f.functionName?.includes(funcName));
164
+ });
165
+ return new NaiteQuery(filtered);
166
+ }
167
+
168
+ /**
169
+ * 데이터 경로 기반 필터링
170
+ * @param path radash get 경로 (예: "data.userId")
171
+ * @param operator 비교 연산자
172
+ * @param value 비교값
173
+ */
174
+ where(path: string, operator: ComparisonOperator | "includes", value: any): NaiteQuery {
175
+ const filtered = this.traces.filter((trace) => {
176
+ const actual = get(trace, path) as any;
177
+
178
+ switch (operator) {
179
+ case ">":
180
+ return actual > value;
181
+ case "<":
182
+ return actual < value;
183
+ case ">=":
184
+ return actual >= value;
185
+ case "<=":
186
+ return actual <= value;
187
+ case "=":
188
+ return actual === value;
189
+ case "!=":
190
+ return actual !== value;
191
+ case "includes":
192
+ return typeof actual === "string" && actual.includes(value);
193
+ default:
194
+ return false;
195
+ }
196
+ });
197
+ return new NaiteQuery(filtered);
198
+ }
199
+
200
+ /**
201
+ * 전체 데이터 배열 반환
202
+ */
203
+ result(): any[] {
204
+ return this.traces.map((t) => t.data);
205
+ }
206
+
207
+ /**
208
+ * 첫 번째 데이터 반환
209
+ */
210
+ first(): any | undefined {
211
+ return this.traces[0]?.data;
212
+ }
213
+
214
+ /**
215
+ * 마지막 데이터 반환
216
+ */
217
+ last(): any | undefined {
218
+ return this.traces[this.traces.length - 1]?.data;
219
+ }
220
+
221
+ /**
222
+ * n번째 데이터 반환
223
+ */
224
+ at(index: number): any | undefined {
225
+ return this.traces[index]?.data;
226
+ }
227
+
228
+ /**
229
+ * 원본 trace 배열 반환 (디버깅/NaiteViewer용)
230
+ */
231
+ getTraces(): NaiteTrace[] {
232
+ return this.traces;
233
+ }
234
+ }
235
+
236
+ // Naite 싱글턴 객체 (추후 logger 연결 등의 상태 관리 필요성 고려)
237
+ export class NaiteClass {
238
+ // 테스트 로그 기록
239
+ t(
240
+ name: string,
241
+ value: any /*이렇게 받은 값이 NaiteTrace로 저장되어 있다가 추후에 vitest에게 meta를 통해 넘겨져 프로세스간 통신을 통해 직렬화되어야 하는 점을 고려하였을 때 여기에 Serializable을 써서 제한을 둘 수도 있지만, 사용상의 편의를 생각하여 any로 받습니다.*/,
242
+ ) {
243
+ // 이 t 함수는 테스트 환경에서만 작동해야 합니다.
244
+ // 그리고 테스트 환경 판단에 왜 isTest() 함수를 사용하지 않았냐면요,,
245
+ // 이렇게 하는게 유틸 함수 불러와서 사용하는 것보다 조금이나마 빠를 것 같았기 때문입니다.
246
+ if (process.env.NODE_ENV !== "test") {
247
+ return;
248
+ }
249
+
250
+ try {
251
+ const context = Sonamu.getContext();
252
+ const store = context?.naiteStore;
253
+
254
+ if (!store) {
255
+ return;
256
+ }
257
+
258
+ // 콜스택 수집
259
+ const stack = extractCallStack();
260
+
261
+ const trace: NaiteTrace = {
262
+ key: name,
263
+ data: value,
264
+ stack,
265
+ at: new Date(),
266
+ };
267
+
268
+ // 항상 배열로 관리
269
+ const existing = store.get(name) ?? [];
270
+ store.set(name, [...existing, trace]);
271
+ } catch {
272
+ // Context 없는 상황에서 Naite.t 호출
273
+ }
274
+ }
275
+
276
+ /**
277
+ * key 또는 wildcard 패턴으로 trace 조회
278
+ * 항상 NaiteQuery 반환하여 체이닝 가능
279
+ */
280
+ get(keyPattern: string): NaiteQuery {
281
+ const context = Sonamu.getContext();
282
+ const store = context?.naiteStore;
283
+
284
+ if (!store) {
285
+ return new NaiteQuery([]);
286
+ }
287
+
288
+ // wildcard 없으면 exact match
289
+ if (!keyPattern.includes("*")) {
290
+ const traces = store.get(keyPattern) ?? [];
291
+ return new NaiteQuery(traces);
292
+ }
293
+
294
+ // wildcard 패턴 매칭
295
+ const allTraces: NaiteTrace[] = [];
296
+ for (const [key, traces] of store.entries()) {
297
+ if (matchesPattern(key, keyPattern)) {
298
+ allTraces.push(...traces);
299
+ }
300
+ }
301
+
302
+ return new NaiteQuery(allTraces);
303
+ }
304
+
305
+ // 전체 리스트 가져오기
306
+ getAll(): { [key: string]: any } {
307
+ const context = Sonamu.getContext();
308
+ if (!context?.naiteStore) {
309
+ return {};
310
+ }
311
+ // NaiteTrace 배열을 data만 추출하여 반환
312
+ const result: { [key: string]: any } = {};
313
+ for (const [key, traces] of context.naiteStore.entries()) {
314
+ if (key.startsWith("mock:")) {
315
+ // Mock 설정은 그대로 반환
316
+ result[key] = traces;
317
+ } else {
318
+ // NaiteTrace 배열은 data만 추출
319
+ result[key] = traces.map((t: NaiteTrace) => t.data);
320
+ }
321
+ }
322
+ return result;
323
+ }
324
+
325
+ /**
326
+ * 스토어에 들어있던 트레이스를 고대로 꺼내옵니다.
327
+ * 이때 값들은 모두 직렬화 가능한 상태로 나가게 됩니다.
328
+ * 테스트 정보와 함께 extensions에 보낼 용도로 만들었습니다.
329
+ * @returns
330
+ */
331
+ getAllTraces(): {
332
+ key: string;
333
+ value: any;
334
+ filePath: string;
335
+ lineNumber: number;
336
+ at: string;
337
+ }[] {
338
+ const context = Sonamu.getContext();
339
+ if (!context?.naiteStore) {
340
+ return [];
341
+ }
342
+
343
+ const traces = Array.from(context.naiteStore.values()).flat();
344
+
345
+ // 직렬화 불가능한 값이 존재한다면 이를 대문짝만하게 알려줍니다! 그치만 알리기만 하고 그냥 지나갑니다 ㅎㅎ
346
+ // 왜 직렬화가 중요한가? 이(getAllTraces) 호출의 결과는 외부로 나가게 되는데,
347
+ // 이때 주 용도가 vitest의 task.meta 필드를 통해 afterEach에서 Sonamu extension으로 전달하는 것입니다.
348
+ // 여기서 meta 필드에 담긴 내용은 프로세스간 통신(process.send) 또는 스레드간 통신(message port)을 통해 전달되어야 하는데,
349
+ // 이로 인해 "직렬화 가능한 값들만 허용"하는 제약이 생깁니다.
350
+ //
351
+ // 이 제약을 의식하여 Naite.t에 직렬화 가능한 값만 넘기게 할 수도 있었지만, 그렇게 하면 불편해질 것 같아서 하지 않았습니다.
352
+ // 따라서 현재 Naite.t는 모든 값을 받을 수 있게 되어 있습니다.
353
+ // 대신 이렇게(getAllTraces) 그 값들을 빼낼 때 JSON.stringify를 사용하여 강제로 직렬화 가능하게 만들었습니다,,
354
+ for (const trace of traces) {
355
+ const check = isSerializable(trace.data);
356
+ if (!check.valid) {
357
+ console.warn(
358
+ "\n" +
359
+ "╔════════════════════════════════════════════════════════════════╗\n" +
360
+ "║ [Naite] Non-serializable value detected! ║\n" +
361
+ "╠════════════════════════════════════════════════════════════════╣\n" +
362
+ `║ Key: ${trace.key.padEnd(57)}║\n` +
363
+ `║ Reason: ${(check.reason ?? "unknown").slice(0, 54).padEnd(54)}║\n` +
364
+ `║ Location: ${(trace.stack[0]?.filePath ?? "unknown").slice(-51).padEnd(52)}║\n` +
365
+ `║ Line: ${String(trace.stack[0]?.lineNumber ?? 0).padEnd(56)}║\n` +
366
+ "╠════════════════════════════════════════════════════════════════╣\n" +
367
+ "║ Naite.t() accepts any type of value. However, values will ║\n" +
368
+ "║ be serialized to JSON when exported via Naite.getAllTraces(). ║\n" +
369
+ "╚════════════════════════════════════════════════════════════════╝\n",
370
+ );
371
+ }
372
+ }
373
+
374
+ return traces.map((trace) => ({
375
+ key: trace.key,
376
+ value: JSON.parse(JSON.stringify(trace.data ?? "")), // 직렬화 가능한 것만 남기려는 눈물겨운 노력,, 안그러면 task.meta에 들어가서 프로세스간 통신 할 때 문제 생기거든요,,
377
+ filePath: trace.stack[0]?.filePath ?? "",
378
+ lineNumber: trace.stack[0]?.lineNumber ?? 0,
379
+ at: trace.at.toISOString(),
380
+ }));
381
+ }
382
+
383
+ // 특정 키 삭제하기
384
+ del(key: string) {
385
+ const context = Sonamu.getContext();
386
+ if (!context?.naiteStore) {
387
+ return;
388
+ }
389
+ context.naiteStore.delete(key);
390
+ }
391
+
392
+ createStore(): NaiteStore {
393
+ return new Map<string, NaiteTrace[]>();
394
+ }
395
+
396
+ // 일반 로그 레벨
397
+ d(_message: string) {
398
+ // TODO: Logger 연결
399
+ console.log(`[DEBUG] ${_message}`);
400
+ }
401
+ i(_message: string) {
402
+ // TODO: Logger 연결
403
+ console.log(`[INFO] ${_message}`);
404
+ }
405
+ w(_message: string) {
406
+ // TODO: Logger 연결
407
+ console.log(`[WARN] ${_message}`);
408
+ }
409
+ e(_message: string) {
410
+ // TODO: Logger 연결
411
+ console.log(`[ERROR] ${_message}`);
412
+ }
413
+ }
414
+
415
+ export const Naite = new NaiteClass();
@@ -1,23 +1,27 @@
1
+ /** biome-ignore-all lint/correctness/useExhaustiveDependencies: shared */
2
+ /** biome-ignore-all lint/suspicious/noExplicitAny: shared */
3
+
1
4
  /*
2
5
  fetch
3
6
  */
4
7
  import type { AxiosRequestConfig } from "axios";
5
8
  import axios from "axios";
6
- import { z, ZodIssue } from "zod";
7
9
  import qs from "qs";
10
+ import { type ZodIssue, z } from "zod";
8
11
 
9
12
  // ISO 8601 및 타임존 포맷의 날짜 문자열을 Date 객체로 변환하는 reviver
10
- function dateReviver(key: string, value: any): any {
13
+ function dateReviver(_key: string, value: any): any {
11
14
  if (typeof value === "string") {
12
15
  // ISO 8601 형식: 2024-01-15T09:30:00.000Z 또는 2024-01-15T09:30:00+09:00
13
- const isoRegex =
14
- /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d{1,3})?)?(Z|[+-]\d{2}:\d{2})?$/;
16
+ const isoRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d{1,3})?)?(Z|[+-]\d{2}:\d{2})?$/;
15
17
 
16
18
  // Timezone 포맷: 2024-01-15 09:30:00+09:00
17
19
  const timezoneRegex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$/;
18
20
 
19
- if ((isoRegex.test(value) || timezoneRegex.test(value)) &&
20
- new Date(value).toString() !== "Invalid Date") {
21
+ if (
22
+ (isoRegex.test(value) || timezoneRegex.test(value)) &&
23
+ new Date(value).toString() !== "Invalid Date"
24
+ ) {
21
25
  return new Date(value);
22
26
  }
23
27
  }
@@ -29,7 +33,7 @@ axios.defaults.transformResponse = [
29
33
  if (typeof data === "string") {
30
34
  try {
31
35
  return JSON.parse(data, dateReviver);
32
- } catch (e) {
36
+ } catch {
33
37
  return data;
34
38
  }
35
39
  }
@@ -61,7 +65,7 @@ export class SonamuError extends Error {
61
65
  constructor(
62
66
  public code: number,
63
67
  public message: string,
64
- public issues: z.ZodIssue[]
68
+ public issues: z.ZodIssue[],
65
69
  ) {
66
70
  super(message);
67
71
  this.isSonamuError = true;
@@ -106,9 +110,7 @@ export async function swrFetcher(args: [string, object]): Promise<any> {
106
110
  const res = await axios.get(`${url}?${qs.stringify(params)}`);
107
111
  return res.data;
108
112
  } catch (e: any) {
109
- const error: any = new Error(
110
- e.response.data.message ?? e.response.message ?? "Unknown"
111
- );
113
+ const error: any = new Error(e.response.data.message ?? e.response.message ?? "Unknown");
112
114
  error.statusCode = e.response?.data.statusCode ?? e.response.status;
113
115
  throw error;
114
116
  }
@@ -119,16 +121,14 @@ export async function swrPostFetcher(args: [string, object]): Promise<any> {
119
121
  const res = await axios.post(url, params);
120
122
  return res.data;
121
123
  } catch (e: any) {
122
- const error: any = new Error(
123
- e.response.data.message ?? e.response.message ?? "Unknown"
124
- );
124
+ const error: any = new Error(e.response.data.message ?? e.response.message ?? "Unknown");
125
125
  error.statusCode = e.response?.data.statusCode ?? e.response.status;
126
126
  throw error;
127
127
  }
128
128
  }
129
129
  export function handleConditional(
130
130
  args: [string, object],
131
- conditional?: () => boolean
131
+ conditional?: () => boolean,
132
132
  ): [string, object] | null {
133
133
  if (conditional) {
134
134
  return conditional() ? args : null;
@@ -139,9 +139,7 @@ export function handleConditional(
139
139
  /*
140
140
  Utils
141
141
  */
142
- export function zArrayable<T extends z.ZodTypeAny>(
143
- shape: T
144
- ): z.ZodUnion<[T, z.ZodArray<T>]> {
142
+ export function zArrayable<T extends z.ZodTypeAny>(shape: T): z.ZodUnion<[T, z.ZodArray<T>]> {
145
143
  return z.union([shape, shape.array()]);
146
144
  }
147
145
 
@@ -175,6 +173,7 @@ export type SSEStreamState = {
175
173
  export type EventHandlers<T> = {
176
174
  [K in keyof T]: (data: T[K]) => void;
177
175
  };
176
+
178
177
  import { useEffect, useRef, useState } from "react";
179
178
 
180
179
  export function useSSEStream<T extends Record<string, any>>(
@@ -183,7 +182,7 @@ export function useSSEStream<T extends Record<string, any>>(
183
182
  handlers: {
184
183
  [K in keyof T]?: (data: T[K]) => void;
185
184
  },
186
- options: SSEStreamOptions = {}
185
+ options: SSEStreamOptions = {},
187
186
  ): SSEStreamState {
188
187
  const { enabled = true, retry = 3, retryInterval = 3000 } = options;
189
188
 
@@ -245,7 +244,7 @@ export function useSSEStream<T extends Record<string, any>>(
245
244
  }));
246
245
  };
247
246
 
248
- eventSource.onerror = (event) => {
247
+ eventSource.onerror = (_event) => {
249
248
  // 이미 다른 연결로 교체되었는지 확인
250
249
  if (eventSourceRef.current !== eventSource) {
251
250
  return; // 이미 새로운 연결이 있으면 무시
@@ -313,10 +312,7 @@ export function useSSEStream<T extends Record<string, any>>(
313
312
  const data = JSON.parse(event.data);
314
313
  handler(data);
315
314
  } catch (error) {
316
- console.error(
317
- `Failed to parse SSE data for event ${eventType}:`,
318
- error
319
- );
315
+ console.error(`Failed to parse SSE data for event ${eventType}:`, error);
320
316
  }
321
317
  setState((prev) => ({
322
318
  ...prev,
package/src/stream/sse.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { z } from "zod";
2
- import type { FastifyRequest, FastifyReply } from "fastify";
1
+ import type { FastifyReply, FastifyRequest } from "fastify";
2
+ import type { z } from "zod";
3
3
 
4
4
  // NOTE(Haze, 251106): context provider에서 인자를 채워주면 createSSE(events)만으로 사용 가능
5
5
  export function createSSEFactory<T extends z.ZodObject>(
6
6
  socket: FastifyRequest["socket"],
7
7
  reply: FastifyReply,
8
- _events: T
8
+ _events: T,
9
9
  ) {
10
10
  return new SSEConnection<T>(socket, reply);
11
11
  }
@@ -15,7 +15,7 @@ class SSEConnection<T extends z.ZodObject> {
15
15
 
16
16
  constructor(
17
17
  private readonly socket: FastifyRequest["socket"],
18
- private readonly reply: FastifyReply
18
+ private readonly reply: FastifyReply,
19
19
  ) {
20
20
  this.socket.on("close", () => {
21
21
  this._closed = true;
@@ -42,7 +42,7 @@ class SSEConnection<T extends z.ZodObject> {
42
42
  event: "end",
43
43
  data: "END",
44
44
  });
45
-
45
+
46
46
  await new Promise((resolve) => setTimeout(resolve, 200));
47
47
  this.reply.raw.end();
48
48
  }