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'> & { export type SerializedRouteData = Omit<RouteData, 'generate' | 'pattern'> & {
generate: undefined; generate: undefined;
pattern: string; pattern: string;
_meta: {
trailingSlash: AstroConfig['trailingSlash'];
};
}; };
export type RuntimeMode = 'development' | 'production'; export type RuntimeMode = 'development' | 'production';

View file

@ -115,7 +115,7 @@ function buildManifest(
.filter((script) => script.stage === 'head-inline') .filter((script) => script.stage === 'head-inline')
.map(({ stage, content }) => ({ stage, children: content })), .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 fs from 'fs';
import path from 'path'; import path from 'path';
import { compile } from 'path-to-regexp';
import slash from 'slash'; import slash from 'slash';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import { warn } from '../../logger/core.js'; import { warn } from '../../logger/core.js';
import { resolvePages } from '../../util.js'; import { resolvePages } from '../../util.js';
import { getRouteGenerator } from './generator.js';
interface Item { interface Item {
basename: string; basename: string;
@ -88,34 +88,6 @@ function getTrailingSlashPattern(addTrailingSlash: AstroConfig['trailingSlash'])
return '\\/?$'; 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) { function isSpread(str: string) {
const spreadPattern = /\[\.{3}/g; const spreadPattern = /\[\.{3}/g;
return spreadPattern.test(str); return spreadPattern.test(str);
@ -271,7 +243,7 @@ export function createRouteManifest(
const component = item.file; const component = item.file;
const trailingSlash = item.isPage ? config.trailingSlash : 'never'; const trailingSlash = item.isPage ? config.trailingSlash : 'never';
const pattern = getPattern(segments, trailingSlash); 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) const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic)
? `/${segments.map((segment) => segment[0].content).join('/')}` ? `/${segments.map((segment) => segment[0].content).join('/')}`
: null; : 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( import { getRouteGenerator } from './generator.js';
pattern: RegExp,
params: string[], export function serializeRouteData(
component: string, routeData: RouteData,
pathname: string | undefined, trailingSlash: AstroConfig['trailingSlash']
type: 'page' | 'endpoint', ): SerializedRouteData {
segments: RoutePart[][]
): RouteData {
return { return {
type, ...routeData,
pattern, generate: undefined,
params, pattern: routeData.pattern.source,
component, _meta: { trailingSlash },
// TODO bring back
generate: () => '',
pathname: pathname || undefined,
segments,
}; };
} }
export function serializeRouteData(routeData: RouteData): SerializedRouteData { export function deserializeRouteData(rawRouteData: SerializedRouteData): RouteData {
// Is there a better way to do this in TypeScript? return {
const outRouteData = routeData as unknown as SerializedRouteData; type: rawRouteData.type,
outRouteData.pattern = routeData.pattern.source; pattern: new RegExp(rawRouteData.pattern),
return outRouteData; params: rawRouteData.params,
} component: rawRouteData.component,
generate: getRouteGenerator(rawRouteData.segments, rawRouteData._meta.trailingSlash),
export function deserializeRouteData(rawRouteData: SerializedRouteData) { pathname: rawRouteData.pathname || undefined,
const { component, params, pathname, type, segments } = rawRouteData; segments: rawRouteData.segments,
const pattern = new RegExp(rawRouteData.pattern); };
return createRouteData(pattern, params, component, pathname, type, segments);
} }