in packages/route-manifest/src/index.ts [194:250]
function defineNestedRoutes(
defineRoute: DefineRouteFunction,
options: DefineRoutesOptions,
parentId?: string,
): void {
const childFileIds = fileIds.filter((id) => {
const parentFileId = findParentFileId(fileIds, id);
return parentFileId === parentId;
});
for (let fileId of childFileIds) {
const parentRoutePath = removeLastLayoutStrFromId(parentId) || '';
const routePath: string | undefined = createRoutePath(
// parentRoutePath = 'home', routeId = 'home/me', the new routeId is 'me'
// in order to escape the child route path is absolute path
fileId.slice(parentRoutePath.length + (parentRoutePath ? 1 : 0)),
);
const routeFilePath = normalizeSlashes(path.join('src', 'pages', files[fileId]));
if (RegExp(`[^${validRouteChar.join('')}]+`).test(routePath)) {
throw new Error(`invalid character in '${routeFilePath}'. Only support char: ${validRouteChar.join(', ')}`);
}
const isIndexRoute = isIndexFileId(fileId);
const fullPath = createRoutePath(fileId);
const uniqueRouteId = (fullPath || '') + (isIndexRoute ? '?index' : '');
if (uniqueRouteId) {
if (uniqueRoutes.has(uniqueRouteId)) {
throw new Error(
`Path ${JSON.stringify(fullPath)} defined by route ${JSON.stringify(routeFilePath)}
conflicts with route ${JSON.stringify(uniqueRoutes.get(uniqueRouteId))}`,
);
} else {
uniqueRoutes.set(uniqueRouteId, fileId);
}
}
if (isIndexRoute) {
let invalidChildRoutes = fileIds.filter(
(id) => findParentFileId(fileIds, id) === fileId,
);
if (invalidChildRoutes.length > 0) {
throw new Error(
`Child routes are not allowed in index routes. Please remove child routes of ${fileId}`,
);
}
defineRoute(routePath, files[fileId], {
index: true,
});
} else {
defineRoute(routePath, files[fileId], () => {
defineNestedRoutes(defineRoute, options, fileId);
});
}
}
}