21 Commits

Author SHA1 Message Date
James Anderson d03c5aa045 test(msw): introduce MSW infrastructure and migrate font-google-build (#1444)
* test(msw): introduce MSW infrastructure and migrate font-google-build

Replaces ad-hoc `globalThis.fetch` hijacking in tests with Mock Service
Worker. MSW intercepts both `globalThis.fetch` and `node:http`/`https`,
so it covers fetches issued by in-process Vite servers and fixture pages
without each test having to manage its own stub.

The setup file enables `onUnhandledRequest: 'error'` so any future test
that issues an unmocked external request fails loudly instead of
silently hitting the network. Loopback hostnames (localhost, 127.0.0.1,
::1) are bypassed because the integration project deliberately hits
in-process test servers via fetch.

What this PR contains:
- `tests/_msw/{handlers,server,setup}.ts` — shared infra
- `setupFiles` wired into both vitest projects (unit + integration)
- `msw` + `@mswjs/interceptors` added to the workspace catalog
- `msw` postinstall skipped via `allowBuilds` (it only copies a browser
  service worker; we exclusively use `msw/node`)
- `tests/font-google-build.test.ts` migrated as the proof of pattern

Temporary handlers for `httpbin.org/uuid` and
`example.com/not-cacheable` keep the existing fixture pages
(`revalidate-tag-test`, `dynamic-error-fetch`) working under the new
guard. These are placeholders flagged with `TODO(msw-migration)` — a
follow-up will replace those live URLs with test-local endpoints.

This is PR 1 of 3:
- PR 2 will migrate `tests/fetch-cache.test.ts`
- PR 3 will migrate `tests/font-google.test.ts` and the font block in
  `tests/app-router.test.ts`

* test(msw): restrict MSW to the unit project + use passthrough for loopback

Two fixes to the initial MSW wiring that surfaced when CI ran the full
suite:

1. The integration project is now excluded from MSW. Integration tests
   spin up in-process HTTP servers and fixture dev servers and exercise
   them via `fetch("http://127.0.0.1:<port>/...")`. Even with a loopback
   `passthrough()` handler installed, the @mswjs/interceptors layer
   interferes with that traffic in subtle ways:

   - `tests/prerender.test.ts > errors without writing .rsc when the
     middleware short-circuit fallback RSC request fails` timed out at
     30s — the 5xx response body never reached the caller.
   - `tests/ecosystem.test.ts > nuqs` hung in `beforeAll` waiting for
     its fixture process to come up, because the readiness fetch
     stalled inside the interceptor.

   Integration tests already talk to real local servers, not the
   internet, so the unhandled-request guard buys little there. The
   value of MSW for this repo is mocking external HTTP for unit tests
   of fetch wrappers (font-google, font-google-build, fetch-cache),
   which is preserved.

2. The `onUnhandledRequest` callback in `setup.ts` that tried to
   silently let loopback through wasn't sufficient — MSW's interceptor
   still ran for those requests and could stall them. Replaced with a
   default `http.all(LOOPBACK_URL_PATTERN, () => passthrough())`
   handler in `handlers.ts` and a plain `onUnhandledRequest: "error"`
   in `setup.ts`. Unit tests like the middleware-rewrite proxy in
   `tests/shims.test.ts` and the JSX-in-JS suite need this to keep
   their in-process HTTP servers reachable.

* test(msw): address BigBonk review notes

- Update PR description in the commit body to drop the stale mention of
  TODO(msw-migration) handlers — they were removed when the integration
  project was excluded from MSW; the fixture pages run there.
- Tighten the loopback IPv4 octet regex from `\d+` to `\d{1,3}` so it
  doesn't match absurdly long octet strings. `URL.hostname` normalises
  real addresses, so this is purely a readability fix.

* test(msw): address remaining BigBonk notes from the initial review

- Add `0.0.0.0` to the loopback passthrough pattern so test servers that
  bind to the unspecified address keep working without per-test mocks.
- Add a `TODO(msw-3)` comment in `server.ts` flagging the
  `SetupServerApi` deprecation in MSW 2.14.6 — the `FetchInterceptor`-only
  construction will need to migrate to `defineNetwork`'s interceptor
  config when we bump to MSW 3.

Both raised by BigBonk on the first review of this PR (the second review
focused on the stale description and the loose `\d+` octet bound, which
were addressed in the previous commit).

* test(msw): scope server.use() inside the try block in font-google-build

Minor structural fix from BigBonk's review: moves the `server.use()`
handler registration inside the `try` block so all setup and the
matching `fs.unlink` cleanup share the same try/finally scope.

No behaviour change — `server.use()` is synchronous and infallible, so
this is purely a structural tidy-up.

* test(msw): correct comment in font-google-build to match interceptor config

BigBonk caught that the comment described the default `setupServer()`
behaviour (which uses both `FetchInterceptor` and `ClientRequestInterceptor`),
but this project's `server.ts` deliberately constructs `SetupServerApi`
with only `FetchInterceptor`. Update the comment to reflect that — it
intercepts `globalThis.fetch`, not `node:http`/`node:https`.

No code change, comment only.
2026-05-22 13:03:08 +00:00
James Anderson a27193fcaf chore: upgrade pnpm 10 to 11 and enable frozenLockfile (#1185)
* chore: upgrade pnpm 10 to 11 and enable frozenLockfile

- Bump packageManager from pnpm@10.32.1 to pnpm@11.1.1
- Migrate .npmrc settings to pnpm-workspace.yaml (pnpm 11 only reads auth/registry from .npmrc)
  - auto-install-peers=false -> autoInstallPeers: false
  - Remove playground save-exact=true (minor pnpm add preference, not needed for builds)
- Convert onlyBuiltDependencies list to allowBuilds map (pnpm 11 format)
- Add frozenLockfile: true and preferFrozenLockfile: true
- Delete .npmrc files (contained no auth settings)

* fix: handle pnpm 11 strictDepBuilds, preserve autoInstallPeers, remove minimumReleaseAgeExclude

- Add unrs-resolver: false to allowBuilds (reviewed, deny build scripts)
- Keep autoInstallPeers: false to match existing lockfile
- Remove minimumReleaseAgeExclude entirely
- Append allowBuilds to scaffolded project's pnpm-workspace.yaml after
  create-next-app so subsequent pnpm steps don't abort
2026-05-13 09:15:02 +00:00
James Anderson 0c4e528554 chore: build vinext on postinstall (#1159) 2026-05-11 09:46:31 +01:00
James Anderson c1c81886d2 test: add coverage summaries for integration tests in ci (#1024) 2026-05-02 21:17:27 +00:00
Nathan Nguyen 1d7c031e30 feat(app-router): feed file metadata routes into head output (#891) 2026-04-30 19:38:32 +01:00
James Anderson ff5e14c41d setup knip (#886)
* setup knip

* nits
2026-04-24 21:30:57 +01:00
James Anderson f8a28fdfe2 chore: add scripts to run unit + integration tests (#712) 2026-03-29 16:20:23 +00:00
Stephen Zhou fd7618c94a chore: move pnpm settings to pnpm-workspace.yaml (#671) 2026-03-23 09:47:39 +00:00
Steve Faulkner 47fec0c871 chore: upgrade vitest to v4 and enable agent reporter (#612)
* chore: bump pnpm to 10.32.1 and enable vitest agent reporter

* chore: upgrade GitHub Actions to Node 24 compatible versions

* perf: re-land unit/integration split and add CI sharding

- Restore unit/integration vitest project split (lost in vp migration)
- vitest 4 supports fileParallelism per-project (was global-only in v3),
  so unit tests now run in parallel (~11s) while integration stays serial
- Add 3-shard matrix for integration tests in CI, cutting wall time from
  ~4.5min to ~1.5min
- Move kv-cache-handler to integration to avoid flakiness under parallelism

* chore: remove unused deploy-preview slash command workflow

* ci: add sentinel job for stable branch protection rule
2026-03-20 16:20:42 -05:00
Stephen Zhou 25f6e0fc87 chore: enable typeAware and typeCheck, use vp check (#551)
* chore: enable typeAware and typeCheck, use vp check

* Build

* Try cache false

* Revert "Try cache false"

This reverts commit 5f76ed02f1.

* Update

* workaround for vp check

* Try no workaround

* Fix check

* Update to 0.1.12

* denyWarnings
2026-03-16 11:00:47 -05:00
Stephen Zhou c17d6941be chore: migrate to vite plus (#535)
* chore: migrate to vite plus

* Disable typeAware and typeCheck

* Update CI

* Fix CI

* Fix test

* Clean

* Run test with vp

* Try revert

* react: false In test

* Fix test

* Revert "Try revert"

This reverts commit 009da10473.

* Update

* Update

* Try revert ci changes

* revert

* Run vp migrate

* Disable typeAware and typeCheck for now

* Better resolve for test

* Use vp dev instead of vite

* Update expect

* Fix NormalizeManifestModuleId

* Try increase timeout

* Update to use vp

* Try new check

* Bring back npx vp

* Migrate CI

* Make next-intl resolvable

* Update

* Update

* Update
2026-03-15 10:50:13 +00:00
Stephen Zhou 20285ccb83 chore: move to pnpm catalogs (#531) 2026-03-13 17:14:35 +00:00
James Anderson 735a443169 chore: upgrade vitest to 4.1 (#512)
* chore: upgrade vitest to 4.1

* fix: clear console.warn spy state before asserting call counts

Vitest 4 changed vi.spyOn to return the same mock when called on an
already-intercepted function. This means console.warn call records from
earlier tests accumulate in the spy, causing toHaveBeenCalledTimes(2) to
see 4 calls instead of 2.

Adding mockClear() after each spy creation resets the call count so the
assertions only reflect calls made within the test itself.
2026-03-13 05:53:39 +00:00
Divanshu Chauhan (divkix) 488fb350d4 fix: pin Rollup to patched version for CVE-2026-27606 (#476) 2026-03-11 18:03:57 +00:00
James Anderson 764a496ce7 add oxfmt formatter (#380)
* add oxfmt formatter: config, scripts, CI, editor setup, docs

* rebuild lockfile

* fix: add Format to required checks list, remove dead ignore pattern

* run fmt

* add format to agents.md again
2026-03-09 14:56:14 +00:00
Stephen Zhou d00e126eb1 fix: align next/constants shim (#58)
* fix: align next/constants shim

* update

* test

* update

* Update lock

---------

Co-authored-by: Steve Faulkner <sfaulkner@cloudflare.com>
2026-03-08 19:06:54 +00:00
Stephen Zhou c0bc16c549 fix: export all google font (#57) 2026-02-28 21:35:54 +00:00
Steve Faulkner 75703d3b72 Align Pages Router worker entry with prod-server request handling (#171)
* Skip deploy previews for fork PRs that lack Cloudflare secrets

Fork PRs don't have access to repository secrets (CLOUDFLARE_API_TOKEN,
CLOUDFLARE_ACCOUNT_ID), so deploy/smoke-test/comment steps always fail.
Add a fork detection condition to skip these steps gracefully. The build
steps still run, so example builds are still validated for fork PRs.

* fix: align Pages Router worker entry with prod-server request handling

The generated Cloudflare Worker entry for Pages Router apps was missing
several request handling steps that the Node.js production server
(prod-server.ts) already handled. This brings the two in sync:

- Run middleware (runMiddleware) before routing
- Apply next.config.js redirects, rewrites (before/after/fallback), and headers
- Handle basePath stripping and trailing slash normalization
- Merge middleware response headers with correct precedence
- Guard renderPage with typeof check

Also updates the two Pages Router examples (pages-router-cloudflare,
realworld-api-rest) and exports vinext/config/config-matchers so the
worker entry can import the shared matching utilities.

* chore: sync pnpm-lock.yaml with upstream package.json changes
2026-02-27 13:01:34 -06:00
ubugeeei 2c650ec089 feat: type aware linting with tsgolint (#38) 2026-02-27 07:37:12 +00:00
Steve Faulkner a151f3da6b chore: upgrade vitest from v3 to v4 (#65)
No breaking changes affect this project — config and test code
required no modifications.
2026-02-25 22:17:48 +00:00
Steve Faulkner 12fea722b6 Initial public release of vinext 2026-02-24 09:29:39 -06:00