[remix] Add unit tests (#9469)

Moves parts of the `@vercel/remix` builder into util functions that have isolated unit tests. No functionality changes.
This commit is contained in:
Nathan Rajlich
2023-02-17 10:46:33 -08:00
committed by GitHub
parent 83ee5ea2b8
commit 63211b8b89
8 changed files with 306 additions and 40 deletions

View File

@@ -1,7 +1,6 @@
import { Project } from 'ts-morph';
import { promises as fs } from 'fs';
import { basename, dirname, extname, join, relative, sep } from 'path';
import { pathToRegexp, Key } from 'path-to-regexp';
import {
debug,
download,
@@ -30,7 +29,12 @@ import type {
BuildResultV2Typical,
} from '@vercel/build-utils';
import type { ConfigRoute } from '@remix-run/dev/dist/config/routes';
import { findConfig } from './utils';
import {
findConfig,
getPathFromRoute,
getRegExpFromPath,
isLayoutRoute,
} from './utils';
const _require: typeof require = eval('require');
@@ -173,12 +177,13 @@ module.exports = config;`;
}
}
const { serverBuildPath, routes: remixRoutes } = remixConfig;
const { serverBuildPath } = remixConfig;
const remixRoutes = Object.values(remixConfig.routes);
// Figure out which pages should be edge functions
const edgePages = new Set<ConfigRoute>();
const project = new Project();
for (const route of Object.values(remixRoutes)) {
for (const route of remixRoutes) {
const routePath = join(remixConfig.appDirectory, route.file);
const staticConfig = getConfig(project, routePath);
const isEdge =
@@ -228,27 +233,11 @@ module.exports = config;`;
},
];
for (const route of Object.values(remixRoutes)) {
for (const route of remixRoutes) {
// Layout routes don't get a function / route added
const isLayoutRoute = Object.values(remixRoutes).some(
r => r.parentId === route.id
);
if (isLayoutRoute) continue;
// Build up the full request path
let currentRoute: ConfigRoute | undefined = route;
const pathParts: string[] = [];
do {
if (currentRoute.index) pathParts.push('index');
if (currentRoute.path) pathParts.push(currentRoute.path);
if (currentRoute.parentId) {
currentRoute = remixRoutes[currentRoute.parentId];
} else {
currentRoute = undefined;
}
} while (currentRoute);
const path = join(...pathParts.reverse());
if (isLayoutRoute(route.id, remixRoutes)) continue;
const path = getPathFromRoute(route, remixConfig.routes);
const isEdge = edgePages.has(route);
const fn =
isEdge && edgeFunction
@@ -264,13 +253,8 @@ module.exports = config;`;
output[path] = fn;
// If this is a dynamic route then add a Vercel route
const keys: Key[] = [];
// Replace "/*" at the end to handle "splat routes"
const splatPath = '/:params+';
const rePath =
path === '*' ? splatPath : `/${path.replace(/\/\*$/, splatPath)}`;
const re = pathToRegexp(rePath, keys);
if (keys.length > 0) {
const re = getRegExpFromPath(path);
if (re) {
routes.push({
src: re.source,
dest: path,

View File

@@ -1,5 +1,10 @@
import { existsSync } from 'fs';
import { join } from 'path';
import { existsSync } from 'fs';
import { pathToRegexp, Key } from 'path-to-regexp';
import type {
ConfigRoute,
RouteManifest,
} from '@remix-run/dev/dist/config/routes';
const configExts = ['.js', '.cjs', '.mjs'];
@@ -12,3 +17,39 @@ export function findConfig(dir: string, basename: string): string | undefined {
return undefined;
}
export function isLayoutRoute(
routeId: string,
routes: Pick<ConfigRoute, 'id' | 'parentId'>[]
): boolean {
return routes.some(r => r.parentId === routeId);
}
export function getPathFromRoute(
route: ConfigRoute,
routes: RouteManifest
): string {
let currentRoute: ConfigRoute | undefined = route;
const pathParts: string[] = [];
do {
if (currentRoute.index) pathParts.push('index');
if (currentRoute.path) pathParts.push(currentRoute.path);
if (currentRoute.parentId) {
currentRoute = routes[currentRoute.parentId];
} else {
currentRoute = undefined;
}
} while (currentRoute);
const path = pathParts.reverse().join('/');
return path;
}
export function getRegExpFromPath(path: string): RegExp | false {
const keys: Key[] = [];
// Replace "/*" at the end to handle "splat routes"
const splatPath = '/:params+';
const rePath =
path === '*' ? splatPath : `/${path.replace(/\/\*$/, splatPath)}`;
const re = pathToRegexp(rePath, keys);
return keys.length > 0 ? re : false;
}