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
@@ -17,7 +17,11 @@
17
17
  * const { company01, user01 } = await loadFixtures(["company01", "user01"]);
18
18
  * ```
19
19
  */
20
- export function createFixtureLoader<T extends Record<string, () => Promise<unknown>>>(loaders: T) {
20
+ type FixtureLoaderValue = object | string | number | boolean | bigint | symbol | null | undefined;
21
+
22
+ export function createFixtureLoader<T extends Record<string, () => Promise<FixtureLoaderValue>>>(
23
+ loaders: T,
24
+ ) {
21
25
  return async function loadFixtures<K extends keyof T>(
22
26
  names: K[],
23
27
  ): Promise<{ [P in K]: Awaited<ReturnType<T[P]>> }> {
@@ -1,5 +1,5 @@
1
1
  import assert from "assert";
2
- import { execSync } from "child_process";
2
+ import { execSync, type ExecSyncOptions } from "child_process";
3
3
  import { readFileSync, writeFileSync } from "fs";
4
4
  import { inspect } from "util";
5
5
 
@@ -7,6 +7,7 @@ import chalk from "chalk";
7
7
  import inflection from "inflection";
8
8
  import { type Knex } from "knex";
9
9
  import { unique } from "radashi";
10
+ import { z } from "zod";
10
11
 
11
12
  import { Sonamu } from "../api/sonamu";
12
13
  import { BaseModel } from "../database/base-model";
@@ -35,6 +36,38 @@ import {
35
36
  } from "../types/types";
36
37
  import { isTest } from "../utils/controller";
37
38
  import { RelationGraph } from "./_relation-graph";
39
+ import { dataExplorerRecordSchema } from "./data-explorer";
40
+ import { type DataExplorerRecord, type DataExplorerValue } from "./data-explorer";
41
+
42
+ const pgConnectionSchema = z
43
+ .object({
44
+ host: z.string().optional(),
45
+ port: z.number().optional(),
46
+ user: z.string().optional(),
47
+ password: z.string().optional(),
48
+ database: z.string(),
49
+ })
50
+ .passthrough();
51
+ const databaseConnectionSchema = z.object({ database: z.string() }).passthrough();
52
+ const fixtureRecordIdsSchema = z.array(z.union([z.number(), z.string()]));
53
+ const relationIdSchema = z.union([z.number(), z.string(), z.null()]);
54
+
55
+ export type FixtureSourceRecord = DataExplorerRecord & {
56
+ id: number | string;
57
+ };
58
+
59
+ type UpsertRowValue = DataExplorerValue | UBRef;
60
+ type UpsertRow = {
61
+ [columnName: string]: UpsertRowValue;
62
+ };
63
+
64
+ function executeFixtureSyncCommand(command: string, options: ExecSyncOptions): void {
65
+ try {
66
+ execSync(command, options);
67
+ } catch (error) {
68
+ throw new Error("Fixture database synchronization command failed", { cause: error });
69
+ }
70
+ }
38
71
 
39
72
  /** 사용자 지정 중복 확인 컬럼 (entityId별로 지정) */
40
73
  export interface DuplicateCheckOptions {
@@ -44,26 +77,26 @@ export interface DuplicateCheckOptions {
44
77
  }
45
78
 
46
79
  export class FixtureManagerClass {
47
- private _tdb: Knex | null = null;
80
+ private testingDb: Knex | null = null;
48
81
  set tdb(tdb: Knex) {
49
- this._tdb = tdb;
82
+ this.testingDb = tdb;
50
83
  }
51
84
  get tdb(): Knex {
52
- if (this._tdb === null) {
85
+ if (this.testingDb === null) {
53
86
  throw new Error("FixtureManager has not been initialized");
54
87
  }
55
- return this._tdb;
88
+ return this.testingDb;
56
89
  }
57
90
 
58
- private _fdb: Knex | null = null;
91
+ private fixtureDb: Knex | null = null;
59
92
  set fdb(fdb: Knex) {
60
- this._fdb = fdb;
93
+ this.fixtureDb = fdb;
61
94
  }
62
95
  get fdb(): Knex {
63
- if (this._fdb === null) {
96
+ if (this.fixtureDb === null) {
64
97
  throw new Error("FixtureManager has not been initialized");
65
98
  }
66
- return this._fdb;
99
+ return this.fixtureDb;
67
100
  }
68
101
  cachedTableNames: string[] | null = null;
69
102
 
@@ -76,16 +109,12 @@ export class FixtureManagerClass {
76
109
  new Map();
77
110
 
78
111
  init() {
79
- if (this._tdb !== null) {
112
+ if (this.testingDb !== null) {
80
113
  return;
81
114
  }
82
115
  if (Sonamu.dbConfig.test && Sonamu.dbConfig.production) {
83
- const tConn = Sonamu.dbConfig.test.connection as Knex.ConnectionConfig & {
84
- port?: number;
85
- };
86
- const pConn = Sonamu.dbConfig.production.connection as Knex.ConnectionConfig & {
87
- port?: number;
88
- };
116
+ const tConn = pgConnectionSchema.parse(Sonamu.dbConfig.test.connection);
117
+ const pConn = pgConnectionSchema.parse(Sonamu.dbConfig.production.connection);
89
118
  if (
90
119
  `${tConn.host ?? "localhost"}:${tConn.port ?? 5432}/${tConn.database}` ===
91
120
  `${pConn.host ?? "localhost"}:${pConn.port ?? 5432}/${pConn.database}`
@@ -103,29 +132,29 @@ export class FixtureManagerClass {
103
132
  pg_dump로 원격 DB를 덤프하고, pg_restore로 로컬에 복원합니다.
104
133
  */
105
134
  async sync() {
106
- const fixtureConn = Sonamu.dbConfig.fixture.connection as Knex.PgConnectionConfig;
107
- const testConn = Sonamu.dbConfig.test.connection as Knex.PgConnectionConfig;
135
+ const fixtureConn = pgConnectionSchema.parse(Sonamu.dbConfig.fixture.connection);
136
+ const testConn = pgConnectionSchema.parse(Sonamu.dbConfig.test.connection);
108
137
 
109
138
  // 1. 로컬 test DB 연결 종료 및 재생성
110
139
  const testPgEnv = { PGPASSWORD: testConn.password || "" };
111
- execSync(
140
+ executeFixtureSyncCommand(
112
141
  `psql -h ${testConn.host} -p ${testConn.port ?? 5432} -U ${testConn.user} -d postgres -c "
113
142
  SELECT pg_terminate_backend(pg_stat_activity.pid)
114
143
  FROM pg_stat_activity
115
144
  WHERE datname = '${testConn.database}'
116
145
  AND pid <> pg_backend_pid();
117
146
  "`,
118
- { stdio: "inherit", env: { ...process.env, ...testPgEnv } as NodeJS.ProcessEnv },
147
+ { stdio: "inherit", env: { ...process.env, ...testPgEnv } },
119
148
  );
120
149
 
121
- execSync(
150
+ executeFixtureSyncCommand(
122
151
  `psql -h ${testConn.host} -p ${testConn.port ?? 5432} -U ${testConn.user} -d postgres -c "DROP DATABASE IF EXISTS \\"${testConn.database}\\""`,
123
- { stdio: "inherit", env: { ...process.env, ...testPgEnv } as NodeJS.ProcessEnv },
152
+ { stdio: "inherit", env: { ...process.env, ...testPgEnv } },
124
153
  );
125
154
 
126
- execSync(
155
+ executeFixtureSyncCommand(
127
156
  `psql -h ${testConn.host} -p ${testConn.port ?? 5432} -U ${testConn.user} -d postgres -c "CREATE DATABASE \\"${testConn.database}\\""`,
128
- { stdio: "inherit", env: { ...process.env, ...testPgEnv } as NodeJS.ProcessEnv },
157
+ { stdio: "inherit", env: { ...process.env, ...testPgEnv } },
129
158
  );
130
159
 
131
160
  // 2. 원격 fixture DB → 로컬 test DB로 복사 (pg_dump | pg_restore)
@@ -133,11 +162,14 @@ export class FixtureManagerClass {
133
162
  const dumpCmd = `pg_dump -h ${fixtureConn.host} -p ${fixtureConn.port ?? 5432} -U ${fixtureConn.user} -d ${fixtureConn.database} -Fc`;
134
163
  const restoreCmd = `pg_restore -h ${testConn.host} -p ${testConn.port ?? 5432} -U ${testConn.user} -d ${testConn.database} --no-owner --no-acl`;
135
164
 
136
- execSync(`${dumpCmd} | PGPASSWORD="${testConn.password || ""}" ${restoreCmd}`, {
137
- stdio: "inherit",
138
- env: { ...process.env, ...fixturePgEnv } as NodeJS.ProcessEnv,
139
- shell: "/bin/bash",
140
- });
165
+ executeFixtureSyncCommand(
166
+ `${dumpCmd} | PGPASSWORD="${testConn.password || ""}" ${restoreCmd}`,
167
+ {
168
+ stdio: "inherit",
169
+ env: { ...process.env, ...fixturePgEnv },
170
+ shell: "/bin/bash",
171
+ },
172
+ );
141
173
 
142
174
  // 3. 시퀀스 리셋 (데이터 복사 후 시퀀스를 MAX(id)로 정렬)
143
175
  await this.resetSequences(Sonamu.dbConfig.test);
@@ -228,8 +260,12 @@ export class FixtureManagerClass {
228
260
  }
229
261
 
230
262
  // 픽스쳐DB, 실DB
231
- const fixtureDatabase = (Sonamu.dbConfig.fixture.connection as Knex.ConnectionConfig).database;
232
- const realDatabase = (Sonamu.dbConfig.production.connection as Knex.ConnectionConfig).database;
263
+ const fixtureDatabase = databaseConnectionSchema.parse(
264
+ Sonamu.dbConfig.fixture.connection,
265
+ ).database;
266
+ const realDatabase = databaseConnectionSchema.parse(
267
+ Sonamu.dbConfig.production.connection,
268
+ ).database;
233
269
 
234
270
  const selfQuery = `INSERT IGNORE INTO \`${fixtureDatabase}\`.\`${entity.table}\` (SELECT * FROM \`${realDatabase}\`.\`${entity.table}\` WHERE \`id\` = ${id})`;
235
271
 
@@ -248,8 +284,8 @@ export class FixtureManagerClass {
248
284
  OneToOne에 joinColumn === false 인 경우
249
285
  Profile / 'profile_id' / row['id'] 호출
250
286
  */
251
- let field: string;
252
- let id: number;
287
+ let relationField: string;
288
+ let relationId: number;
253
289
  if (isOneToOneRelationProp(relation) && !relation.hasJoinColumn) {
254
290
  const relatedEntity = EntityManager.get(relation.with);
255
291
  const relatedIdColumnName = relatedEntity.props.find(
@@ -258,23 +294,23 @@ export class FixtureManagerClass {
258
294
  if (!relatedIdColumnName) {
259
295
  throw new Error(`${relatedEntity.id}의 ${entity.id} 관계 프롭을 찾을 수 없습니다.`);
260
296
  }
261
- field = `${relatedIdColumnName}_id`;
262
- id = row.id;
297
+ relationField = `${relatedIdColumnName}_id`;
298
+ relationId = row.id;
263
299
  } else {
264
- field = "id";
265
- id = row[`${relation.name}_id`];
300
+ relationField = "id";
301
+ relationId = row[`${relation.name}_id`];
266
302
  }
267
303
  return {
268
304
  entityId: relation.with,
269
- field,
270
- id,
305
+ field: relationField,
306
+ id: relationId,
271
307
  };
272
308
  })
273
309
  .filter((arg) => arg.id !== null);
274
310
 
275
311
  const relQueries = await Promise.all(
276
- args.map(async (args) => {
277
- return this.getImportQueries(args.entityId, args.field, args.id);
312
+ args.map(async (relationArgs) => {
313
+ return this.getImportQueries(relationArgs.entityId, relationArgs.field, relationArgs.id);
278
314
  }),
279
315
  );
280
316
 
@@ -282,13 +318,13 @@ export class FixtureManagerClass {
282
318
  }
283
319
 
284
320
  async destroy() {
285
- if (this._tdb) {
286
- await this._tdb.destroy();
287
- this._tdb = null;
321
+ if (this.testingDb) {
322
+ await this.testingDb.destroy();
323
+ this.testingDb = null;
288
324
  }
289
- if (this._fdb) {
290
- await this._fdb.destroy();
291
- this._fdb = null;
325
+ if (this.fixtureDb) {
326
+ await this.fixtureDb.destroy();
327
+ this.fixtureDb = null;
292
328
  }
293
329
  await BaseModel.destroy();
294
330
  }
@@ -327,7 +363,7 @@ export class FixtureManagerClass {
327
363
  for (const row of rows) {
328
364
  const initialRecordsLength = fixtures.length;
329
365
  const newRecords = await this.createFixtureRecord(entity, row, {
330
- _db: sourceDB,
366
+ db: sourceDB,
331
367
  });
332
368
  fixtures.push(...newRecords);
333
369
  const currentFixtureRecord = fixtures.find((r) => r.fixtureId === `${entityId}#${row.id}`);
@@ -342,32 +378,32 @@ export class FixtureManagerClass {
342
378
  }
343
379
 
344
380
  for (const fixture of fixtures) {
345
- const entity = EntityManager.get(fixture.entityId);
381
+ const fixtureEntity = EntityManager.get(fixture.entityId);
346
382
 
347
383
  // 사용자 지정 컬럼 기준 중복 확인 → target
348
384
  const customColumns = duplicateCheck?.columns?.[fixture.entityId];
349
385
  if (customColumns && customColumns.length > 0) {
350
386
  const customDuplicateRow = await this.checkDuplicateByColumns(
351
387
  targetDB,
352
- entity,
388
+ fixtureEntity,
353
389
  fixture,
354
390
  customColumns,
355
391
  );
356
392
  if (customDuplicateRow) {
357
- const [record] = await this.createFixtureRecord(entity, customDuplicateRow, {
393
+ const [record] = await this.createFixtureRecord(fixtureEntity, customDuplicateRow, {
358
394
  singleRecord: true,
359
- _db: targetDB,
395
+ db: targetDB,
360
396
  });
361
397
  fixture.target = record;
362
398
  }
363
399
  }
364
400
 
365
401
  // Unique index 기준 중복 확인 → fixture.unique
366
- const uniqueRow = await this.checkUniqueViolation(targetDB, entity, fixture);
402
+ const uniqueRow = await this.checkUniqueViolation(targetDB, fixtureEntity, fixture);
367
403
  if (uniqueRow) {
368
- const [record] = await this.createFixtureRecord(entity, uniqueRow, {
404
+ const [record] = await this.createFixtureRecord(fixtureEntity, uniqueRow, {
369
405
  singleRecord: true,
370
- _db: targetDB,
406
+ db: targetDB,
371
407
  });
372
408
  fixture.unique = record;
373
409
  }
@@ -380,26 +416,17 @@ export class FixtureManagerClass {
380
416
  }
381
417
 
382
418
  async createFixtureRecord(
383
- entity: Entity,
384
- row: {
385
- id: number | string;
386
- [key: string]: string | number | boolean | null;
387
- },
419
+ rootEntity: Entity,
420
+ rootRow: FixtureSourceRecord,
388
421
  options?: {
389
422
  singleRecord?: boolean;
390
- _db?: Knex;
423
+ db?: Knex;
391
424
  },
392
425
  ): Promise<FixtureRecord[]> {
393
426
  const records: FixtureRecord[] = [];
394
427
  const visitedEntities = new Set<string>();
395
428
 
396
- const create = async (
397
- entity: Entity,
398
- row: {
399
- id: number | string;
400
- [key: string]: string | number | boolean | null;
401
- },
402
- ) => {
429
+ const create = async (entity: Entity, row: FixtureSourceRecord) => {
403
430
  const fixtureId = `${entity.id}#${row.id}`;
404
431
  if (visitedEntities.has(fixtureId)) {
405
432
  return;
@@ -420,12 +447,14 @@ export class FixtureManagerClass {
420
447
  continue;
421
448
  }
422
449
 
450
+ // SAFETY: FixtureRecord의 레거시 값 타입보다 실제 DB/JSON fixture 값 계약이 넓습니다.
451
+ const columnValue = row[prop.name] as FixtureRecord["columns"][string]["value"];
423
452
  record.columns[prop.name] = {
424
453
  prop: prop,
425
- value: row[prop.name],
454
+ value: columnValue,
426
455
  };
427
456
 
428
- const db = options?._db ?? BaseModel.getDB("w");
457
+ const db = options?.db ?? BaseModel.getDB("w");
429
458
  if (isManyToManyRelationProp(prop)) {
430
459
  const relatedEntity = EntityManager.get(prop.with);
431
460
  const throughTable = prop.joinTable;
@@ -454,7 +483,7 @@ export class FixtureManagerClass {
454
483
  record.columns[prop.name].value = relatedRow?.id;
455
484
  }
456
485
  } else if (isRelationProp(prop)) {
457
- const relatedId = row[`${prop.name}_id`];
486
+ const relatedId = relationIdSchema.parse(row[`${prop.name}_id`]);
458
487
  record.columns[prop.name].value = relatedId;
459
488
  if (relatedId) {
460
489
  record.belongsRecords.push(`${prop.with}#${relatedId}`);
@@ -463,7 +492,10 @@ export class FixtureManagerClass {
463
492
  const relatedEntity = EntityManager.get(prop.with);
464
493
  const relatedRow = await db(relatedEntity.table).where("id", relatedId).first();
465
494
  if (relatedRow) {
466
- await create(relatedEntity, relatedRow);
495
+ await create(relatedEntity, {
496
+ ...dataExplorerRecordSchema.parse(relatedRow),
497
+ id: z.union([z.number(), z.string()]).parse(relatedRow.id),
498
+ });
467
499
  }
468
500
  }
469
501
  }
@@ -472,7 +504,7 @@ export class FixtureManagerClass {
472
504
  records.push(record);
473
505
  };
474
506
 
475
- await create(entity, row);
507
+ await create(rootEntity, rootRow);
476
508
 
477
509
  return records;
478
510
  }
@@ -504,7 +536,7 @@ export class FixtureManagerClass {
504
536
  ? (() => {
505
537
  const workerId = parseInt(process.env.VITEST_POOL_ID ?? "1", 10);
506
538
  const baseConfig = Sonamu.dbConfig[dbName];
507
- const connection = baseConfig.connection as { database: string };
539
+ const connection = databaseConnectionSchema.parse(baseConfig.connection);
508
540
  return {
509
541
  ...baseConfig,
510
542
  connection: { ...connection, database: `${connection.database}_${workerId}` },
@@ -591,7 +623,7 @@ export class FixtureManagerClass {
591
623
 
592
624
  // upsert 실행 전 uuid 목록 저장
593
625
  const table = this.builder.getTable(tableName);
594
- const uuids = table.rows.map((row) => row.uuid as string);
626
+ const uuids = table.rows.map((row) => z.string().parse(row.uuid));
595
627
 
596
628
  !isTest() &&
597
629
  console.log(
@@ -599,10 +631,11 @@ export class FixtureManagerClass {
599
631
  `Upserting ${tableName} with ${uuids.length} rows (level ${levels.indexOf(levelFixtures) + 1}/${levels.length})`,
600
632
  ),
601
633
  );
602
- const ids = (await this.builder.upsert(
603
- trx,
604
- tableName as keyof DatabaseSchemaExtend,
605
- )) as (number | string)[];
634
+ // SAFETY: tableName은 등록된 Entity의 실제 테이블명에서만 생성됩니다.
635
+ const schemaTableName = tableName as keyof DatabaseSchemaExtend;
636
+ const ids = fixtureRecordIdsSchema.parse(
637
+ await this.builder.upsert(trx, schemaTableName),
638
+ );
606
639
 
607
640
  // 순서 기반 uuid -> id 매핑
608
641
  // self-reference가 없으므로 등록 순서 = 반환 순서 보장
@@ -734,7 +767,7 @@ export class FixtureManagerClass {
734
767
  insertedIdsByTable?: Map<string, Map<string, number | string>>,
735
768
  ): UBRef {
736
769
  const entity = EntityManager.get(fixture.entityId);
737
- const row: Record<string, unknown> = {};
770
+ const row: UpsertRow = {};
738
771
 
739
772
  // Override 모드 판단: target 또는 unique가 있고 override=true인 경우
740
773
  const existingRecord = fixture.target ?? fixture.unique;
@@ -778,7 +811,7 @@ export class FixtureManagerClass {
778
811
  isBelongsToOneRelationProp(prop) ||
779
812
  (isOneToOneRelationProp(prop) && prop.hasJoinColumn)
780
813
  ) {
781
- const relatedId = column.value as number | null;
814
+ const relatedId = relationIdSchema.parse(column.value);
782
815
  if (relatedId !== null && relatedId !== undefined) {
783
816
  const relatedFixtureId = `${prop.with}#${relatedId}`;
784
817
 
@@ -814,7 +847,7 @@ export class FixtureManagerClass {
814
847
  // HasMany, ManyToMany는 별도 처리
815
848
  } else {
816
849
  // 일반 컬럼
817
- row[propName] = this.convertColumnValue(prop as EntityProp, column.value);
850
+ row[propName] = this.convertColumnValue(prop, column.value);
818
851
  }
819
852
  }
820
853
 
@@ -829,7 +862,10 @@ export class FixtureManagerClass {
829
862
  /**
830
863
  * 컬럼 값 변환
831
864
  */
832
- private convertColumnValue(prop: EntityProp, value: unknown): unknown {
865
+ private convertColumnValue(
866
+ prop: EntityProp,
867
+ value: FixtureRecord["columns"][string]["value"],
868
+ ): DataExplorerValue {
833
869
  if (value === null || value === undefined) {
834
870
  return null;
835
871
  }
@@ -840,8 +876,11 @@ export class FixtureManagerClass {
840
876
  return value;
841
877
 
842
878
  case "date":
843
- if (typeof value === "string" || typeof value === "number") {
844
- return new Date(value);
879
+ {
880
+ const dateSource = z.union([z.string(), z.number()]).safeParse(value);
881
+ if (dateSource.success) {
882
+ return new Date(dateSource.data);
883
+ }
845
884
  }
846
885
  return value;
847
886
 
@@ -874,7 +913,7 @@ export class FixtureManagerClass {
874
913
  const targetTable = EntityManager.get(prop.with);
875
914
  if (!this.builder.hasTable(targetTable.table)) continue;
876
915
 
877
- const relatedIds = column.value as number[];
916
+ const relatedIds = fixtureRecordIdsSchema.parse(column.value);
878
917
  if (relatedIds.length === 0) continue;
879
918
 
880
919
  const joinTable = prop.joinTable;
@@ -974,7 +1013,7 @@ export class FixtureManagerClass {
974
1013
 
975
1014
  // self-reference가 모두 이미 처리됐거나 null인 경우
976
1015
  const canProcess = selfRefProps.every((prop) => {
977
- const refId = fixture.columns[prop.name]?.value as number | null;
1016
+ const refId = relationIdSchema.parse(fixture.columns[prop.name]?.value);
978
1017
  if (refId === null || refId === undefined) return true;
979
1018
  const refFixtureId = `${prop.with}#${refId}`;
980
1019
  // 이미 처리됐거나, 현재 fixtures에 포함되지 않은 경우 (외부 참조)
@@ -1005,9 +1044,9 @@ export class FixtureManagerClass {
1005
1044
  }
1006
1045
 
1007
1046
  private async checkUniqueViolation(db: Knex, entity: Entity, fixture: FixtureRecord) {
1008
- const _uniqueIndexes = entity.indexes?.filter((i) => i.type === "unique") ?? [];
1047
+ const entityUniqueIndexes = entity.indexes?.filter((i) => i.type === "unique") ?? [];
1009
1048
 
1010
- const uniqueIndexes = _uniqueIndexes.filter((index) =>
1049
+ const uniqueIndexes = entityUniqueIndexes.filter((index) =>
1011
1050
  index.columns.every((column) => !column.name.startsWith(`${entity.table}__`)),
1012
1051
  );
1013
1052
  if (uniqueIndexes.length === 0) {
@@ -1059,7 +1098,7 @@ export class FixtureManagerClass {
1059
1098
  return null;
1060
1099
  }
1061
1100
 
1062
- const whereClause: Record<string, unknown> = {};
1101
+ const whereClause: DataExplorerRecord = {};
1063
1102
 
1064
1103
  for (const column of columns) {
1065
1104
  // relation 필드인 경우 _id 붙이기
@@ -1,7 +1,11 @@
1
+ import { z } from "zod";
2
+
1
3
  import { loadConfig } from "../api/config";
2
4
  import { DB } from "../database/db";
3
5
  import { ParallelDBManager } from "./parallel-db-manager";
4
6
 
7
+ const postgresConnectionSchema = z.object({ database: z.string() }).passthrough();
8
+
5
9
  function restoreProcessEnv(snapshot: NodeJS.ProcessEnv): void {
6
10
  for (const key of Object.keys(process.env)) {
7
11
  if (!(key in snapshot)) {
@@ -48,11 +52,11 @@ export function createGlobalSetup() {
48
52
 
49
53
  const maxWorkers = config.test.maxWorkers ?? 4;
50
54
  const dbConfig = DB.generateDBConfig(config.database, config.projectName);
51
- const testConnection = dbConfig.test.connection;
52
- const templateDb = (testConnection as { database: string }).database;
55
+ const testConnection = postgresConnectionSchema.parse(dbConfig.test.connection);
56
+ const templateDb = testConnection.database;
53
57
 
54
58
  const adminConnection = {
55
- ...(testConnection as Record<string, unknown>),
59
+ ...testConnection,
56
60
  database: "postgres",
57
61
  };
58
62
 
@@ -1,10 +1,15 @@
1
1
  export { createBetterAuthRequest } from "../auth/better-auth-request";
2
+ export {
3
+ configureSyncerFilesystem,
4
+ type SyncerFilesystemDependencies,
5
+ } from "../syncer/filesystem-dependencies";
2
6
  export * from "./bootstrap";
3
7
  export * from "./data-explorer";
4
8
  export * from "./dev-vitest-manager";
5
9
  export * from "./fixture-generator";
6
10
  export * from "./fixture-loader";
7
11
  export * from "./fixture-manager";
12
+ export * from "./filesystem";
8
13
  export * from "./global-setup";
9
14
  export * from "./naite-vitest-reporter";
10
15
  export * from "./parallel-db-manager";
@@ -162,7 +162,9 @@ describe("EntityJsonSchema searchText/opclass validation", () => {
162
162
  subsets: validEntity.subsets,
163
163
  enums: validEntity.enums,
164
164
  };
165
- const validResult = TemplateOptions.shape.entity.safeParse(validTemplateEntity);
165
+ const validResult = TemplateOptions.pick({ entity: true }).safeParse({
166
+ entity: validTemplateEntity,
167
+ });
166
168
  expect(validResult.success).toBe(true);
167
169
 
168
170
  const invalidEntity = createBaseEntity();
@@ -180,7 +182,9 @@ describe("EntityJsonSchema searchText/opclass validation", () => {
180
182
  subsets: invalidEntity.subsets,
181
183
  enums: invalidEntity.enums,
182
184
  };
183
- const invalidResult = TemplateOptions.shape.entity.safeParse(invalidTemplateEntity);
185
+ const invalidResult = TemplateOptions.pick({ entity: true }).safeParse({
186
+ entity: invalidTemplateEntity,
187
+ });
184
188
  expect(invalidResult.success).toBe(false);
185
189
  });
186
190
 
@@ -202,7 +206,9 @@ describe("EntityJsonSchema searchText/opclass validation", () => {
202
206
  subsets: customNamedType.subsets,
203
207
  enums: customNamedType.enums,
204
208
  };
205
- const customTemplateResult = TemplateOptions.shape.entity.safeParse(customTemplateEntity);
209
+ const customTemplateResult = TemplateOptions.pick({ entity: true }).safeParse({
210
+ entity: customTemplateEntity,
211
+ });
206
212
  expect(customTemplateResult.success).toBe(true);
207
213
  });
208
214