9 Commits

Author SHA1 Message Date
James Anderson 9cec92beaa refactor: migrate ssrLoadModule to moduleRunner.import (#570)
* refactor: migrate ssrLoadModule to moduleRunner.import

Replace all server.ssrLoadModule() calls in dev-server.ts and api-handler.ts
with runner.import() via the ModuleImporter interface, following the Vite
Module Runner migration guide. Remove ssrFixStacktrace calls which are not
needed with Module Runner APIs. Update call sites in index.ts to pass the
existing getPagesRunner() lazy factory as the runner argument. Update tests
to use ModuleImporter-shaped mocks instead of the old ViteDevServer mock.

* refactor: address bonk review comments

- Fix misleading stack trace comments: ssrFixStacktrace is not applicable
  to ModuleRunner (not that it rewrites automatically)
- Update ALS-ARCHITECTURE.md to reference runner.import() instead of
  server.ssrLoadModule()
- Add importModule() typed helper to instrumentation.ts to centralise
  the Record<string, any> cast, removing 12 inline eslint-disable comments
- Remove dead ssrLoadModule mock from pages-router ISR test (createSSRHandler
  no longer calls server.ssrLoadModule)
2026-03-17 14:23:20 +00: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
Jared Stowell f360380112 fix: Pages API body parser for invalid JSON and repeated form keys (#446)
* Fix Pages API parsing parity

* Fix Pages API body parsing parity

* Fix empty form body parity

* Regenerate entry-templates snapshots after merge

* fix: propagate statusText through prod server sendCompressed non-compressed path

The sendCompressed function had a statusText parameter but only used it in
the compressed response path. The non-compressed else branch called
res.writeHead directly without forwarding statusText, so short error
responses (like 'Invalid JSON' at 12 bytes, well below COMPRESS_THRESHOLD)
lost their custom reason phrase and fell back to the default 'Bad Request'.

Fix: replace the direct res.writeHead call in the else branch with the
writeHead closure that already handles the statusText conditional.

Also set statusText on the ApiBodyParseError response in the pages server
entry template so the value is present for prod-server to forward.

---------

Co-authored-by: James <james@eli.cx>
2026-03-11 13:24:36 +00:00
Jared Stowell 3b982066d0 fix: align Pages API body parsing and res.send(Buffer) (#428)
* Fix Buffer handling in Pages API res

* fix: skip reporting handled Pages API parse errors

* address review: blank line nit, content-length parity for Buffer, fix duplicate Content-Length in sendCompressed

* fix: set content-length for Buffer in production res.send() to match dev parity

---------

Co-authored-by: James <james@eli.cx>
2026-03-11 11:16:51 +00:00
Jared Stowell ec1b9da131 fix: preserve Pages Router query arrays and hash in asPath (#421)
* Handle array query params

* Fix router query merge order
2026-03-10 22:17:36 +00:00
Nathan Nguyen 0b63ad5237 perf: pre-split route patterns and hoist URL split out of match loop (#396)
* perf: pre-split route patterns and hoist URL split out of match loop

Route matching runs on every request and iterates all routes until a
match is found. Previously, matchPattern() re-split both the URL and
the pattern string on every iteration:

  for (const route of routes) {
    // url.split("/") — same URL, re-split every iteration
    // pattern.split("/") — pattern never pre-computed
    matchPattern(normalizedUrl, route.pattern);
  }

For a 50-route app on a 404, that's 50 URL splits + 50 pattern splits
+ 50 Object.create(null) + 100 .filter(Boolean) calls.

Fix:
- Add `patternParts: string[]` to Route and AppRoute interfaces,
  computed once at scan time
- Split the URL once in matchRoute/matchAppRoute before the loop
- Pass pre-split arrays to matchPattern instead of raw strings
- Apply the same optimization to generated production entries
  (pages-server-entry.ts, app-rsc-entry.ts)
- Fix intercepting route lookup to use the new array-based API

* update entry-templates snapshots

---------

Co-authored-by: James <james@eli.cx>
2026-03-10 08:18:30 +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
Nathan Nguyen c1ceef2aaf test: add unit tests for Pages Router api-handler (#318)
Cover body parsing (JSON, form-urlencoded, plain text, empty, malformed),
cookie parsing (single, multiple, values with =, missing header),
req/res extensions (status chaining, json, send for objects/strings/numbers/null,
redirect with default 307 and custom status codes), query string and dynamic
param merging (including array promotion for duplicate keys), MAX_BODY_SIZE
enforcement (413 for >1 MB), and error handling (missing default export,
non-function export, handler throws, ssrFixStacktrace integration).
2026-03-07 17:11:56 +00:00