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,8 +1,9 @@
1
1
  import { getLogger } from "@logtape/logtape";
2
- import { type BetterAuthPlugin } from "better-auth";
2
+ import { type AuthContext, type BetterAuthPlugin, type GenericEndpointContext } from "better-auth";
3
3
  import { createAuthMiddleware } from "better-auth/api";
4
4
 
5
5
  import { DB } from "../../database/db";
6
+ import { isObjectValue, isStringValue } from "../../utils/runtime-value";
6
7
  import { ingestAuditEvent } from "../audit-log-ingestor";
7
8
  import { buildAuditEventCatalog } from "./builders";
8
9
  import {
@@ -10,12 +11,8 @@ import {
10
11
  type AuditLogEvent,
11
12
  type BuilderLocation,
12
13
  type BuilderTrigger,
13
- type InvitationSnapshot,
14
- type MemberSnapshot,
15
- type OrganizationSnapshot,
16
14
  ROUTES,
17
15
  type SessionSnapshot,
18
- type TeamSnapshot,
19
16
  type UserProfileLite,
20
17
  type UserSnapshot,
21
18
  type VerificationSnapshot,
@@ -85,34 +82,14 @@ const getOrganizationTriggerInfo = (user: { id?: string } | null | undefined): B
85
82
  // ============================================================================
86
83
  // better-auth ctx 타입 helpers (내부 shape은 런타임 구조를 기준으로 좁혀 사용한다)
87
84
  // ============================================================================
88
- type BetterAuthRequestCtx = {
89
- path?: string;
90
- body?: Record<string, unknown> | null | undefined;
91
- params?: Record<string, string | undefined> | null | undefined;
92
- context: {
93
- session?: {
94
- session?: { userId?: string };
95
- user?: { id?: string };
96
- } | null;
85
+ type BetterAuthRequestCtx = GenericEndpointContext & {
86
+ context: GenericEndpointContext["context"] & {
97
87
  location?: BuilderLocation | null;
98
- adapter?: {
99
- findOne: (args: {
100
- model: string;
101
- select?: string[];
102
- where: { field: string; value: unknown }[];
103
- }) => Promise<Record<string, unknown> | null>;
104
- };
105
- returned?: unknown;
106
88
  };
107
89
  };
108
90
 
109
91
  // databaseHooks after 콜백의 ctx는 선택적이며 shape을 런타임에서 좁힌다.
110
- const narrowRequestCtx = (raw: unknown): BetterAuthRequestCtx | null => {
111
- if (!raw || typeof raw !== "object") return null;
112
- const candidate = raw as { context?: unknown };
113
- if (!candidate.context || typeof candidate.context !== "object") return null;
114
- return raw as BetterAuthRequestCtx;
115
- };
92
+ const narrowRequestCtx = (raw: GenericEndpointContext | null): BetterAuthRequestCtx | null => raw;
116
93
 
117
94
  // adapter.findOne 호출 실패 시 null을 반환한다. dash 헬퍼와 동일 정책.
118
95
  const fetchUserBy = async (
@@ -129,18 +106,22 @@ const fetchUserBy = async (
129
106
  select: ["id", "name", "email"],
130
107
  where: [{ field, value }],
131
108
  });
132
- if (!row) return null;
109
+ if (!row || !isObjectValue(row)) return null;
110
+ const id = "id" in row ? row.id : undefined;
111
+ const name = "name" in row ? row.name : undefined;
112
+ const email = "email" in row ? row.email : undefined;
133
113
  return {
134
- id: String(row.id),
135
- name: typeof row.name === "string" ? row.name : undefined,
136
- email: typeof row.email === "string" ? row.email : undefined,
114
+ id: String(id),
115
+ name: isStringValue(name) ? name : undefined,
116
+ email: isStringValue(email) ? email : undefined,
137
117
  };
138
118
  } catch {
139
119
  return null;
140
120
  }
141
121
  };
142
122
 
143
- const isNonEmptyString = (v: unknown): v is string => typeof v === "string" && v.length > 0;
123
+ const isNonEmptyString = <Value>(value: Value): value is Value & string =>
124
+ isStringValue(value) && value.length > 0;
144
125
 
145
126
  // dash 제거 시 함께 사라진 location 공급 경로를 대체한다.
146
127
  // 우선순위: cf-connecting-ip > x-forwarded-for(첫 항목) > x-real-ip > x-vercel-forwarded-for
@@ -152,25 +133,30 @@ const IP_HEADER_ORDER = [
152
133
  "x-vercel-forwarded-for",
153
134
  ] as const;
154
135
 
155
- const readHeader = (headers: unknown, key: string): string | null => {
136
+ type HeaderCollection =
137
+ | Headers
138
+ | { [key: string]: string | string[] | undefined }
139
+ | null
140
+ | undefined;
141
+
142
+ const readHeader = (headers: HeaderCollection, key: string): string | null => {
156
143
  if (!headers) return null;
157
144
  if (headers instanceof Headers) {
158
145
  return headers.get(key);
159
146
  }
160
- if (typeof headers === "object") {
161
- const map = headers as Record<string, unknown>;
162
- const v = map[key] ?? map[key.toLowerCase()];
163
- if (typeof v === "string") return v;
164
- if (Array.isArray(v) && typeof v[0] === "string") return v[0];
147
+ if (isObjectValue(headers)) {
148
+ const v = headers[key] ?? headers[key.toLowerCase()];
149
+ if (isStringValue(v)) return v;
150
+ if (Array.isArray(v) && isStringValue(v[0])) return v[0];
165
151
  }
166
152
  return null;
167
153
  };
168
154
 
169
- const extractLocationFromHeaders = (headers: unknown): BuilderLocation => {
155
+ const extractLocationFromHeaders = (headers: HeaderCollection): BuilderLocation => {
170
156
  let ipAddress: string | null = null;
171
157
  for (const key of IP_HEADER_ORDER) {
172
158
  const raw = readHeader(headers, key);
173
- if (typeof raw === "string" && raw.length > 0) {
159
+ if (isStringValue(raw) && raw.length > 0) {
174
160
  const first = raw.split(",")[0]?.trim();
175
161
  if (first) {
176
162
  ipAddress = first;
@@ -191,20 +177,15 @@ const extractLocationFromHeaders = (headers: unknown): BuilderLocation => {
191
177
  // ============================================================================
192
178
  // Organization hook 래핑 헬퍼
193
179
  // ============================================================================
194
- type OrgHookFn = (...args: unknown[]) => Promise<unknown>;
195
-
196
180
  // 주어진 organizationHooks 레코드에 대해 해당 name의 기존 hook을 chain한다.
197
181
  // handler는 payload 객체(첫 번째 인자)만 받아서 audit emit을 수행한다.
198
- const wrapOrgHook = <Payload>(
199
- hooks: Record<string, unknown>,
200
- name: string,
182
+ const wrapOrgHook = <Payload extends object>(
183
+ previous: ((payload: Payload) => Promise<void>) | undefined,
201
184
  handler: (payload: Payload) => Promise<void>,
202
- ): void => {
203
- const prev = hooks[name] as OrgHookFn | undefined;
204
- hooks[name] = async (...args: unknown[]): Promise<unknown> => {
205
- await handler(args[0] as Payload);
206
- if (prev) return prev(...args);
207
- return undefined;
185
+ ): ((payload: Payload) => Promise<void>) => {
186
+ return async (payload) => {
187
+ await handler(payload);
188
+ await previous?.(payload);
208
189
  };
209
190
  };
210
191
 
@@ -219,6 +200,10 @@ const wrapOrgHook = <Payload>(
219
200
  * - dash의 infra 연결/API endpoint 제공 범위는 포함하지 않고, audit-event emit/ingest 경로만 유지한다.
220
201
  * - security 4종은 R1 결정에 따라 scope out (builders.ts의 TODO 주석 참조).
221
202
  */
203
+ function locationFor(ctx: BetterAuthRequestCtx): BuilderLocation | undefined {
204
+ return ctx.context.location ?? undefined;
205
+ }
206
+
222
207
  export function sonamuAuditLog(): BetterAuthPlugin {
223
208
  const logger = getLogger(["sonamu", "audit-log"]);
224
209
  const catalog = buildAuditEventCatalog();
@@ -239,13 +224,10 @@ export function sonamuAuditLog(): BetterAuthPlugin {
239
224
  const triggerFor = (ctx: BetterAuthRequestCtx, subjectUserId: string): BuilderTrigger =>
240
225
  getTriggerInfo(ctx.path, ctx.context.session?.session?.userId ?? null, subjectUserId);
241
226
 
242
- const locationFor = (ctx: BetterAuthRequestCtx): BuilderLocation | undefined =>
243
- ctx.context.location ?? undefined;
244
-
245
227
  return {
246
228
  id: "sonamu-audit-log",
247
229
 
248
- init(pluginCtx: unknown) {
230
+ init(pluginCtx) {
249
231
  installOrganizationHooks(pluginCtx, catalog, emit, logger);
250
232
 
251
233
  // dash 7283-7449 미러: databaseHooks (user/session/account/verification).
@@ -254,10 +236,11 @@ export function sonamuAuditLog(): BetterAuthPlugin {
254
236
  databaseHooks: {
255
237
  user: {
256
238
  create: {
257
- after: async (rawUser: unknown, rawCtx?: unknown): Promise<void> => {
239
+ after: async (rawUser, rawCtx): Promise<void> => {
258
240
  const ctx = narrowRequestCtx(rawCtx);
259
241
  if (!ctx) return;
260
- const user = rawUser as UserSnapshot;
242
+ const user =
243
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawUser as UserSnapshot;
261
244
  await emit(
262
245
  catalog.user.trackUserSignedUp(
263
246
  user,
@@ -268,19 +251,23 @@ export function sonamuAuditLog(): BetterAuthPlugin {
268
251
  },
269
252
  },
270
253
  update: {
271
- after: async (rawUser: unknown, rawCtx?: unknown): Promise<void> => {
254
+ after: async (rawUser, rawCtx): Promise<void> => {
272
255
  const ctx = narrowRequestCtx(rawCtx);
273
256
  if (!ctx) return;
274
- const user = rawUser as UserSnapshot & {
275
- emailVerified?: boolean;
276
- image?: string | null;
277
- };
257
+ const user =
258
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawUser as UserSnapshot & {
259
+ emailVerified?: boolean;
260
+ image?: string | null;
261
+ };
278
262
  const path = ctx.path;
279
263
  const trigger = triggerFor(ctx, user.id);
280
264
  const location = locationFor(ctx);
281
265
 
282
266
  if (matchesAnyRoute(path, [ROUTES.UPDATE_USER, ROUTES.DASH_UPDATE_USER])) {
283
- const updatedFields = Object.keys((ctx.body as object) ?? {});
267
+ const updatedFields = Object.keys(
268
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ (ctx.body as object) ??
269
+ {},
270
+ );
284
271
  const isOnlyImageUpdate =
285
272
  updatedFields.length === 1 && updatedFields[0] === "image";
286
273
  const isOnlyEmailVerifiedUpdate =
@@ -306,7 +293,10 @@ export function sonamuAuditLog(): BetterAuthPlugin {
306
293
  }
307
294
  }
308
295
  } else if (matchesAnyRoute(path, [ROUTES.CHANGE_EMAIL])) {
309
- const updatedFields = Object.keys((ctx.body as object) ?? {});
296
+ const updatedFields = Object.keys(
297
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ (ctx.body as object) ??
298
+ {},
299
+ );
310
300
  await emit(
311
301
  catalog.user.trackUserProfileUpdated(user, updatedFields, trigger, location),
312
302
  );
@@ -331,10 +321,11 @@ export function sonamuAuditLog(): BetterAuthPlugin {
331
321
  },
332
322
  },
333
323
  delete: {
334
- after: async (rawUser: unknown, rawCtx?: unknown): Promise<void> => {
324
+ after: async (rawUser, rawCtx): Promise<void> => {
335
325
  const ctx = narrowRequestCtx(rawCtx);
336
326
  if (!ctx) return;
337
- const user = rawUser as UserSnapshot;
327
+ const user =
328
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawUser as UserSnapshot;
338
329
  await emit(
339
330
  catalog.user.trackUserDeleted(user, triggerFor(ctx, user.id), locationFor(ctx)),
340
331
  );
@@ -344,18 +335,19 @@ export function sonamuAuditLog(): BetterAuthPlugin {
344
335
  session: {
345
336
  create: {
346
337
  before: async (
347
- rawSession: unknown,
348
- rawCtx?: unknown,
338
+ rawSession,
339
+ rawCtx,
349
340
  ): Promise<{ data: { loginMethod: string | null } } | undefined> => {
350
341
  void rawSession;
351
342
  const ctx = narrowRequestCtx(rawCtx);
352
343
  if (!ctx) return undefined;
353
344
  return { data: { loginMethod: getLoginMethod(ctx.path, ctx.params?.id) } };
354
345
  },
355
- after: async (rawSession: unknown, rawCtx?: unknown): Promise<void> => {
346
+ after: async (rawSession, rawCtx): Promise<void> => {
356
347
  const ctx = narrowRequestCtx(rawCtx);
357
348
  if (!ctx) return;
358
- const session = rawSession as SessionSnapshot;
349
+ const session =
350
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawSession as SessionSnapshot;
359
351
  if (!session.userId) return;
360
352
  const location = locationFor(ctx);
361
353
  const loginMethod = getLoginMethod(ctx.path, ctx.params?.id) ?? undefined;
@@ -402,10 +394,11 @@ export function sonamuAuditLog(): BetterAuthPlugin {
402
394
  },
403
395
  },
404
396
  delete: {
405
- after: async (rawSession: unknown, rawCtx?: unknown): Promise<void> => {
397
+ after: async (rawSession, rawCtx): Promise<void> => {
406
398
  const ctx = narrowRequestCtx(rawCtx);
407
399
  if (!ctx) return;
408
- const session = rawSession as SessionSnapshot;
400
+ const session =
401
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawSession as SessionSnapshot;
409
402
  const location = locationFor(ctx);
410
403
  const enrichedSession: SessionSnapshot = { ...session };
411
404
  const user = await fetchUserBy(ctx, "id", session.userId);
@@ -450,10 +443,11 @@ export function sonamuAuditLog(): BetterAuthPlugin {
450
443
  },
451
444
  account: {
452
445
  create: {
453
- after: async (rawAccount: unknown, rawCtx?: unknown): Promise<void> => {
446
+ after: async (rawAccount, rawCtx): Promise<void> => {
454
447
  const ctx = narrowRequestCtx(rawCtx);
455
448
  if (!ctx) return;
456
- const account = rawAccount as AccountSnapshot;
449
+ const account =
450
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawAccount as AccountSnapshot;
457
451
  if (!account.userId) return;
458
452
  const user = await fetchUserBy(ctx, "id", account.userId);
459
453
  await emit(
@@ -467,10 +461,11 @@ export function sonamuAuditLog(): BetterAuthPlugin {
467
461
  },
468
462
  },
469
463
  update: {
470
- after: async (rawAccount: unknown, rawCtx?: unknown): Promise<void> => {
464
+ after: async (rawAccount, rawCtx): Promise<void> => {
471
465
  const ctx = narrowRequestCtx(rawCtx);
472
466
  if (!ctx) return;
473
- const account = rawAccount as AccountSnapshot;
467
+ const account =
468
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawAccount as AccountSnapshot;
474
469
  if (!account.userId) return;
475
470
  if (
476
471
  !matchesAnyRoute(ctx.path, [
@@ -494,10 +489,11 @@ export function sonamuAuditLog(): BetterAuthPlugin {
494
489
  },
495
490
  },
496
491
  delete: {
497
- after: async (rawAccount: unknown, rawCtx?: unknown): Promise<void> => {
492
+ after: async (rawAccount, rawCtx): Promise<void> => {
498
493
  const ctx = narrowRequestCtx(rawCtx);
499
494
  if (!ctx) return;
500
- const account = rawAccount as AccountSnapshot;
495
+ const account =
496
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawAccount as AccountSnapshot;
501
497
  if (!account.userId) return;
502
498
  const user = await fetchUserBy(ctx, "id", account.userId);
503
499
  await emit(
@@ -513,11 +509,12 @@ export function sonamuAuditLog(): BetterAuthPlugin {
513
509
  },
514
510
  verification: {
515
511
  create: {
516
- after: async (rawVerification: unknown, rawCtx?: unknown): Promise<void> => {
512
+ after: async (rawVerification, rawCtx): Promise<void> => {
517
513
  const ctx = narrowRequestCtx(rawCtx);
518
514
  if (!ctx) return;
519
515
  if (!matchesAnyRoute(ctx.path, [ROUTES.REQUEST_PASSWORD_RESET])) return;
520
- const verification = rawVerification as VerificationSnapshot;
516
+ const verification =
517
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawVerification as VerificationSnapshot;
521
518
  const sessionUserId = ctx.context.session?.user?.id ?? "unknown";
522
519
  const trigger = getTriggerInfo(ctx.path, sessionUserId, sessionUserId);
523
520
  const user = await fetchUserBy(ctx, "id", verification.value);
@@ -532,11 +529,12 @@ export function sonamuAuditLog(): BetterAuthPlugin {
532
529
  },
533
530
  },
534
531
  delete: {
535
- after: async (rawVerification: unknown, rawCtx?: unknown): Promise<void> => {
532
+ after: async (rawVerification, rawCtx): Promise<void> => {
536
533
  const ctx = narrowRequestCtx(rawCtx);
537
534
  if (!ctx) return;
538
535
  if (!matchesAnyRoute(ctx.path, [ROUTES.RESET_PASSWORD])) return;
539
- const verification = rawVerification as VerificationSnapshot;
536
+ const verification =
537
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ rawVerification as VerificationSnapshot;
540
538
  const sessionUserId = ctx.context.session?.user?.id ?? "unknown";
541
539
  const trigger = getTriggerInfo(ctx.path, sessionUserId, sessionUserId);
542
540
  const user = await fetchUserBy(ctx, "id", verification.value);
@@ -563,12 +561,7 @@ export function sonamuAuditLog(): BetterAuthPlugin {
563
561
  // 모든 요청에서 ctx.context.location을 채워 이후 빌더들이 ipAddress/city/countryCode를 기록할 수 있게 한다.
564
562
  matcher: () => true,
565
563
  handler: createAuthMiddleware(async (rawCtx) => {
566
- const ctx = rawCtx as {
567
- headers?: unknown;
568
- request?: { headers?: unknown } | undefined;
569
- context?: { location?: BuilderLocation | null } & Record<string, unknown>;
570
- };
571
- if (!ctx.context) return;
564
+ const ctx: BetterAuthRequestCtx = rawCtx;
572
565
  const headers = ctx.headers ?? ctx.request?.headers;
573
566
  ctx.context.location = extractLocationFromHeaders(headers);
574
567
  }),
@@ -578,12 +571,11 @@ export function sonamuAuditLog(): BetterAuthPlugin {
578
571
  {
579
572
  // dash 7462-7487 미러: verification email send, sign-in attempts.
580
573
  // GET 요청은 콜백 경로만 통과시킨다.
581
- matcher: (ctx: unknown): boolean => {
582
- const c = ctx as { request?: { method?: string; url?: string } };
583
- if (c.request?.method !== "GET") return true;
584
- if (!c.request.url) return false;
574
+ matcher: (ctx): boolean => {
575
+ if (ctx.request?.method !== "GET") return true;
576
+ if (!ctx.request.url) return false;
585
577
  try {
586
- const p = new URL(c.request.url).pathname;
578
+ const p = new URL(ctx.request.url).pathname;
587
579
  return matchesAnyRoute(p, [
588
580
  ROUTES.SIGN_IN_SOCIAL_CALLBACK,
589
581
  ROUTES.SIGN_IN_OAUTH_CALLBACK,
@@ -608,10 +600,11 @@ export function sonamuAuditLog(): BetterAuthPlugin {
608
600
  ctx.context.session &&
609
601
  !isErrored
610
602
  ) {
611
- const sessionEntity = ctx.context.session.session as SessionSnapshot | undefined;
612
- const user = ctx.context.session.user as
613
- | { name?: string; email?: string }
614
- | undefined;
603
+ const sessionEntity =
604
+ /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ ctx.context
605
+ .session.session as SessionSnapshot | undefined;
606
+ const user = /* SAFETY: better-auth 훅과 어댑터 계약이 이 값의 타입을 보장한다. */ ctx
607
+ .context.session.user as { name?: string; email?: string } | undefined;
615
608
  if (sessionEntity && user) {
616
609
  await emit(
617
610
  catalog.session.trackEmailVerificationSent(sessionEntity, user, trigger),
@@ -619,13 +612,12 @@ export function sonamuAuditLog(): BetterAuthPlugin {
619
612
  }
620
613
  }
621
614
 
622
- const body =
623
- (ctx.body as { email?: string; provider?: string; idToken?: string } | null) ?? null;
615
+ const body = ctx.body;
624
616
  // email sign-in attempt failed
625
617
  if (
626
618
  matchesAnyRoute(ctx.path, [ROUTES.SIGN_IN_EMAIL, ROUTES.SIGN_IN_EMAIL_OTP]) &&
627
619
  isErrored &&
628
- body?.email
620
+ isStringValue(body?.email)
629
621
  ) {
630
622
  const user = await fetchUserBy(ctx, "email", body.email);
631
623
  await emit(
@@ -641,8 +633,8 @@ export function sonamuAuditLog(): BetterAuthPlugin {
641
633
  if (
642
634
  matchesAnyRoute(ctx.path, [ROUTES.SIGN_IN_SOCIAL]) &&
643
635
  isErrored &&
644
- body?.provider &&
645
- body?.idToken
636
+ isStringValue(body?.provider) &&
637
+ isStringValue(body?.idToken)
646
638
  ) {
647
639
  await emit(
648
640
  catalog.session.trackSocialSignInAttempt(
@@ -679,57 +671,42 @@ type EventEmitter = (event: AuditLogEvent) => Promise<void>;
679
671
  type AuditLogger = ReturnType<typeof getLogger>;
680
672
 
681
673
  function installOrganizationHooks(
682
- pluginCtx: unknown,
674
+ pluginCtx: AuthContext,
683
675
  catalog: ReturnType<typeof buildAuditEventCatalog>,
684
676
  emit: EventEmitter,
685
677
  logger: AuditLogger,
686
678
  ): void {
687
- const getPlugin = (pluginCtx as { getPlugin?: (id: string) => unknown })?.getPlugin;
688
- const organizationPlugin =
689
- typeof getPlugin === "function" ? getPlugin.call(pluginCtx, "organization") : null;
679
+ const organizationPlugin = pluginCtx.getPlugin("organization");
690
680
 
691
- if (!organizationPlugin || typeof organizationPlugin !== "object") {
681
+ if (!organizationPlugin) {
692
682
  logger.debug("organization plugin not active; skipping instrumentation");
693
683
  return;
694
684
  }
695
685
 
696
- const orgPlugin = organizationPlugin as {
697
- options?: { organizationHooks?: Record<string, unknown> };
698
- };
699
- orgPlugin.options = orgPlugin.options ?? {};
700
- const hooks = (orgPlugin.options.organizationHooks = orgPlugin.options.organizationHooks ?? {});
701
-
702
- wrapOrgHook<{ organization: OrganizationSnapshot; user: UserSnapshot }>(
703
- hooks,
704
- "afterCreateOrganization",
705
- async (p) =>
706
- emit(
707
- catalog.organization.trackOrganizationCreated(
708
- p.organization,
709
- getOrganizationTriggerInfo(p.user),
710
- ),
686
+ organizationPlugin.options = organizationPlugin.options ?? {};
687
+ const hooks = (organizationPlugin.options.organizationHooks =
688
+ organizationPlugin.options.organizationHooks ?? {});
689
+
690
+ hooks.afterCreateOrganization = wrapOrgHook(hooks.afterCreateOrganization, async (p) =>
691
+ emit(
692
+ catalog.organization.trackOrganizationCreated(
693
+ p.organization,
694
+ getOrganizationTriggerInfo(p.user),
711
695
  ),
696
+ ),
712
697
  );
713
698
 
714
- wrapOrgHook<{ organization?: OrganizationSnapshot; user: UserSnapshot }>(
715
- hooks,
716
- "afterUpdateOrganization",
717
- async (p) => {
718
- if (!p.organization) return;
719
- await emit(
720
- catalog.organization.trackOrganizationUpdated(
721
- p.organization,
722
- getOrganizationTriggerInfo(p.user),
723
- ),
724
- );
725
- },
726
- );
699
+ hooks.afterUpdateOrganization = wrapOrgHook(hooks.afterUpdateOrganization, async (p) => {
700
+ if (!p.organization) return;
701
+ await emit(
702
+ catalog.organization.trackOrganizationUpdated(
703
+ p.organization,
704
+ getOrganizationTriggerInfo(p.user),
705
+ ),
706
+ );
707
+ });
727
708
 
728
- wrapOrgHook<{
729
- organization: OrganizationSnapshot;
730
- member: MemberSnapshot;
731
- user: UserSnapshot;
732
- }>(hooks, "afterAddMember", async (p) =>
709
+ hooks.afterAddMember = wrapOrgHook(hooks.afterAddMember, async (p) =>
733
710
  emit(
734
711
  catalog.member.trackOrganizationMemberAdded(
735
712
  p.organization,
@@ -740,11 +717,7 @@ function installOrganizationHooks(
740
717
  ),
741
718
  );
742
719
 
743
- wrapOrgHook<{
744
- organization: OrganizationSnapshot;
745
- member: MemberSnapshot;
746
- user: UserSnapshot;
747
- }>(hooks, "afterRemoveMember", async (p) =>
720
+ hooks.afterRemoveMember = wrapOrgHook(hooks.afterRemoveMember, async (p) =>
748
721
  emit(
749
722
  catalog.member.trackOrganizationMemberRemoved(
750
723
  p.organization,
@@ -755,12 +728,7 @@ function installOrganizationHooks(
755
728
  ),
756
729
  );
757
730
 
758
- wrapOrgHook<{
759
- organization: OrganizationSnapshot;
760
- member: MemberSnapshot;
761
- user: UserSnapshot;
762
- previousRole: string;
763
- }>(hooks, "afterUpdateMemberRole", async (p) =>
731
+ hooks.afterUpdateMemberRole = wrapOrgHook(hooks.afterUpdateMemberRole, async (p) =>
764
732
  emit(
765
733
  catalog.member.trackOrganizationMemberRoleUpdated(
766
734
  p.organization,
@@ -772,11 +740,7 @@ function installOrganizationHooks(
772
740
  ),
773
741
  );
774
742
 
775
- wrapOrgHook<{
776
- organization: OrganizationSnapshot;
777
- invitation: InvitationSnapshot;
778
- inviter: UserSnapshot;
779
- }>(hooks, "afterCreateInvitation", async (p) =>
743
+ hooks.afterCreateInvitation = wrapOrgHook(hooks.afterCreateInvitation, async (p) =>
780
744
  emit(
781
745
  catalog.invitation.trackOrganizationMemberInvited(
782
746
  p.organization,
@@ -787,12 +751,7 @@ function installOrganizationHooks(
787
751
  ),
788
752
  );
789
753
 
790
- wrapOrgHook<{
791
- organization: OrganizationSnapshot;
792
- invitation: InvitationSnapshot;
793
- member: MemberSnapshot;
794
- user: UserSnapshot;
795
- }>(hooks, "afterAcceptInvitation", async (p) =>
754
+ hooks.afterAcceptInvitation = wrapOrgHook(hooks.afterAcceptInvitation, async (p) =>
796
755
  emit(
797
756
  catalog.invitation.trackOrganizationMemberInviteAccepted(
798
757
  p.organization,
@@ -804,11 +763,7 @@ function installOrganizationHooks(
804
763
  ),
805
764
  );
806
765
 
807
- wrapOrgHook<{
808
- organization: OrganizationSnapshot;
809
- invitation: InvitationSnapshot;
810
- user: UserSnapshot;
811
- }>(hooks, "afterRejectInvitation", async (p) =>
766
+ hooks.afterRejectInvitation = wrapOrgHook(hooks.afterRejectInvitation, async (p) =>
812
767
  emit(
813
768
  catalog.invitation.trackOrganizationMemberInviteRejected(
814
769
  p.organization,
@@ -819,11 +774,7 @@ function installOrganizationHooks(
819
774
  ),
820
775
  );
821
776
 
822
- wrapOrgHook<{
823
- organization: OrganizationSnapshot;
824
- invitation: InvitationSnapshot;
825
- cancelledBy: UserSnapshot;
826
- }>(hooks, "afterCancelInvitation", async (p) =>
777
+ hooks.afterCancelInvitation = wrapOrgHook(hooks.afterCancelInvitation, async (p) =>
827
778
  emit(
828
779
  catalog.invitation.trackOrganizationMemberInviteCanceled(
829
780
  p.organization,
@@ -834,11 +785,7 @@ function installOrganizationHooks(
834
785
  ),
835
786
  );
836
787
 
837
- wrapOrgHook<{
838
- organization: OrganizationSnapshot;
839
- team: TeamSnapshot;
840
- user: UserSnapshot;
841
- }>(hooks, "afterCreateTeam", async (p) =>
788
+ hooks.afterCreateTeam = wrapOrgHook(hooks.afterCreateTeam, async (p) =>
842
789
  emit(
843
790
  catalog.team.trackOrganizationTeamCreated(
844
791
  p.organization,
@@ -848,11 +795,7 @@ function installOrganizationHooks(
848
795
  ),
849
796
  );
850
797
 
851
- wrapOrgHook<{
852
- organization: OrganizationSnapshot;
853
- team?: TeamSnapshot;
854
- user: UserSnapshot;
855
- }>(hooks, "afterUpdateTeam", async (p) => {
798
+ hooks.afterUpdateTeam = wrapOrgHook(hooks.afterUpdateTeam, async (p) => {
856
799
  if (!p.team) return;
857
800
  await emit(
858
801
  catalog.team.trackOrganizationTeamUpdated(
@@ -863,11 +806,7 @@ function installOrganizationHooks(
863
806
  );
864
807
  });
865
808
 
866
- wrapOrgHook<{
867
- organization: OrganizationSnapshot;
868
- team: TeamSnapshot;
869
- user: UserSnapshot;
870
- }>(hooks, "afterDeleteTeam", async (p) =>
809
+ hooks.afterDeleteTeam = wrapOrgHook(hooks.afterDeleteTeam, async (p) =>
871
810
  emit(
872
811
  catalog.team.trackOrganizationTeamDeleted(
873
812
  p.organization,
@@ -877,12 +816,7 @@ function installOrganizationHooks(
877
816
  ),
878
817
  );
879
818
 
880
- wrapOrgHook<{
881
- organization: OrganizationSnapshot;
882
- team: TeamSnapshot;
883
- user: UserSnapshot;
884
- teamMember: { teamId: string; userId: string };
885
- }>(hooks, "afterAddTeamMember", async (p) =>
819
+ hooks.afterAddTeamMember = wrapOrgHook(hooks.afterAddTeamMember, async (p) =>
886
820
  emit(
887
821
  catalog.team.trackOrganizationTeamMemberAdded(
888
822
  p.organization,
@@ -894,12 +828,7 @@ function installOrganizationHooks(
894
828
  ),
895
829
  );
896
830
 
897
- wrapOrgHook<{
898
- organization: OrganizationSnapshot;
899
- team: TeamSnapshot;
900
- user: UserSnapshot;
901
- teamMember: { teamId: string; userId: string };
902
- }>(hooks, "afterRemoveTeamMember", async (p) =>
831
+ hooks.afterRemoveTeamMember = wrapOrgHook(hooks.afterRemoveTeamMember, async (p) =>
903
832
  emit(
904
833
  catalog.team.trackOrganizationTeamMemberRemoved(
905
834
  p.organization,