Serialize route generation (#3354)
This commit is contained in:
parent
9481a3c08d
commit
4ac792a02d
5 changed files with 61 additions and 59 deletions
|
@ -974,6 +974,9 @@ export interface RouteData {
|
|||
export type SerializedRouteData = Omit<RouteData, 'generate' | 'pattern'> & {
|
||||
generate: undefined;
|
||||
pattern: string;
|
||||
_meta: {
|
||||
trailingSlash: AstroConfig['trailingSlash'];
|
||||
};
|
||||
};
|
||||
|
||||
export type RuntimeMode = 'development' | 'production';
|
||||
|
|
|
@ -115,7 +115,7 @@ function buildManifest(
|
|||
.filter((script) => script.stage === 'head-inline')
|
||||
.map(({ stage, content }) => ({ stage, children: content })),
|
||||
],
|
||||
routeData: serializeRouteData(pageData.route),
|
||||
routeData: serializeRouteData(pageData.route, astroConfig.trailingSlash),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@ import type { LogOptions } from '../../logger/core';
|
|||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { compile } from 'path-to-regexp';
|
||||
import slash from 'slash';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { warn } from '../../logger/core.js';
|
||||
import { resolvePages } from '../../util.js';
|
||||
import { getRouteGenerator } from './generator.js';
|
||||
|
||||
interface Item {
|
||||
basename: string;
|
||||
|
@ -88,34 +88,6 @@ function getTrailingSlashPattern(addTrailingSlash: AstroConfig['trailingSlash'])
|
|||
return '\\/?$';
|
||||
}
|
||||
|
||||
function getGenerator(segments: RoutePart[][], addTrailingSlash: AstroConfig['trailingSlash']) {
|
||||
const template = segments
|
||||
.map((segment) => {
|
||||
return segment[0].spread
|
||||
? `/:${segment[0].content.slice(3)}(.*)?`
|
||||
: '/' +
|
||||
segment
|
||||
.map((part) => {
|
||||
if (part)
|
||||
return part.dynamic
|
||||
? `:${part.content}`
|
||||
: part.content
|
||||
.normalize()
|
||||
.replace(/\?/g, '%3F')
|
||||
.replace(/#/g, '%23')
|
||||
.replace(/%5B/g, '[')
|
||||
.replace(/%5D/g, ']')
|
||||
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
})
|
||||
.join('');
|
||||
})
|
||||
.join('');
|
||||
|
||||
const trailing = addTrailingSlash !== 'never' && segments.length ? '/' : '';
|
||||
const toPath = compile(template + trailing);
|
||||
return toPath;
|
||||
}
|
||||
|
||||
function isSpread(str: string) {
|
||||
const spreadPattern = /\[\.{3}/g;
|
||||
return spreadPattern.test(str);
|
||||
|
@ -271,7 +243,7 @@ export function createRouteManifest(
|
|||
const component = item.file;
|
||||
const trailingSlash = item.isPage ? config.trailingSlash : 'never';
|
||||
const pattern = getPattern(segments, trailingSlash);
|
||||
const generate = getGenerator(segments, trailingSlash);
|
||||
const generate = getRouteGenerator(segments, trailingSlash);
|
||||
const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic)
|
||||
? `/${segments.map((segment) => segment[0].content).join('/')}`
|
||||
: null;
|
||||
|
|
34
packages/astro/src/core/routing/manifest/generator.ts
Normal file
34
packages/astro/src/core/routing/manifest/generator.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import type { AstroConfig, RoutePart } from '../../../@types/astro';
|
||||
|
||||
import { compile } from 'path-to-regexp';
|
||||
|
||||
export function getRouteGenerator(
|
||||
segments: RoutePart[][],
|
||||
addTrailingSlash: AstroConfig['trailingSlash']
|
||||
) {
|
||||
const template = segments
|
||||
.map((segment) => {
|
||||
return segment[0].spread
|
||||
? `/:${segment[0].content.slice(3)}(.*)?`
|
||||
: '/' +
|
||||
segment
|
||||
.map((part) => {
|
||||
if (part)
|
||||
return part.dynamic
|
||||
? `:${part.content}`
|
||||
: part.content
|
||||
.normalize()
|
||||
.replace(/\?/g, '%3F')
|
||||
.replace(/#/g, '%23')
|
||||
.replace(/%5B/g, '[')
|
||||
.replace(/%5D/g, ']')
|
||||
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
})
|
||||
.join('');
|
||||
})
|
||||
.join('');
|
||||
|
||||
const trailing = addTrailingSlash !== 'never' && segments.length ? '/' : '';
|
||||
const toPath = compile(template + trailing);
|
||||
return toPath;
|
||||
}
|
|
@ -1,34 +1,27 @@
|
|||
import type { RouteData, SerializedRouteData, RoutePart } from '../../../@types/astro';
|
||||
import type { RouteData, SerializedRouteData, AstroConfig } from '../../../@types/astro';
|
||||
|
||||
function createRouteData(
|
||||
pattern: RegExp,
|
||||
params: string[],
|
||||
component: string,
|
||||
pathname: string | undefined,
|
||||
type: 'page' | 'endpoint',
|
||||
segments: RoutePart[][]
|
||||
): RouteData {
|
||||
import { getRouteGenerator } from './generator.js';
|
||||
|
||||
export function serializeRouteData(
|
||||
routeData: RouteData,
|
||||
trailingSlash: AstroConfig['trailingSlash']
|
||||
): SerializedRouteData {
|
||||
return {
|
||||
type,
|
||||
pattern,
|
||||
params,
|
||||
component,
|
||||
// TODO bring back
|
||||
generate: () => '',
|
||||
pathname: pathname || undefined,
|
||||
segments,
|
||||
...routeData,
|
||||
generate: undefined,
|
||||
pattern: routeData.pattern.source,
|
||||
_meta: { trailingSlash },
|
||||
};
|
||||
}
|
||||
|
||||
export function serializeRouteData(routeData: RouteData): SerializedRouteData {
|
||||
// Is there a better way to do this in TypeScript?
|
||||
const outRouteData = routeData as unknown as SerializedRouteData;
|
||||
outRouteData.pattern = routeData.pattern.source;
|
||||
return outRouteData;
|
||||
}
|
||||
|
||||
export function deserializeRouteData(rawRouteData: SerializedRouteData) {
|
||||
const { component, params, pathname, type, segments } = rawRouteData;
|
||||
const pattern = new RegExp(rawRouteData.pattern);
|
||||
return createRouteData(pattern, params, component, pathname, type, segments);
|
||||
export function deserializeRouteData(rawRouteData: SerializedRouteData): RouteData {
|
||||
return {
|
||||
type: rawRouteData.type,
|
||||
pattern: new RegExp(rawRouteData.pattern),
|
||||
params: rawRouteData.params,
|
||||
component: rawRouteData.component,
|
||||
generate: getRouteGenerator(rawRouteData.segments, rawRouteData._meta.trailingSlash),
|
||||
pathname: rawRouteData.pathname || undefined,
|
||||
segments: rawRouteData.segments,
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue