Files
suaveplan/openspec/archive/2026-05-02-testing-integration-vite-entry-fix/proposal.md
2026-05-27 23:29:53 +01:00

4.9 KiB

Why

Six of the seven testing-integration-* plugin packages have a packaging bug that makes them unimportable from outside their own package. Their package.json declares "exports": { ".": { "import": "./dist/index.js" } }, but their vite.config.ts is missing output.entryFileNames: "[name].js" while still using preserveModules: true. Vite's lib mode then derives the entry filename from the package name (@suaveplan/testing-integration-surrealdb → dist/testing-integration-surrealdb.js), so dist/index.js is never written.

Verified empirically:

Package dist/index.js
testing-integration ✅ PRESENT
testing-integration-garage-s3 ✅ PRESENT
testing-integration-mailpit ❌ MISSING
testing-integration-postgres ❌ MISSING
testing-integration-redis ❌ MISSING
testing-integration-step-ca ❌ MISSING
testing-integration-surrealdb ❌ MISSING
testing-integration-typesense ❌ MISSING

Consequence: any consumer that imports @suaveplan/testing-integration-surrealdb (or the other five) gets Failed to resolve entry for package … The package may have incorrect main/module/exports specified in its package.json. from esbuild/vite/Bun. This is the root cause of the empty consumer list noted in surrealdb-integration-tests — the fixtures are not just unwired, they are unreachable.

The bug ships green from CI today because each package's own unit suite resolves fixture code via relative paths inside src/, never crossing the package boundary; bunx turbo build succeeds because Vite emitting some .js file is enough; and the existing pre-publish gate does not include a "consumer can resolve me" check.

What Changes

vite.config.ts in six packages

Add output.entryFileNames: "[name].js" to the rollupOptions.output block in each of:

  • packages/dev/testing-integration-mailpit/vite.config.ts
  • packages/dev/testing-integration-postgres/vite.config.ts
  • packages/dev/testing-integration-redis/vite.config.ts
  • packages/dev/testing-integration-step-ca/vite.config.ts
  • packages/dev/testing-integration-surrealdb/vite.config.ts
  • packages/dev/testing-integration-typesense/vite.config.ts

After the change, bunx turbo build --filter=@suaveplan/testing-integration-* produces dist/index.js in every package. Output remains ESM-only with preserveModules: true; only the entry filename derivation changes.

testing-integration-garage-s3 already has the fix and testing-integration (core) does not need it (different shape — flat barrel emit). Both are left untouched.

Cross-package resolve smoke test

A new repo-level script scripts/check-fixture-resolves.ts performs a programmatic import("@suaveplan/testing-integration-<name>") for every fixture package and asserts the import does not throw. Wired into the // #check task in turbo.json so the bug cannot regress silently. Equivalent in spirit to a pre-publish smoke test that's faster than running an integration suite.

Out of scope

  • Changing the existing lib.entry shape in any package. The minimum delta is output.entryFileNames.
  • Touching testing-integration-garage-s3 (already correct) or testing-integration (different shape).
  • Wiring any consumer to the now-resolvable fixtures. That is surrealdb-integration-tests and the per-package consumer changes that follow it.
  • Subpath exports (./fixture/*, ./constants). Those resolve correctly today because they reference specific built files.

Capabilities

Modified Capabilities

  • testing-integration-mailpit — adds a packaging requirement that dist/index.js MUST exist after bun run build.
  • testing-integration-postgres — same.
  • testing-integration-redis — same.
  • testing-integration-step-ca — same.
  • testing-integration-surrealdb — same.
  • testing-integration-typesense — same.

(Six identical "main entry resolves" requirements ADDED to the existing capability spec for each package. The repo-level resolve check is captured under a new shared capability testing-integration-resolve-check.)

New Capabilities

  • testing-integration-resolve-check — a repo-level script + turbo gate that imports every testing-integration-* package by its public name and fails CI if any does not resolve.

Impact

  • Affected code: six vite.config.ts files (one line each), scripts/check-fixture-resolves.ts (new, ~40 lines), turbo.json (add the check:fixture-resolves task).
  • Affected consumers: unblocks @suaveplan/database/surrealdb (current surrealdb-integration-tests change) and every future consumer that imports any of the six fixtures.
  • CLAUDE.md / MANIFEST.md: no package added/removed; no manifest regen.
  • Pre-publish gate: unchanged — coverage and lint still pass on the affected packages.
  • Risk: very low. The fix is the same output-filename rewrite that testing-integration-garage-s3 already uses successfully; we are aligning the broken six to it.