@cosmicdrift/kumiko-framework 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/package.json +7 -7
  2. package/src/__tests__/{anonymous-access.integration.ts → anonymous-access.integration.test.ts} +12 -9
  3. package/src/__tests__/{error-contract.integration.ts → error-contract.integration.test.ts} +5 -4
  4. package/src/__tests__/{field-access.integration.ts → field-access.integration.test.ts} +3 -3
  5. package/src/__tests__/{full-stack.integration.ts → full-stack.integration.test.ts} +7 -16
  6. package/src/__tests__/{ownership.integration.ts → ownership.integration.test.ts} +3 -2
  7. package/src/__tests__/{raw-table.integration.ts → raw-table.integration.test.ts} +18 -30
  8. package/src/__tests__/{reference-data.integration.ts → reference-data.integration.test.ts} +24 -11
  9. package/src/__tests__/{transition-guard.integration.ts → transition-guard.integration.test.ts} +12 -10
  10. package/src/api/__tests__/api.test.ts +1 -1
  11. package/src/api/__tests__/auth-middleware-transport.test.ts +1 -1
  12. package/src/api/__tests__/auth-routes-cookie.test.ts +1 -1
  13. package/src/api/__tests__/{batch.integration.ts → batch.integration.test.ts} +30 -30
  14. package/src/api/__tests__/body-limit.test.ts +1 -1
  15. package/src/api/__tests__/csrf-middleware.test.ts +1 -1
  16. package/src/api/__tests__/{dispatcher-live.integration.ts → dispatcher-live.integration.test.ts} +10 -9
  17. package/src/api/__tests__/metrics-endpoint.test.ts +1 -1
  18. package/src/api/__tests__/{nested-write.integration.ts → nested-write.integration.test.ts} +13 -16
  19. package/src/api/__tests__/readiness.test.ts +1 -1
  20. package/src/api/__tests__/request-id-middleware.test.ts +1 -1
  21. package/src/api/__tests__/sse-broker.test.ts +12 -12
  22. package/src/api/__tests__/sse-route.test.ts +1 -1
  23. package/src/api/readiness.ts +2 -2
  24. package/src/auth/__tests__/roles.test.ts +2 -2
  25. package/src/bun-db/__tests__/PATTERN.md +73 -0
  26. package/src/bun-db/__tests__/_helpers.ts +103 -0
  27. package/src/bun-db/__tests__/batch-methods.integration.test.ts +143 -0
  28. package/src/bun-db/__tests__/batch-methods.test.ts +20 -0
  29. package/src/bun-db/__tests__/bun-test-db.ts +19 -0
  30. package/src/bun-db/__tests__/bun-test-stack.ts +6 -0
  31. package/src/bun-db/__tests__/column-types.integration.test.ts +132 -0
  32. package/src/bun-db/__tests__/compound-types.integration.test.ts +134 -0
  33. package/src/bun-db/__tests__/jsonb-edge-cases.integration.test.ts +235 -0
  34. package/src/bun-db/__tests__/smoke.integration.test.ts +43 -0
  35. package/src/bun-db/__tests__/sql-methods.integration.test.ts +231 -0
  36. package/src/bun-db/__tests__/where-patterns.integration.test.ts +185 -0
  37. package/src/bun-db/connection.ts +84 -0
  38. package/src/bun-db/index.ts +31 -0
  39. package/src/bun-db/query.ts +845 -0
  40. package/src/compliance/__tests__/duration-spec.test.ts +1 -1
  41. package/src/compliance/__tests__/profiles.test.ts +1 -1
  42. package/src/compliance/__tests__/sub-processors.test.ts +1 -1
  43. package/src/db/__tests__/{apply-entity-event-tenant.integration.ts → apply-entity-event-tenant.integration.test.ts} +13 -11
  44. package/src/db/__tests__/big-int-field.test.ts +15 -14
  45. package/src/db/__tests__/column-ddl.integration.test.ts +113 -0
  46. package/src/db/__tests__/compound-types.test.ts +1 -1
  47. package/src/db/__tests__/{config-seed.integration.ts → config-seed.integration.test.ts} +32 -27
  48. package/src/db/__tests__/connection-options.test.ts +1 -1
  49. package/src/db/__tests__/dialect-instant.test.ts +1 -1
  50. package/src/db/__tests__/encryption.test.ts +1 -1
  51. package/src/db/__tests__/{drizzle-table-types.test.ts → entity-table-types.test.ts} +16 -16
  52. package/src/db/__tests__/{event-store-executor-list.integration.ts → event-store-executor-list.integration.test.ts} +12 -7
  53. package/src/db/__tests__/{event-store-executor.integration.ts → event-store-executor.integration.test.ts} +19 -12
  54. package/src/db/__tests__/{implicit-projection-equivalence.integration.ts → implicit-projection-equivalence.integration.test.ts} +35 -29
  55. package/src/db/__tests__/located-timestamp.test.ts +1 -1
  56. package/src/db/__tests__/money.test.ts +1 -1
  57. package/src/db/__tests__/{multi-row-insert.integration.ts → multi-row-insert.integration.test.ts} +18 -11
  58. package/src/db/__tests__/parse-auto-verb.test.ts +1 -1
  59. package/src/db/__tests__/{required-not-null-migration-safety.integration.ts → required-not-null-migration-safety.integration.test.ts} +28 -24
  60. package/src/db/__tests__/{schema-migration.integration.ts → schema-migration.integration.test.ts} +32 -28
  61. package/src/db/__tests__/sql-inventory.test.ts +56 -0
  62. package/src/db/__tests__/table-builder-indexes.test.ts +30 -11
  63. package/src/db/__tests__/table-builder-required.test.ts +20 -22
  64. package/src/db/__tests__/{tenant-db.integration.ts → tenant-db.integration.test.ts} +106 -144
  65. package/src/db/__tests__/{unique-violation-mapping.integration.ts → unique-violation-mapping.integration.test.ts} +13 -8
  66. package/src/db/api.ts +46 -0
  67. package/src/db/apply-entity-event.ts +45 -36
  68. package/src/db/assert-exists-in.ts +5 -16
  69. package/src/db/bun-provider.ts +37 -0
  70. package/src/db/config-seed.ts +4 -4
  71. package/src/db/connection.ts +14 -57
  72. package/src/db/cursor.ts +5 -56
  73. package/src/db/dialect.ts +472 -99
  74. package/src/db/eagerload.ts +5 -12
  75. package/src/db/entity-table-meta.ts +390 -0
  76. package/src/db/event-store-executor.ts +158 -100
  77. package/src/db/index.ts +33 -5
  78. package/src/db/migrate-generator.ts +350 -0
  79. package/src/db/migrate-runner.ts +206 -0
  80. package/src/db/postgres-provider.ts +25 -0
  81. package/src/db/queries/entity-read.ts +15 -0
  82. package/src/db/queries/es-ops.ts +17 -0
  83. package/src/db/queries/event-consumer.ts +170 -0
  84. package/src/db/queries/event-store-admin.ts +127 -0
  85. package/src/db/queries/event-store.ts +155 -0
  86. package/src/db/queries/projection-rebuild.ts +59 -0
  87. package/src/db/queries/raw-sql.ts +15 -0
  88. package/src/db/queries/schema-drift.ts +35 -0
  89. package/src/db/queries/seed-context.ts +58 -0
  90. package/src/db/queries/table-ops.ts +11 -0
  91. package/src/db/queries/test-stack.ts +56 -0
  92. package/src/db/query-api.ts +22 -0
  93. package/src/db/query.ts +30 -0
  94. package/src/db/reference-data.ts +19 -22
  95. package/src/db/render-ddl.ts +57 -0
  96. package/src/db/row-helpers.ts +3 -52
  97. package/src/db/schema-inspection.ts +17 -4
  98. package/src/db/sql-inventory.ts +208 -0
  99. package/src/db/table-builder.ts +48 -40
  100. package/src/db/tenant-db.ts +105 -326
  101. package/src/engine/__tests__/auth-claims-registrar.test.ts +1 -1
  102. package/src/engine/__tests__/boot-validator-api-exposure.test.ts +3 -3
  103. package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +1 -1
  104. package/src/engine/__tests__/boot-validator-pii-retention.test.ts +5 -5
  105. package/src/engine/__tests__/boot-validator-s0-integration.test.ts +3 -3
  106. package/src/engine/__tests__/boot-validator.test.ts +4 -3
  107. package/src/engine/__tests__/build-app-schema.test.ts +1 -1
  108. package/src/engine/__tests__/build-target.test.ts +1 -1
  109. package/src/engine/__tests__/claim-keys.test.ts +1 -1
  110. package/src/engine/__tests__/codemod-pipeline.test.ts +3 -3
  111. package/src/engine/__tests__/config-helpers.test.ts +1 -1
  112. package/src/engine/__tests__/effective-features.test.ts +1 -1
  113. package/src/engine/__tests__/engine.test.ts +1 -1
  114. package/src/engine/__tests__/entity-handlers.test.ts +3 -3
  115. package/src/engine/__tests__/event-helpers.test.ts +3 -3
  116. package/src/engine/__tests__/extends-registrar.test.ts +4 -4
  117. package/src/engine/__tests__/factories-long-text.test.ts +1 -1
  118. package/src/engine/__tests__/factories-time.test.ts +1 -1
  119. package/src/engine/__tests__/field-predicates.test.ts +1 -1
  120. package/src/engine/__tests__/hook-phases.test.ts +1 -1
  121. package/src/engine/__tests__/identifiers.test.ts +1 -1
  122. package/src/engine/__tests__/lifecycle-hooks.test.ts +1 -1
  123. package/src/engine/__tests__/nav.test.ts +1 -1
  124. package/src/engine/__tests__/ownership.test.ts +10 -11
  125. package/src/engine/__tests__/parse-ref-target.test.ts +1 -1
  126. package/src/engine/__tests__/pipeline-engine.test.ts +1 -1
  127. package/src/engine/__tests__/{pipeline-handler.integration.ts → pipeline-handler.integration.test.ts} +38 -52
  128. package/src/engine/__tests__/{pipeline-observability.integration.ts → pipeline-observability.integration.test.ts} +1 -1
  129. package/src/engine/__tests__/{pipeline-performance.integration.ts → pipeline-performance.integration.test.ts} +1 -1
  130. package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +1 -1
  131. package/src/engine/__tests__/post-query-hook.test.ts +1 -1
  132. package/src/engine/__tests__/projection-helpers.test.ts +25 -17
  133. package/src/engine/__tests__/projection.test.ts +4 -4
  134. package/src/engine/__tests__/qualified-name.test.ts +1 -1
  135. package/src/engine/__tests__/raw-table.test.ts +9 -8
  136. package/src/engine/__tests__/resolve-config-or-param.test.ts +5 -5
  137. package/src/engine/__tests__/run-in.test.ts +1 -1
  138. package/src/engine/__tests__/schema-builder.test.ts +1 -1
  139. package/src/engine/__tests__/screen.test.ts +1 -1
  140. package/src/engine/__tests__/search-payload-extension.test.ts +3 -3
  141. package/src/engine/__tests__/state-machine.test.ts +1 -1
  142. package/src/engine/__tests__/steps-aggregate-append-event.test.ts +7 -7
  143. package/src/engine/__tests__/steps-aggregate-create.test.ts +4 -4
  144. package/src/engine/__tests__/steps-aggregate-update.test.ts +3 -3
  145. package/src/engine/__tests__/steps-call-feature.test.ts +5 -5
  146. package/src/engine/__tests__/steps-mail-send.test.ts +7 -7
  147. package/src/engine/__tests__/steps-read.test.ts +34 -40
  148. package/src/engine/__tests__/steps-resolver-utils.test.ts +6 -6
  149. package/src/engine/__tests__/steps-unsafe-projection-delete.test.ts +24 -19
  150. package/src/engine/__tests__/steps-unsafe-projection-upsert.test.ts +28 -17
  151. package/src/engine/__tests__/steps-webhook-send.test.ts +6 -6
  152. package/src/engine/__tests__/steps-workflow.test.ts +7 -7
  153. package/src/engine/__tests__/system-user.test.ts +1 -1
  154. package/src/engine/__tests__/validate-projection-allowlist.test.ts +4 -5
  155. package/src/engine/__tests__/validation-hooks.test.ts +1 -1
  156. package/src/engine/__tests__/visual-tree-patterns.test.ts +1 -1
  157. package/src/engine/boot-validator/entity-handler.ts +3 -3
  158. package/src/engine/boot-validator/ownership.ts +1 -1
  159. package/src/engine/define-feature.ts +1 -2
  160. package/src/engine/entity-handlers.ts +5 -5
  161. package/src/engine/factories.ts +1 -1
  162. package/src/engine/feature-ast/__tests__/canonical-form.test.ts +1 -1
  163. package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +1 -1
  164. package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +2 -2
  165. package/src/engine/feature-ast/__tests__/parse.test.ts +1 -1
  166. package/src/engine/feature-ast/__tests__/patch.test.ts +1 -1
  167. package/src/engine/feature-ast/__tests__/patcher.test.ts +1 -1
  168. package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +1 -1
  169. package/src/engine/feature-ast/__tests__/visual-tree-parse.test.ts +1 -1
  170. package/src/engine/ownership.ts +113 -41
  171. package/src/engine/pattern-library/__tests__/library.test.ts +2 -2
  172. package/src/engine/projection-helpers.ts +2 -11
  173. package/src/engine/registry.ts +2 -2
  174. package/src/engine/steps/read-find-many.ts +13 -13
  175. package/src/engine/steps/read-find-one.ts +7 -9
  176. package/src/engine/steps/unsafe-projection-delete.ts +4 -5
  177. package/src/engine/steps/unsafe-projection-upsert.ts +63 -31
  178. package/src/engine/types/feature.ts +7 -2
  179. package/src/engine/types/fields.ts +4 -5
  180. package/src/engine/types/step.ts +10 -10
  181. package/src/engine/validate-projection-allowlist.ts +23 -3
  182. package/src/entrypoint/__tests__/{entrypoint-job-wiring.integration.ts → entrypoint-job-wiring.integration.test.ts} +4 -3
  183. package/src/entrypoint/__tests__/{split-deploy.integration.ts → split-deploy.integration.test.ts} +4 -3
  184. package/src/env/__tests__/compose-env-schema.test.ts +1 -1
  185. package/src/env/__tests__/dry-run.test.ts +1 -1
  186. package/src/errors/__tests__/classes.test.ts +1 -1
  187. package/src/errors/__tests__/write-failures.test.ts +1 -1
  188. package/src/es-ops/__tests__/{context.integration.ts → context.integration.test.ts} +43 -29
  189. package/src/es-ops/__tests__/{runner.integration.ts → runner.integration.test.ts} +25 -23
  190. package/src/es-ops/__tests__/runner.test.ts +29 -19
  191. package/src/es-ops/context.ts +9 -43
  192. package/src/es-ops/operations-schema.ts +2 -2
  193. package/src/es-ops/runner.ts +12 -26
  194. package/src/event-store/__tests__/{admin-api.integration.ts → admin-api.integration.test.ts} +71 -45
  195. package/src/event-store/__tests__/{event-store.integration.ts → event-store.integration.test.ts} +7 -5
  196. package/src/event-store/__tests__/{get-stream-version-perf.integration.ts → get-stream-version-perf.integration.test.ts} +5 -3
  197. package/src/event-store/__tests__/{perf.integration.ts → perf.integration.test.ts} +24 -16
  198. package/src/event-store/__tests__/{snapshot.integration.ts → snapshot.integration.test.ts} +34 -28
  199. package/src/event-store/__tests__/{upcaster-dead-letter.integration.ts → upcaster-dead-letter.integration.test.ts} +11 -12
  200. package/src/event-store/__tests__/{upcaster.integration.ts → upcaster.integration.test.ts} +19 -32
  201. package/src/event-store/admin-api.ts +55 -83
  202. package/src/event-store/archive.ts +15 -39
  203. package/src/event-store/event-store.ts +92 -86
  204. package/src/event-store/events-schema.ts +2 -1
  205. package/src/event-store/index.ts +1 -0
  206. package/src/event-store/snapshot.ts +26 -24
  207. package/src/event-store/upcaster-dead-letter.ts +19 -18
  208. package/src/files/__tests__/content-disposition.test.ts +1 -1
  209. package/src/files/__tests__/{file-field-pipeline.integration.ts → file-field-pipeline.integration.test.ts} +8 -5
  210. package/src/files/__tests__/file-handle.test.ts +1 -1
  211. package/src/files/__tests__/{files.integration.ts → files.integration.test.ts} +32 -17
  212. package/src/files/__tests__/read-stream.test.ts +1 -1
  213. package/src/files/__tests__/{storage-tracking.integration.ts → storage-tracking.integration.test.ts} +26 -30
  214. package/src/files/__tests__/write-stream.test.ts +1 -1
  215. package/src/files/__tests__/zip-stream.test.ts +1 -1
  216. package/src/files/file-ref-table.ts +2 -2
  217. package/src/files/file-routes.ts +7 -9
  218. package/src/files/storage-tracking.ts +9 -17
  219. package/src/i18n/__tests__/i18n.test.ts +1 -1
  220. package/src/jobs/__tests__/{job-event-trigger.integration.ts → job-event-trigger.integration.test.ts} +6 -3
  221. package/src/jobs/__tests__/{job-multi-trigger.integration.ts → job-multi-trigger.integration.test.ts} +6 -3
  222. package/src/jobs/__tests__/{jobs.integration.ts → jobs.integration.test.ts} +5 -7
  223. package/src/lifecycle/__tests__/{lifecycle-server.integration.ts → lifecycle-server.integration.test.ts} +1 -1
  224. package/src/lifecycle/__tests__/lifecycle.test.ts +6 -6
  225. package/src/lifecycle/__tests__/signal-handlers.test.ts +6 -6
  226. package/src/logging/__tests__/pino-trace-bridge.test.ts +1 -1
  227. package/src/migrations/__tests__/compare-snapshots.test.ts +1 -1
  228. package/src/migrations/__tests__/{detect-drift.integration.ts → detect-drift.integration.test.ts} +34 -26
  229. package/src/migrations/__tests__/{detect-projections-to-rebuild.integration.ts → detect-projections-to-rebuild.integration.test.ts} +1 -1
  230. package/src/migrations/__tests__/rebuild-marker.test.ts +1 -1
  231. package/src/migrations/projection-detection.ts +12 -1
  232. package/src/migrations/schema-drift.ts +7 -23
  233. package/src/observability/__tests__/console-provider.test.ts +1 -1
  234. package/src/observability/__tests__/metric-validator.test.ts +1 -1
  235. package/src/observability/__tests__/noop-provider.test.ts +1 -1
  236. package/src/observability/__tests__/{observability.integration.ts → observability.integration.test.ts} +5 -8
  237. package/src/observability/__tests__/prometheus-meter.test.ts +1 -1
  238. package/src/observability/__tests__/recording-meter.test.ts +1 -1
  239. package/src/observability/__tests__/recording-tracer.test.ts +1 -1
  240. package/src/observability/__tests__/sensitive-filter.test.ts +1 -1
  241. package/src/pipeline/__tests__/{archive-stream.integration.ts → archive-stream.integration.test.ts} +3 -3
  242. package/src/pipeline/__tests__/auth-claims-resolver.test.ts +9 -9
  243. package/src/pipeline/__tests__/{cascade-handler.integration.ts → cascade-handler.integration.test.ts} +18 -15
  244. package/src/pipeline/__tests__/cascade-handler.test.ts +1 -1
  245. package/src/pipeline/__tests__/{causation-chain.integration.ts → causation-chain.integration.test.ts} +12 -13
  246. package/src/pipeline/__tests__/{ctx-bridge.integration.ts → ctx-bridge.integration.test.ts} +12 -11
  247. package/src/pipeline/__tests__/dispatcher.test.ts +2 -2
  248. package/src/pipeline/__tests__/{distributed-lock.integration.ts → distributed-lock.integration.test.ts} +1 -1
  249. package/src/pipeline/__tests__/{domain-events-projections.integration.ts → domain-events-projections.integration.test.ts} +13 -15
  250. package/src/pipeline/__tests__/{event-dedup.integration.ts → event-dedup.integration.test.ts} +1 -1
  251. package/src/pipeline/__tests__/{event-define-event-strict.integration.ts → event-define-event-strict.integration.test.ts} +6 -16
  252. package/src/pipeline/__tests__/{event-dispatcher-lifecycle.integration.ts → event-dispatcher-lifecycle.integration.test.ts} +1 -1
  253. package/src/pipeline/__tests__/{event-dispatcher-multi-instance.integration.ts → event-dispatcher-multi-instance.integration.test.ts} +3 -2
  254. package/src/pipeline/__tests__/{event-dispatcher-pg-listen.integration.ts → event-dispatcher-pg-listen.integration.test.ts} +1 -1
  255. package/src/pipeline/__tests__/{event-dispatcher-recovery.integration.ts → event-dispatcher-recovery.integration.test.ts} +2 -2
  256. package/src/pipeline/__tests__/{event-dispatcher-second-audit.integration.ts → event-dispatcher-second-audit.integration.test.ts} +17 -16
  257. package/src/pipeline/__tests__/event-dispatcher-strict.test.ts +14 -12
  258. package/src/pipeline/__tests__/{event-dispatcher.integration.ts → event-dispatcher.integration.test.ts} +8 -15
  259. package/src/pipeline/__tests__/{event-retention.integration.ts → event-retention.integration.test.ts} +28 -25
  260. package/src/pipeline/__tests__/{fetch-for-writing.integration.ts → fetch-for-writing.integration.test.ts} +6 -6
  261. package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +4 -4
  262. package/src/pipeline/__tests__/{load-aggregate-query.integration.ts → load-aggregate-query.integration.test.ts} +9 -5
  263. package/src/pipeline/__tests__/{msp-error-mode.integration.ts → msp-error-mode.integration.test.ts} +1 -1
  264. package/src/pipeline/__tests__/{msp-multi-hop.integration.ts → msp-multi-hop.integration.test.ts} +9 -8
  265. package/src/pipeline/__tests__/{msp-rebuild.integration.ts → msp-rebuild.integration.test.ts} +47 -55
  266. package/src/pipeline/__tests__/{multi-stream-projection.integration.ts → multi-stream-projection.integration.test.ts} +19 -53
  267. package/src/pipeline/__tests__/{perf-rebuild.integration.ts → perf-rebuild.integration.test.ts} +36 -34
  268. package/src/pipeline/__tests__/{post-query-hook.integration.ts → post-query-hook.integration.test.ts} +1 -1
  269. package/src/pipeline/__tests__/{projection-rebuild.integration.ts → projection-rebuild.integration.test.ts} +21 -30
  270. package/src/pipeline/__tests__/{query-projection.integration.ts → query-projection.integration.test.ts} +6 -5
  271. package/src/pipeline/__tests__/{redis-pipeline.integration.ts → redis-pipeline.integration.test.ts} +3 -1
  272. package/src/pipeline/cascade-handler.ts +13 -21
  273. package/src/pipeline/dispatcher.ts +43 -48
  274. package/src/pipeline/event-consumer-state.ts +11 -2
  275. package/src/pipeline/event-dispatcher.ts +86 -146
  276. package/src/pipeline/event-retention.ts +14 -24
  277. package/src/pipeline/msp-rebuild.ts +54 -78
  278. package/src/pipeline/projection-rebuild.ts +65 -67
  279. package/src/pipeline/projection-state.ts +2 -2
  280. package/src/random/__tests__/generate.test.ts +13 -13
  281. package/src/rate-limit/__tests__/{dispatcher-l3.integration.ts → dispatcher-l3.integration.test.ts} +1 -1
  282. package/src/rate-limit/__tests__/{middleware.integration.ts → middleware.integration.test.ts} +1 -1
  283. package/src/rate-limit/__tests__/{resolver.integration.ts → resolver.integration.test.ts} +1 -1
  284. package/src/redis/__tests__/redis-options.test.ts +1 -1
  285. package/src/search/__tests__/{meilisearch-adapter.integration.ts → meilisearch-adapter.integration.test.ts} +1 -1
  286. package/src/search/__tests__/search-adapter.test.ts +1 -1
  287. package/src/secrets/__tests__/dek-cache.test.ts +1 -3
  288. package/src/secrets/__tests__/env-master-key-provider.test.ts +1 -1
  289. package/src/secrets/__tests__/envelope.test.ts +1 -1
  290. package/src/secrets/__tests__/leak-guard.test.ts +1 -1
  291. package/src/secrets/__tests__/rotation.test.ts +1 -1
  292. package/src/stack/db.ts +25 -48
  293. package/src/stack/push-entity-projection-tables.ts +2 -4
  294. package/src/stack/table-helpers.ts +98 -61
  295. package/src/stack/test-stack.ts +8 -7
  296. package/src/testing/__tests__/db-cleanup.test.ts +40 -0
  297. package/src/testing/__tests__/e2e-generator.test.ts +1 -1
  298. package/src/testing/__tests__/{ensure-entity-table.integration.ts → ensure-entity-table.integration.test.ts} +7 -14
  299. package/src/testing/db-cleanup.ts +44 -0
  300. package/src/testing/expect-error.ts +1 -1
  301. package/src/testing/index.ts +2 -0
  302. package/src/testing/multipart-helper.ts +94 -0
  303. package/src/testing/shared-entities.ts +5 -5
  304. package/src/time/__tests__/polyfill.test.ts +1 -1
  305. package/src/time/__tests__/tz-context.test.ts +1 -1
  306. package/src/utils/__tests__/assert.test.ts +1 -1
  307. package/src/utils/__tests__/env-parse.test.ts +1 -1
  308. package/CHANGELOG.md +0 -472
  309. package/src/db/__tests__/cursor.test.ts +0 -41
  310. package/src/db/__tests__/db-helpers.test.ts +0 -369
  311. package/src/db/__tests__/drizzle-helpers.integration.ts +0 -186
  312. package/src/db/__tests__/row-helpers.test.ts +0 -59
  313. package/src/engine/steps/_drizzle-boundary.ts +0 -19
  314. package/src/files/__tests__/file-field-column.integration.ts +0 -103
@@ -5,8 +5,8 @@
5
5
  // Singular/Plural). Der Bug aus dem U5a-Review (`{hours: 6}` fiel auf
6
6
  // 30d-Default) wird hier zentral verhindert.
7
7
 
8
+ import { beforeAll, describe, expect, test } from "bun:test";
8
9
  import { ensureTemporalPolyfill, getTemporal } from "@cosmicdrift/kumiko-framework/time";
9
- import { beforeAll, describe, expect, test } from "vitest";
10
10
  import { addDurationSpec, describeDurationSpec, durationSpecToMs } from "../duration-spec";
11
11
 
12
12
  beforeAll(async () => {
@@ -6,7 +6,7 @@
6
6
  // 3. Deep-merge-Semantik beim Override (rekursiv, Top-Level-Replace nicht)
7
7
  // 4. Override darf einzelne Felder gezielt setzen ohne Required-Drops
8
8
 
9
- import { describe, expect, test } from "vitest";
9
+ import { describe, expect, test } from "bun:test";
10
10
  import { complianceProfileOverrideSchema } from "../override-schema";
11
11
  import {
12
12
  COMPLIANCE_PROFILES,
@@ -4,7 +4,7 @@
4
4
  // oder hinzufuegt ohne dass die DPA/Tenant-Notification-Pipeline das
5
5
  // mitbekommt.
6
6
 
7
- import { describe, expect, test } from "vitest";
7
+ import { describe, expect, test } from "bun:test";
8
8
  import {
9
9
  getActiveSubProcessors,
10
10
  getPlannedSubProcessors,
@@ -15,15 +15,16 @@
15
15
  // zerbrechen — der bestehende seed-Test wäre der einzige Catcher, und
16
16
  // der lief vor dem Refactor durch Zufall grün.
17
17
 
18
- import { eq, sql } from "drizzle-orm";
19
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
18
+ import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
19
+ import { type BunTestDb, createTestDb } from "../../bun-db/__tests__/bun-test-db";
20
+ import { asRawClient, selectMany } from "../../db/query";
20
21
  import { createEntity, createTextField } from "../../engine/factories";
21
22
  import type { TenantId } from "../../engine/types";
22
23
  import type { StoredEvent } from "../../event-store";
23
24
  import { createEventsTable } from "../../event-store";
24
- import { createTestDb, type TestDb } from "../../stack";
25
+ import { ensureTemporalPolyfill } from "../../time/polyfill";
25
26
  import { applyEntityEvent } from "../apply-entity-event";
26
- import { buildDrizzleTable } from "../table-builder";
27
+ import { buildEntityTable } from "../table-builder";
27
28
 
28
29
  const entity = createEntity({
29
30
  table: "read_apply_tenant_check",
@@ -31,14 +32,15 @@ const entity = createEntity({
31
32
  name: createTextField({ required: true }),
32
33
  },
33
34
  });
34
- const table = buildDrizzleTable("apply-tenant-check", entity);
35
+ const table = buildEntityTable("apply-tenant-check", entity);
35
36
 
36
- let testDb: TestDb;
37
+ let testDb: BunTestDb;
37
38
 
38
39
  beforeAll(async () => {
40
+ await ensureTemporalPolyfill();
39
41
  testDb = await createTestDb();
40
42
  await createEventsTable(testDb.db);
41
- await testDb.db.execute(sql`
43
+ await asRawClient(testDb.db).unsafe(`
42
44
  CREATE TABLE read_apply_tenant_check (
43
45
  id uuid PRIMARY KEY,
44
46
  tenant_id uuid NOT NULL,
@@ -57,7 +59,7 @@ afterAll(async () => {
57
59
  });
58
60
 
59
61
  beforeEach(async () => {
60
- await testDb.db.execute(sql`TRUNCATE read_apply_tenant_check`);
62
+ await asRawClient(testDb.db).unsafe(`TRUNCATE read_apply_tenant_check`);
61
63
  });
62
64
 
63
65
  const TENANT_OPERATOR = "11111111-1111-1111-1111-111111111111" as TenantId;
@@ -85,7 +87,7 @@ describe("applyEntityEvent — tenantId-Defaulting", () => {
85
87
  const result = await applyEntityEvent(event, table, entity, testDb.db);
86
88
  expect(result.kind).toBe("applied");
87
89
 
88
- const [row] = await testDb.db.select().from(table).where(eq(table["id"], event.aggregateId));
90
+ const [row] = await selectMany(testDb.db, table, { id: event.aggregateId });
89
91
  expect(row?.["tenantId"]).toBe(TENANT_OPERATOR);
90
92
  expect(row?.["name"]).toBe("without-tenantId-in-payload");
91
93
  });
@@ -101,7 +103,7 @@ describe("applyEntityEvent — tenantId-Defaulting", () => {
101
103
  const result = await applyEntityEvent(event, table, entity, testDb.db);
102
104
  expect(result.kind).toBe("applied");
103
105
 
104
- const [row] = await testDb.db.select().from(table).where(eq(table["id"], event.aggregateId));
106
+ const [row] = await selectMany(testDb.db, table, { id: event.aggregateId });
105
107
  expect(row?.["tenantId"]).toBe(TENANT_TARGET);
106
108
  expect(row?.["tenantId"]).not.toBe(TENANT_OPERATOR);
107
109
  });
@@ -148,7 +150,7 @@ describe("applyEntityEvent — tenantId-Defaulting", () => {
148
150
  const result = await applyEntityEvent(event, table, entity, testDb.db);
149
151
  expect(result.kind).toBe("applied");
150
152
 
151
- const [row] = await testDb.db.select().from(table).where(eq(table["id"], event.aggregateId));
153
+ const [row] = await selectMany(testDb.db, table, { id: event.aggregateId });
152
154
  // event.aggregateId wins, nicht payload.id
153
155
  expect(row?.["id"]).toBe(event.aggregateId);
154
156
  // event.version wins, nicht payload.version
@@ -3,7 +3,7 @@
3
3
  //
4
4
  // Pinst:
5
5
  // - createBigIntField liefert FieldDefinition.type === "bigInt"
6
- // - buildDrizzleTable mappt auf bigint(name, mode:"number"), nicht
6
+ // - buildEntityTable mappt auf bigint(name, mode:"number"), nicht
7
7
  // integer (32-bit) → kein silent 2 GB-Cap
8
8
  // - Zod-Schema akzeptiert int + safe-integer + lehnt non-int + Float
9
9
  // + non-safe-integer ab
@@ -15,19 +15,20 @@
15
15
  // einrichten — pinst dort auf realer Postgres + Drizzle-customType-
16
16
  // Path statt parallel-mock hier.
17
17
 
18
- import { describe, expect, test } from "vitest";
18
+ import { describe, expect, test } from "bun:test";
19
19
  import { createBigIntField, createEntity, createNumberField } from "../../engine";
20
20
  import { buildInsertSchema } from "../../engine/schema-builder";
21
- import { buildDrizzleTable } from "../table-builder";
21
+ import { buildEntityTable } from "../table-builder";
22
22
 
23
- function colByName(table: ReturnType<typeof buildDrizzleTable>, dbName: string) {
24
- for (const col of Object.values(table) as Array<{
25
- name?: string;
26
- notNull?: boolean;
27
- columnType?: string;
28
- dataType?: string;
29
- }>) {
30
- if (col && typeof col === "object" && col.name === dbName) return col;
23
+ function colByName(table: unknown, dbName: string) {
24
+ const cols = (
25
+ table as { columns?: ReadonlyArray<{ name: string; notNull?: boolean; pgType?: string }> }
26
+ ).columns;
27
+ if (!cols) throw new Error("Table has no columns metadata");
28
+ for (const c of cols) {
29
+ if (c.name === dbName) {
30
+ return { name: c.name, notNull: c.notNull, columnType: c.pgType, dataType: c.pgType };
31
+ }
31
32
  }
32
33
  throw new Error(`Column ${dbName} not found in table`);
33
34
  }
@@ -53,7 +54,7 @@ describe("createBigIntField factory", () => {
53
54
  });
54
55
  });
55
56
 
56
- describe("buildDrizzleTable — bigInt-Mapping", () => {
57
+ describe("buildEntityTable — bigInt-Mapping", () => {
57
58
  test("bigInt-Spalte ist DISTINCT von number-Spalte (number=integer/32-bit, bigInt=bigint/64-bit)", () => {
58
59
  const entity = createEntity({
59
60
  fields: {
@@ -61,7 +62,7 @@ describe("buildDrizzleTable — bigInt-Mapping", () => {
61
62
  bigCount: createBigIntField({}),
62
63
  },
63
64
  });
64
- const table = buildDrizzleTable("counters", entity);
65
+ const table = buildEntityTable("counters", entity);
65
66
 
66
67
  const small = colByName(table, "small_count");
67
68
  const big = colByName(table, "big_count");
@@ -79,7 +80,7 @@ describe("buildDrizzleTable — bigInt-Mapping", () => {
79
80
  optionalBig: createBigIntField({}),
80
81
  },
81
82
  });
82
- const table = buildDrizzleTable("t", entity);
83
+ const table = buildEntityTable("t", entity);
83
84
  expect(colByName(table, "required_big").notNull).toBe(true);
84
85
  expect(colByName(table, "optional_big").notNull).toBe(false);
85
86
  });
@@ -0,0 +1,113 @@
1
+ // DDL-Render-Test: alle pgTable Column-Types + Builder-Optionen.
2
+ import { describe, expect, test } from "bun:test";
3
+ import {
4
+ bigint,
5
+ bigserial,
6
+ integer,
7
+ jsonb,
8
+ boolean as pgBoolean,
9
+ table as pgTable,
10
+ serial,
11
+ text,
12
+ timestamp,
13
+ uuid,
14
+ } from "../dialect";
15
+ import { renderTableDdl } from "../render-ddl";
16
+
17
+ function findIndex(ddl: readonly string[], pattern: RegExp): boolean {
18
+ return ddl.some((s) => pattern.test(s));
19
+ }
20
+
21
+ describe("renderTableDdl — column types", () => {
22
+ test("uuid notNull primaryKey defaultRandom", () => {
23
+ const t = pgTable("t_uuid", { id: uuid("id").primaryKey().defaultRandom() });
24
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
25
+ const ddl = renderTableDdl(t as any);
26
+ expect(ddl[0]).toContain('"id" uuid PRIMARY KEY DEFAULT gen_random_uuid()');
27
+ });
28
+
29
+ test("text notNull unique", () => {
30
+ const t = pgTable("t_text", { slug: text("slug").notNull().unique() });
31
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
32
+ const ddl = renderTableDdl(t as any);
33
+ expect(ddl[0]).toContain('"slug" text NOT NULL');
34
+ expect(findIndex(ddl, /UNIQUE INDEX/)).toBe(true);
35
+ });
36
+
37
+ test("integer default", () => {
38
+ const t = pgTable("t_int", { count: integer("count").default(0) });
39
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
40
+ const ddl = renderTableDdl(t as any);
41
+ expect(ddl[0]).toContain('"count" integer DEFAULT 0');
42
+ });
43
+
44
+ test("serial primaryKey", () => {
45
+ const t = pgTable("t_serial", { id: serial("id").primaryKey() });
46
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
47
+ const ddl = renderTableDdl(t as any);
48
+ expect(ddl[0]).toContain('"id" serial PRIMARY KEY');
49
+ });
50
+
51
+ test("bigserial primaryKey", () => {
52
+ const t = pgTable("t_bigserial", { id: bigserial("id").primaryKey() });
53
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
54
+ const ddl = renderTableDdl(t as any);
55
+ expect(ddl[0]).toContain('"id" bigserial PRIMARY KEY');
56
+ });
57
+
58
+ test("bigint notNull", () => {
59
+ const t = pgTable("t_bigint", { amount: bigint("amount").notNull() });
60
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
61
+ const ddl = renderTableDdl(t as any);
62
+ expect(ddl[0]).toContain('"amount" bigint NOT NULL');
63
+ });
64
+
65
+ test("boolean default", () => {
66
+ const t = pgTable("t_bool", { active: pgBoolean("active").default(true) });
67
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
68
+ const ddl = renderTableDdl(t as any);
69
+ expect(ddl[0]).toContain('"active" boolean DEFAULT true');
70
+ });
71
+
72
+ test("jsonb notNull", () => {
73
+ const t = pgTable("t_jsonb", { data: jsonb("data").notNull() });
74
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
75
+ const ddl = renderTableDdl(t as any);
76
+ expect(ddl[0]).toContain('"data" jsonb NOT NULL');
77
+ });
78
+
79
+ test("timestamptz defaultNow", () => {
80
+ const t = pgTable("t_ts", {
81
+ created: timestamp("created", { withTimezone: true }).notNull().defaultNow(),
82
+ });
83
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
84
+ const ddl = renderTableDdl(t as any);
85
+ expect(ddl[0]).toContain('"created" timestamp with time zone DEFAULT now() NOT NULL');
86
+ });
87
+
88
+ test("bigint generatedAlwaysAsIdentity primaryKey", () => {
89
+ const t = pgTable("t_ident", { id: bigint("id").primaryKey().generatedAlwaysAsIdentity() });
90
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
91
+ const ddl = renderTableDdl(t as any);
92
+ expect(ddl[0]).toContain("GENERATED ALWAYS AS IDENTITY");
93
+ expect(ddl[0]).not.toContain("DEFAULT"); // identity replaces default
94
+ });
95
+
96
+ test("composite: multiple columns with various options", () => {
97
+ const t = pgTable("t_composite", {
98
+ pk: bigint("pk").primaryKey().generatedAlwaysAsIdentity(),
99
+ name: text("name").notNull(),
100
+ slug: text("slug").notNull().unique(),
101
+ active: pgBoolean("active").default(true),
102
+ data: jsonb("data"),
103
+ created: timestamp("created", { withTimezone: true }).notNull().defaultNow(),
104
+ });
105
+ // biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
106
+ const ddl = renderTableDdl(t as any);
107
+ expect(ddl[0]).toContain("GENERATED ALWAYS AS IDENTITY");
108
+ expect(ddl[0]).toContain('"name" text NOT NULL');
109
+ expect(ddl[0]).toContain('"active" boolean DEFAULT true');
110
+ expect(ddl[0]).toContain('"data" jsonb');
111
+ expect(findIndex(ddl, /UNIQUE INDEX.*slug/)).toBe(true);
112
+ });
113
+ });
@@ -5,7 +5,7 @@
5
5
  // - Reihenfolge ist deterministisch + Konverter überlappen nicht
6
6
  // - Pure (kein input-mutate)
7
7
 
8
- import { describe, expect, test } from "vitest";
8
+ import { describe, expect, test } from "bun:test";
9
9
  import {
10
10
  createEntity,
11
11
  createLocatedTimestampField,
@@ -1,5 +1,6 @@
1
- import { sql } from "drizzle-orm";
2
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
2
+ import { type BunTestDb, createTestDb } from "../../bun-db/__tests__/bun-test-db";
3
+ import { asRawClient } from "../../db/query";
3
4
  import {
4
5
  createEntity,
5
6
  createSystemConfig,
@@ -9,10 +10,11 @@ import {
9
10
  SYSTEM_TENANT_ID,
10
11
  } from "../../engine";
11
12
  import type { ConfigSeedDef, Registry } from "../../engine/types";
12
- import { createTestDb, type TestDb, unsafeCreateEntityTable } from "../../stack";
13
+ import { unsafeCreateEntityTable } from "../../stack";
14
+ import { ensureTemporalPolyfill } from "../../time/polyfill";
13
15
  import { seedConfigValues } from "../config-seed";
14
16
  import { createEncryptionProvider } from "../encryption";
15
- import { buildDrizzleTable } from "../table-builder";
17
+ import { buildEntityTable } from "../table-builder";
16
18
 
17
19
  // --- Test Entity ---
18
20
  // Mirrors the config-value entity from bundled-features with a unique
@@ -32,7 +34,7 @@ const configEntity = createEntity({
32
34
  },
33
35
  ],
34
36
  });
35
- const configTable = buildDrizzleTable("cfgSeedTest", configEntity);
37
+ const configTable = buildEntityTable("cfgSeedTest", configEntity);
36
38
 
37
39
  // --- Registry Stub ---
38
40
  const KEY_DEFS = {
@@ -53,24 +55,25 @@ const encryption = createEncryptionProvider(
53
55
  Buffer.from("0123456789abcdef0123456789abcdef").toString("base64"),
54
56
  );
55
57
 
56
- let testDb: TestDb;
58
+ let testDb: BunTestDb;
57
59
 
58
60
  async function countRows(): Promise<number> {
59
- const [r] = await testDb.db.execute<{ count: number }>(
60
- sql`SELECT COUNT(*)::int AS count FROM read_cfg_seed_test`,
61
+ const [r] = await asRawClient(testDb.db).unsafe<{ count: number }>(
62
+ `SELECT COUNT(*)::int AS count FROM read_cfg_seed_test`,
61
63
  );
62
64
  return r?.count ?? 0;
63
65
  }
64
66
 
65
67
  async function countEvents(): Promise<number> {
66
- const [r] = await testDb.db.execute<{ count: number }>(
67
- sql`SELECT COUNT(*)::int AS count FROM kumiko_events`,
68
+ const [r] = await asRawClient(testDb.db).unsafe<{ count: number }>(
69
+ `SELECT COUNT(*)::int AS count FROM kumiko_events`,
68
70
  );
69
71
  return r?.count ?? 0;
70
72
  }
71
73
 
72
74
  // --- Setup ---
73
75
  beforeAll(async () => {
76
+ await ensureTemporalPolyfill();
74
77
  testDb = await createTestDb();
75
78
  await unsafeCreateEntityTable(testDb.db, configEntity, "cfgSeedTest");
76
79
  });
@@ -80,7 +83,9 @@ afterAll(async () => {
80
83
  });
81
84
 
82
85
  beforeEach(async () => {
83
- await testDb.db.execute(sql`TRUNCATE kumiko_events, read_cfg_seed_test RESTART IDENTITY CASCADE`);
86
+ await asRawClient(testDb.db).unsafe(
87
+ `TRUNCATE kumiko_events, read_cfg_seed_test RESTART IDENTITY CASCADE`,
88
+ );
84
89
  });
85
90
 
86
91
  // --- Tests ---
@@ -150,8 +155,8 @@ describe("seedConfigValues", () => {
150
155
  expect(result).toEqual({ created: 0, skipped: 1 });
151
156
 
152
157
  // Old value persists
153
- const [row] = await testDb.db.execute<{ value: string }>(
154
- sql`SELECT value FROM read_cfg_seed_test WHERE key = 'test:config:max-upload' LIMIT 1`,
158
+ const [row] = await asRawClient(testDb.db).unsafe<{ value: string }>(
159
+ `SELECT value FROM read_cfg_seed_test WHERE key = 'test:config:max-upload' LIMIT 1`,
155
160
  );
156
161
  expect(row).toBeDefined();
157
162
  expect(JSON.parse(row!.value)).toBe(10);
@@ -168,28 +173,28 @@ describe("seedConfigValues", () => {
168
173
 
169
174
  await seedConfigValues(seeds, configTable, configEntity, mockRegistry, testDb.db);
170
175
 
171
- const rows = await testDb.db.execute<{
176
+ const rows = await asRawClient(testDb.db).unsafe<{
172
177
  key: string;
173
- tenantId: string;
178
+ tenantId: string | null;
174
179
  userId: string | null;
175
180
  }>(
176
- sql`SELECT key, tenant_id AS "tenantId", user_id AS "userId" FROM read_cfg_seed_test ORDER BY key`,
181
+ `SELECT key, tenant_id AS "tenantId", user_id AS "userId" FROM read_cfg_seed_test ORDER BY key`,
177
182
  );
178
183
 
179
- const sys = rows.find((r) => r.key === "test:config:service-url");
180
- const tnt = rows.find((r) => r.key === "test:config:max-upload");
181
- const usr = rows.find((r) => r.key === "test:config:theme");
184
+ const sys = rows.find((r: Record<string, unknown>) => r["key"] === "test:config:service-url");
185
+ const tnt = rows.find((r: Record<string, unknown>) => r["key"] === "test:config:max-upload");
186
+ const usr = rows.find((r: Record<string, unknown>) => r["key"] === "test:config:theme");
182
187
 
183
- expect(sys!.tenantId).toBe(SYSTEM_TENANT_ID);
184
- expect(sys!.userId).toBeNull();
188
+ expect(sys!["tenantId"]).toBe(SYSTEM_TENANT_ID);
189
+ expect(sys!["userId"]).toBeNull();
185
190
 
186
- expect(tnt!.tenantId).toBe(SYSTEM_TENANT_ID);
187
- expect(tnt!.userId).toBeNull();
191
+ expect(tnt!["tenantId"]).toBe(SYSTEM_TENANT_ID);
192
+ expect(tnt!["userId"]).toBeNull();
188
193
 
189
194
  // user-scope seed must live under the user's actual tenantId so the
190
195
  // resolver cascade can match it — never under SYSTEM_TENANT_ID.
191
- expect(usr!.tenantId).toBe(TENANT_A);
192
- expect(usr!.userId).toBe("u-1");
196
+ expect(usr!["tenantId"]).toBe(TENANT_A);
197
+ expect(usr!["userId"]).toBe("u-1");
193
198
  });
194
199
 
195
200
  test("user-scope seed without tenantId throws (would be unreachable)", async () => {
@@ -227,8 +232,8 @@ describe("seedConfigValues", () => {
227
232
  );
228
233
  expect(result).toEqual({ created: 1, skipped: 0 });
229
234
 
230
- const [row] = await testDb.db.execute<{ value: string }>(
231
- sql`SELECT value FROM read_cfg_seed_test WHERE key = 'test:config:stripe-key' LIMIT 1`,
235
+ const [row] = await asRawClient(testDb.db).unsafe<{ value: string }>(
236
+ `SELECT value FROM read_cfg_seed_test WHERE key = 'test:config:stripe-key' LIMIT 1`,
232
237
  );
233
238
  expect(row).toBeDefined();
234
239
  // value column holds ciphertext, never the plain token. The
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test } from "bun:test";
2
2
  import { dbConnectionOptionsFromEnv } from "../connection";
3
3
 
4
4
  // createDbConnection itself opens a real postgres.js socket, so it's
@@ -15,7 +15,7 @@ import { ensureTemporalPolyfill } from "../../time/polyfill";
15
15
 
16
16
  await ensureTemporalPolyfill();
17
17
 
18
- import { describe, expect, test } from "vitest";
18
+ import { describe, expect, test } from "bun:test";
19
19
  import { instantToDriver as toDriver } from "../dialect";
20
20
 
21
21
  describe("instant() customType — toDriver", () => {
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test } from "bun:test";
2
2
  import { createEncryptionProvider } from "../encryption";
3
3
 
4
4
  // 32 bytes base64-encoded for AES-256
@@ -1,5 +1,5 @@
1
- // Type-Tests für DrizzleTable<E>: pinned das vertragliche Verhalten der
2
- // Generic-Inferenz-Pipeline createEntity → buildDrizzleTable. Wenn ein
1
+ // Type-Tests für EntityTable<E>: pinned das vertragliche Verhalten der
2
+ // Generic-Inferenz-Pipeline createEntity → buildEntityTable. Wenn ein
3
3
  // Branch in `fieldToColumns` driftet aber `ColumnsForField` im Type-
4
4
  // System nicht mitkommt (oder umgekehrt), schlagen diese Tests fehl
5
5
  // BEVOR ein Consumer in den Wald läuft.
@@ -8,7 +8,7 @@
8
8
  // repräsentative Fälle: required-Literal, required-Default, money-Pair,
9
9
  // locatedTimestamp-Pair, multiSelect-jsonb-default, idType-Variation.
10
10
 
11
- import { describe, expect, expectTypeOf, test } from "vitest";
11
+ import { describe, expect, expectTypeOf, test } from "bun:test";
12
12
  import {
13
13
  createBooleanField,
14
14
  createDateField,
@@ -22,9 +22,9 @@ import {
22
22
  createTimestampField,
23
23
  createTzField,
24
24
  } from "../../engine";
25
- import { buildDrizzleTable } from "../table-builder";
25
+ import { buildEntityTable } from "../table-builder";
26
26
 
27
- describe("DrizzleTable<E> — Property-Names existieren", () => {
27
+ describe("EntityTable<E> — Property-Names existieren", () => {
28
28
  const sampleEntity = createEntity({
29
29
  table: "x",
30
30
  fields: {
@@ -33,7 +33,7 @@ describe("DrizzleTable<E> — Property-Names existieren", () => {
33
33
  priority: createSelectField({ options: ["low", "high"] as const }),
34
34
  },
35
35
  });
36
- const t = buildDrizzleTable("sample", sampleEntity);
36
+ const t = buildEntityTable("sample", sampleEntity);
37
37
 
38
38
  test("base-columns sind getypt", () => {
39
39
  expectTypeOf(t.id).not.toBeNever();
@@ -61,7 +61,7 @@ describe("DrizzleTable<E> — Property-Names existieren", () => {
61
61
  });
62
62
  });
63
63
 
64
- describe("DrizzleTable<E> — Money produces two columns", () => {
64
+ describe("EntityTable<E> — Money produces two columns", () => {
65
65
  const ent = createEntity({
66
66
  table: "invoice",
67
67
  fields: {
@@ -69,7 +69,7 @@ describe("DrizzleTable<E> — Money produces two columns", () => {
69
69
  shipping: createMoneyField(),
70
70
  },
71
71
  });
72
- const t = buildDrizzleTable("invoice", ent);
72
+ const t = buildEntityTable("invoice", ent);
73
73
 
74
74
  test("money-amount column existiert", () => {
75
75
  expectTypeOf(t.amount).not.toBeNever();
@@ -82,14 +82,14 @@ describe("DrizzleTable<E> — Money produces two columns", () => {
82
82
  });
83
83
  });
84
84
 
85
- describe("DrizzleTable<E> — locatedTimestamp produces Utc + Tz", () => {
85
+ describe("EntityTable<E> — locatedTimestamp produces Utc + Tz", () => {
86
86
  const ent = createEntity({
87
87
  table: "delivery",
88
88
  fields: {
89
89
  pickup: createLocatedTimestampField({ required: true }),
90
90
  },
91
91
  });
92
- const t = buildDrizzleTable("delivery", ent);
92
+ const t = buildEntityTable("delivery", ent);
93
93
 
94
94
  test("Utc und Tz Spalten existieren", () => {
95
95
  expectTypeOf(t.pickupUtc).not.toBeNever();
@@ -104,7 +104,7 @@ describe("DrizzleTable<E> — locatedTimestamp produces Utc + Tz", () => {
104
104
  });
105
105
  });
106
106
 
107
- describe("DrizzleTable<E> — files/images produzieren keine columns", () => {
107
+ describe("EntityTable<E> — files/images produzieren keine columns", () => {
108
108
  // files/images werden über fileRefsTable resolved, nicht in der entity-table.
109
109
  // Ein Type-Test der das pinnt würde createFilesField verlangen — wir lassen
110
110
  // das hier weg, weil das Authoring-Pattern "createXField" ohne file-helper
@@ -115,7 +115,7 @@ describe("DrizzleTable<E> — files/images produzieren keine columns", () => {
115
115
  });
116
116
  });
117
117
 
118
- describe("DrizzleTable<E> — verschiedene Feld-Typen existieren", () => {
118
+ describe("EntityTable<E> — verschiedene Feld-Typen existieren", () => {
119
119
  const ent = createEntity({
120
120
  table: "many",
121
121
  fields: {
@@ -127,7 +127,7 @@ describe("DrizzleTable<E> — verschiedene Feld-Typen existieren", () => {
127
127
  tags: createMultiSelectField({ options: ["a", "b"] as const }),
128
128
  },
129
129
  });
130
- const t = buildDrizzleTable("many", ent);
130
+ const t = buildEntityTable("many", ent);
131
131
 
132
132
  test("alle Felder als columns sichtbar", () => {
133
133
  expectTypeOf(t.txt).not.toBeNever();
@@ -139,7 +139,7 @@ describe("DrizzleTable<E> — verschiedene Feld-Typen existieren", () => {
139
139
  });
140
140
  });
141
141
 
142
- describe("DrizzleTable<E> — idType wirkt", () => {
142
+ describe("EntityTable<E> — idType wirkt", () => {
143
143
  const uuidEnt = createEntity({
144
144
  table: "uuid_ent",
145
145
  fields: { name: createTextField() },
@@ -150,8 +150,8 @@ describe("DrizzleTable<E> — idType wirkt", () => {
150
150
  fields: { name: createTextField() },
151
151
  idType: "serial",
152
152
  });
153
- const tu = buildDrizzleTable("uuid_ent", uuidEnt);
154
- const ts = buildDrizzleTable("serial_ent", serialEnt);
153
+ const tu = buildEntityTable("uuid_ent", uuidEnt);
154
+ const ts = buildEntityTable("serial_ent", serialEnt);
155
155
 
156
156
  test("uuid-Entity exposed id existiert", () => {
157
157
  expectTypeOf(tu.id).not.toBeNever();
@@ -4,13 +4,15 @@
4
4
  // items-create.integration im Showcase abgedeckt — nicht ausreichend
5
5
  // für Framework-Code der von jeder App genutzt wird.
6
6
 
7
- import { sql } from "drizzle-orm";
8
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
7
+ import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
8
+ import { type BunTestDb, createTestDb } from "../../bun-db/__tests__/bun-test-db";
9
+ import { asRawClient } from "../../db/query";
9
10
  import { createEntity, createNumberField, createTextField } from "../../engine";
10
11
  import { createEventsTable } from "../../event-store";
11
- import { createTestDb, type TestDb, TestUsers, unsafeCreateEntityTable } from "../../stack";
12
+ import { TestUsers, unsafeCreateEntityTable } from "../../stack";
13
+ import { ensureTemporalPolyfill } from "../../time/polyfill";
12
14
  import { createEventStoreExecutor } from "../event-store-executor";
13
- import { buildDrizzleTable } from "../table-builder";
15
+ import { buildEntityTable } from "../table-builder";
14
16
  import { createTenantDb, type TenantDb } from "../tenant-db";
15
17
 
16
18
  const entity = createEntity({
@@ -20,13 +22,14 @@ const entity = createEntity({
20
22
  rank: createNumberField({ sortable: true }),
21
23
  },
22
24
  });
23
- const table = buildDrizzleTable("pagerItem", entity);
25
+ const table = buildEntityTable("pagerItem", entity);
24
26
 
25
- let testDb: TestDb;
27
+ let testDb: BunTestDb;
26
28
  let tdb: TenantDb;
27
29
  const admin = TestUsers.admin;
28
30
 
29
31
  beforeAll(async () => {
32
+ await ensureTemporalPolyfill();
30
33
  testDb = await createTestDb();
31
34
  await unsafeCreateEntityTable(testDb.db, entity, "pagerItem");
32
35
  await createEventsTable(testDb.db);
@@ -38,7 +41,9 @@ afterAll(async () => {
38
41
  });
39
42
 
40
43
  beforeEach(async () => {
41
- await testDb.db.execute(sql`TRUNCATE kumiko_events, read_pager_items RESTART IDENTITY CASCADE`);
44
+ await asRawClient(testDb.db).unsafe(
45
+ `TRUNCATE kumiko_events, read_pager_items RESTART IDENTITY CASCADE`,
46
+ );
42
47
  });
43
48
 
44
49
  describe("event-store-executor.list — offset + totalCount (Tier 2.6d)", () => {