/
fetchRouterManifest.ts
84 lines (75 loc) · 2.43 KB
/
fetchRouterManifest.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/**
* 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<TRegex = string> = {
file: string;
page: string;
routeKeys: Record<string, string>;
namedRegex: TRegex;
generated?: boolean;
};
export type ExpoRouterServerManifestV1<TRegex = string> = {
apiRoutes: ExpoRouterServerManifestV1Route<TRegex>[];
htmlRoutes: ExpoRouterServerManifestV1Route<TRegex>[];
notFoundRoutes: ExpoRouterServerManifestV1Route<TRegex>[];
};
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<TRegex = string>(
projectRoot: string,
options: {
asJson?: boolean;
appDir: string;
} & import('expo-router/build/routes-manifest').Options
): Promise<ExpoRouterServerManifestV1<TRegex> | null> {
const getManifest = getExpoRouteManifestBuilderAsync(projectRoot);
const paths = getRoutePaths(options.appDir);
// Get the serialized manifest
const jsonManifest = getManifest(paths, options);
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<string>
): ExpoRouterServerManifestV1<RegExp> {
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),
};
}),
};
}