Serialize route generation (#3354)

This commit is contained in:
Juan Martín Seery 2022-05-12 17:39:17 -03:00 committed by GitHub
parent 9481a3c08d
commit 4ac792a02d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 59 deletions

View file

@ -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';

View file

@ -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),
});
}

View file

@ -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;

View 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;
}

View file

@ -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,
};
}