Bug fix: Order of params for routing has to match (#2593)

* make sure route params are sorted before comparing stringified keys

* including changeset for a patch release
This commit is contained in:
Tony Sullivan 2022-02-16 15:49:03 +00:00 committed by GitHub
parent b4dcc0f8d3
commit 40c0e2b3f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 5 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Dynamic route params should ignore param order when matching paths

View file

@ -33,8 +33,7 @@ async function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise<[Param
routeCacheEntry = await callGetStaticPaths(mod, route, true, logging);
routeCache.set(route, routeCacheEntry);
}
const paramsKey = JSON.stringify(params);
const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, paramsKey);
const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, params);
if (!matchedStaticPath) {
throw new Error(`[getStaticPaths] route pattern matched, but no matching static path found. (${pathname})`);
}

View file

@ -1,4 +1,4 @@
import type { ComponentInstance, GetStaticPathsItem, GetStaticPathsResult, GetStaticPathsResultKeyed, RouteData, RSS } from '../../@types/astro';
import type { ComponentInstance, GetStaticPathsItem, GetStaticPathsResult, GetStaticPathsResultKeyed, Params, RouteData, RSS } from '../../@types/astro';
import { LogOptions, warn, debug } from '../logger.js';
import { generatePaginateFunction } from './paginate.js';
@ -6,6 +6,11 @@ import { validateGetStaticPathsModule, validateGetStaticPathsResult } from '../r
type RSSFn = (...args: any[]) => any;
function stringifyParams(params: Params) {
// Always sort keys before stringifying to make sure objects match regardless of parameter ordering
return JSON.stringify(params, Object.keys(params).sort());
}
export async function callGetStaticPaths(mod: ComponentInstance, route: RouteData, isValidate: boolean, logging: LogOptions): Promise<RouteCacheEntry> {
validateGetStaticPathsModule(mod);
const resultInProgress = {
@ -23,7 +28,7 @@ export async function callGetStaticPaths(mod: ComponentInstance, route: RouteDat
const keyedStaticPaths = staticPaths as GetStaticPathsResultKeyed;
keyedStaticPaths.keyed = new Map<string, GetStaticPathsItem>();
for (const sp of keyedStaticPaths) {
const paramsKey = JSON.stringify(sp.params);
const paramsKey = stringifyParams(sp.params);
keyedStaticPaths.keyed.set(paramsKey, sp);
}
if (isValidate) {
@ -73,7 +78,8 @@ export class RouteCache {
}
}
export function findPathItemByKey(staticPaths: GetStaticPathsResultKeyed, paramsKey: string) {
export function findPathItemByKey(staticPaths: GetStaticPathsResultKeyed, params: Params) {
const paramsKey = stringifyParams(params);
let matchedStaticPath = staticPaths.keyed.get(paramsKey);
if (matchedStaticPath) {
return matchedStaticPath;

View file

@ -0,0 +1,17 @@
---
export async function getStaticPaths() {
return [
{ params: { year: '2022', slug: 'post-1' } },
{ params: { slug: 'post-2', year: '2022' } },
]
}
const { year, slug } = Astro.request.params
---
<html>
<head>
<title>{year} | {slug}</title>
</head>
<body></body>
</html>