@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
@@ -1,22 +1,26 @@
1
- import { pgTable, text, uuid } from "drizzle-orm/pg-core";
2
- import { beforeEach, describe, expect, it, vi } from "vitest";
1
+ import { beforeEach, describe, expect, it, mock } from "bun:test";
2
+ import { table, text, uuid } from "../../db/dialect";
3
3
  import { getStep } from "../define-step";
4
4
  import { buildUnsafeProjectionUpsertStep } from "../steps/unsafe-projection-upsert";
5
5
  import type { PipelineCtx } from "../types/step";
6
6
 
7
- const testTable = pgTable("test_projection", {
7
+ const testTable = table("test_projection", {
8
8
  id: uuid("id").primaryKey().defaultRandom(),
9
9
  tenantId: uuid("tenant_id").notNull(),
10
10
  externalId: text("external_id").notNull().unique(),
11
11
  label: text("label"),
12
12
  });
13
13
 
14
- const mockConflictBuilder = { onConflictDoUpdate: vi.fn() };
15
- const mockValuesBuilder = { values: vi.fn(() => mockConflictBuilder) };
16
- const mockDb = { insert: vi.fn(() => mockValuesBuilder) };
14
+ // New bun-db path: step uses asRawClient(ctx.db.raw).unsafe(sqlText, params).
15
+ // Capture the raw SQL string + params per call instead of the old
16
+ // insert/values/onConflictDoUpdate chain.
17
+ const unsafeMock = mock(async (_sqlText: string, _params: unknown[]) => []);
18
+ const beginMock = mock(async (fn: (tx: unknown) => Promise<unknown>) => fn({}));
19
+ const rawDb = { unsafe: unsafeMock, begin: beginMock };
20
+ const ctxDb = { raw: rawDb };
17
21
 
18
22
  const mockCtx = {
19
- db: mockDb,
23
+ db: ctxDb,
20
24
  event: { type: "test", payload: {} },
21
25
  steps: {},
22
26
  scope: {},
@@ -46,7 +50,7 @@ describe("buildUnsafeProjectionUpsertStep", () => {
46
50
  });
47
51
 
48
52
  it("accepts a function row resolver", () => {
49
- const resolver = vi.fn(() => ({ tenantId: "t1", externalId: "e1" }));
53
+ const resolver = mock(() => ({ tenantId: "t1", externalId: "e1" }));
50
54
  const step = buildUnsafeProjectionUpsertStep({
51
55
  table: testTable,
52
56
  on: ["externalId"],
@@ -67,7 +71,7 @@ describe("buildUnsafeProjectionUpsertStep", () => {
67
71
 
68
72
  describe("unsafeProjectionUpsert run", () => {
69
73
  beforeEach(() => {
70
- vi.clearAllMocks();
74
+ mock.clearAllMocks();
71
75
  });
72
76
 
73
77
  it("throws when a conflict-key column does not exist on the table", async () => {
@@ -92,14 +96,19 @@ describe("unsafeProjectionUpsert run", () => {
92
96
 
93
97
  await stepDef!.run({ table: testTable, on: ["externalId"], row }, mockCtx);
94
98
 
95
- expect(mockDb.insert).toHaveBeenCalledOnce();
96
- expect(mockConflictBuilder.onConflictDoUpdate).toHaveBeenCalledOnce();
97
-
98
- const conflictArgs = mockConflictBuilder.onConflictDoUpdate.mock.calls[0]![0]!;
99
- expect(conflictArgs.set).toEqual({ tenantId: "t1", label: "hello" });
99
+ expect(unsafeMock).toHaveBeenCalledTimes(1);
100
+ const [sqlText, params] = unsafeMock.mock.calls[0]!;
101
+ expect(sqlText).toMatch(/INSERT INTO "test_projection"/);
102
+ expect(sqlText).toMatch(/ON CONFLICT \("external_id"\) DO UPDATE SET/);
103
+ // SET clause excludes the conflict-key column ("external_id") but
104
+ // includes the other columns (tenant_id, label).
105
+ expect(sqlText).toMatch(/"tenant_id" = \$/);
106
+ expect(sqlText).toMatch(/"label" = \$/);
107
+ expect(sqlText).not.toMatch(/"external_id" = \$\d+,/);
108
+ expect(params).toEqual(["t1", "e1", "hello", "t1", "hello"]);
100
109
  });
101
110
 
102
- it("calls insert().onConflictDoUpdate with the resolved row and conflict targets", async () => {
111
+ it("calls INSERT ... ON CONFLICT DO UPDATE with the resolved row + conflict targets", async () => {
103
112
  const stepDef = getStep("unsafeProjectionUpsert");
104
113
 
105
114
  await stepDef!.run(
@@ -111,7 +120,9 @@ describe("unsafeProjectionUpsert run", () => {
111
120
  mockCtx,
112
121
  );
113
122
 
114
- expect(mockDb.insert).toHaveBeenCalled();
115
- expect(mockConflictBuilder.onConflictDoUpdate).toHaveBeenCalled();
123
+ expect(unsafeMock).toHaveBeenCalled();
124
+ const [sqlText] = unsafeMock.mock.calls[0]!;
125
+ expect(sqlText).toMatch(/INSERT INTO "test_projection"/);
126
+ expect(sqlText).toMatch(/ON CONFLICT \("external_id"\) DO UPDATE/);
116
127
  });
117
128
  });
@@ -1,4 +1,4 @@
1
- import { beforeEach, describe, expect, it, vi } from "vitest";
1
+ import { beforeEach, describe, expect, it, mock } from "bun:test";
2
2
  import { getStep } from "../define-step";
3
3
  import {
4
4
  STEP_DISPATCH_AGGREGATE_TYPE,
@@ -7,7 +7,7 @@ import {
7
7
  import { buildWebhookSendStep } from "../steps/webhook-send";
8
8
  import type { PipelineCtx } from "../types/step";
9
9
 
10
- const mockUnsafeAppendEvent = vi.fn();
10
+ const mockUnsafeAppendEvent = mock();
11
11
 
12
12
  const mockCtx = {
13
13
  unsafeAppendEvent: mockUnsafeAppendEvent,
@@ -50,7 +50,7 @@ describe("buildWebhookSendStep", () => {
50
50
 
51
51
  describe("webhook.send run", () => {
52
52
  beforeEach(() => {
53
- vi.clearAllMocks();
53
+ mock.clearAllMocks();
54
54
  });
55
55
 
56
56
  it("appends a step.dispatch-requested system event with the webhook spec", async () => {
@@ -67,7 +67,7 @@ describe("webhook.send run", () => {
67
67
  mockCtx,
68
68
  );
69
69
 
70
- expect(mockUnsafeAppendEvent).toHaveBeenCalledOnce();
70
+ expect(mockUnsafeAppendEvent).toHaveBeenCalledTimes(1);
71
71
  const eventArg = mockUnsafeAppendEvent.mock.calls[0]![0];
72
72
 
73
73
  expect(eventArg.aggregateType).toBe(STEP_DISPATCH_AGGREGATE_TYPE);
@@ -79,8 +79,8 @@ describe("webhook.send run", () => {
79
79
 
80
80
  it("resolves function-based url and body resolvers", async () => {
81
81
  const stepDef = getStep("webhook.send");
82
- const urlFn = vi.fn(() => "https://hooks.example/dynamic");
83
- const bodyFn = vi.fn(() => ({ key: "value" }));
82
+ const urlFn = mock(() => "https://hooks.example/dynamic");
83
+ const bodyFn = mock(() => ({ key: "value" }));
84
84
 
85
85
  await stepDef!.run(
86
86
  {
@@ -1,4 +1,4 @@
1
- import { beforeEach, describe, expect, it, vi } from "vitest";
1
+ import { beforeEach, describe, expect, it, mock } from "bun:test";
2
2
  import { getStep } from "../define-step";
3
3
  import {
4
4
  SUSPEND_SENTINEL,
@@ -11,7 +11,7 @@ import { buildWaitStep } from "../steps/wait";
11
11
  import { buildWaitForEventStep } from "../steps/wait-for-event";
12
12
  import type { PipelineCtx } from "../types/step";
13
13
 
14
- const mockUnsafeAppendEvent = vi.fn();
14
+ const mockUnsafeAppendEvent = mock();
15
15
 
16
16
  const workflowCtx = {
17
17
  unsafeAppendEvent: mockUnsafeAppendEvent,
@@ -46,7 +46,7 @@ describe("buildWaitStep", () => {
46
46
 
47
47
  describe("workflow.wait run", () => {
48
48
  beforeEach(() => {
49
- vi.clearAllMocks();
49
+ mock.clearAllMocks();
50
50
  });
51
51
 
52
52
  it("throws when used outside defineWorkflow (no ctx.workflow)", async () => {
@@ -64,7 +64,7 @@ describe("workflow.wait run", () => {
64
64
  const result = await stepDef!.run({ for: "PT1H" }, workflowCtx);
65
65
 
66
66
  expect(result).toBe(SUSPEND_SENTINEL);
67
- expect(mockUnsafeAppendEvent).toHaveBeenCalledOnce();
67
+ expect(mockUnsafeAppendEvent).toHaveBeenCalledTimes(1);
68
68
  const eventArg = mockUnsafeAppendEvent.mock.calls[0]![0];
69
69
  expect(eventArg.aggregateType).toBe(WORKFLOW_AGGREGATE_TYPE);
70
70
  expect(eventArg.type).toBe(WORKFLOW_WAITING_TYPE);
@@ -108,7 +108,7 @@ describe("buildWaitForEventStep", () => {
108
108
 
109
109
  describe("workflow.waitForEvent run", () => {
110
110
  beforeEach(() => {
111
- vi.clearAllMocks();
111
+ mock.clearAllMocks();
112
112
  });
113
113
 
114
114
  it("throws when used outside defineWorkflow", async () => {
@@ -129,7 +129,7 @@ describe("workflow.waitForEvent run", () => {
129
129
  );
130
130
 
131
131
  expect(result).toBe(SUSPEND_SENTINEL);
132
- expect(mockUnsafeAppendEvent).toHaveBeenCalledOnce();
132
+ expect(mockUnsafeAppendEvent).toHaveBeenCalledTimes(1);
133
133
  const eventArg = mockUnsafeAppendEvent.mock.calls[0]![0];
134
134
  expect(eventArg.aggregateType).toBe(WORKFLOW_AGGREGATE_TYPE);
135
135
  expect(eventArg.type).toBe(WORKFLOW_WAITING_FOR_EVENT_TYPE);
@@ -162,7 +162,7 @@ describe("buildRetryStep", () => {
162
162
 
163
163
  describe("workflow.retry run", () => {
164
164
  beforeEach(() => {
165
- vi.clearAllMocks();
165
+ mock.clearAllMocks();
166
166
  });
167
167
 
168
168
  it("throws when used outside defineWorkflow", async () => {
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test } from "bun:test";
2
2
  import { hasAccess } from "../access";
3
3
  import { createApp } from "../create-app";
4
4
  import { defineFeature } from "../define-feature";
@@ -3,11 +3,10 @@
3
3
  // is included here, plus the self-registration via defineStep({ subPaths })
4
4
  // gate (Followup #15).
5
5
 
6
+ import { describe, expect, it } from "bun:test";
6
7
  import { randomUUID } from "node:crypto";
7
- import { eq } from "drizzle-orm";
8
- import { pgTable, text, uuid } from "drizzle-orm/pg-core";
9
- import { describe, expect, it } from "vitest";
10
8
  import { z } from "zod";
9
+ import { table as pgTable, text, uuid } from "../../db/dialect";
11
10
  import { defineFeature } from "../define-feature";
12
11
  import { defineWriteHandler } from "../define-handler";
13
12
  import { defineStep } from "../define-step";
@@ -117,7 +116,7 @@ describe("validateProjectionAllowlist", () => {
117
116
  perform: pipeline<Record<string, never>, { ok: true }>(({ r }) => [
118
117
  r.step.unsafeProjectionDelete({
119
118
  table: widgetsTable,
120
- where: () => eq(widgetsTable.id, "anything"),
119
+ where: () => ({ id: "anything" }),
121
120
  }),
122
121
  r.step.return({ isSuccess: true as const, data: { ok: true } }),
123
122
  ]),
@@ -140,7 +139,7 @@ describe("validateProjectionAllowlist", () => {
140
139
  perform: pipeline<Record<string, never>, { ok: true }>(({ r }) => [
141
140
  r.step.unsafeProjectionDelete({
142
141
  table: demoLogTable,
143
- where: () => eq(demoLogTable.id, "anything"),
142
+ where: () => ({ id: "anything" }),
144
143
  }),
145
144
  r.step.return({ isSuccess: true as const, data: { ok: true } }),
146
145
  ]),
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test } from "bun:test";
2
2
  import { createEntity, createRegistry, createTextField, defineFeature } from "../index";
3
3
  import type { ValidationError } from "../validation";
4
4
  import { runValidation } from "../validation";
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test } from "bun:test";
2
2
  import { buildTarget, createRegistry, defineFeature } from "../index";
3
3
  import type { TreeChildrenSubscribe, TreeNode } from "../types/tree-node";
4
4
 
@@ -177,7 +177,7 @@ export function validateLocatedTimestamps(feature: FeatureDefinition): void {
177
177
  // in der multi-Variante). Catched at boot, lange bevor drizzle-kit beim
178
178
  // generate-Run zickt.
179
179
  //
180
- // `tenantId` als einzige Spalte ist redundant — buildDrizzleTable legt
180
+ // `tenantId` als einzige Spalte ist redundant — buildEntityTable legt
181
181
  // den Index sowieso automatisch an. Wir lassen die Composite-Form erlaubt
182
182
  // (`["tenantId", "key"]` ist sinnvoll), nur die rein-tenantId-Single-
183
183
  // column-Form blockieren wir.
@@ -225,13 +225,13 @@ export function validateEntityIndexes(feature: FeatureDefinition): void {
225
225
  }
226
226
  }
227
227
  // UNIQUE-constraint auf tenantId ist semantisch (1:1 tenant→entity)
228
- // und NICHT redundant — buildDrizzleTable's auto-Index ist nur ein
228
+ // und NICHT redundant — buildEntityTable's auto-Index ist nur ein
229
229
  // Performance-Hint, kein constraint. Nur die rein-tenantId-Single-
230
230
  // column-non-unique-Form blockieren.
231
231
  if (def.columns.length === 1 && def.columns[0] === "tenantId" && !def.unique) {
232
232
  throw new Error(
233
233
  `${where}: single-column index on "tenantId" is redundant — ` +
234
- `buildDrizzleTable always creates one automatically. Remove this entry.`,
234
+ `buildEntityTable always creates one automatically. Remove this entry.`,
235
235
  );
236
236
  }
237
237
  }
@@ -16,7 +16,7 @@ export function validateOwnershipRules(
16
16
  for (const [entityName, entity] of Object.entries(feature.entities)) {
17
17
  const columnNames = new Set<string>(Object.keys(entity.fields));
18
18
  // Framework-managed columns that rules are allowed to reference too.
19
- // These are the base columns buildDrizzleTable adds unconditionally.
19
+ // These are the base columns buildEntityTable adds unconditionally.
20
20
  const frameworkColumns = ["id", "tenantId", "version", "insertedAt", "modifiedAt"];
21
21
  for (const col of frameworkColumns) columnNames.add(col);
22
22
 
@@ -1,4 +1,3 @@
1
- import type { PgTable } from "drizzle-orm/pg-core";
2
1
  import type { ZodType, z } from "zod";
3
2
  import { toTableName } from "../db/table-builder";
4
3
  import { LifecycleHookTypes } from "./constants";
@@ -759,7 +758,7 @@ export function defineFeature<const TName extends string, TExports = undefined>(
759
758
  httpRoutes[key] = definition;
760
759
  },
761
760
 
762
- rawTable(rawTableName: string, table: PgTable, options: RawTableOptions): void {
761
+ rawTable(rawTableName: string, table: unknown, options: RawTableOptions): void {
763
762
  // Same kebab guard as r.projection / r.screen / r.nav so authoring-time
764
763
  // mistakes surface at the feature file, not deep in registry boot.
765
764
  if (!isKebabSegment(rawTableName)) {
@@ -7,7 +7,7 @@ import {
7
7
  enrichWithReferences,
8
8
  } from "../db/eagerload";
9
9
  import { createEventStoreExecutor, type EventStoreExecutor } from "../db/event-store-executor";
10
- import { buildDrizzleTable } from "../db/table-builder";
10
+ import { buildEntityTable } from "../db/table-builder";
11
11
  import { assertUnreachable } from "../utils";
12
12
  import { buildInsertSchema, buildUpdateSchema } from "./schema-builder";
13
13
  import type { AccessRule, EntityDefinition, QueryHandlerDef, WriteHandlerDef } from "./types";
@@ -133,7 +133,7 @@ export function defineEntityWriteHandler(
133
133
  );
134
134
  }
135
135
 
136
- const table = buildDrizzleTable(entityName, entity);
136
+ const table = buildEntityTable(entityName, entity);
137
137
  const executor = createEventStoreExecutor(table, entity, { entityName });
138
138
 
139
139
  let schema: ZodType;
@@ -182,7 +182,7 @@ export function defineEntityQueryHandler(
182
182
  ): QueryHandlerDef {
183
183
  const { entityName, verb } = parseHandlerName(name, QUERY_VERBS);
184
184
 
185
- const table = buildDrizzleTable(entityName, entity);
185
+ const table = buildEntityTable(entityName, entity);
186
186
  const executor = createEventStoreExecutor(table, entity, { entityName });
187
187
 
188
188
  let schema: ZodType;
@@ -319,14 +319,14 @@ type AnyTable = TableColumns<any>;
319
319
  //
320
320
  // const { table, executor } = createEntityExecutor("counter", counterEntity);
321
321
  //
322
- // Keep using the explicit buildDrizzleTable / createEventStoreExecutor duo
322
+ // Keep using the explicit buildEntityTable / createEventStoreExecutor duo
323
323
  // when you need search-adapter / entity-cache options on the executor — this
324
324
  // helper covers the zero-config case.
325
325
  export function createEntityExecutor(
326
326
  entityName: string,
327
327
  entity: EntityDefinition,
328
328
  ): { readonly table: AnyTable; readonly executor: EventStoreExecutor } {
329
- const table = buildDrizzleTable(entityName, entity);
329
+ const table = buildEntityTable(entityName, entity);
330
330
  const executor = createEventStoreExecutor(table, entity, { entityName });
331
331
  return { table, executor };
332
332
  }
@@ -25,7 +25,7 @@ import type {
25
25
 
26
26
  // Generic über `R extends true | false` (statt `boolean`) damit
27
27
  // `createTextField({ required: true })` literal `required: true` im
28
- // Return-Type behält. `boolean` würde widenen — DrizzleTable<E>'s
28
+ // Return-Type behält. `boolean` würde widenen — EntityTable<E>'s
29
29
  // Mapped-Type könnte dann nicht zwischen `required: true` und
30
30
  // `required: false` dispatchen, jede Column würde zu nullable
31
31
  // degradieren. Default `R = false` matcht den runtime-default. Pattern
@@ -16,8 +16,8 @@
16
16
  // `// kumiko-feature-version: 1` — sodass künftige Format-Bumps
17
17
  // gezielt migriert werden können (separater Migrator pro Version).
18
18
 
19
+ import { describe, expect, test } from "bun:test";
19
20
  import { Project } from "ts-morph";
20
- import { describe, expect, test } from "vitest";
21
21
  import { parseSourceFile } from "../parse";
22
22
 
23
23
  const CANONICAL_FEATURE = `
@@ -7,8 +7,8 @@
7
7
  // That is fine for framework-internal code, but the AI Builder must
8
8
  // NEVER produce code with ParseErrors. This test pins the contract.
9
9
 
10
+ import { describe, expect, test } from "bun:test";
10
11
  import { Project } from "ts-morph";
11
- import { describe, expect, test } from "vitest";
12
12
  import { parseSourceFile } from "../parse";
13
13
 
14
14
  const INLINE_FEATURE = `
@@ -23,8 +23,8 @@
23
23
  // generated features and Designer-authored features will follow the
24
24
  // inline contract by construction.
25
25
 
26
+ import { describe, expect, test } from "bun:test";
26
27
  import { resolve } from "node:path";
27
- import { describe, expect, test } from "vitest";
28
28
  import { parseFeatureFile } from "../parse";
29
29
  import type { FeaturePattern } from "../patterns";
30
30
 
@@ -119,7 +119,7 @@ describe("parseFeatureFile against real Kumiko features", () => {
119
119
  for (const error of result.errors) {
120
120
  expect(error.methodName).toMatch(/^[a-zA-Z]+$/);
121
121
  expect(error.reason.length).toBeGreaterThan(10);
122
- expect(error.source.file).toContain(feature.path.split("/").pop());
122
+ expect(error.source.file as string).toContain(feature.path.split("/").pop()!);
123
123
  expect(error.source.start.line).toBeGreaterThan(0);
124
124
  expect(error.source.raw).toContain("r.");
125
125
  }
@@ -10,8 +10,8 @@
10
10
  // and surfaced as UnknownPattern with the correct methodName, so the
11
11
  // Designer/AI know the call exists.
12
12
 
13
+ import { describe, expect, test } from "bun:test";
13
14
  import { Project } from "ts-morph";
14
- import { describe, expect, test } from "vitest";
15
15
  import { parseSourceFile } from "../parse";
16
16
 
17
17
  function createProject() {
@@ -5,8 +5,8 @@
5
5
  // pinned by parse.test.ts + render-roundtrip.test.ts) so a failure
6
6
  // here narrows the cause to patch.ts itself.
7
7
 
8
+ import { describe, expect, test } from "bun:test";
8
9
  import { Project, type SourceFile } from "ts-morph";
9
- import { describe, expect, test } from "vitest";
10
10
  import { parseSourceFile } from "../parse";
11
11
  import { addPattern, applyChanges, type PatternId, removePattern, replacePattern } from "../patch";
12
12
  import { createFeaturePatcher } from "../patcher";
@@ -8,8 +8,8 @@
8
8
  // arg layout the AI/Designer provides and creates a syntactically valid
9
9
  // pattern.
10
10
 
11
+ import { describe, expect, test } from "bun:test";
11
12
  import { Project, type SourceFile } from "ts-morph";
12
- import { describe, expect, test } from "vitest";
13
13
  import { parseSourceFile } from "../parse";
14
14
  import { createFeaturePatcher } from "../patcher";
15
15
 
@@ -8,8 +8,8 @@
8
8
  // (where the pattern came from) and the rendered file (where it ends
9
9
  // up at canonical positions). We compare every other field.
10
10
 
11
+ import { describe, expect, test } from "bun:test";
11
12
  import { Project } from "ts-morph";
12
- import { describe, expect, test } from "vitest";
13
13
  import { parseSourceFile } from "../parse";
14
14
  import type { FeaturePattern } from "../patterns";
15
15
  import { renderFeatureFile, renderPattern } from "../render";
@@ -7,8 +7,8 @@
7
7
  // AST extractor + the Designer/AI consumers (renderPattern,
8
8
  // getEditability, PATTERN_LIBRARY). Both halves must agree on shape.
9
9
 
10
+ import { describe, expect, test } from "bun:test";
10
11
  import { Project } from "ts-morph";
11
- import { describe, expect, test } from "vitest";
12
12
  import { parseSourceFile } from "../parse";
13
13
  import { getEditability } from "../patterns";
14
14
  import { renderPattern } from "../render";