Skip to content

chore: prep for NestJS 12 (deep-import removal, dual ESM/CJS, Vitest)#509

Open
drieshooghe wants to merge 2 commits into
masterfrom
nestjs-12-prep
Open

chore: prep for NestJS 12 (deep-import removal, dual ESM/CJS, Vitest)#509
drieshooghe wants to merge 2 commits into
masterfrom
nestjs-12-prep

Conversation

@drieshooghe
Copy link
Copy Markdown
Member

Summary

Lays the groundwork so the eventual NestJS 11 → 12 bump becomes a mechanical version-pin change. Validated end-to-end against @nestjs/core@12.0.0-alpha.5 locally (171/171 unit tests green, no config tweaks).

NestJS 12 (targeted Q3 2026 per nestjs/nest#16391) ships all official packages as ESM with strict exports maps and moves the default test runner from Jest to Vitest. Two changes here:

bc042c6 — source-level prep

  • Replace @nestjs/core/injector/* deep imports in packages/core/lib/services/explorer.service.ts with the public DiscoveryService API. Centralize the wrapper type as ProviderWrapper (sourced from DiscoveryService['getProviders']) and route the buses/event-map through it. No remaining deep imports anywhere in source or tests.
  • Dual-publish CJS + ESM from every package: tsup --format cjs,esm --dts, condition-specific exports map with split .d.mts/.d.ts declarations.
  • Add the missing @nestjs/common peer to every integration package (only @nestjs/core was declared).

ef9bc91 — Vitest migration

Jest + @swc/jest can't load ESM-only @nestjs/* without convoluted transformIgnorePatterns. Vitest understands ESM natively, which is where the NestJS toolchain is heading anyway.

  • Drop jest, @swc/jest, @types/jest, jest-mock. Add vitest@^4, @vitest/coverage-v8, unplugin-swc (handles decorator metadata).
  • Shared base at packages/config/vitest/base.mjs; per-package vitest.config.mts extends it. The .mjs/.mts split matters: Vite 7 is ESM-only and a TS base would need a Node-level TS loader — plain .mjs sidesteps that.
  • Move Jest moduleNameMapper aliases to Vite resolve.alias (same regex shapes).
  • 48 spec files converted: jest.fn → vi.fn, jest.spyOn → vi.spyOn, jest.useFakeTimers/useRealTimers → vi.*, jest.Mocked<T> → Mocked<T> (with import type { Mocked } from 'vitest').
  • One stray jest.fn() in packages/testing/e2e/e2e-suite.ts fixed too.
  • "types": ["node", "vitest/globals"] in each package tsconfig so describe/it/expect/vi resolve without per-file imports.
  • Drop the broken test:cov:check script (shell-quoted JSON never worked); threshold enforcement (90/80/90) now lives in the shared vitest config.

Consumer impact

Source-level changes are internal-only — the public EventSourcingModule.forRoot{,Async} / forFeature surface, all decorators, and bus APIs are unchanged. The dual-publish change is purely additive: existing CJS consumers keep getting dist/index.js; ESM consumers now get a native dist/index.mjs instead of CJS-via-interop.

Strategy when v12 GA lands: drop v11, release as @ocoda/event-sourcing v4.0.0.

Test plan

  • pnpm build --filter="./packages/**" — 5/5 packages emit CJS + ESM + dual .d.ts/.d.mts
  • pnpm --filter @ocoda/event-sourcing test — 171/171 tests pass on Vitest 4 (NestJS 11)
  • pnpm --filter @ocoda/event-sourcing test:cov — 96.46% lines / 86.44% branches / 95.83% functions
  • pnpm run ci --filter="./packages/**" — biome clean
  • Smoke test built artifacts: node esm.mjs + node cjs.cjs against dist/index.{mjs,js}
  • NestJS 12.0.0-alpha.5 dry-run with sed-applied peer/dev-dep bumps: install, build, 171/171 tests, coverage, lint all green — reverted before commit, but confirms zero remaining source-level issues for the GA bump
  • Integration suites (mongodb/postgres/dynamodb/mariadb) run in CI via the existing reusable workflow against docker services on both Node 20 + 22

🤖 Generated with Claude Code

drieshooghe and others added 2 commits May 28, 2026 08:12
Replace `@nestjs/core/injector/*` deep imports with the public `DiscoveryService`
API so the lib survives NestJS 12's CJS→ESM transition and stricter `exports`
maps. Centralize the wrapper type as `ProviderWrapper` (sourced from
`DiscoveryService['getProviders']`) and route the buses/event-map through it.

Ship both ESM (`dist/index.mjs`) and CJS (`dist/index.js`) from every
publishable package via tsup, with a condition-specific `exports` map and dual
`.d.mts`/`.d.ts` declarations. Add the missing `@nestjs/common` peer dep on
every integration package.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Jest+@swc/jest can't load ESM-only @nestjs/* packages without convoluted
transformIgnorePatterns. Vitest natively understands ESM, which is where the
NestJS toolchain is heading per the v12 roadmap. This unblocks the v12 bump.

- Drop jest, @swc/jest, @types/jest, jest-mock; add vitest, @vitest/coverage-v8,
  unplugin-swc (handles decorator metadata).
- Replace each packages/*/jest.config.js with vitest.config.mts; shared base
  at packages/config/vitest/base.mjs (.mjs so it loads natively under Node ESM
  alongside Vite 7).
- Move Jest moduleNameMapper aliases to Vite resolve.alias.
- Convert spec files: jest.fn → vi.fn, jest.spyOn → vi.spyOn,
  jest.useFakeTimers/useRealTimers → vi equivalents, jest.Mocked<T> → Mocked<T>
  from 'vitest'.
- packages/testing/e2e/e2e-suite.ts: switch its lone jest.fn() to vi.fn().
- Add "types": ["node", "vitest/globals"] to package tsconfigs so describe/
  it/expect/vi are typed without per-file imports.
- Drop the broken test:cov:check script (shell-quoted JSON never worked);
  threshold enforcement now lives in the shared vitest config.
- Update .npmignore entries from jest.config.js to vitest.config.mts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 28, 2026

⚠️ No Changeset found

Latest commit: ef9bc91

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@codecov
Copy link
Copy Markdown

codecov Bot commented May 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.41%. Comparing base (3dfc123) to head (ef9bc91).
⚠️ Report is 11 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #509      +/-   ##
==========================================
- Coverage   90.93%   90.41%   -0.52%     
==========================================
  Files          98       98              
  Lines        2217     2024     -193     
  Branches      531      529       -2     
==========================================
- Hits         2016     1830     -186     
+ Misses         80       74       -6     
+ Partials      121      120       -1     
Flag Coverage Δ
core 87.51% <100.00%> (-1.82%) ⬇️
integrations 80.88% <ø> (-0.32%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/core/lib/command-bus.ts 92.85% <100.00%> (+2.23%) ⬆️
packages/core/lib/event-bus.ts 90.62% <100.00%> (+3.78%) ⬆️
packages/core/lib/event-map.ts 93.93% <100.00%> (+2.04%) ⬆️
packages/core/lib/query-bus.ts 93.10% <100.00%> (+2.19%) ⬆️
packages/core/lib/services/explorer.service.ts 90.00% <100.00%> (+0.71%) ⬆️

... and 80 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant