sonamu 0.10.11 → 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 (519) 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 +133 -29
  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 +13 -7
  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 +61 -36
  142. package/dist/migration/migrator.d.ts.map +1 -1
  143. package/dist/migration/migrator.js +276 -167
  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/migration/types.d.ts +54 -0
  149. package/dist/migration/types.d.ts.map +1 -1
  150. package/dist/naite/naite-reporter.js +2 -2
  151. package/dist/naite/naite.d.ts +74 -15
  152. package/dist/naite/naite.d.ts.map +1 -1
  153. package/dist/naite/naite.js +5 -19
  154. package/dist/runtime-type.d.ts +6 -0
  155. package/dist/runtime-type.d.ts.map +1 -0
  156. package/dist/runtime-type.js +26 -0
  157. package/dist/ssr/hmr-opt-out.d.ts +26 -0
  158. package/dist/ssr/hmr-opt-out.d.ts.map +1 -0
  159. package/dist/ssr/hmr-opt-out.js +59 -0
  160. package/dist/ssr/renderer.d.ts.map +1 -1
  161. package/dist/ssr/renderer.js +4 -1
  162. package/dist/storage/base-file.js +14 -14
  163. package/dist/storage/buffered-file.d.ts +2 -2
  164. package/dist/storage/buffered-file.d.ts.map +1 -1
  165. package/dist/storage/buffered-file.js +12 -12
  166. package/dist/storage/s3-driver.d.ts.map +1 -1
  167. package/dist/storage/s3-driver.js +1 -1
  168. package/dist/storage/uploaded-file.d.ts +2 -2
  169. package/dist/storage/uploaded-file.d.ts.map +1 -1
  170. package/dist/storage/uploaded-file.js +8 -8
  171. package/dist/stream/sse.js +11 -11
  172. package/dist/stream/ws-core.d.ts +1 -1
  173. package/dist/stream/ws-core.d.ts.map +1 -1
  174. package/dist/stream/ws-delivery.d.ts +1 -1
  175. package/dist/stream/ws-delivery.d.ts.map +1 -1
  176. package/dist/stream/ws-delivery.js +6 -4
  177. package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
  178. package/dist/stream/ws-local-connection-store.js +4 -2
  179. package/dist/stream/ws-presence-store.js +1 -1
  180. package/dist/stream/ws-registry.d.ts +4 -4
  181. package/dist/stream/ws-registry.d.ts.map +1 -1
  182. package/dist/stream/ws-registry.js +4 -2
  183. package/dist/stream/ws-telemetry.d.ts +16 -12
  184. package/dist/stream/ws-telemetry.d.ts.map +1 -1
  185. package/dist/stream/ws-telemetry.js +22 -18
  186. package/dist/stream/ws.d.ts +18 -12
  187. package/dist/stream/ws.d.ts.map +1 -1
  188. package/dist/stream/ws.js +26 -22
  189. package/dist/syncer/api-parser.js +1 -1
  190. package/dist/syncer/checksum.d.ts.map +1 -1
  191. package/dist/syncer/checksum.js +7 -8
  192. package/dist/syncer/code-generator.d.ts.map +1 -1
  193. package/dist/syncer/code-generator.js +13 -14
  194. package/dist/syncer/entity-operations.d.ts.map +1 -1
  195. package/dist/syncer/entity-operations.js +5 -6
  196. package/dist/syncer/file-copy.d.ts +5 -0
  197. package/dist/syncer/file-copy.d.ts.map +1 -0
  198. package/dist/syncer/file-copy.js +36 -0
  199. package/dist/syncer/file-patterns.d.ts +1 -0
  200. package/dist/syncer/file-patterns.d.ts.map +1 -1
  201. package/dist/syncer/file-patterns.js +5 -2
  202. package/dist/syncer/file-tracking.d.ts.map +1 -1
  203. package/dist/syncer/file-tracking.js +5 -4
  204. package/dist/syncer/filesystem-dependencies.d.ts +15 -0
  205. package/dist/syncer/filesystem-dependencies.d.ts.map +1 -0
  206. package/dist/syncer/filesystem-dependencies.js +53 -0
  207. package/dist/syncer/module-loader.d.ts +1 -1
  208. package/dist/syncer/module-loader.d.ts.map +1 -1
  209. package/dist/syncer/module-loader.js +6 -4
  210. package/dist/syncer/syncer-actions.d.ts +4 -0
  211. package/dist/syncer/syncer-actions.d.ts.map +1 -1
  212. package/dist/syncer/syncer-actions.js +34 -17
  213. package/dist/syncer/syncer.d.ts +17 -6
  214. package/dist/syncer/syncer.d.ts.map +1 -1
  215. package/dist/syncer/syncer.js +71 -29
  216. package/dist/syncer/watcher.d.ts.map +1 -1
  217. package/dist/syncer/watcher.js +3 -3
  218. package/dist/tasks/decorator.d.ts +6 -6
  219. package/dist/tasks/decorator.d.ts.map +1 -1
  220. package/dist/tasks/decorator.js +4 -4
  221. package/dist/tasks/step-wrapper.d.ts +6 -4
  222. package/dist/tasks/step-wrapper.d.ts.map +1 -1
  223. package/dist/tasks/step-wrapper.js +5 -5
  224. package/dist/tasks/workflow-manager.d.ts.map +1 -1
  225. package/dist/tasks/workflow-manager.js +13 -7
  226. package/dist/template/entity-converter.d.ts +1 -1
  227. package/dist/template/entity-converter.d.ts.map +1 -1
  228. package/dist/template/entity-converter.js +2 -2
  229. package/dist/template/helpers.d.ts +8 -6
  230. package/dist/template/helpers.d.ts.map +1 -1
  231. package/dist/template/helpers.js +1 -1
  232. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  233. package/dist/template/implementations/generated.template.js +4 -4
  234. package/dist/template/implementations/generated_http.template.d.ts +7 -4
  235. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  236. package/dist/template/implementations/generated_http.template.js +21 -21
  237. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  238. package/dist/template/implementations/generated_sso.template.js +6 -3
  239. package/dist/template/implementations/http_validators.template.d.ts +18 -0
  240. package/dist/template/implementations/http_validators.template.d.ts.map +1 -0
  241. package/dist/template/implementations/http_validators.template.js +127 -0
  242. package/dist/template/implementations/model.template.d.ts.map +1 -1
  243. package/dist/template/implementations/model.template.js +1 -1
  244. package/dist/template/implementations/queries.template.js +1 -1
  245. package/dist/template/implementations/sd.template.d.ts.map +1 -1
  246. package/dist/template/implementations/sd.template.js +79 -39
  247. package/dist/template/implementations/services.template.d.ts.map +1 -1
  248. package/dist/template/implementations/services.template.js +6 -4
  249. package/dist/template/implementations/view_form.template.d.ts +6 -1
  250. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  251. package/dist/template/implementations/view_form.template.js +23 -15
  252. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  253. package/dist/template/implementations/view_list.template.js +11 -6
  254. package/dist/template/template-manager.d.ts.map +1 -1
  255. package/dist/template/template-manager.js +9 -7
  256. package/dist/template/template-types.d.ts +12 -5
  257. package/dist/template/template-types.d.ts.map +1 -1
  258. package/dist/template/template-types.js +1 -1
  259. package/dist/template/template.d.ts +2 -2
  260. package/dist/template/template.d.ts.map +1 -1
  261. package/dist/template/template.js +6 -4
  262. package/dist/template/zod-converter.d.ts +0 -19
  263. package/dist/template/zod-converter.d.ts.map +1 -1
  264. package/dist/template/zod-converter.js +100 -84
  265. package/dist/testing/_relation-graph.d.ts.map +1 -1
  266. package/dist/testing/_relation-graph.js +2 -1
  267. package/dist/testing/bootstrap.d.ts.map +1 -1
  268. package/dist/testing/bootstrap.js +9 -6
  269. package/dist/testing/data-explorer.d.ts +32 -7
  270. package/dist/testing/data-explorer.d.ts.map +1 -1
  271. package/dist/testing/data-explorer.js +77 -31
  272. package/dist/testing/dev-test-routes.d.ts +8 -1
  273. package/dist/testing/dev-test-routes.d.ts.map +1 -1
  274. package/dist/testing/dev-test-routes.js +125 -108
  275. package/dist/testing/dev-vitest-manager.d.ts +54 -8
  276. package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
  277. package/dist/testing/dev-vitest-manager.js +24 -9
  278. package/dist/testing/faker-mappings.d.ts +412 -1
  279. package/dist/testing/faker-mappings.d.ts.map +1 -1
  280. package/dist/testing/faker-mappings.js +1 -1
  281. package/dist/testing/filesystem.d.ts +2 -0
  282. package/dist/testing/filesystem.d.ts.map +1 -0
  283. package/dist/testing/filesystem.js +7 -0
  284. package/dist/testing/fixture-generator.d.ts +25 -8
  285. package/dist/testing/fixture-generator.d.ts.map +1 -1
  286. package/dist/testing/fixture-generator.js +132 -73
  287. package/dist/testing/fixture-loader.d.ts +3 -1
  288. package/dist/testing/fixture-loader.d.ts.map +1 -1
  289. package/dist/testing/fixture-loader.js +1 -20
  290. package/dist/testing/fixture-manager.d.ts +8 -7
  291. package/dist/testing/fixture-manager.d.ts.map +1 -1
  292. package/dist/testing/fixture-manager.js +91 -59
  293. package/dist/testing/global-setup.d.ts.map +1 -1
  294. package/dist/testing/global-setup.js +5 -2
  295. package/dist/testing/index.d.ts +2 -0
  296. package/dist/testing/index.d.ts.map +1 -1
  297. package/dist/testing/index.js +6 -3
  298. package/dist/types/types.d.ts +101 -99
  299. package/dist/types/types.d.ts.map +1 -1
  300. package/dist/types/types.js +234 -225
  301. package/dist/ui/ai-api.d.ts.map +1 -1
  302. package/dist/ui/ai-api.js +1 -1
  303. package/dist/ui/ai-client.d.ts.map +1 -1
  304. package/dist/ui/ai-client.js +28 -18
  305. package/dist/ui/api.d.ts.map +1 -1
  306. package/dist/ui/api.js +146 -210
  307. package/dist/ui/async-route.d.ts +3 -0
  308. package/dist/ui/async-route.d.ts.map +1 -0
  309. package/dist/ui/async-route.js +12 -0
  310. package/dist/ui/cdd-service.d.ts +9 -7
  311. package/dist/ui/cdd-service.d.ts.map +1 -1
  312. package/dist/ui/cdd-service.js +7 -5
  313. package/dist/ui/migrations-api.d.ts +3 -0
  314. package/dist/ui/migrations-api.d.ts.map +1 -0
  315. package/dist/ui/migrations-api.js +215 -0
  316. package/dist/ui-web/assets/index-D3QNH-Dv.css +1 -0
  317. package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
  318. package/dist/ui-web/index.html +2 -2
  319. package/dist/utils/formatter.d.ts.map +1 -1
  320. package/dist/utils/formatter.js +7 -5
  321. package/dist/utils/fs-utils.d.ts +3 -3
  322. package/dist/utils/fs-utils.d.ts.map +1 -1
  323. package/dist/utils/fs-utils.js +6 -6
  324. package/dist/utils/model.d.ts +3 -5
  325. package/dist/utils/model.d.ts.map +1 -1
  326. package/dist/utils/model.js +1 -1
  327. package/dist/utils/object-utils.d.ts +1 -1
  328. package/dist/utils/object-utils.d.ts.map +1 -1
  329. package/dist/utils/object-utils.js +17 -16
  330. package/dist/utils/process-utils.d.ts.map +1 -1
  331. package/dist/utils/process-utils.js +4 -2
  332. package/dist/utils/runtime-value.d.ts +13 -0
  333. package/dist/utils/runtime-value.d.ts.map +1 -0
  334. package/dist/utils/runtime-value.js +40 -0
  335. package/dist/utils/sql-parser.d.ts +8 -1
  336. package/dist/utils/sql-parser.d.ts.map +1 -1
  337. package/dist/utils/sql-parser.js +6 -3
  338. package/dist/utils/type-utils.d.ts.map +1 -1
  339. package/dist/utils/type-utils.js +10 -8
  340. package/dist/utils/utils.d.ts +2 -2
  341. package/dist/utils/utils.d.ts.map +1 -1
  342. package/dist/utils/utils.js +11 -8
  343. package/dist/utils/zod-error.d.ts.map +1 -1
  344. package/dist/utils/zod-error.js +7 -4
  345. package/dist/vector/chunking.d.ts.map +1 -1
  346. package/dist/vector/chunking.js +1 -1
  347. package/dist/vector/embedding.d.ts.map +1 -1
  348. package/dist/vector/embedding.js +1 -1
  349. package/dist/vector/types.d.ts +3 -2
  350. package/dist/vector/types.d.ts.map +1 -1
  351. package/package.json +11 -7
  352. package/src/ai/agents/agent.ts +5 -5
  353. package/src/ai/agents/types.ts +1 -1
  354. package/src/ai/providers/rtzr/__tests__/model.test.ts +2 -2
  355. package/src/ai/providers/rtzr/error.ts +5 -3
  356. package/src/ai/providers/rtzr/model.ts +3 -2
  357. package/src/ai/providers/rtzr/options.ts +10 -5
  358. package/src/ai/providers/rtzr/provider.ts +10 -10
  359. package/src/ai/providers/rtzr/utils.ts +3 -1
  360. package/src/api/__tests__/config.test.ts +11 -21
  361. package/src/api/__tests__/sonamu.http-validator.test.ts +512 -0
  362. package/src/api/__tests__/sonamu.websocket.test.ts +51 -41
  363. package/src/api/__tests__/zod-compiler-policy.test.ts +95 -0
  364. package/src/api/caster.ts +6 -8
  365. package/src/api/code-converters.ts +136 -36
  366. package/src/api/config.ts +62 -4
  367. package/src/api/context.ts +3 -3
  368. package/src/api/decorators.ts +28 -17
  369. package/src/api/http-validator.ts +149 -0
  370. package/src/api/sonamu.ts +459 -152
  371. package/src/api/websocket-helpers.ts +24 -17
  372. package/src/auth/audit-log/builders.ts +3 -2
  373. package/src/auth/audit-log/client-ip.ts +4 -2
  374. package/src/auth/audit-log/events.ts +15 -1
  375. package/src/auth/audit-log/plugin.ts +129 -200
  376. package/src/auth/audit-log-ingestor.ts +19 -15
  377. package/src/auth/auth-generator.ts +10 -5
  378. package/src/auth/better-auth-request.ts +4 -3
  379. package/src/auth/knex-adapter.ts +8 -2
  380. package/src/auth/plugins/entity-definitions/index.ts +6 -5
  381. package/src/bin/__tests__/http-validator-benchmark.test.ts +94 -0
  382. package/src/bin/__tests__/test-command.test.ts +9 -15
  383. package/src/bin/__tests__/ts-loader-register.test.ts +15 -17
  384. package/src/bin/__tests__/zod-compiler-build.test.ts +307 -0
  385. package/src/bin/build-config.ts +167 -0
  386. package/src/bin/cli.ts +155 -38
  387. package/src/bin/compiler-policy.ts +35 -0
  388. package/src/bin/fixture.ts +14 -3
  389. package/src/bin/test-command.ts +74 -29
  390. package/src/bin/ts-loader-registration.ts +22 -4
  391. package/src/cache/decorator.ts +10 -3
  392. package/src/compress/compress.ts +17 -4
  393. package/src/cone/cone-generator.ts +34 -6
  394. package/src/database/__tests__/db.test.ts +1 -0
  395. package/src/database/__tests__/puri.test.ts +16 -15
  396. package/src/database/__tests__/transaction-scope.test.ts +5 -0
  397. package/src/database/_batch_update.ts +1 -0
  398. package/src/database/base-model.ts +81 -50
  399. package/src/database/base-model.types.ts +6 -6
  400. package/src/database/db.ts +29 -19
  401. package/src/database/knex.ts +30 -17
  402. package/src/database/puri-subset.test-d.ts +17 -0
  403. package/src/database/puri.ts +181 -143
  404. package/src/database/puri.types.test-d.ts +31 -1
  405. package/src/database/puri.types.ts +23 -21
  406. package/src/database/upsert-builder.ts +75 -53
  407. package/src/dict/sd.ts +15 -5
  408. package/src/dict/sonamu-dictionary.ts +6 -6
  409. package/src/dict/utils.ts +9 -1
  410. package/src/entity/entity-manager.ts +26 -9
  411. package/src/entity/entity-template-cone.ts +5 -10
  412. package/src/entity/entity.ts +50 -34
  413. package/src/env.ts +7 -3
  414. package/src/exceptions/error-handler.ts +17 -2
  415. package/src/exceptions/so-exceptions.ts +26 -20
  416. package/src/filter/utils.ts +21 -11
  417. package/src/index.ts +3 -0
  418. package/src/logger/configure.ts +26 -18
  419. package/src/migration/__tests__/migrator.test.ts +50 -57
  420. package/src/migration/code-generation.ts +132 -104
  421. package/src/migration/index-where-predicate.ts +51 -24
  422. package/src/migration/migration-set.ts +11 -5
  423. package/src/migration/migrator.ts +392 -244
  424. package/src/migration/postgresql-schema-reader.ts +52 -47
  425. package/src/migration/slack-confirm.ts +17 -15
  426. package/src/migration/types.ts +57 -0
  427. package/src/naite/naite-reporter.ts +1 -1
  428. package/src/naite/naite.ts +97 -24
  429. package/src/runtime-type.ts +34 -0
  430. package/src/ssr/hmr-opt-out.ts +78 -0
  431. package/src/ssr/renderer.ts +6 -0
  432. package/src/storage/base-file.ts +13 -13
  433. package/src/storage/buffered-file.ts +11 -11
  434. package/src/storage/s3-driver.ts +4 -1
  435. package/src/storage/uploaded-file.ts +8 -8
  436. package/src/stream/__tests__/ws-contracts.test.ts +4 -2
  437. package/src/stream/__tests__/ws-telemetry.test.ts +1 -1
  438. package/src/stream/__tests__/ws.test.ts +30 -6
  439. package/src/stream/sse.ts +12 -11
  440. package/src/stream/ws-core.ts +1 -1
  441. package/src/stream/ws-delivery.ts +16 -7
  442. package/src/stream/ws-local-connection-store.ts +2 -3
  443. package/src/stream/ws-presence-store.ts +6 -1
  444. package/src/stream/ws-registry.ts +16 -7
  445. package/src/stream/ws-telemetry.ts +66 -43
  446. package/src/stream/ws.ts +73 -39
  447. package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +3 -2
  448. package/src/syncer/__tests__/http-validator-registry.test.ts +137 -0
  449. package/src/syncer/api-parser.ts +67 -27
  450. package/src/syncer/checksum.ts +17 -11
  451. package/src/syncer/code-generator.ts +25 -17
  452. package/src/syncer/entity-operations.ts +3 -5
  453. package/src/syncer/file-copy.ts +46 -0
  454. package/src/syncer/file-patterns.ts +11 -8
  455. package/src/syncer/file-tracking.ts +3 -4
  456. package/src/syncer/filesystem-dependencies.ts +73 -0
  457. package/src/syncer/module-loader.ts +8 -4
  458. package/src/syncer/syncer-actions.ts +56 -18
  459. package/src/syncer/syncer.ts +116 -43
  460. package/src/syncer/watcher.ts +8 -4
  461. package/src/tasks/decorator.ts +20 -12
  462. package/src/tasks/step-wrapper.ts +19 -9
  463. package/src/tasks/workflow-manager.ts +15 -9
  464. package/src/template/__tests__/http_validators.template.test.ts +160 -0
  465. package/src/template/__tests__/services.template.mutation.test.ts +24 -23
  466. package/src/template/__tests__/services.template.websocket.test.ts +21 -25
  467. package/src/template/entity-converter.ts +5 -2
  468. package/src/template/helpers.ts +8 -9
  469. package/src/template/implementations/generated.template.ts +5 -4
  470. package/src/template/implementations/generated_http.template.ts +61 -15
  471. package/src/template/implementations/generated_sso.template.ts +15 -4
  472. package/src/template/implementations/http_validators.template.ts +175 -0
  473. package/src/template/implementations/model.template.ts +3 -1
  474. package/src/template/implementations/sd.template.ts +81 -41
  475. package/src/template/implementations/services.template.ts +2 -2
  476. package/src/template/implementations/view_form.template.ts +56 -39
  477. package/src/template/implementations/view_list.template.ts +31 -23
  478. package/src/template/template-manager.ts +15 -13
  479. package/src/template/template-types.ts +13 -5
  480. package/src/template/template.ts +4 -3
  481. package/src/template/zod-converter.ts +206 -91
  482. package/src/testing/__tests__/dev-test-routes.test.ts +85 -25
  483. package/src/testing/__tests__/dev-vitest-manager.test.ts +15 -15
  484. package/src/testing/_relation-graph.ts +4 -1
  485. package/src/testing/bootstrap.ts +12 -5
  486. package/src/testing/data-explorer.ts +102 -53
  487. package/src/testing/dev-test-routes.ts +87 -50
  488. package/src/testing/dev-vitest-manager.ts +88 -32
  489. package/src/testing/faker-mappings.ts +2 -2
  490. package/src/testing/filesystem.ts +1 -0
  491. package/src/testing/fixture-generator.ts +191 -131
  492. package/src/testing/fixture-loader.ts +5 -1
  493. package/src/testing/fixture-manager.ts +129 -90
  494. package/src/testing/global-setup.ts +7 -3
  495. package/src/testing/index.ts +5 -0
  496. package/src/types/__tests__/entity-json-schema-search-text.test.ts +9 -3
  497. package/src/types/types.ts +184 -158
  498. package/src/ui/ai-api.ts +9 -7
  499. package/src/ui/ai-client.ts +61 -56
  500. package/src/ui/api.ts +726 -770
  501. package/src/ui/async-route.ts +4 -0
  502. package/src/ui/cdd-service.ts +35 -12
  503. package/src/ui/migrations-api.ts +381 -0
  504. package/src/utils/formatter.ts +7 -3
  505. package/src/utils/fs-utils.ts +5 -5
  506. package/src/utils/model.ts +4 -5
  507. package/src/utils/object-utils.ts +32 -22
  508. package/src/utils/process-utils.ts +4 -1
  509. package/src/utils/runtime-value.ts +43 -0
  510. package/src/utils/sql-parser.ts +13 -6
  511. package/src/utils/type-utils.ts +9 -7
  512. package/src/utils/utils.ts +19 -21
  513. package/src/utils/zod-error.ts +4 -2
  514. package/src/vector/chunking.ts +6 -1
  515. package/src/vector/embedding.ts +2 -1
  516. package/src/vector/types.ts +4 -2
  517. package/tsdown.api.config.ts +5 -2
  518. package/dist/ui-web/assets/index-CJf8uJYf.js +0 -176
  519. package/dist/ui-web/assets/index-GMMIVGja.css +0 -1
@@ -1,6 +1,23 @@
1
+ import { runtimeTypeOf } from "../runtime-type";
2
+ import { isFunctionValue, isObjectValue } from "../utils/runtime-value";
1
3
  import { InMemoryEventStore, InMemoryMetricStore, InMemorySpanStore } from "./ws-telemetry-memory";
2
4
  import { generateSpanId, generateTraceId, parseTraceParent } from "./ws-telemetry-trace";
3
5
 
6
+ export type WebSocketTelemetryValue =
7
+ | null
8
+ | undefined
9
+ | bigint
10
+ | boolean
11
+ | number
12
+ | string
13
+ | Date
14
+ | WebSocketTelemetryValue[]
15
+ | WebSocketTelemetryAttributes;
16
+
17
+ export interface WebSocketTelemetryAttributes {
18
+ [key: string]: WebSocketTelemetryValue;
19
+ }
20
+
4
21
  // -- Record types (unchanged) --
5
22
 
6
23
  export type WebSocketTelemetryRecordBase = {
@@ -24,7 +41,7 @@ export type WebSocketTelemetryEventRecord = WebSocketTelemetryRecordBase & {
24
41
  name: string;
25
42
  level: "debug" | "info" | "warn" | "error";
26
43
  attributes?: Record<string, string | number | boolean>;
27
- detail?: Record<string, unknown>;
44
+ detail?: WebSocketTelemetryAttributes;
28
45
  payloadPreview?: string;
29
46
  };
30
47
 
@@ -49,12 +66,12 @@ export type WebSocketTelemetrySpanRecord = WebSocketTelemetryRecordBase & {
49
66
  events?: Array<{
50
67
  name: string;
51
68
  timestamp: number;
52
- attributes?: Record<string, unknown>;
69
+ attributes?: WebSocketTelemetryAttributes;
53
70
  }>;
54
71
  links?: Array<{
55
72
  traceId: string;
56
73
  spanId: string;
57
- attributes?: Record<string, unknown>;
74
+ attributes?: WebSocketTelemetryAttributes;
58
75
  }>;
59
76
  };
60
77
 
@@ -72,8 +89,8 @@ export type WebSocketTelemetryEventInput = {
72
89
  connectionId?: string;
73
90
  userId?: string;
74
91
  attributes?: Record<string, string | number | boolean>;
75
- detail?: Record<string, unknown>;
76
- payload?: unknown;
92
+ detail?: WebSocketTelemetryAttributes;
93
+ payload?: WebSocketTelemetryValue;
77
94
  traceId?: string;
78
95
  spanId?: string;
79
96
  parentSpanId?: string;
@@ -113,12 +130,12 @@ export type WebSocketSpanInput = {
113
130
  events?: Array<{
114
131
  name: string;
115
132
  timestamp: number;
116
- attributes?: Record<string, unknown>;
133
+ attributes?: WebSocketTelemetryAttributes;
117
134
  }>;
118
135
  links?: Array<{
119
136
  traceId: string;
120
137
  spanId: string;
121
- attributes?: Record<string, unknown>;
138
+ attributes?: WebSocketTelemetryAttributes;
122
139
  }>;
123
140
  };
124
141
 
@@ -434,7 +451,7 @@ function isSensitiveKey(key: string): boolean {
434
451
  return SENSITIVE_KEY_PATTERNS.some((pattern) => normalized.includes(pattern));
435
452
  }
436
453
 
437
- function redactValue(value: unknown, key?: string): unknown {
454
+ function redactValue(value: WebSocketTelemetryValue, key?: string): WebSocketTelemetryValue {
438
455
  if (key !== undefined && isSensitiveKey(key)) {
439
456
  return REDACTED_VALUE;
440
457
  }
@@ -447,8 +464,8 @@ function redactValue(value: unknown, key?: string): unknown {
447
464
  return value;
448
465
  }
449
466
 
450
- if (value && typeof value === "object") {
451
- const redacted: Record<string, unknown> = {};
467
+ if (value && isObjectValue(value)) {
468
+ const redacted: WebSocketTelemetryAttributes = {};
452
469
  for (const [childKey, childValue] of Object.entries(value)) {
453
470
  redacted[childKey] = redactValue(childValue, childKey);
454
471
  }
@@ -464,6 +481,7 @@ function redactValue(value: unknown, key?: string): unknown {
464
481
  */
465
482
  function defaultSensitiveKeyRedact(record: WebSocketTelemetryRecord): WebSocketTelemetryRecord {
466
483
  if (record.type === "event") {
484
+ // SAFETY: redactor는 이벤트 레코드의 키 구조를 유지하고 값만 마스킹한다.
467
485
  return {
468
486
  ...record,
469
487
  attributes: record.attributes
@@ -477,6 +495,7 @@ function defaultSensitiveKeyRedact(record: WebSocketTelemetryRecord): WebSocketT
477
495
  }
478
496
 
479
497
  if (record.type === "metric") {
498
+ // SAFETY: redactor는 메트릭 레코드의 키 구조를 유지하고 값만 마스킹한다.
480
499
  return {
481
500
  ...record,
482
501
  tags: record.tags
@@ -486,6 +505,7 @@ function defaultSensitiveKeyRedact(record: WebSocketTelemetryRecord): WebSocketT
486
505
  };
487
506
  }
488
507
 
508
+ // SAFETY: redactor는 span과 하위 이벤트·링크의 키 구조를 유지하고 값만 마스킹한다.
489
509
  return {
490
510
  ...record,
491
511
  attributes: record.attributes
@@ -494,19 +514,19 @@ function defaultSensitiveKeyRedact(record: WebSocketTelemetryRecord): WebSocketT
494
514
  events: record.events?.map((event) => ({
495
515
  ...event,
496
516
  attributes: event.attributes
497
- ? (redactValue(event.attributes) as Record<string, unknown>)
517
+ ? (redactValue(event.attributes) as WebSocketTelemetryAttributes)
498
518
  : undefined,
499
519
  })),
500
520
  links: record.links?.map((link) => ({
501
521
  ...link,
502
522
  attributes: link.attributes
503
- ? (redactValue(link.attributes) as Record<string, unknown>)
523
+ ? (redactValue(link.attributes) as WebSocketTelemetryAttributes)
504
524
  : undefined,
505
525
  })),
506
526
  };
507
527
  }
508
528
 
509
- function truncatePayloadPreview(payload: unknown, maxBytes: number): string {
529
+ function truncatePayloadPreview(payload: WebSocketTelemetryValue, maxBytes: number): string {
510
530
  try {
511
531
  const serialized = JSON.stringify(redactValue(payload));
512
532
  if (Buffer.byteLength(serialized, "utf-8") <= maxBytes) {
@@ -536,8 +556,8 @@ function truncateUtf8String(value: string, maxBytes: number): string {
536
556
  return result + suffix;
537
557
  }
538
558
 
539
- export function isPromiseLike(value: unknown): value is Promise<void> {
540
- return typeof value === "object" && value !== null && "then" in value && "catch" in value;
559
+ export function isPromiseLike<Value>(value: Value): value is Value & Promise<void> {
560
+ return isObjectValue(value) && value !== null && "then" in value && "catch" in value;
541
561
  }
542
562
 
543
563
  // -- TokenBucket (unchanged) --
@@ -679,7 +699,7 @@ type ResolvedSpanPipelineOptions = {
679
699
  type InternalEventReporter = (
680
700
  name: string,
681
701
  level: WebSocketTelemetryEventRecord["level"],
682
- detail?: Record<string, unknown>,
702
+ detail?: WebSocketTelemetryAttributes,
683
703
  ) => void;
684
704
 
685
705
  // -- TelemetryPipeline (abstract) --
@@ -695,7 +715,7 @@ abstract class TelemetryPipeline<
695
715
  > {
696
716
  abstract readonly signal: "event" | "metric" | "span";
697
717
  protected readonly sinks: TSink[];
698
- protected readonly _store: TStore;
718
+ protected readonly telemetryStore: TStore;
699
719
  protected readonly tokenBucket: TokenBucket;
700
720
  protected readonly maxInFlightEmits: number;
701
721
  protected readonly runtimeMetadata: RuntimeMetadata;
@@ -717,7 +737,7 @@ abstract class TelemetryPipeline<
717
737
  runtimeMetadata: RuntimeMetadata,
718
738
  ) {
719
739
  this.sinks = sinks;
720
- this._store = store;
740
+ this.telemetryStore = store;
721
741
  this.tokenBucket = new TokenBucket(maxRecordsPerSecond, maxRecordsPerSecond);
722
742
  this.maxInFlightEmits = maxInFlightEmits;
723
743
  this.sharedRedactor = sharedRedactor;
@@ -726,7 +746,7 @@ abstract class TelemetryPipeline<
726
746
  }
727
747
 
728
748
  get store(): TStore {
729
- return this._store;
749
+ return this.telemetryStore;
730
750
  }
731
751
 
732
752
  setInternalEventReporter(reporter: InternalEventReporter): void {
@@ -772,7 +792,8 @@ abstract class TelemetryPipeline<
772
792
  this.droppedCount += 1;
773
793
  return;
774
794
  }
775
- prepared = afterDefault as TRecord;
795
+ prepared =
796
+ /* SAFETY: 등록된 WebSocket 이벤트 스키마가 이 값의 타입을 보장한다. */ afterDefault as TRecord;
776
797
  } catch {
777
798
  this.droppedCount += 1;
778
799
  return;
@@ -860,7 +881,7 @@ abstract class TelemetryPipeline<
860
881
  }
861
882
 
862
883
  // result.type === record.type === TRecord["type"]이므로 narrowed TRecord로 안전하게 좁힐 수 있다.
863
- return result as TRecord;
884
+ return /* SAFETY: 등록된 WebSocket 이벤트 스키마가 이 값의 타입을 보장한다. */ result as TRecord;
864
885
  }
865
886
 
866
887
  protected dispatchToSinks(record: TRecord, selfObserveFailures = true): void {
@@ -885,9 +906,9 @@ abstract class TelemetryPipeline<
885
906
  () => {
886
907
  this.decrementInFlightEmit(sink);
887
908
  },
888
- (error: unknown) => {
909
+ (cause: unknown) => {
889
910
  this.decrementInFlightEmit(sink);
890
- this.observeSinkFailure("emit", error, selfObserveFailures);
911
+ this.observeSinkFailure("emit", cause, selfObserveFailures);
891
912
  },
892
913
  );
893
914
  }
@@ -906,9 +927,9 @@ abstract class TelemetryPipeline<
906
927
  this.inFlightEmits.set(sink, current - 1);
907
928
  }
908
929
 
909
- private observeSinkFailure(
930
+ private observeSinkFailure<Value>(
910
931
  phase: "emit" | "shutdown",
911
- error: unknown,
932
+ error: Value,
912
933
  selfObserveFailure: boolean,
913
934
  ): void {
914
935
  this.sinkFailureCount += 1;
@@ -916,14 +937,14 @@ abstract class TelemetryPipeline<
916
937
  this.dispatchInternalEvent("ws.telemetry.sink.failed", "warn", {
917
938
  phase,
918
939
  signal: this.signal,
919
- errorType: error instanceof Error ? error.name : typeof error,
940
+ errorType: error instanceof Error ? error.name : runtimeTypeOf(error),
920
941
  });
921
942
  }
922
943
 
923
944
  protected dispatchInternalEvent(
924
945
  name: string,
925
946
  level: WebSocketTelemetryEventRecord["level"],
926
- detail?: Record<string, unknown>,
947
+ detail?: WebSocketTelemetryAttributes,
927
948
  ): void {
928
949
  if (this.internalEventReporter === undefined) return;
929
950
  try {
@@ -953,8 +974,8 @@ abstract class TelemetryPipeline<
953
974
  let timeout: ReturnType<typeof setTimeout> | null = null;
954
975
  const shutdownPromise = result.then(
955
976
  () => "completed" as const,
956
- (error: unknown) => {
957
- throw error;
977
+ (cause: unknown) => {
978
+ throw cause;
958
979
  },
959
980
  );
960
981
  const timeoutPromise = new Promise<"timeout">((resolve) => {
@@ -1056,7 +1077,7 @@ class EventPipeline extends TelemetryPipeline<
1056
1077
  dispatchInternalDiagnosticEvent(
1057
1078
  name: string,
1058
1079
  level: WebSocketTelemetryEventRecord["level"],
1059
- detail?: Record<string, unknown>,
1080
+ detail?: WebSocketTelemetryAttributes,
1060
1081
  ): void {
1061
1082
  const record: WebSocketTelemetryEventRecord = {
1062
1083
  type: "event",
@@ -1172,7 +1193,7 @@ class MetricPipeline extends TelemetryPipeline<
1172
1193
 
1173
1194
  if (
1174
1195
  this.collectionInterval &&
1175
- typeof this.collectionInterval === "object" &&
1196
+ isObjectValue(this.collectionInterval) &&
1176
1197
  "unref" in this.collectionInterval
1177
1198
  ) {
1178
1199
  this.collectionInterval.unref();
@@ -1595,28 +1616,30 @@ function buildController(
1595
1616
  // 신호별 redactor / beforeRecord 해석.
1596
1617
  // null이면 sharedRedactor를 undefined로 덮어써 step 2 자체를 skip한다.
1597
1618
  const eventsSharedRedactor = eventsOpt.redactor === null ? undefined : defaults.redactor;
1598
- const eventsSignalRedactor =
1599
- typeof eventsOpt.redactor === "function" ? eventsOpt.redactor : undefined;
1619
+ const eventsSignalRedactor = isFunctionValue(eventsOpt.redactor) ? eventsOpt.redactor : undefined;
1600
1620
  const eventsSharedBeforeRecord =
1601
1621
  eventsOpt.beforeRecord === null ? undefined : defaults.beforeRecord;
1602
- const eventsSignalBeforeRecord =
1603
- typeof eventsOpt.beforeRecord === "function" ? eventsOpt.beforeRecord : undefined;
1622
+ const eventsSignalBeforeRecord = isFunctionValue(eventsOpt.beforeRecord)
1623
+ ? eventsOpt.beforeRecord
1624
+ : undefined;
1604
1625
 
1605
1626
  const metricsSharedRedactor = metricsOpt.redactor === null ? undefined : defaults.redactor;
1606
- const metricsSignalRedactor =
1607
- typeof metricsOpt.redactor === "function" ? metricsOpt.redactor : undefined;
1627
+ const metricsSignalRedactor = isFunctionValue(metricsOpt.redactor)
1628
+ ? metricsOpt.redactor
1629
+ : undefined;
1608
1630
  const metricsSharedBeforeRecord =
1609
1631
  metricsOpt.beforeRecord === null ? undefined : defaults.beforeRecord;
1610
- const metricsSignalBeforeRecord =
1611
- typeof metricsOpt.beforeRecord === "function" ? metricsOpt.beforeRecord : undefined;
1632
+ const metricsSignalBeforeRecord = isFunctionValue(metricsOpt.beforeRecord)
1633
+ ? metricsOpt.beforeRecord
1634
+ : undefined;
1612
1635
 
1613
1636
  const spansSharedRedactor = spansOpt.redactor === null ? undefined : defaults.redactor;
1614
- const spansSignalRedactor =
1615
- typeof spansOpt.redactor === "function" ? spansOpt.redactor : undefined;
1637
+ const spansSignalRedactor = isFunctionValue(spansOpt.redactor) ? spansOpt.redactor : undefined;
1616
1638
  const spansSharedBeforeRecord =
1617
1639
  spansOpt.beforeRecord === null ? undefined : defaults.beforeRecord;
1618
- const spansSignalBeforeRecord =
1619
- typeof spansOpt.beforeRecord === "function" ? spansOpt.beforeRecord : undefined;
1640
+ const spansSignalBeforeRecord = isFunctionValue(spansOpt.beforeRecord)
1641
+ ? spansOpt.beforeRecord
1642
+ : undefined;
1620
1643
 
1621
1644
  // events
1622
1645
  const eventSinks: WebSocketTelemetryEventSink[] = eventsOpt.sinks ? [...eventsOpt.sinks] : [];
package/src/stream/ws.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import { type EventEmitter } from "node:events";
2
3
  import { hostname } from "node:os";
3
4
 
4
- import { type WebSocket } from "ws";
5
+ import { type RawData, type WebSocket } from "ws";
5
6
  import { z } from "zod";
6
7
 
8
+ import { runtimeTypeOf } from "../runtime-type";
9
+ import { isStringValue } from "../utils/runtime-value";
7
10
  import { type WebSocketAudience } from "./ws-audience";
8
11
  import { type WebSocketClusterBus } from "./ws-cluster-bus";
9
12
  import { type WebSocketPresenceStore } from "./ws-presence-store";
@@ -46,7 +49,7 @@ const OUTBOUND_RETRY_DELAY_MS = 5;
46
49
  // meta는 optional이므로 기존 `{event, data}` 메시지도 그대로 파싱됨 (backward-compatible)
47
50
  const WebSocketEnvelopeSchema = z.object({
48
51
  event: z.string(),
49
- data: z.unknown(),
52
+ data: z.json(),
50
53
  meta: z
51
54
  .object({
52
55
  traceparent: z.string().optional(),
@@ -61,17 +64,25 @@ type MessageHandler<T> = (
61
64
  ) => void | Promise<void>;
62
65
  type CloseHandler = () => void | Promise<void>;
63
66
 
64
- export type WebSocketEventMap = Record<string, unknown>;
67
+ export type WebSocketEventMap<EventPayload = never> = Record<string, EventPayload>;
68
+ export type WebSocketTransport = Pick<
69
+ WebSocket,
70
+ "bufferedAmount" | "close" | "ping" | "readyState" | "send" | "terminate"
71
+ > & {
72
+ off: (...args: Parameters<EventEmitter["off"]>) => void;
73
+ on: (...args: Parameters<EventEmitter["on"]>) => void;
74
+ };
65
75
 
66
- type InferWebSocketEventMap<TSchema extends z.ZodRawShape> = z.infer<z.ZodObject<TSchema>>;
76
+ type WebSocketEventFields = Record<string, z.ZodType>;
77
+ type InferWebSocketEventMap<TSchema extends WebSocketEventFields> = z.infer<z.ZodObject<TSchema>>;
67
78
 
68
- export type WebSocketOutEvents<TOut extends WebSocketEventMap = WebSocketEventMap> = TOut;
79
+ export type WebSocketOutEvents<TOut extends object = WebSocketEventMap> = TOut;
69
80
 
70
- export type WebSocketInEvents<TIn extends WebSocketEventMap = WebSocketEventMap> = TIn;
81
+ export type WebSocketInEvents<TIn extends object = WebSocketEventMap> = TIn;
71
82
 
72
83
  export interface WebSocketConnection<
73
- TOut extends WebSocketEventMap = WebSocketEventMap,
74
- TIn extends WebSocketEventMap = WebSocketEventMap,
84
+ TOut extends object = WebSocketEventMap,
85
+ TIn extends object = WebSocketEventMap,
75
86
  > extends ManagedWebSocketConnection {
76
87
  transport: "ws";
77
88
  onClose(callback: CloseHandler): void;
@@ -90,11 +101,14 @@ export interface WebSocketConnection<
90
101
  clearUserId(): void;
91
102
  }
92
103
 
93
- export type AnyWebSocketConnection = WebSocketConnection<WebSocketEventMap, WebSocketEventMap>;
104
+ export type AnyWebSocketConnection = WebSocketConnection<object, object>;
94
105
 
95
106
  type ParsedEnvelope = z.infer<typeof WebSocketEnvelopeSchema>;
96
107
 
97
- type WebSocketConnectionOptions<TOut extends z.ZodRawShape, TIn extends z.ZodRawShape> = {
108
+ type WebSocketConnectionOptions<
109
+ TOut extends WebSocketEventFields,
110
+ TIn extends WebSocketEventFields,
111
+ > = {
98
112
  namespace?: string;
99
113
  heartbeat?: number;
100
114
  active?: boolean;
@@ -137,8 +151,11 @@ export class WebSocketRuntime {
137
151
  this.registry = new WebSocketRegistry(registryOptions);
138
152
  }
139
153
 
140
- registerConnection<TOutSchema extends z.ZodRawShape, TInSchema extends z.ZodRawShape>(
141
- socket: WebSocket,
154
+ registerConnection<
155
+ TOutSchema extends WebSocketEventFields,
156
+ TInSchema extends WebSocketEventFields,
157
+ >(
158
+ socket: WebSocketTransport,
142
159
  options: Omit<
143
160
  WebSocketConnectionOptions<TOutSchema, TInSchema>,
144
161
  "registry" | "telemetryController"
@@ -155,19 +172,29 @@ export class WebSocketRuntime {
155
172
  this.registry.activate(connectionId);
156
173
  }
157
174
 
158
- broadcast(event: string, data: unknown, namespace?: string): void {
175
+ broadcast<Data>(event: string, data: Data, namespace?: string): void {
159
176
  this.registry.broadcast(event, data, namespace);
160
177
  }
161
178
 
162
- publishToRoom(roomId: WebSocketRoomId, event: string, data: unknown, namespace?: string): void {
179
+ publishToRoom<Data>(
180
+ roomId: WebSocketRoomId,
181
+ event: string,
182
+ data: Data,
183
+ namespace?: string,
184
+ ): void {
163
185
  this.registry.publishToRoom(roomId, event, data, namespace);
164
186
  }
165
187
 
166
- publishToUser(userId: WebSocketUserId, event: string, data: unknown, namespace?: string): void {
188
+ publishToUser<Data>(
189
+ userId: WebSocketUserId,
190
+ event: string,
191
+ data: Data,
192
+ namespace?: string,
193
+ ): void {
167
194
  this.registry.publishToUser(userId, event, data, namespace);
168
195
  }
169
196
 
170
- publishToAudience(audience: WebSocketAudience, event: string, data: unknown): void {
197
+ publishToAudience<Data>(audience: WebSocketAudience, event: string, data: Data): void {
171
198
  this.registry.publishToAudience(audience, event, data);
172
199
  }
173
200
 
@@ -185,7 +212,10 @@ export function createWebSocketRuntime(options: WebSocketRuntimeOptions = {}): W
185
212
  return new WebSocketRuntime(options);
186
213
  }
187
214
 
188
- class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extends z.ZodRawShape>
215
+ class WebSocketConnectionImpl<
216
+ TOutSchema extends WebSocketEventFields,
217
+ TInSchema extends WebSocketEventFields,
218
+ >
189
219
  implements
190
220
  WebSocketConnection<InferWebSocketEventMap<TOutSchema>, InferWebSocketEventMap<TInSchema>>,
191
221
  TelemetryInspectableConnection,
@@ -212,10 +242,10 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
212
242
  private readonly connectionStartedAt = performance.now();
213
243
 
214
244
  // connection 수명 동안 유지되는 식별자. setUserId/clearUserId로 업데이트되며 emit hot path에서 매번 registry lookup하지 않도록 캐시함
215
- private _userId?: string;
245
+ private currentUserId?: string;
216
246
 
217
247
  get userId(): string | undefined {
218
- return this._userId;
248
+ return this.currentUserId;
219
249
  }
220
250
 
221
251
  private closedInternal = false;
@@ -226,7 +256,7 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
226
256
  private outboundFlushScheduled = false;
227
257
 
228
258
  constructor(
229
- private readonly socket: WebSocket,
259
+ private readonly socket: WebSocketTransport,
230
260
  private readonly options: WebSocketConnectionOptions<TOutSchema, TInSchema>,
231
261
  ) {
232
262
  this.namespace = options.namespace ?? "default";
@@ -235,8 +265,8 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
235
265
  this.connectionSpanId = options.spanId;
236
266
  this.connectionParentSpanId = options.parentSpanId;
237
267
  this.connectionSampled = options.sampled;
238
- this.eventSchemasIn = options.inEvents.shape as unknown as Record<string, z.ZodTypeAny>;
239
- this.eventSchemasOut = options.outEvents.shape as unknown as Record<string, z.ZodTypeAny>;
268
+ this.eventSchemasIn = options.inEvents["shape"];
269
+ this.eventSchemasOut = options.outEvents["shape"];
240
270
 
241
271
  let resolveClosePromise!: () => void;
242
272
  this.closePromise = new Promise<void>((resolve) => {
@@ -266,7 +296,9 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
266
296
  ): void {
267
297
  const eventKey = String(event);
268
298
  const handlers = this.messageHandlers.get(eventKey) ?? [];
269
- handlers.push(handler as MessageHandler<unknown>);
299
+ handlers.push(
300
+ /* SAFETY: 등록된 WebSocket 이벤트 스키마가 이 값의 타입을 보장한다. */ handler as MessageHandler<unknown>,
301
+ );
270
302
  this.messageHandlers.set(eventKey, handlers);
271
303
  this.flushPendingMessages(eventKey);
272
304
  }
@@ -278,7 +310,7 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
278
310
  this.publishValidated(String(event), data);
279
311
  }
280
312
 
281
- publishUntyped(event: string, data: unknown): void {
313
+ publishUntyped<Data>(event: string, data: Data): void {
282
314
  this.publishValidated(event, data);
283
315
  }
284
316
 
@@ -295,12 +327,12 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
295
327
  }
296
328
 
297
329
  setUserId(userId: WebSocketUserId): void {
298
- this._userId = String(userId);
330
+ this.currentUserId = String(userId);
299
331
  this.options.registry.setUserId(this.id, userId);
300
332
  }
301
333
 
302
334
  clearUserId(): void {
303
- this._userId = undefined;
335
+ this.currentUserId = undefined;
304
336
  this.options.registry.clearUserId(this.id);
305
337
  }
306
338
 
@@ -327,7 +359,7 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
327
359
  return {
328
360
  connectionId: this.id,
329
361
  namespace: this.namespace,
330
- userId: this._userId,
362
+ userId: this.currentUserId,
331
363
  traceId: this.connectionTraceId,
332
364
  spanId: this.connectionSpanId,
333
365
  parentSpanId: this.connectionParentSpanId,
@@ -368,7 +400,7 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
368
400
  }
369
401
 
370
402
  // 인바운드 메시지를 순차 처리 큐에 올림. Sonamu envelope 검증 수행
371
- private readonly handleMessage = (raw: unknown) => {
403
+ private readonly handleMessage = (raw: RawData) => {
372
404
  this.enqueueMessageTask(async () => {
373
405
  const text = normalizeMessage(raw);
374
406
  const parsedEnvelope = safeParseEnvelope(text);
@@ -391,7 +423,7 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
391
423
  };
392
424
 
393
425
  private readonly handleClose = (code?: number, reason?: Buffer | string) => {
394
- const reasonText = typeof reason === "string" ? reason : reason?.toString();
426
+ const reasonText = isStringValue(reason) ? reason : reason?.toString();
395
427
  this.markClosed(code, reasonText);
396
428
  };
397
429
 
@@ -487,7 +519,7 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
487
519
  const messageTraceFields = {
488
520
  connectionId: this.id,
489
521
  namespace: this.namespace,
490
- userId: this._userId,
522
+ userId: this.currentUserId,
491
523
  traceId: traceCtx.traceId,
492
524
  spanId: traceCtx.spanId,
493
525
  parentSpanId: traceCtx.parentSpanId,
@@ -545,7 +577,7 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
545
577
  }
546
578
  }
547
579
 
548
- private publishValidated(event: string, data: unknown): void {
580
+ private publishValidated<Data>(event: string, data: Data): void {
549
581
  const schema = this.eventSchemasOut[event];
550
582
  if (!schema) {
551
583
  this.options.telemetryController.emit({
@@ -584,7 +616,6 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
584
616
  data: parsed.data,
585
617
  }),
586
618
  event,
587
- parsed.data,
588
619
  );
589
620
  }
590
621
 
@@ -705,8 +736,8 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
705
736
  }
706
737
 
707
738
  // queue가 한계에 도달하면 1013으로 닫아 느린 소비자가 메모리를 끝없이 잡아먹지 못하게 함
708
- // data 인자는 telemetry payload preview 용도로만 사용하며 pendingOutboundMessages에는 저장하지 않음 (큐 메모리 보호)
709
- private enqueueOutboundMessage(payload: string, event: string, data: unknown): void {
739
+ // telemetry preview는 직렬화된 payload에서 복원해 전송 데이터와 같은 JSON 계약을 유지함
740
+ private enqueueOutboundMessage(payload: string, event: string): void {
710
741
  if (this.pendingOutboundMessages.length >= MAX_PENDING_OUTBOUND_MESSAGES) {
711
742
  this.options.telemetryController.emit({
712
743
  name: "ws.backpressure.overflow",
@@ -723,7 +754,7 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
723
754
  level: "debug",
724
755
  ...this.telemetryFields(),
725
756
  detail: { event },
726
- payload: data,
757
+ payload: safeParseEnvelope(payload)?.data,
727
758
  });
728
759
  this.scheduleOutboundFlush();
729
760
  }
@@ -818,7 +849,7 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
818
849
  status: "error",
819
850
  ...fields,
820
851
  attributes: { event },
821
- errorType: error instanceof Error ? error.name : typeof error,
852
+ errorType: error instanceof Error ? error.name : runtimeTypeOf(error),
822
853
  });
823
854
  this.close(WS_CLOSE_CODE_INTERNAL_ERROR, "Outbound publish failed");
824
855
  return;
@@ -838,8 +869,8 @@ class WebSocketConnectionImpl<TOutSchema extends z.ZodRawShape, TInSchema extend
838
869
  }
839
870
  }
840
871
 
841
- function normalizeMessage(raw: unknown): string {
842
- if (typeof raw === "string") {
872
+ function normalizeMessage(raw: RawData): string {
873
+ if (isStringValue(raw)) {
843
874
  return raw;
844
875
  }
845
876
 
@@ -862,7 +893,10 @@ function normalizeMessage(raw: unknown): string {
862
893
 
863
894
  function safeParseEnvelope(raw: string): ParsedEnvelope | null {
864
895
  try {
865
- const parsed = JSON.parse(raw) as unknown;
896
+ const parsed =
897
+ /* SAFETY: 등록된 WebSocket 이벤트 스키마가 이 값의 타입을 보장한다. */ JSON.parse(
898
+ raw,
899
+ ) as unknown;
866
900
  const validated = WebSocketEnvelopeSchema.safeParse(parsed);
867
901
  return validated.success ? validated.data : null;
868
902
  } catch {
@@ -6,6 +6,7 @@ import { afterEach, beforeEach, describe, expect, it } from "vitest";
6
6
  import { z } from "zod";
7
7
 
8
8
  import { registeredApis } from "../../api/decorators";
9
+ import { type AbsolutePath } from "../../utils/path-utils";
9
10
  import { readApisFromFile } from "../api-parser";
10
11
 
11
12
  describe("readApisFromFile websocket type refs", () => {
@@ -47,7 +48,7 @@ describe("readApisFromFile websocket type refs", () => {
47
48
  });
48
49
 
49
50
  tempDir = await mkdtemp(path.join(tmpdir(), "sonamu-api-parser-"));
50
- const filePath = path.join(tempDir, "chat.frame.ts");
51
+ const filePath: AbsolutePath = `/${path.relative("/", path.join(tempDir, "chat.frame.ts"))}`;
51
52
  await writeFile(
52
53
  filePath,
53
54
  `
@@ -64,7 +65,7 @@ class ChatFrameClass {
64
65
  `.trim(),
65
66
  );
66
67
 
67
- const [api] = await readApisFromFile(filePath as `${string}.ts`);
68
+ const [api] = await readApisFromFile(filePath);
68
69
 
69
70
  expect(api?.websocketOptions?.outEventsTypeRef).toEqual({
70
71
  t: "ref",