/** * Copyright © 2022 650 Industries. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import resolveFrom from 'resolve-from'; import { getRoutePaths } from './router'; export type ExpoRouterServerManifestV1Route = { page: string; routeKeys: Record; namedRegex: TRegex; generated?: boolean; }; export type ExpoRouterServerManifestV1 = { apiRoutes: ExpoRouterServerManifestV1Route[]; htmlRoutes: ExpoRouterServerManifestV1Route[]; notFoundRoutes: ExpoRouterServerManifestV1Route[]; }; function getExpoRouteManifestBuilderAsync(projectRoot: string) { return require(resolveFrom(projectRoot, 'expo-router/build/routes-manifest')) .createRoutesManifest as typeof import('expo-router/build/routes-manifest').createRoutesManifest; } // TODO: Simplify this now that we use Node.js directly, no need for the Metro bundler caching layer. export async function fetchManifest( projectRoot: string, options: { asJson?: boolean; appDir: string } ): Promise | null> { const getManifest = getExpoRouteManifestBuilderAsync(projectRoot); const paths = getRoutePaths(options.appDir); // Get the serialized manifest const jsonManifest = getManifest(paths); if (!jsonManifest) { return null; } if (!jsonManifest.htmlRoutes || !jsonManifest.apiRoutes) { throw new Error('Routes manifest is malformed: ' + JSON.stringify(jsonManifest, null, 2)); } if (!options.asJson) { // @ts-expect-error return inflateManifest(jsonManifest); } // @ts-expect-error return jsonManifest; } // Convert the serialized manifest to a usable format export function inflateManifest( json: ExpoRouterServerManifestV1 ): ExpoRouterServerManifestV1 { return { ...json, htmlRoutes: json.htmlRoutes?.map((value) => { return { ...value, namedRegex: new RegExp(value.namedRegex), }; }), apiRoutes: json.apiRoutes?.map((value) => { return { ...value, namedRegex: new RegExp(value.namedRegex), }; }), notFoundRoutes: json.notFoundRoutes?.map((value) => { return { ...value, namedRegex: new RegExp(value.namedRegex), }; }), }; }