sonamu 0.10.12 → 0.10.13

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 (513) hide show
  1. package/dist/ai/agents/agent.d.ts +1 -1
  2. package/dist/ai/agents/agent.d.ts.map +1 -1
  3. package/dist/ai/agents/agent.js +5 -6
  4. package/dist/ai/agents/types.d.ts +1 -1
  5. package/dist/ai/agents/types.d.ts.map +1 -1
  6. package/dist/ai/providers/rtzr/api.js +18 -18
  7. package/dist/ai/providers/rtzr/error.d.ts.map +1 -1
  8. package/dist/ai/providers/rtzr/error.js +17 -15
  9. package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
  10. package/dist/ai/providers/rtzr/model.js +3 -2
  11. package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
  12. package/dist/ai/providers/rtzr/options.js +16 -16
  13. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
  14. package/dist/ai/providers/rtzr/provider.js +9 -9
  15. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
  16. package/dist/ai/providers/rtzr/utils.js +1 -1
  17. package/dist/api/caster.d.ts.map +1 -1
  18. package/dist/api/caster.js +17 -17
  19. package/dist/api/code-converters.d.ts +4 -2
  20. package/dist/api/code-converters.d.ts.map +1 -1
  21. package/dist/api/code-converters.js +100 -19
  22. package/dist/api/config.d.ts +16 -1
  23. package/dist/api/config.d.ts.map +1 -1
  24. package/dist/api/config.js +28 -21
  25. package/dist/api/context.d.ts +2 -2
  26. package/dist/api/context.d.ts.map +1 -1
  27. package/dist/api/context.js +1 -1
  28. package/dist/api/decorators.d.ts.map +1 -1
  29. package/dist/api/decorators.js +18 -11
  30. package/dist/api/http-validator.d.ts +36 -0
  31. package/dist/api/http-validator.d.ts.map +1 -0
  32. package/dist/api/http-validator.js +72 -0
  33. package/dist/api/index.js +6 -4
  34. package/dist/api/sonamu.d.ts +59 -20
  35. package/dist/api/sonamu.d.ts.map +1 -1
  36. package/dist/api/sonamu.js +250 -106
  37. package/dist/api/websocket-helpers.d.ts +7 -5
  38. package/dist/api/websocket-helpers.d.ts.map +1 -1
  39. package/dist/api/websocket-helpers.js +6 -6
  40. package/dist/auth/audit-log/builders.d.ts.map +1 -1
  41. package/dist/auth/audit-log/builders.js +1 -1
  42. package/dist/auth/audit-log/client-ip.d.ts +1 -1
  43. package/dist/auth/audit-log/client-ip.d.ts.map +1 -1
  44. package/dist/auth/audit-log/client-ip.js +4 -2
  45. package/dist/auth/audit-log/events.d.ts +5 -1
  46. package/dist/auth/audit-log/events.d.ts.map +1 -1
  47. package/dist/auth/audit-log/events.js +1 -1
  48. package/dist/auth/audit-log/plugin.d.ts +0 -8
  49. package/dist/auth/audit-log/plugin.d.ts.map +1 -1
  50. package/dist/auth/audit-log/plugin.js +48 -52
  51. package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
  52. package/dist/auth/audit-log-ingestor.js +16 -12
  53. package/dist/auth/auth-generator.d.ts.map +1 -1
  54. package/dist/auth/auth-generator.js +1 -1
  55. package/dist/auth/better-auth-request.d.ts.map +1 -1
  56. package/dist/auth/better-auth-request.js +6 -5
  57. package/dist/auth/knex-adapter.js +1 -1
  58. package/dist/auth/plugins/entity-definitions/index.d.ts +13 -1
  59. package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
  60. package/dist/auth/plugins/entity-definitions/index.js +1 -1
  61. package/dist/auth/plugins/wrappers/admin.d.ts +1 -1
  62. package/dist/bin/build-config.d.ts +25 -0
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +105 -2
  65. package/dist/bin/cli.js +131 -27
  66. package/dist/bin/compiler-policy.d.ts +3 -0
  67. package/dist/bin/compiler-policy.d.ts.map +1 -0
  68. package/dist/bin/compiler-policy.js +24 -0
  69. package/dist/bin/fixture.d.ts.map +1 -1
  70. package/dist/bin/fixture.js +5 -3
  71. package/dist/bin/test-command.d.ts +22 -1
  72. package/dist/bin/test-command.d.ts.map +1 -1
  73. package/dist/bin/test-command.js +18 -10
  74. package/dist/bin/ts-loader-registration.d.ts +7 -1
  75. package/dist/bin/ts-loader-registration.d.ts.map +1 -1
  76. package/dist/bin/ts-loader-registration.js +13 -4
  77. package/dist/cache/decorator.d.ts.map +1 -1
  78. package/dist/cache/decorator.js +11 -4
  79. package/dist/compress/compress.d.ts.map +1 -1
  80. package/dist/compress/compress.js +1 -1
  81. package/dist/cone/cone-generator.d.ts +14 -1
  82. package/dist/cone/cone-generator.d.ts.map +1 -1
  83. package/dist/cone/cone-generator.js +13 -9
  84. package/dist/database/_batch_update.js +1 -1
  85. package/dist/database/base-model.d.ts +22 -10
  86. package/dist/database/base-model.d.ts.map +1 -1
  87. package/dist/database/base-model.js +26 -16
  88. package/dist/database/base-model.types.d.ts +15 -3
  89. package/dist/database/base-model.types.d.ts.map +1 -1
  90. package/dist/database/db.d.ts +12 -2
  91. package/dist/database/db.d.ts.map +1 -1
  92. package/dist/database/db.js +10 -7
  93. package/dist/database/knex.d.ts.map +1 -1
  94. package/dist/database/knex.js +17 -14
  95. package/dist/database/puri.d.ts +11 -9
  96. package/dist/database/puri.d.ts.map +1 -1
  97. package/dist/database/puri.js +93 -79
  98. package/dist/database/puri.types.d.ts +21 -21
  99. package/dist/database/puri.types.d.ts.map +1 -1
  100. package/dist/database/puri.types.js +1 -1
  101. package/dist/database/upsert-builder.d.ts +12 -10
  102. package/dist/database/upsert-builder.d.ts.map +1 -1
  103. package/dist/database/upsert-builder.js +20 -12
  104. package/dist/dict/sd.d.ts.map +1 -1
  105. package/dist/dict/sd.js +1 -1
  106. package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
  107. package/dist/dict/sonamu-dictionary.js +1 -1
  108. package/dist/dict/utils.d.ts.map +1 -1
  109. package/dist/dict/utils.js +7 -2
  110. package/dist/entity/entity-manager.d.ts +13 -4
  111. package/dist/entity/entity-manager.d.ts.map +1 -1
  112. package/dist/entity/entity-manager.js +19 -11
  113. package/dist/entity/entity-template-cone.d.ts +73 -5
  114. package/dist/entity/entity-template-cone.d.ts.map +1 -1
  115. package/dist/entity/entity-template-cone.js +4 -2
  116. package/dist/entity/entity.d.ts +6 -2
  117. package/dist/entity/entity.d.ts.map +1 -1
  118. package/dist/entity/entity.js +30 -28
  119. package/dist/env.d.ts +3 -1
  120. package/dist/env.d.ts.map +1 -1
  121. package/dist/env.js +1 -1
  122. package/dist/exceptions/error-handler.d.ts.map +1 -1
  123. package/dist/exceptions/error-handler.js +7 -2
  124. package/dist/exceptions/so-exceptions.d.ts +24 -20
  125. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  126. package/dist/exceptions/so-exceptions.js +4 -2
  127. package/dist/filter/utils.d.ts +7 -2
  128. package/dist/filter/utils.d.ts.map +1 -1
  129. package/dist/filter/utils.js +8 -6
  130. package/dist/index.d.ts +3 -0
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +12 -6
  133. package/dist/logger/configure.d.ts.map +1 -1
  134. package/dist/logger/configure.js +10 -10
  135. package/dist/migration/code-generation.d.ts.map +1 -1
  136. package/dist/migration/code-generation.js +50 -46
  137. package/dist/migration/index-where-predicate.d.ts.map +1 -1
  138. package/dist/migration/index-where-predicate.js +22 -8
  139. package/dist/migration/migration-set.d.ts.map +1 -1
  140. package/dist/migration/migration-set.js +1 -1
  141. package/dist/migration/migrator.d.ts +3 -2
  142. package/dist/migration/migrator.d.ts.map +1 -1
  143. package/dist/migration/migrator.js +27 -21
  144. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
  145. package/dist/migration/postgresql-schema-reader.js +51 -36
  146. package/dist/migration/slack-confirm.d.ts.map +1 -1
  147. package/dist/migration/slack-confirm.js +1 -1
  148. package/dist/naite/naite-reporter.js +2 -2
  149. package/dist/naite/naite.d.ts +74 -15
  150. package/dist/naite/naite.d.ts.map +1 -1
  151. package/dist/naite/naite.js +5 -19
  152. package/dist/runtime-type.d.ts +6 -0
  153. package/dist/runtime-type.d.ts.map +1 -0
  154. package/dist/runtime-type.js +26 -0
  155. package/dist/ssr/hmr-opt-out.d.ts +26 -0
  156. package/dist/ssr/hmr-opt-out.d.ts.map +1 -0
  157. package/dist/ssr/hmr-opt-out.js +59 -0
  158. package/dist/ssr/renderer.d.ts.map +1 -1
  159. package/dist/ssr/renderer.js +4 -1
  160. package/dist/storage/base-file.js +14 -14
  161. package/dist/storage/buffered-file.d.ts +2 -2
  162. package/dist/storage/buffered-file.d.ts.map +1 -1
  163. package/dist/storage/buffered-file.js +12 -12
  164. package/dist/storage/s3-driver.d.ts.map +1 -1
  165. package/dist/storage/s3-driver.js +1 -1
  166. package/dist/storage/uploaded-file.d.ts +2 -2
  167. package/dist/storage/uploaded-file.d.ts.map +1 -1
  168. package/dist/storage/uploaded-file.js +8 -8
  169. package/dist/stream/sse.js +11 -11
  170. package/dist/stream/ws-core.d.ts +1 -1
  171. package/dist/stream/ws-core.d.ts.map +1 -1
  172. package/dist/stream/ws-delivery.d.ts +1 -1
  173. package/dist/stream/ws-delivery.d.ts.map +1 -1
  174. package/dist/stream/ws-delivery.js +6 -4
  175. package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
  176. package/dist/stream/ws-local-connection-store.js +4 -2
  177. package/dist/stream/ws-presence-store.js +1 -1
  178. package/dist/stream/ws-registry.d.ts +4 -4
  179. package/dist/stream/ws-registry.d.ts.map +1 -1
  180. package/dist/stream/ws-registry.js +4 -2
  181. package/dist/stream/ws-telemetry.d.ts +16 -12
  182. package/dist/stream/ws-telemetry.d.ts.map +1 -1
  183. package/dist/stream/ws-telemetry.js +22 -18
  184. package/dist/stream/ws.d.ts +18 -12
  185. package/dist/stream/ws.d.ts.map +1 -1
  186. package/dist/stream/ws.js +26 -22
  187. package/dist/syncer/api-parser.js +1 -1
  188. package/dist/syncer/checksum.d.ts.map +1 -1
  189. package/dist/syncer/checksum.js +7 -8
  190. package/dist/syncer/code-generator.d.ts.map +1 -1
  191. package/dist/syncer/code-generator.js +13 -14
  192. package/dist/syncer/entity-operations.d.ts.map +1 -1
  193. package/dist/syncer/entity-operations.js +5 -6
  194. package/dist/syncer/file-copy.d.ts +5 -0
  195. package/dist/syncer/file-copy.d.ts.map +1 -0
  196. package/dist/syncer/file-copy.js +36 -0
  197. package/dist/syncer/file-patterns.d.ts +1 -0
  198. package/dist/syncer/file-patterns.d.ts.map +1 -1
  199. package/dist/syncer/file-patterns.js +5 -2
  200. package/dist/syncer/file-tracking.d.ts.map +1 -1
  201. package/dist/syncer/file-tracking.js +5 -4
  202. package/dist/syncer/filesystem-dependencies.d.ts +15 -0
  203. package/dist/syncer/filesystem-dependencies.d.ts.map +1 -0
  204. package/dist/syncer/filesystem-dependencies.js +53 -0
  205. package/dist/syncer/module-loader.d.ts +1 -1
  206. package/dist/syncer/module-loader.d.ts.map +1 -1
  207. package/dist/syncer/module-loader.js +6 -4
  208. package/dist/syncer/syncer-actions.d.ts +4 -0
  209. package/dist/syncer/syncer-actions.d.ts.map +1 -1
  210. package/dist/syncer/syncer-actions.js +34 -17
  211. package/dist/syncer/syncer.d.ts +17 -6
  212. package/dist/syncer/syncer.d.ts.map +1 -1
  213. package/dist/syncer/syncer.js +71 -29
  214. package/dist/syncer/watcher.d.ts.map +1 -1
  215. package/dist/syncer/watcher.js +3 -3
  216. package/dist/tasks/decorator.d.ts +6 -6
  217. package/dist/tasks/decorator.d.ts.map +1 -1
  218. package/dist/tasks/decorator.js +4 -4
  219. package/dist/tasks/step-wrapper.d.ts +6 -4
  220. package/dist/tasks/step-wrapper.d.ts.map +1 -1
  221. package/dist/tasks/step-wrapper.js +5 -5
  222. package/dist/tasks/workflow-manager.d.ts.map +1 -1
  223. package/dist/tasks/workflow-manager.js +13 -7
  224. package/dist/template/entity-converter.d.ts +1 -1
  225. package/dist/template/entity-converter.d.ts.map +1 -1
  226. package/dist/template/entity-converter.js +2 -2
  227. package/dist/template/helpers.d.ts +8 -6
  228. package/dist/template/helpers.d.ts.map +1 -1
  229. package/dist/template/helpers.js +1 -1
  230. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  231. package/dist/template/implementations/generated.template.js +4 -4
  232. package/dist/template/implementations/generated_http.template.d.ts +7 -4
  233. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  234. package/dist/template/implementations/generated_http.template.js +21 -21
  235. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  236. package/dist/template/implementations/generated_sso.template.js +6 -3
  237. package/dist/template/implementations/http_validators.template.d.ts +18 -0
  238. package/dist/template/implementations/http_validators.template.d.ts.map +1 -0
  239. package/dist/template/implementations/http_validators.template.js +127 -0
  240. package/dist/template/implementations/model.template.d.ts.map +1 -1
  241. package/dist/template/implementations/model.template.js +1 -1
  242. package/dist/template/implementations/queries.template.js +1 -1
  243. package/dist/template/implementations/sd.template.d.ts.map +1 -1
  244. package/dist/template/implementations/sd.template.js +79 -39
  245. package/dist/template/implementations/services.template.d.ts.map +1 -1
  246. package/dist/template/implementations/services.template.js +6 -4
  247. package/dist/template/implementations/view_form.template.d.ts +6 -1
  248. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  249. package/dist/template/implementations/view_form.template.js +23 -15
  250. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  251. package/dist/template/implementations/view_list.template.js +11 -6
  252. package/dist/template/template-manager.d.ts.map +1 -1
  253. package/dist/template/template-manager.js +9 -7
  254. package/dist/template/template-types.d.ts +12 -5
  255. package/dist/template/template-types.d.ts.map +1 -1
  256. package/dist/template/template-types.js +1 -1
  257. package/dist/template/template.d.ts +2 -2
  258. package/dist/template/template.d.ts.map +1 -1
  259. package/dist/template/template.js +6 -4
  260. package/dist/template/zod-converter.d.ts +0 -19
  261. package/dist/template/zod-converter.d.ts.map +1 -1
  262. package/dist/template/zod-converter.js +100 -84
  263. package/dist/testing/_relation-graph.d.ts.map +1 -1
  264. package/dist/testing/_relation-graph.js +2 -1
  265. package/dist/testing/bootstrap.d.ts.map +1 -1
  266. package/dist/testing/bootstrap.js +9 -6
  267. package/dist/testing/data-explorer.d.ts +32 -7
  268. package/dist/testing/data-explorer.d.ts.map +1 -1
  269. package/dist/testing/data-explorer.js +77 -31
  270. package/dist/testing/dev-test-routes.d.ts +8 -1
  271. package/dist/testing/dev-test-routes.d.ts.map +1 -1
  272. package/dist/testing/dev-test-routes.js +125 -108
  273. package/dist/testing/dev-vitest-manager.d.ts +54 -8
  274. package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
  275. package/dist/testing/dev-vitest-manager.js +24 -9
  276. package/dist/testing/faker-mappings.d.ts +412 -1
  277. package/dist/testing/faker-mappings.d.ts.map +1 -1
  278. package/dist/testing/faker-mappings.js +1 -1
  279. package/dist/testing/filesystem.d.ts +2 -0
  280. package/dist/testing/filesystem.d.ts.map +1 -0
  281. package/dist/testing/filesystem.js +7 -0
  282. package/dist/testing/fixture-generator.d.ts +25 -8
  283. package/dist/testing/fixture-generator.d.ts.map +1 -1
  284. package/dist/testing/fixture-generator.js +132 -73
  285. package/dist/testing/fixture-loader.d.ts +3 -1
  286. package/dist/testing/fixture-loader.d.ts.map +1 -1
  287. package/dist/testing/fixture-loader.js +1 -20
  288. package/dist/testing/fixture-manager.d.ts +8 -7
  289. package/dist/testing/fixture-manager.d.ts.map +1 -1
  290. package/dist/testing/fixture-manager.js +91 -59
  291. package/dist/testing/global-setup.d.ts.map +1 -1
  292. package/dist/testing/global-setup.js +5 -2
  293. package/dist/testing/index.d.ts +2 -0
  294. package/dist/testing/index.d.ts.map +1 -1
  295. package/dist/testing/index.js +6 -3
  296. package/dist/types/types.d.ts +101 -99
  297. package/dist/types/types.d.ts.map +1 -1
  298. package/dist/types/types.js +234 -225
  299. package/dist/ui/ai-api.d.ts.map +1 -1
  300. package/dist/ui/ai-api.js +1 -1
  301. package/dist/ui/ai-client.d.ts.map +1 -1
  302. package/dist/ui/ai-client.js +28 -18
  303. package/dist/ui/api.d.ts.map +1 -1
  304. package/dist/ui/api.js +135 -128
  305. package/dist/ui/async-route.d.ts +3 -0
  306. package/dist/ui/async-route.d.ts.map +1 -0
  307. package/dist/ui/async-route.js +12 -0
  308. package/dist/ui/cdd-service.d.ts +9 -7
  309. package/dist/ui/cdd-service.d.ts.map +1 -1
  310. package/dist/ui/cdd-service.js +7 -5
  311. package/dist/ui/migrations-api.d.ts.map +1 -1
  312. package/dist/ui/migrations-api.js +17 -15
  313. package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
  314. package/dist/ui-web/index.html +1 -1
  315. package/dist/utils/formatter.d.ts.map +1 -1
  316. package/dist/utils/formatter.js +7 -5
  317. package/dist/utils/fs-utils.d.ts +3 -3
  318. package/dist/utils/fs-utils.d.ts.map +1 -1
  319. package/dist/utils/fs-utils.js +6 -6
  320. package/dist/utils/model.d.ts +3 -5
  321. package/dist/utils/model.d.ts.map +1 -1
  322. package/dist/utils/model.js +1 -1
  323. package/dist/utils/object-utils.d.ts +1 -1
  324. package/dist/utils/object-utils.d.ts.map +1 -1
  325. package/dist/utils/object-utils.js +17 -16
  326. package/dist/utils/process-utils.d.ts.map +1 -1
  327. package/dist/utils/process-utils.js +4 -2
  328. package/dist/utils/runtime-value.d.ts +13 -0
  329. package/dist/utils/runtime-value.d.ts.map +1 -0
  330. package/dist/utils/runtime-value.js +40 -0
  331. package/dist/utils/sql-parser.d.ts +8 -1
  332. package/dist/utils/sql-parser.d.ts.map +1 -1
  333. package/dist/utils/sql-parser.js +6 -3
  334. package/dist/utils/type-utils.d.ts.map +1 -1
  335. package/dist/utils/type-utils.js +10 -8
  336. package/dist/utils/utils.d.ts +2 -2
  337. package/dist/utils/utils.d.ts.map +1 -1
  338. package/dist/utils/utils.js +11 -8
  339. package/dist/utils/zod-error.d.ts.map +1 -1
  340. package/dist/utils/zod-error.js +7 -4
  341. package/dist/vector/chunking.d.ts.map +1 -1
  342. package/dist/vector/chunking.js +1 -1
  343. package/dist/vector/embedding.d.ts.map +1 -1
  344. package/dist/vector/embedding.js +1 -1
  345. package/dist/vector/types.d.ts +3 -2
  346. package/dist/vector/types.d.ts.map +1 -1
  347. package/package.json +5 -3
  348. package/src/ai/agents/agent.ts +5 -5
  349. package/src/ai/agents/types.ts +1 -1
  350. package/src/ai/providers/rtzr/__tests__/model.test.ts +2 -2
  351. package/src/ai/providers/rtzr/error.ts +5 -3
  352. package/src/ai/providers/rtzr/model.ts +3 -2
  353. package/src/ai/providers/rtzr/options.ts +10 -5
  354. package/src/ai/providers/rtzr/provider.ts +10 -10
  355. package/src/ai/providers/rtzr/utils.ts +3 -1
  356. package/src/api/__tests__/config.test.ts +11 -21
  357. package/src/api/__tests__/sonamu.http-validator.test.ts +512 -0
  358. package/src/api/__tests__/sonamu.websocket.test.ts +51 -41
  359. package/src/api/__tests__/zod-compiler-policy.test.ts +95 -0
  360. package/src/api/caster.ts +6 -8
  361. package/src/api/code-converters.ts +136 -36
  362. package/src/api/config.ts +62 -4
  363. package/src/api/context.ts +3 -3
  364. package/src/api/decorators.ts +28 -17
  365. package/src/api/http-validator.ts +149 -0
  366. package/src/api/sonamu.ts +459 -152
  367. package/src/api/websocket-helpers.ts +24 -17
  368. package/src/auth/audit-log/builders.ts +3 -2
  369. package/src/auth/audit-log/client-ip.ts +4 -2
  370. package/src/auth/audit-log/events.ts +15 -1
  371. package/src/auth/audit-log/plugin.ts +129 -200
  372. package/src/auth/audit-log-ingestor.ts +19 -15
  373. package/src/auth/auth-generator.ts +10 -5
  374. package/src/auth/better-auth-request.ts +4 -3
  375. package/src/auth/knex-adapter.ts +8 -2
  376. package/src/auth/plugins/entity-definitions/index.ts +6 -5
  377. package/src/bin/__tests__/http-validator-benchmark.test.ts +94 -0
  378. package/src/bin/__tests__/test-command.test.ts +9 -15
  379. package/src/bin/__tests__/ts-loader-register.test.ts +15 -17
  380. package/src/bin/__tests__/zod-compiler-build.test.ts +307 -0
  381. package/src/bin/build-config.ts +167 -0
  382. package/src/bin/cli.ts +153 -36
  383. package/src/bin/compiler-policy.ts +35 -0
  384. package/src/bin/fixture.ts +14 -3
  385. package/src/bin/test-command.ts +74 -29
  386. package/src/bin/ts-loader-registration.ts +22 -4
  387. package/src/cache/decorator.ts +10 -3
  388. package/src/compress/compress.ts +17 -4
  389. package/src/cone/cone-generator.ts +34 -6
  390. package/src/database/__tests__/db.test.ts +1 -0
  391. package/src/database/__tests__/puri.test.ts +16 -15
  392. package/src/database/__tests__/transaction-scope.test.ts +5 -0
  393. package/src/database/_batch_update.ts +1 -0
  394. package/src/database/base-model.ts +81 -50
  395. package/src/database/base-model.types.ts +6 -6
  396. package/src/database/db.ts +29 -19
  397. package/src/database/knex.ts +30 -17
  398. package/src/database/puri-subset.test-d.ts +17 -0
  399. package/src/database/puri.ts +181 -143
  400. package/src/database/puri.types.test-d.ts +31 -1
  401. package/src/database/puri.types.ts +23 -21
  402. package/src/database/upsert-builder.ts +75 -53
  403. package/src/dict/sd.ts +15 -5
  404. package/src/dict/sonamu-dictionary.ts +6 -6
  405. package/src/dict/utils.ts +9 -1
  406. package/src/entity/entity-manager.ts +26 -9
  407. package/src/entity/entity-template-cone.ts +5 -10
  408. package/src/entity/entity.ts +50 -34
  409. package/src/env.ts +7 -3
  410. package/src/exceptions/error-handler.ts +17 -2
  411. package/src/exceptions/so-exceptions.ts +26 -20
  412. package/src/filter/utils.ts +21 -11
  413. package/src/index.ts +3 -0
  414. package/src/logger/configure.ts +26 -18
  415. package/src/migration/__tests__/migrator.test.ts +50 -57
  416. package/src/migration/code-generation.ts +132 -104
  417. package/src/migration/index-where-predicate.ts +51 -24
  418. package/src/migration/migration-set.ts +11 -5
  419. package/src/migration/migrator.ts +68 -41
  420. package/src/migration/postgresql-schema-reader.ts +52 -47
  421. package/src/migration/slack-confirm.ts +17 -15
  422. package/src/naite/naite-reporter.ts +1 -1
  423. package/src/naite/naite.ts +97 -24
  424. package/src/runtime-type.ts +34 -0
  425. package/src/ssr/hmr-opt-out.ts +78 -0
  426. package/src/ssr/renderer.ts +6 -0
  427. package/src/storage/base-file.ts +13 -13
  428. package/src/storage/buffered-file.ts +11 -11
  429. package/src/storage/s3-driver.ts +4 -1
  430. package/src/storage/uploaded-file.ts +8 -8
  431. package/src/stream/__tests__/ws-contracts.test.ts +4 -2
  432. package/src/stream/__tests__/ws-telemetry.test.ts +1 -1
  433. package/src/stream/__tests__/ws.test.ts +30 -6
  434. package/src/stream/sse.ts +12 -11
  435. package/src/stream/ws-core.ts +1 -1
  436. package/src/stream/ws-delivery.ts +16 -7
  437. package/src/stream/ws-local-connection-store.ts +2 -3
  438. package/src/stream/ws-presence-store.ts +6 -1
  439. package/src/stream/ws-registry.ts +16 -7
  440. package/src/stream/ws-telemetry.ts +66 -43
  441. package/src/stream/ws.ts +73 -39
  442. package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +3 -2
  443. package/src/syncer/__tests__/http-validator-registry.test.ts +137 -0
  444. package/src/syncer/api-parser.ts +67 -27
  445. package/src/syncer/checksum.ts +17 -11
  446. package/src/syncer/code-generator.ts +25 -17
  447. package/src/syncer/entity-operations.ts +3 -5
  448. package/src/syncer/file-copy.ts +46 -0
  449. package/src/syncer/file-patterns.ts +11 -8
  450. package/src/syncer/file-tracking.ts +3 -4
  451. package/src/syncer/filesystem-dependencies.ts +73 -0
  452. package/src/syncer/module-loader.ts +8 -4
  453. package/src/syncer/syncer-actions.ts +56 -18
  454. package/src/syncer/syncer.ts +116 -43
  455. package/src/syncer/watcher.ts +8 -4
  456. package/src/tasks/decorator.ts +20 -12
  457. package/src/tasks/step-wrapper.ts +19 -9
  458. package/src/tasks/workflow-manager.ts +15 -9
  459. package/src/template/__tests__/http_validators.template.test.ts +160 -0
  460. package/src/template/__tests__/services.template.mutation.test.ts +24 -23
  461. package/src/template/__tests__/services.template.websocket.test.ts +21 -25
  462. package/src/template/entity-converter.ts +5 -2
  463. package/src/template/helpers.ts +8 -9
  464. package/src/template/implementations/generated.template.ts +5 -4
  465. package/src/template/implementations/generated_http.template.ts +61 -15
  466. package/src/template/implementations/generated_sso.template.ts +15 -4
  467. package/src/template/implementations/http_validators.template.ts +175 -0
  468. package/src/template/implementations/model.template.ts +3 -1
  469. package/src/template/implementations/sd.template.ts +81 -41
  470. package/src/template/implementations/services.template.ts +2 -2
  471. package/src/template/implementations/view_form.template.ts +56 -39
  472. package/src/template/implementations/view_list.template.ts +31 -23
  473. package/src/template/template-manager.ts +15 -13
  474. package/src/template/template-types.ts +13 -5
  475. package/src/template/template.ts +4 -3
  476. package/src/template/zod-converter.ts +206 -91
  477. package/src/testing/__tests__/dev-test-routes.test.ts +85 -25
  478. package/src/testing/__tests__/dev-vitest-manager.test.ts +15 -15
  479. package/src/testing/_relation-graph.ts +4 -1
  480. package/src/testing/bootstrap.ts +12 -5
  481. package/src/testing/data-explorer.ts +102 -53
  482. package/src/testing/dev-test-routes.ts +87 -50
  483. package/src/testing/dev-vitest-manager.ts +88 -32
  484. package/src/testing/faker-mappings.ts +2 -2
  485. package/src/testing/filesystem.ts +1 -0
  486. package/src/testing/fixture-generator.ts +191 -131
  487. package/src/testing/fixture-loader.ts +5 -1
  488. package/src/testing/fixture-manager.ts +129 -90
  489. package/src/testing/global-setup.ts +7 -3
  490. package/src/testing/index.ts +5 -0
  491. package/src/types/__tests__/entity-json-schema-search-text.test.ts +9 -3
  492. package/src/types/types.ts +184 -158
  493. package/src/ui/ai-api.ts +9 -7
  494. package/src/ui/ai-client.ts +61 -56
  495. package/src/ui/api.ts +727 -616
  496. package/src/ui/async-route.ts +4 -0
  497. package/src/ui/cdd-service.ts +35 -12
  498. package/src/ui/migrations-api.ts +63 -51
  499. package/src/utils/formatter.ts +7 -3
  500. package/src/utils/fs-utils.ts +5 -5
  501. package/src/utils/model.ts +4 -5
  502. package/src/utils/object-utils.ts +32 -22
  503. package/src/utils/process-utils.ts +4 -1
  504. package/src/utils/runtime-value.ts +43 -0
  505. package/src/utils/sql-parser.ts +13 -6
  506. package/src/utils/type-utils.ts +9 -7
  507. package/src/utils/utils.ts +19 -21
  508. package/src/utils/zod-error.ts +4 -2
  509. package/src/vector/chunking.ts +6 -1
  510. package/src/vector/embedding.ts +2 -1
  511. package/src/vector/types.ts +4 -2
  512. package/tsdown.api.config.ts +5 -2
  513. package/dist/ui-web/assets/index-C0m1pk6K.js +0 -177
@@ -1,5 +1,3 @@
1
- /* oxlint-disable @typescript-eslint/no-explicit-any */ // Naite는 expect와 호응하도록 any를 허용함
2
-
3
1
  import { getLogger } from "@logtape/logtape";
4
2
  import { get } from "radashi";
5
3
 
@@ -7,6 +5,7 @@ import { Sonamu } from "../api/sonamu";
7
5
  import { type ComparisonOperator } from "../database/puri.types";
8
6
  import { convertNaiteKeyToCategory } from "../logger/category";
9
7
  import { isSerializable } from "../utils/object-utils";
8
+ import { isNumberValue, isStringValue } from "../utils/runtime-value";
10
9
 
11
10
  // StackFrame 타입
12
11
  interface StackFrame {
@@ -18,11 +17,78 @@ interface StackFrame {
18
17
  // NaiteTrace 타입
19
18
  interface NaiteTrace {
20
19
  key: string;
21
- data: any;
20
+ data: NaiteData;
22
21
  stack: StackFrame[]; // 콜스택 정보
23
22
  at: Date;
24
23
  }
25
24
 
25
+ // Naite는 직렬화 가능성 검사를 내보내기 시점에 수행하므로 모든 JavaScript 값을 기록할 수 있습니다.
26
+ export type NaiteData = null | undefined | bigint | boolean | number | object | string | symbol;
27
+
28
+ export interface NaiteEventRegistry {
29
+ actionGenerateServices: readonly object[];
30
+ "fs/promises:rm": {
31
+ path: string;
32
+ options?: object;
33
+ };
34
+ "fs/promises:writeFile": {
35
+ path: string;
36
+ data: string;
37
+ };
38
+ "puri:executed-query": string;
39
+ "puri:ub-batch-updated": {
40
+ tableName: string;
41
+ rowCount: number;
42
+ whereColumns: string[];
43
+ };
44
+ "puri:ub-clean-orphans": {
45
+ tableName: string;
46
+ cleanOrphans: string[];
47
+ deletedCount: number;
48
+ };
49
+ "puri:ub-inherit": {
50
+ tableName: string;
51
+ inheritColumns: string[];
52
+ excludedFromUpdate: string[];
53
+ };
54
+ "puri:ub-ref-resolved": {
55
+ tableName: string;
56
+ field: string;
57
+ from: UBReference;
58
+ to: NaiteData;
59
+ };
60
+ "puri:ub-register": {
61
+ tableName: string;
62
+ uuid: string;
63
+ isUuidReused: boolean;
64
+ row: object & { user_id: UBReference };
65
+ };
66
+ "puri:ub-upserted": {
67
+ tableName: string;
68
+ mode: "insert" | "upsert";
69
+ rowCount: number;
70
+ returnedIds: Array<number | string>;
71
+ };
72
+ }
73
+
74
+ interface UBReference {
75
+ uuid: string;
76
+ of: string;
77
+ use?: string;
78
+ }
79
+
80
+ export interface NaiteResult<Payload> extends Array<Payload> {
81
+ 0: Payload;
82
+ 1: Payload;
83
+ [index: number]: Payload;
84
+ find<Match extends Payload>(
85
+ predicate: (value: Payload, index: number, values: Payload[]) => value is Match,
86
+ ): Match;
87
+ find(predicate: (value: Payload, index: number, values: Payload[]) => boolean): Payload;
88
+ }
89
+
90
+ type NaiteValuesByKey = Record<string, NaiteTrace[] | Array<NaiteTrace["data"]>>;
91
+
26
92
  // Naite.t가 저장되는 타입 (항상 배열로 통일)
27
93
  export type NaiteStore = Map<string, NaiteTrace[]>;
28
94
 
@@ -30,7 +96,7 @@ export type NaiteStore = Map<string, NaiteTrace[]>;
30
96
  // bootstrap.ts의 TaskMeta augmentation, dev-vitest-manager.ts에서도 이 타입을 공유합니다.
31
97
  export type SerializedTrace = {
32
98
  key: string;
33
- value: any;
99
+ value: unknown;
34
100
  filePath: string;
35
101
  lineNumber: number;
36
102
  at: string;
@@ -140,22 +206,22 @@ function matchesPattern(key: string, pattern: string): boolean {
140
206
  * NaiteQuery 클래스
141
207
  * 체이닝을 통한 trace 필터링 및 조회
142
208
  */
143
- export class NaiteQuery {
209
+ export class NaiteQuery<Payload extends NaiteData = NaiteData> {
144
210
  constructor(private traces: NaiteTrace[]) {}
145
211
 
146
- private isComparableValue(value: unknown): value is number | string {
147
- return typeof value === "number" || typeof value === "string";
212
+ private isComparableValue<Value>(value: Value): value is Value & (number | string) {
213
+ return isNumberValue(value) || isStringValue(value);
148
214
  }
149
215
 
150
216
  /**
151
217
  * 파일명으로 필터링
152
218
  * @param fileName 파일명 (예: "syncer.test.ts")
153
219
  */
154
- fromFile(fileName: string): NaiteQuery {
220
+ fromFile(fileName: string): NaiteQuery<Payload> {
155
221
  const filtered = this.traces.filter((t) =>
156
222
  t.stack.some((frame) => frame.filePath.endsWith(`/${fileName}`)),
157
223
  );
158
- return new NaiteQuery(filtered);
224
+ return new NaiteQuery<Payload>(filtered);
159
225
  }
160
226
 
161
227
  /**
@@ -166,7 +232,7 @@ export class NaiteQuery {
166
232
  fromFunction(
167
233
  funcName: string,
168
234
  options: { from: "direct" | "indirect" | "both" } = { from: "both" },
169
- ): NaiteQuery {
235
+ ): NaiteQuery<Payload> {
170
236
  const filtered = this.traces.filter((t) => {
171
237
  if (options.from === "direct") {
172
238
  // stack[0]만 확인 (직접 호출)
@@ -179,7 +245,7 @@ export class NaiteQuery {
179
245
  // 전체 스택에서 확인
180
246
  return t.stack.some((f) => f.functionName?.includes(funcName));
181
247
  });
182
- return new NaiteQuery(filtered);
248
+ return new NaiteQuery<Payload>(filtered);
183
249
  }
184
250
 
185
251
  /**
@@ -188,7 +254,11 @@ export class NaiteQuery {
188
254
  * @param operator 비교 연산자
189
255
  * @param value 비교값
190
256
  */
191
- where(path: string, operator: ComparisonOperator | "includes", value: any): NaiteQuery {
257
+ where<Value extends NaiteData>(
258
+ path: string,
259
+ operator: ComparisonOperator | "includes",
260
+ value: Value,
261
+ ): NaiteQuery<Payload> {
192
262
  const filtered = this.traces.filter((trace) => {
193
263
  const actual = get(trace, path);
194
264
 
@@ -206,39 +276,43 @@ export class NaiteQuery {
206
276
  case "!=":
207
277
  return actual !== value;
208
278
  case "includes":
209
- return typeof actual === "string" && actual.includes(value);
279
+ return isStringValue(actual) && isStringValue(value) && actual.includes(value);
210
280
  default:
211
281
  return false;
212
282
  }
213
283
  });
214
- return new NaiteQuery(filtered);
284
+ return new NaiteQuery<Payload>(filtered);
215
285
  }
216
286
 
217
287
  /**
218
288
  * 전체 데이터 배열 반환
219
289
  */
220
- result(): any[] {
290
+ result(): NaiteResult<Payload>;
291
+ result(): NaiteData[] {
221
292
  return this.traces.map((t) => t.data);
222
293
  }
223
294
 
224
295
  /**
225
296
  * 첫 번째 데이터 반환
226
297
  */
227
- first(): any | undefined {
298
+ first(): Payload;
299
+ first(): NaiteData {
228
300
  return this.traces[0]?.data;
229
301
  }
230
302
 
231
303
  /**
232
304
  * 마지막 데이터 반환
233
305
  */
234
- last(): any | undefined {
306
+ last(): Payload;
307
+ last(): NaiteData {
235
308
  return this.traces[this.traces.length - 1]?.data;
236
309
  }
237
310
 
238
311
  /**
239
312
  * n번째 데이터 반환
240
313
  */
241
- at(index: number): any | undefined {
314
+ at(index: number): Payload;
315
+ at(index: number): NaiteData {
242
316
  return this.traces[index]?.data;
243
317
  }
244
318
 
@@ -253,10 +327,7 @@ export class NaiteQuery {
253
327
  // Naite 싱글턴 객체 (추후 logger 연결 등의 상태 관리 필요성 고려)
254
328
  export class NaiteClass {
255
329
  // 테스트 로그 기록
256
- t(
257
- name: string,
258
- value: any /*이렇게 받은 값이 NaiteTrace로 저장되어 있다가 추후에 vitest에게 meta를 통해 넘겨져 프로세스간 통신을 통해 직렬화되어야 하는 점을 고려하였을 때 여기에 Serializable을 써서 제한을 둘 수도 있지만, 사용상의 편의를 생각하여 any로 받습니다.*/,
259
- ) {
330
+ t<Value extends NaiteData>(name: string, value: Value) {
260
331
  // 이 t 함수는 테스트 환경에서만 작동해야 합니다.
261
332
  // 그리고 테스트 환경 판단에 왜 isTest() 함수를 사용하지 않았냐면요,,
262
333
  // 이렇게 하는게 유틸 함수 불러와서 사용하는 것보다 조금이나마 빠를 것 같았기 때문입니다.
@@ -302,6 +373,8 @@ export class NaiteClass {
302
373
  * key 또는 wildcard 패턴으로 trace 조회
303
374
  * 항상 NaiteQuery 반환하여 체이닝 가능
304
375
  */
376
+ get<Key extends keyof NaiteEventRegistry>(keyPattern: Key): NaiteQuery<NaiteEventRegistry[Key]>;
377
+ get(keyPattern: string): NaiteQuery;
305
378
  get(keyPattern: string): NaiteQuery {
306
379
  const context = Sonamu.getContext();
307
380
  const store = context?.naiteStore;
@@ -328,13 +401,13 @@ export class NaiteClass {
328
401
  }
329
402
 
330
403
  // 전체 리스트 가져오기
331
- getAll(): { [key: string]: any } {
404
+ getAll() {
332
405
  const context = Sonamu.getContext();
333
406
  if (!context?.naiteStore) {
334
407
  return {};
335
408
  }
336
409
  // NaiteTrace 배열을 data만 추출하여 반환
337
- const result: { [key: string]: any } = {};
410
+ const result: NaiteValuesByKey = {};
338
411
  for (const [key, traces] of context.naiteStore.entries()) {
339
412
  if (key.startsWith("mock:")) {
340
413
  // Mock 설정은 그대로 반환
@@ -0,0 +1,34 @@
1
+ import {
2
+ isBigIntValue,
3
+ isFunctionValue,
4
+ isNumberValue,
5
+ isStringValue,
6
+ isSymbolValue,
7
+ } from "./utils/runtime-value";
8
+
9
+ export type RuntimeType =
10
+ | "bigint"
11
+ | "boolean"
12
+ | "function"
13
+ | "number"
14
+ | "object"
15
+ | "string"
16
+ | "symbol"
17
+ | "undefined";
18
+
19
+ /** 런타임 값이 불리언인지 판별합니다. */
20
+ export function isBooleanValue<Value>(value: Value): value is Value & boolean {
21
+ return value === true || value === false;
22
+ }
23
+
24
+ /** JavaScript의 typeof 결과를 단항 연산자 없이 동일하게 계산합니다. */
25
+ export function runtimeTypeOf<Value>(value: Value): RuntimeType {
26
+ if (value === undefined) return "undefined";
27
+ if (isStringValue(value)) return "string";
28
+ if (isNumberValue(value)) return "number";
29
+ if (isBooleanValue(value)) return "boolean";
30
+ if (isBigIntValue(value)) return "bigint";
31
+ if (isSymbolValue(value)) return "symbol";
32
+ if (isFunctionValue(value)) return "function";
33
+ return "object";
34
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * 페이지 단위 HMR 비활성화(`?hmr=false`).
3
+ *
4
+ * 에이전트가 코드를 고치는 동안 사람이 보고 있는 탭이 계속 새로고침되는 것을 막기 위해,
5
+ * 해당 URL로 연 페이지에서만 Vite HMR을 끊는다.
6
+ *
7
+ * Vite는 페이지 단위 HMR 토글을 제공하지 않는다. `server.hmr: false`는 서버 전체에 적용되고,
8
+ * HTML에서 `/@vite/client` 스크립트 태그만 제거하는 방식도 통하지 않는다.
9
+ * 변환된 모듈마다 `import { createHotContext } from "/@vite/client"`가 들어가기 때문이다.
10
+ *
11
+ * 그래서 HMR 웹소켓 자체를 막는다. Vite HMR 소켓은 서브프로토콜로 구분되므로
12
+ * (`vite-hmr`, 재연결 확인은 `vite-ping`), 앱이 같은 포트에서 쓰는 웹소켓
13
+ * (Sonamu telemetry, ctx.ws 등)은 그대로 두고 HMR만 골라낼 수 있다.
14
+ *
15
+ * 연결 실패로 처리하지 않고 "영원히 연결 중"인 더미 소켓을 돌려주는 이유는,
16
+ * Vite 클라이언트가 소켓이 닫히면 재연결을 폴링하다가 성공 시 `location.reload()`를
17
+ * 호출하기 때문이다. close/error 이벤트를 아예 발생시키지 않아야 새로고침되지 않는다.
18
+ */
19
+
20
+ const HMR_OPT_OUT_QUERY = "hmr";
21
+
22
+ /** 요청 URL에 `?hmr=false`가 있는지 확인한다. */
23
+ export function isHmrDisabledByQuery(url: string): boolean {
24
+ const queryIndex = url.indexOf("?");
25
+ if (queryIndex === -1) {
26
+ return false;
27
+ }
28
+
29
+ const params = new URLSearchParams(url.slice(queryIndex + 1));
30
+ const value = params.get(HMR_OPT_OUT_QUERY);
31
+ return value === "false" || value === "0";
32
+ }
33
+
34
+ /**
35
+ * HMR 웹소켓만 무력화하는 인라인 스크립트.
36
+ * 모듈 스크립트(`type="module"`)는 지연 실행되므로, 이 classic 스크립트가 항상 먼저 실행된다.
37
+ */
38
+ export const HMR_OPT_OUT_SCRIPT = `<script>
39
+ (() => {
40
+ var NativeWebSocket = window.WebSocket;
41
+ if (!NativeWebSocket) return;
42
+ var HMR_PROTOCOLS = ["vite-hmr", "vite-ping"];
43
+
44
+ function createIdleSocket(url) {
45
+ // 열리지도 닫히지도 않는 더미. close/error를 발생시키면 Vite가 재연결 후 새로고침한다.
46
+ return {
47
+ url: String(url),
48
+ readyState: 0,
49
+ protocol: "",
50
+ bufferedAmount: 0,
51
+ extensions: "",
52
+ binaryType: "blob",
53
+ onopen: null, onclose: null, onerror: null, onmessage: null,
54
+ addEventListener: function () {},
55
+ removeEventListener: function () {},
56
+ dispatchEvent: function () { return false; },
57
+ send: function () {},
58
+ close: function () {},
59
+ CONNECTING: 0, OPEN: 1, CLOSING: 2, CLOSED: 3,
60
+ };
61
+ }
62
+
63
+ window.WebSocket = new Proxy(NativeWebSocket, {
64
+ construct: function (Target, args) {
65
+ var requested = args[1];
66
+ var protocols = Array.isArray(requested) ? requested : requested ? [requested] : [];
67
+ var isHmr = protocols.some(function (protocol) {
68
+ return HMR_PROTOCOLS.indexOf(protocol) !== -1;
69
+ });
70
+ if (isHmr) {
71
+ console.info("[sonamu] hmr=false: 이 페이지의 Vite HMR 연결을 막았습니다. 변경 사항은 반영되지 않습니다.");
72
+ return createIdleSocket(args[0]);
73
+ }
74
+ return new Target(...args);
75
+ },
76
+ });
77
+ })();
78
+ </script>`;
@@ -6,6 +6,7 @@ import { type ViteDevServer } from "vite";
6
6
  import { applyCacheHeaders } from "../cache-control/cache-control";
7
7
  import { type CacheControlRequest } from "../cache-control/types";
8
8
  import { type SonamuFastifyConfig } from "../types/types";
9
+ import { HMR_OPT_OUT_SCRIPT, isHmrDisabledByQuery } from "./hmr-opt-out";
9
10
  import { type PreloadedData, type SSRRoute } from "./types";
10
11
 
11
12
  export async function renderSSR(
@@ -61,6 +62,11 @@ export async function renderSSR(
61
62
  // Vite가 주입한 스크립트 추출
62
63
  viteScripts = extractScriptTags(transformedHtml);
63
64
 
65
+ // ?hmr=false로 연 페이지는 HMR 웹소켓만 끊어 새로고침되지 않게 한다.
66
+ if (isHmrDisabledByQuery(url)) {
67
+ viteScripts = `${HMR_OPT_OUT_SCRIPT}\n${viteScripts}`;
68
+ }
69
+
64
70
  const entryModule = await vite.ssrLoadModule("/src/entry-server.generated.tsx");
65
71
  render = entryModule.render;
66
72
  } else {
@@ -17,46 +17,46 @@ export abstract class BaseFile {
17
17
  url?: string;
18
18
  signedUrl?: string;
19
19
  }) {
20
- this._filename = params.filename;
21
- this._mimetype = params.mimetype;
22
- this._size = params.size;
23
- this._url = params.url;
24
- this._signedUrl = params.signedUrl;
20
+ this["_filename"] = params.filename;
21
+ this["_mimetype"] = params.mimetype;
22
+ this["_size"] = params.size;
23
+ this["_url"] = params.url;
24
+ this["_signedUrl"] = params.signedUrl;
25
25
  }
26
26
 
27
27
  /** 원본 파일명 */
28
28
  get filename(): string {
29
- return this._filename;
29
+ return this["_filename"];
30
30
  }
31
31
 
32
32
  /** MIME 타입 */
33
33
  get mimetype(): string {
34
- return this._mimetype;
34
+ return this["_mimetype"];
35
35
  }
36
36
 
37
37
  /** 파일 크기 (bytes) */
38
38
  get size(): number {
39
- return this._size;
39
+ return this["_size"];
40
40
  }
41
41
 
42
42
  /** 확장자 (점 제외) */
43
43
  get extname(): string | false {
44
- return mime.extension(this._mimetype);
44
+ return mime.extension(this["_mimetype"]);
45
45
  }
46
46
 
47
47
  /** 저장된 URL (Unsigned) */
48
48
  get url(): string {
49
- if (this._url === undefined) {
49
+ if (this["_url"] === undefined) {
50
50
  throw new Error("url이 설정되지 않았습니다.");
51
51
  }
52
- return this._url;
52
+ return this["_url"];
53
53
  }
54
54
 
55
55
  /** 저장된 URL (Signed) */
56
56
  get signedUrl(): string {
57
- if (this._signedUrl === undefined) {
57
+ if (this["_signedUrl"] === undefined) {
58
58
  throw new Error("signedUrl이 설정되지 않았습니다.");
59
59
  }
60
- return this._signedUrl;
60
+ return this["_signedUrl"];
61
61
  }
62
62
  }
@@ -10,8 +10,8 @@ import { type DriverKey } from "./drivers";
10
10
  * 메모리에 로드된 상태로, md5 계산이나 이미지 처리 등 유연한 작업이 가능합니다.
11
11
  */
12
12
  export class BufferedFile extends BaseFile {
13
- private _file: MultipartFile;
14
- private _buffer: Buffer;
13
+ private fileValue: MultipartFile;
14
+ private bufferValue: Buffer;
15
15
 
16
16
  constructor(file: MultipartFile, buffer: Buffer) {
17
17
  super({
@@ -19,18 +19,18 @@ export class BufferedFile extends BaseFile {
19
19
  mimetype: file.mimetype,
20
20
  size: buffer.length,
21
21
  });
22
- this._file = file;
23
- this._buffer = buffer;
22
+ this.fileValue = file;
23
+ this.bufferValue = buffer;
24
24
  }
25
25
 
26
26
  /** 파일 Buffer */
27
27
  get buffer(): Buffer {
28
- return this._buffer;
28
+ return this.bufferValue;
29
29
  }
30
30
 
31
31
  /** MD5 해시 계산 */
32
32
  async md5(): Promise<string> {
33
- return createHash("md5").update(this._buffer).digest("hex");
33
+ return createHash("md5").update(this.bufferValue).digest("hex");
34
34
  }
35
35
 
36
36
  /**
@@ -44,19 +44,19 @@ export class BufferedFile extends BaseFile {
44
44
  const { Sonamu } = await import("../api/sonamu");
45
45
  const disk = Sonamu.storage.use(diskName);
46
46
 
47
- await disk.put(key, new Uint8Array(this._buffer), {
47
+ await disk.put(key, new Uint8Array(this.bufferValue), {
48
48
  contentType: this.mimetype,
49
49
  });
50
50
 
51
- this._url = await disk.getUrl(key);
52
- this._signedUrl = await disk.getSignedUrl(key);
51
+ this["_url"] = await disk.getUrl(key);
52
+ this["_signedUrl"] = await disk.getSignedUrl(key);
53
53
 
54
54
  // signed url은 만료 시간이 있기 때문에, unsigned url을 반환합니다.
55
- return this._url;
55
+ return this["_url"];
56
56
  }
57
57
 
58
58
  /** 원본 MultipartFile 접근 */
59
59
  get raw(): MultipartFile {
60
- return this._file;
60
+ return this.fileValue;
61
61
  }
62
62
  }
@@ -62,7 +62,10 @@ export class SonamuS3Driver extends S3Driver {
62
62
 
63
63
  // ACL 지원 시에만 설정
64
64
  if (this.sonamuSupportsACL) {
65
- uploadParams.ACL = (visibility === "public" ? "public-read" : "private") as ObjectCannedACL;
65
+ uploadParams.ACL =
66
+ /* SAFETY: 호출 경계의 선행 검증과 소유 타입 계약이 이 값의 타입을 보장한다. */ (
67
+ visibility === "public" ? "public-read" : "private"
68
+ ) as ObjectCannedACL;
66
69
  }
67
70
 
68
71
  const upload = new Upload({
@@ -6,8 +6,8 @@ import { type DriverKey } from "./drivers";
6
6
  * 이미 저장소에 스트리밍 완료된 상태로, url/key 등 메타데이터만 접근 가능합니다.
7
7
  */
8
8
  export class UploadedFile extends BaseFile {
9
- private _key: string;
10
- private _diskName: DriverKey;
9
+ private keyValue: string;
10
+ private diskNameValue: DriverKey;
11
11
 
12
12
  constructor(params: {
13
13
  filename: string;
@@ -25,18 +25,18 @@ export class UploadedFile extends BaseFile {
25
25
  url: params.url,
26
26
  signedUrl: params.signedUrl,
27
27
  });
28
- this._key = params.key;
29
- this._diskName = params.diskName;
28
+ this.keyValue = params.key;
29
+ this.diskNameValue = params.diskName;
30
30
  }
31
31
 
32
32
  /** 저장소 내 키 */
33
33
  get key(): string {
34
- return this._key;
34
+ return this.keyValue;
35
35
  }
36
36
 
37
37
  /** 저장된 디스크 이름 */
38
38
  get diskName(): DriverKey {
39
- return this._diskName;
39
+ return this.diskNameValue;
40
40
  }
41
41
 
42
42
  /**
@@ -45,9 +45,9 @@ export class UploadedFile extends BaseFile {
45
45
  */
46
46
  async download(): Promise<Buffer> {
47
47
  const { Sonamu } = await import("../api/sonamu");
48
- const disk = Sonamu.storage.use(this._diskName);
48
+ const disk = Sonamu.storage.use(this.diskNameValue);
49
49
 
50
- const uint8Array = await disk.get(this._key);
50
+ const uint8Array = await disk.get(this.keyValue);
51
51
  return Buffer.from(uint8Array);
52
52
  }
53
53
  }
@@ -13,6 +13,8 @@ import { WebSocketDeliveryEngine } from "../ws-delivery";
13
13
  import { WebSocketLocalConnectionStore } from "../ws-local-connection-store";
14
14
  import { InMemoryWebSocketPresenceStore } from "../ws-presence-store";
15
15
 
16
+ type PublishedData = Parameters<ManagedWebSocketConnection["publishUntyped"]>[1];
17
+
16
18
  async function waitForAsyncQueue(rounds: number = 3): Promise<void> {
17
19
  for (let index = 0; index < rounds; index += 1) {
18
20
  await new Promise<void>((resolve) => {
@@ -48,7 +50,7 @@ class ContractClusterBus implements WebSocketClusterBus {
48
50
  }
49
51
 
50
52
  class ContractConnection implements ManagedWebSocketConnection {
51
- readonly sent: Array<{ event: string; data: unknown }> = [];
53
+ readonly sent: Array<{ event: string; data: PublishedData }> = [];
52
54
  closed = false;
53
55
 
54
56
  constructor(
@@ -56,7 +58,7 @@ class ContractConnection implements ManagedWebSocketConnection {
56
58
  readonly namespace: string,
57
59
  ) {}
58
60
 
59
- publishUntyped(event: string, data: unknown): void {
61
+ publishUntyped<Data>(event: string, data: Data): void {
60
62
  this.sent.push({ event, data });
61
63
  }
62
64
 
@@ -562,7 +562,7 @@ describe("metric source", () => {
562
562
  };
563
563
 
564
564
  const unsubscribe = controller.registerMetricSource(source);
565
- expect(typeof unsubscribe).toBe("function");
565
+ expect(unsubscribe).toBeInstanceOf(Function);
566
566
 
567
567
  const snapshotBefore = controller.getMetricsSnapshot();
568
568
  expect(snapshotBefore.activeConnections).toBe(7);
@@ -1,10 +1,9 @@
1
1
  import { EventEmitter } from "node:events";
2
2
 
3
3
  import { describe, expect, it, vi } from "vitest";
4
- import { type WebSocket } from "ws";
5
4
  import { z } from "zod";
6
5
 
7
- import { createWebSocketRuntime } from "../ws";
6
+ import { createWebSocketRuntime, type WebSocketTransport } from "../ws";
8
7
  import { WebSocketAudience } from "../ws-audience";
9
8
  import {
10
9
  type WebSocketClusterBus,
@@ -48,8 +47,33 @@ class FakeWebSocket extends EventEmitter {
48
47
  }
49
48
  }
50
49
 
51
- function asWebSocket(socket: FakeWebSocket): WebSocket {
52
- return socket as unknown as WebSocket;
50
+ function asWebSocket(socket: FakeWebSocket): WebSocketTransport {
51
+ return {
52
+ get bufferedAmount() {
53
+ return socket.bufferedAmount;
54
+ },
55
+ get readyState() {
56
+ return socket.readyState;
57
+ },
58
+ close(code, reason) {
59
+ socket.close(code, reason?.toString());
60
+ },
61
+ off(...args) {
62
+ socket.off(...args);
63
+ },
64
+ on(...args) {
65
+ socket.on(...args);
66
+ },
67
+ ping() {
68
+ socket.ping();
69
+ },
70
+ send(data) {
71
+ socket.send(data.toString());
72
+ },
73
+ terminate() {
74
+ socket.terminate();
75
+ },
76
+ };
53
77
  }
54
78
 
55
79
  class FakeClusterBus implements WebSocketClusterBus {
@@ -665,8 +689,8 @@ describe("WebSocketRuntime", () => {
665
689
  namespace: "chat",
666
690
  });
667
691
 
668
- let unhandled: unknown = null;
669
- const handleUnhandledRejection = (reason: unknown) => {
692
+ let unhandled: Error | null = null;
693
+ const handleUnhandledRejection = (reason: Error) => {
670
694
  unhandled = reason;
671
695
  };
672
696
  process.once("unhandledRejection", handleUnhandledRejection);