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:
parent
b4dcc0f8d3
commit
40c0e2b3f6
4 changed files with 32 additions and 5 deletions
5
.changeset/sweet-spoons-cheer.md
Normal file
5
.changeset/sweet-spoons-cheer.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Dynamic route params should ignore param order when matching paths
|
|
@ -33,8 +33,7 @@ async function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise<[Param
|
||||||
routeCacheEntry = await callGetStaticPaths(mod, route, true, logging);
|
routeCacheEntry = await callGetStaticPaths(mod, route, true, logging);
|
||||||
routeCache.set(route, routeCacheEntry);
|
routeCache.set(route, routeCacheEntry);
|
||||||
}
|
}
|
||||||
const paramsKey = JSON.stringify(params);
|
const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, params);
|
||||||
const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, paramsKey);
|
|
||||||
if (!matchedStaticPath) {
|
if (!matchedStaticPath) {
|
||||||
throw new Error(`[getStaticPaths] route pattern matched, but no matching static path found. (${pathname})`);
|
throw new Error(`[getStaticPaths] route pattern matched, but no matching static path found. (${pathname})`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 { LogOptions, warn, debug } from '../logger.js';
|
||||||
|
|
||||||
import { generatePaginateFunction } from './paginate.js';
|
import { generatePaginateFunction } from './paginate.js';
|
||||||
|
@ -6,6 +6,11 @@ import { validateGetStaticPathsModule, validateGetStaticPathsResult } from '../r
|
||||||
|
|
||||||
type RSSFn = (...args: any[]) => any;
|
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> {
|
export async function callGetStaticPaths(mod: ComponentInstance, route: RouteData, isValidate: boolean, logging: LogOptions): Promise<RouteCacheEntry> {
|
||||||
validateGetStaticPathsModule(mod);
|
validateGetStaticPathsModule(mod);
|
||||||
const resultInProgress = {
|
const resultInProgress = {
|
||||||
|
@ -23,7 +28,7 @@ export async function callGetStaticPaths(mod: ComponentInstance, route: RouteDat
|
||||||
const keyedStaticPaths = staticPaths as GetStaticPathsResultKeyed;
|
const keyedStaticPaths = staticPaths as GetStaticPathsResultKeyed;
|
||||||
keyedStaticPaths.keyed = new Map<string, GetStaticPathsItem>();
|
keyedStaticPaths.keyed = new Map<string, GetStaticPathsItem>();
|
||||||
for (const sp of keyedStaticPaths) {
|
for (const sp of keyedStaticPaths) {
|
||||||
const paramsKey = JSON.stringify(sp.params);
|
const paramsKey = stringifyParams(sp.params);
|
||||||
keyedStaticPaths.keyed.set(paramsKey, sp);
|
keyedStaticPaths.keyed.set(paramsKey, sp);
|
||||||
}
|
}
|
||||||
if (isValidate) {
|
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);
|
let matchedStaticPath = staticPaths.keyed.get(paramsKey);
|
||||||
if (matchedStaticPath) {
|
if (matchedStaticPath) {
|
||||||
return matchedStaticPath;
|
return matchedStaticPath;
|
||||||
|
|
17
packages/astro/test/fixtures/astro-get-static-paths/src/pages/blog/[year]/[slug].astro
vendored
Normal file
17
packages/astro/test/fixtures/astro-get-static-paths/src/pages/blog/[year]/[slug].astro
vendored
Normal 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>
|
Loading…
Reference in a new issue