Commit Graph

3 Commits

Author SHA1 Message Date
James Anderson c5cebaa496 refactor(prerender): extract shared static-paths normalization (#1231)
* refactor(prerender): extract shared static-paths normalization

PR #1227 added the same getStaticPaths-entry normalization logic to
three files: packages/vinext/src/build/prerender.ts,
packages/vinext/src/server/pages-page-data.ts, and
packages/vinext/src/server/dev-server.ts. Each site handled the
string-vs-object branch, the missing-params guard, and the query-string
+ trailing-slash trimming on its own.

Hoist the shared logic into packages/vinext/src/routing/route-pattern.ts
alongside the existing matchRoutePattern helper. Two new exports:

- normalizeStaticPathname(pathname): the shared query-strip and
  trailing-slash-strip used by every call site for path comparison.
- normalizeStaticPathsEntry(entry, routePattern): the build-time helper,
  returning { params } | { error }; reused by prerenderPages.

Both server-side matchers (matchesPagesStaticPath in pages-page-data.ts
and the dev-server's request handling) now share the normalizeStaticPathname
helper and the StaticPathsEntry type. Their runtime matching behaviour is
preserved exactly, including the missing-params -> false (404) guard.

Pure refactor: no behaviour changes. Existing tests in
tests/prerender.test.ts (the safety net from #1227) still pass; new
focused unit tests added to tests/route-pattern.test.ts cover the helper
shape, string and object entries, catch-all patterns, percent-encoded
segments, and every error path.

* fix: drop unused NormalizedStaticPathsEntry export

knip flagged the type as an unused exported type. It's only referenced
inside route-pattern.ts as the return-type alias of normalizeStaticPathsEntry,
so make it module-local.
2026-05-15 09:51:49 +00:00
Nathan Nguyen 6c786d69a9 fix(routing): decode matched params with decodeURIComponent (#1049)
* fix(routing): decode matched params with decodeURIComponent

Vinext's segment-safe normalization preserves encoded delimiters (%2F) for
correct route matching, but the captured param values were left undecoded.
This caused dynamic params to return "a%2Fb" instead of "a/b", diverging
from Next.js which decodes at the route-matcher level.

Add decodeURIComponent pass in trieMatch and matchRoutePattern — the two
route matching entry points — so all downstream consumers (pages, route
handlers, metadata, useParams) receive decoded param values.

Mirrors Next.js: packages/next/src/shared/lib/router/utils/route-matcher.ts L25-27

* test(app-rsc-route-matching): update param decode assertion to match new behavior
2026-05-04 18:58:48 +01:00
Nathan Nguyen a3580bc79b refactor(metadata): share route pattern helpers (#996)
* refactor(metadata): share route pattern helpers

Metadata route handling repeated the same dynamic segment normalization and pattern matching in several places. That made the file-convention metadata path harder to review and kept generic routing behavior inside metadata-specific modules.

Move route pattern parsing, matching, and dynamic segment filling into a normal routing module. Reuse it from metadata route build data, file-based metadata, metadata route response matching, and app RSC intercept matching, then consolidate duplicated icon descriptor normalization in the metadata server and shim code.

Add focused route-pattern tests and keep the existing metadata and shim tests covering consumer behavior.

* fix(routing): preserve prototype-named route params

The shared route pattern matcher used a normal object for matched params, unlike the previous metadata and App RSC matchers. A route parameter named __proto__ could mutate the params object's prototype instead of being stored as an own value.

Restore a null-prototype params map and add regression coverage for single and catch-all prototype-named route params.

* fix(routing): preserve literal intercept target segments
2026-05-01 23:30:59 +01:00