expo-router 3.5.14 → 3.5.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/getRoutes.d.ts +5 -21
- package/build/getRoutes.d.ts.map +1 -1
- package/build/getRoutes.js +57 -476
- package/build/getRoutes.js.map +1 -1
- package/build/getRoutesCore.d.ts +37 -0
- package/build/getRoutesCore.d.ts.map +1 -0
- package/build/getRoutesCore.js +468 -0
- package/build/getRoutesCore.js.map +1 -0
- package/build/getRoutesSSR.d.ts +20 -0
- package/build/getRoutesSSR.d.ts.map +1 -0
- package/build/getRoutesSSR.js +80 -0
- package/build/getRoutesSSR.js.map +1 -0
- package/build/routes-manifest.d.ts +1 -1
- package/build/routes-manifest.d.ts.map +1 -1
- package/build/routes-manifest.js +2 -2
- package/build/routes-manifest.js.map +1 -1
- package/build/typed-routes/index.js +1 -0
- package/build/typed-routes/index.js.map +1 -1
- package/package.json +3 -3
package/build/getRoutes.d.ts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
preserveApiRoutes?: boolean;
|
|
6
|
-
ignoreRequireErrors?: boolean;
|
|
7
|
-
ignoreEntryPoints?: boolean;
|
|
8
|
-
internal_stripLoadRoute?: boolean;
|
|
9
|
-
skipGenerated?: boolean;
|
|
10
|
-
importMode?: string;
|
|
11
|
-
platformRoutes?: boolean;
|
|
12
|
-
platform?: string;
|
|
13
|
-
};
|
|
1
|
+
import type { RouteNode } from './Route';
|
|
2
|
+
import { type Options as OptionsCore } from './getRoutesCore';
|
|
3
|
+
import type { RequireContext } from './types';
|
|
4
|
+
export type Options = Omit<OptionsCore, 'getSystemRoute'>;
|
|
14
5
|
/**
|
|
15
6
|
* Given a Metro context module, return an array of nested routes.
|
|
16
7
|
*
|
|
@@ -25,12 +16,5 @@ export type Options = {
|
|
|
25
16
|
*/
|
|
26
17
|
export declare function getRoutes(contextModule: RequireContext, options?: Options): RouteNode | null;
|
|
27
18
|
export declare function getExactRoutes(contextModule: RequireContext, options?: Options): RouteNode | null;
|
|
28
|
-
export
|
|
29
|
-
/**
|
|
30
|
-
* Generates a set of strings which have the router array syntax extrapolated.
|
|
31
|
-
*
|
|
32
|
-
* /(a,b)/(c,d)/e.tsx => new Set(['a/c/e.tsx', 'a/d/e.tsx', 'b/c/e.tsx', 'b/d/e.tsx'])
|
|
33
|
-
*/
|
|
34
|
-
export declare function extrapolateGroups(key: string, keys?: Set<string>): Set<string>;
|
|
35
|
-
export declare function generateDynamic(path: string): DynamicConvention[] | null;
|
|
19
|
+
export { generateDynamic, extrapolateGroups, getIgnoreList } from './getRoutesCore';
|
|
36
20
|
//# sourceMappingURL=getRoutes.d.ts.map
|
package/build/getRoutes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRoutes.d.ts","sourceRoot":"","sources":["../src/getRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"getRoutes.d.ts","sourceRoot":"","sources":["../src/getRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAA8B,KAAK,OAAO,IAAI,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;AAC1D;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,aAAa,EAAE,cAAc,EAAE,OAAO,GAAE,OAAY,GAAG,SAAS,GAAG,IAAI,CAkDhG;AAED,wBAAgB,cAAc,CAC5B,aAAa,EAAE,cAAc,EAC7B,OAAO,GAAE,OAAY,GACpB,SAAS,GAAG,IAAI,CAKlB;AAED,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/build/getRoutes.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
const validPlatforms = new Set(['android', 'ios', 'native', 'web']);
|
|
3
|
+
exports.getIgnoreList = exports.extrapolateGroups = exports.generateDynamic = exports.getExactRoutes = exports.getRoutes = void 0;
|
|
4
|
+
const getRoutesCore_1 = require("./getRoutesCore");
|
|
6
5
|
/**
|
|
7
6
|
* Given a Metro context module, return an array of nested routes.
|
|
8
7
|
*
|
|
@@ -16,16 +15,57 @@ const validPlatforms = new Set(['android', 'ios', 'native', 'web']);
|
|
|
16
15
|
* - If multiple routes have the same name, the most specific route is used
|
|
17
16
|
*/
|
|
18
17
|
function getRoutes(contextModule, options = {}) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
return (0, getRoutesCore_1.getRoutes)(contextModule, {
|
|
19
|
+
getSystemRoute({ route, type }) {
|
|
20
|
+
if (route === '' && type === 'layout') {
|
|
21
|
+
// Root layout when no layout is defined.
|
|
22
|
+
return {
|
|
23
|
+
type: 'layout',
|
|
24
|
+
loadRoute: () => ({
|
|
25
|
+
default: require('./views/Navigator')
|
|
26
|
+
.DefaultNavigator,
|
|
27
|
+
}),
|
|
28
|
+
// Generate a fake file name for the directory
|
|
29
|
+
contextKey: 'expo-router/build/views/Navigator.js',
|
|
30
|
+
route: '',
|
|
31
|
+
generated: true,
|
|
32
|
+
dynamic: null,
|
|
33
|
+
children: [],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
else if (route === '_sitemap' && type === 'route') {
|
|
37
|
+
return {
|
|
38
|
+
loadRoute() {
|
|
39
|
+
const { Sitemap, getNavOptions } = require('./views/Sitemap');
|
|
40
|
+
return { default: Sitemap, getNavOptions };
|
|
41
|
+
},
|
|
42
|
+
route: '_sitemap',
|
|
43
|
+
type: 'route',
|
|
44
|
+
contextKey: 'expo-router/build/views/Sitemap.js',
|
|
45
|
+
generated: true,
|
|
46
|
+
internal: true,
|
|
47
|
+
dynamic: null,
|
|
48
|
+
children: [],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
else if (route === '+not-found' && type === 'route') {
|
|
52
|
+
return {
|
|
53
|
+
loadRoute() {
|
|
54
|
+
return { default: require('./views/Unmatched').Unmatched };
|
|
55
|
+
},
|
|
56
|
+
type: 'route',
|
|
57
|
+
route: '+not-found',
|
|
58
|
+
contextKey: 'expo-router/build/views/Unmatched.js',
|
|
59
|
+
generated: true,
|
|
60
|
+
internal: true,
|
|
61
|
+
dynamic: [{ name: '+not-found', deep: true, notFound: true }],
|
|
62
|
+
children: [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
throw new Error(`Unknown system route: ${route} and type: ${type}`);
|
|
66
|
+
},
|
|
67
|
+
...options,
|
|
68
|
+
});
|
|
29
69
|
}
|
|
30
70
|
exports.getRoutes = getRoutes;
|
|
31
71
|
function getExactRoutes(contextModule, options = {}) {
|
|
@@ -35,467 +75,8 @@ function getExactRoutes(contextModule, options = {}) {
|
|
|
35
75
|
});
|
|
36
76
|
}
|
|
37
77
|
exports.getExactRoutes = getExactRoutes;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
function
|
|
42
|
-
const importMode = options.importMode || process.env.EXPO_ROUTER_IMPORT_MODE;
|
|
43
|
-
const ignoreList = [/^\.\/\+(html|native-intent)\.[tj]sx?$/]; // Ignore the top level ./+html file
|
|
44
|
-
if (options.ignore) {
|
|
45
|
-
ignoreList.push(...options.ignore);
|
|
46
|
-
}
|
|
47
|
-
if (!options.preserveApiRoutes) {
|
|
48
|
-
ignoreList.push(/\+api\.[tj]sx?$/);
|
|
49
|
-
}
|
|
50
|
-
const rootDirectory = {
|
|
51
|
-
files: new Map(),
|
|
52
|
-
subdirectories: new Map(),
|
|
53
|
-
};
|
|
54
|
-
let hasRoutes = false;
|
|
55
|
-
let isValid = false;
|
|
56
|
-
for (const filePath of contextModule.keys()) {
|
|
57
|
-
if (ignoreList.some((regex) => regex.test(filePath))) {
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
isValid = true;
|
|
61
|
-
const meta = getFileMeta(filePath, options);
|
|
62
|
-
// This is a file that should be ignored. e.g maybe it has an invalid platform?
|
|
63
|
-
if (meta.specificity < 0) {
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
let node = {
|
|
67
|
-
type: meta.isApi ? 'api' : meta.isLayout ? 'layout' : 'route',
|
|
68
|
-
loadRoute() {
|
|
69
|
-
if (options.ignoreRequireErrors) {
|
|
70
|
-
try {
|
|
71
|
-
return contextModule(filePath);
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
return {};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
return contextModule(filePath);
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
contextKey: filePath,
|
|
82
|
-
route: '',
|
|
83
|
-
dynamic: null,
|
|
84
|
-
children: [], // While we are building the directory tree, we don't know the node's children just yet. This is added during hoisting
|
|
85
|
-
};
|
|
86
|
-
if (process.env.NODE_ENV === 'development') {
|
|
87
|
-
// If the user has set the `EXPO_ROUTER_IMPORT_MODE` to `sync` then we should
|
|
88
|
-
// filter the missing routes.
|
|
89
|
-
if (node.type !== 'api' && importMode === 'sync') {
|
|
90
|
-
if (!node.loadRoute()?.default) {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* A single filepath may be extrapolated into multiple routes if it contains array syntax.
|
|
97
|
-
* Another way to thinking about is that a filepath node is present in multiple leaves of the directory tree.
|
|
98
|
-
*/
|
|
99
|
-
for (const route of extrapolateGroups(meta.route)) {
|
|
100
|
-
// Traverse the directory tree to its leaf node, creating any missing directories along the way
|
|
101
|
-
const subdirectoryParts = route.split('/').slice(0, -1);
|
|
102
|
-
// Start at the root directory and traverse the path to the leaf directory
|
|
103
|
-
let directory = rootDirectory;
|
|
104
|
-
for (const part of subdirectoryParts) {
|
|
105
|
-
let subDirectory = directory.subdirectories.get(part);
|
|
106
|
-
// Create any missing subdirectories
|
|
107
|
-
if (!subDirectory) {
|
|
108
|
-
subDirectory = {
|
|
109
|
-
files: new Map(),
|
|
110
|
-
subdirectories: new Map(),
|
|
111
|
-
};
|
|
112
|
-
directory.subdirectories.set(part, subDirectory);
|
|
113
|
-
}
|
|
114
|
-
directory = subDirectory;
|
|
115
|
-
}
|
|
116
|
-
// Clone the node for this route
|
|
117
|
-
node = { ...node, route };
|
|
118
|
-
if (meta.isLayout) {
|
|
119
|
-
directory.layout ??= [];
|
|
120
|
-
const existing = directory.layout[meta.specificity];
|
|
121
|
-
if (existing) {
|
|
122
|
-
// In production, use the first route found
|
|
123
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
124
|
-
throw new Error(`The layouts "${filePath}" and "${existing.contextKey}" conflict on the route "/${route}". Please remove or rename one of these files.`);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
node = getLayoutNode(node, options);
|
|
129
|
-
directory.layout[meta.specificity] = node;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
else if (meta.isApi) {
|
|
133
|
-
const fileKey = `${route}+api`;
|
|
134
|
-
let nodes = directory.files.get(fileKey);
|
|
135
|
-
if (!nodes) {
|
|
136
|
-
nodes = [];
|
|
137
|
-
directory.files.set(fileKey, nodes);
|
|
138
|
-
}
|
|
139
|
-
// API Routes have no specificity, they are always the first node
|
|
140
|
-
const existing = nodes[0];
|
|
141
|
-
if (existing) {
|
|
142
|
-
// In production, use the first route found
|
|
143
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
144
|
-
throw new Error(`The API route file "${filePath}" and "${existing.contextKey}" conflict on the route "/${route}". Please remove or rename one of these files.`);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
nodes[0] = node;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
let nodes = directory.files.get(route);
|
|
153
|
-
if (!nodes) {
|
|
154
|
-
nodes = [];
|
|
155
|
-
directory.files.set(route, nodes);
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* If there is an existing node with the same specificity, then we have a conflict.
|
|
159
|
-
* NOTE(Platform Routes):
|
|
160
|
-
* We cannot check for specificity conflicts here, as we haven't processed all the context keys yet!
|
|
161
|
-
* This will be checked during hoisting, as well as enforcing that all routes have a non-platform route.
|
|
162
|
-
*/
|
|
163
|
-
const existing = nodes[meta.specificity];
|
|
164
|
-
if (existing) {
|
|
165
|
-
// In production, use the first route found
|
|
166
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
167
|
-
throw new Error(`The route files "${filePath}" and "${existing.contextKey}" conflict on the route "/${route}". Please remove or rename one of these files.`);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
hasRoutes ||= true;
|
|
172
|
-
nodes[meta.specificity] = node;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
// If there are no routes/layouts then we should display the tutorial.
|
|
178
|
-
if (!isValid) {
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* If there are no top-level _layout, add a default _layout
|
|
183
|
-
* While this is a generated route, it will still be generated even if skipGenerated is true.
|
|
184
|
-
*/
|
|
185
|
-
if (!rootDirectory.layout) {
|
|
186
|
-
rootDirectory.layout = [
|
|
187
|
-
{
|
|
188
|
-
type: 'layout',
|
|
189
|
-
loadRoute: () => ({
|
|
190
|
-
default: require('./views/Navigator')
|
|
191
|
-
.DefaultNavigator,
|
|
192
|
-
}),
|
|
193
|
-
// Generate a fake file name for the directory
|
|
194
|
-
contextKey: 'expo-router/build/views/Navigator.js',
|
|
195
|
-
route: '',
|
|
196
|
-
generated: true,
|
|
197
|
-
dynamic: null,
|
|
198
|
-
children: [],
|
|
199
|
-
},
|
|
200
|
-
];
|
|
201
|
-
}
|
|
202
|
-
// Only include the sitemap if there are routes.
|
|
203
|
-
if (!options.skipGenerated) {
|
|
204
|
-
if (hasRoutes) {
|
|
205
|
-
appendSitemapRoute(rootDirectory);
|
|
206
|
-
}
|
|
207
|
-
appendNotFoundRoute(rootDirectory);
|
|
208
|
-
}
|
|
209
|
-
return rootDirectory;
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Flatten the directory tree into routes, hoisting routes to the nearest _layout.
|
|
213
|
-
*/
|
|
214
|
-
function flattenDirectoryTreeToRoutes(directory, options,
|
|
215
|
-
/* The nearest _layout file in the directory tree */
|
|
216
|
-
layout,
|
|
217
|
-
/* Route names are relative to their layout */
|
|
218
|
-
pathToRemove = '') {
|
|
219
|
-
/**
|
|
220
|
-
* This directory has a _layout file so it becomes the new target for hoisting routes.
|
|
221
|
-
*/
|
|
222
|
-
if (directory.layout) {
|
|
223
|
-
const previousLayout = layout;
|
|
224
|
-
layout = getMostSpecific(directory.layout);
|
|
225
|
-
// Add the new layout as a child of its parent
|
|
226
|
-
if (previousLayout) {
|
|
227
|
-
previousLayout.children.push(layout);
|
|
228
|
-
}
|
|
229
|
-
if (options.internal_stripLoadRoute) {
|
|
230
|
-
delete layout.loadRoute;
|
|
231
|
-
}
|
|
232
|
-
// `route` is the absolute pathname. We need to make this relative to the last _layout
|
|
233
|
-
const newRoute = layout.route.replace(pathToRemove, '');
|
|
234
|
-
pathToRemove = layout.route ? `${layout.route}/` : '';
|
|
235
|
-
// Now update this layout with the new relative route and dynamic conventions
|
|
236
|
-
layout.route = newRoute;
|
|
237
|
-
layout.dynamic = generateDynamic(layout.route);
|
|
238
|
-
}
|
|
239
|
-
// This should never occur as there will always be a root layout, but it makes the type system happy
|
|
240
|
-
if (!layout)
|
|
241
|
-
throw new Error('Expo Router Internal Error: No nearest layout');
|
|
242
|
-
for (const routes of directory.files.values()) {
|
|
243
|
-
const routeNode = getMostSpecific(routes);
|
|
244
|
-
// `route` is the absolute pathname. We need to make this relative to the nearest layout
|
|
245
|
-
routeNode.route = routeNode.route.replace(pathToRemove, '');
|
|
246
|
-
routeNode.dynamic = generateDynamic(routeNode.route);
|
|
247
|
-
if (options.internal_stripLoadRoute) {
|
|
248
|
-
delete routeNode.loadRoute;
|
|
249
|
-
}
|
|
250
|
-
layout.children.push(routeNode);
|
|
251
|
-
}
|
|
252
|
-
// Recursively flatten the subdirectories
|
|
253
|
-
for (const child of directory.subdirectories.values()) {
|
|
254
|
-
flattenDirectoryTreeToRoutes(child, options, layout, pathToRemove);
|
|
255
|
-
}
|
|
256
|
-
return layout;
|
|
257
|
-
}
|
|
258
|
-
function getFileMeta(key, options) {
|
|
259
|
-
// Remove the leading `./`
|
|
260
|
-
key = key.replace(/^\.\//, '');
|
|
261
|
-
const parts = key.split('/');
|
|
262
|
-
let route = (0, matchers_1.removeSupportedExtensions)(key);
|
|
263
|
-
const filename = parts[parts.length - 1];
|
|
264
|
-
const [filenameWithoutExtensions, platformExtension] = (0, matchers_1.removeSupportedExtensions)(filename).split('.');
|
|
265
|
-
const isLayout = filenameWithoutExtensions === '_layout';
|
|
266
|
-
const isApi = filename.match(/\+api\.(\w+\.)?[jt]sx?$/);
|
|
267
|
-
if (filenameWithoutExtensions.startsWith('(') && filenameWithoutExtensions.endsWith(')')) {
|
|
268
|
-
throw new Error(`Invalid route ./${key}. Routes cannot end with '(group)' syntax`);
|
|
269
|
-
}
|
|
270
|
-
// Nested routes cannot start with the '+' character, except for the '+not-found' route
|
|
271
|
-
if (!isApi && filename.startsWith('+') && filenameWithoutExtensions !== '+not-found') {
|
|
272
|
-
const renamedRoute = [...parts.slice(0, -1), filename.slice(1)].join('/');
|
|
273
|
-
throw new Error(`Invalid route ./${key}. Route nodes cannot start with the '+' character. "Please rename to ${renamedRoute}"`);
|
|
274
|
-
}
|
|
275
|
-
let specificity = 0;
|
|
276
|
-
const hasPlatformExtension = validPlatforms.has(platformExtension);
|
|
277
|
-
const usePlatformRoutes = options.platformRoutes ?? true;
|
|
278
|
-
if (hasPlatformExtension) {
|
|
279
|
-
if (!usePlatformRoutes) {
|
|
280
|
-
// If the user has disabled platform routes, then we should ignore this file
|
|
281
|
-
specificity = -1;
|
|
282
|
-
}
|
|
283
|
-
else if (!options.platform) {
|
|
284
|
-
// If we don't have a platform, then we should ignore this file
|
|
285
|
-
// This used by typed routes, sitemap, etc
|
|
286
|
-
specificity = -1;
|
|
287
|
-
}
|
|
288
|
-
else if (platformExtension === options.platform) {
|
|
289
|
-
// If the platform extension is the same as the options.platform, then it is the most specific
|
|
290
|
-
specificity = 2;
|
|
291
|
-
}
|
|
292
|
-
else if (platformExtension === 'native' && options.platform !== 'web') {
|
|
293
|
-
// `native` is allow but isn't as specific as the platform
|
|
294
|
-
specificity = 1;
|
|
295
|
-
}
|
|
296
|
-
else if (platformExtension !== options.platform) {
|
|
297
|
-
// Somehow we have a platform extension that doesn't match the options.platform and it isn't native
|
|
298
|
-
// This is an invalid file and we will ignore it
|
|
299
|
-
specificity = -1;
|
|
300
|
-
}
|
|
301
|
-
if (isApi && specificity !== 0) {
|
|
302
|
-
throw new Error(`Api routes cannot have platform extensions. Please remove '.${platformExtension}' from './${key}'`);
|
|
303
|
-
}
|
|
304
|
-
route = route.replace(new RegExp(`.${platformExtension}$`), '');
|
|
305
|
-
}
|
|
306
|
-
return {
|
|
307
|
-
route,
|
|
308
|
-
specificity,
|
|
309
|
-
isLayout,
|
|
310
|
-
isApi,
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
function getIgnoreList(options) {
|
|
314
|
-
const ignore = [/^\.\/\+html\.[tj]sx?$/, ...(options?.ignore ?? [])];
|
|
315
|
-
if (options?.preserveApiRoutes !== true) {
|
|
316
|
-
ignore.push(/\+api\.[tj]sx?$/);
|
|
317
|
-
}
|
|
318
|
-
return ignore;
|
|
319
|
-
}
|
|
320
|
-
exports.getIgnoreList = getIgnoreList;
|
|
321
|
-
/**
|
|
322
|
-
* Generates a set of strings which have the router array syntax extrapolated.
|
|
323
|
-
*
|
|
324
|
-
* /(a,b)/(c,d)/e.tsx => new Set(['a/c/e.tsx', 'a/d/e.tsx', 'b/c/e.tsx', 'b/d/e.tsx'])
|
|
325
|
-
*/
|
|
326
|
-
function extrapolateGroups(key, keys = new Set()) {
|
|
327
|
-
const match = (0, matchers_1.matchArrayGroupName)(key);
|
|
328
|
-
if (!match) {
|
|
329
|
-
keys.add(key);
|
|
330
|
-
return keys;
|
|
331
|
-
}
|
|
332
|
-
const groups = match.split(',');
|
|
333
|
-
const groupsSet = new Set(groups);
|
|
334
|
-
if (groupsSet.size !== groups.length) {
|
|
335
|
-
throw new Error(`Array syntax cannot contain duplicate group name "${groups}" in "${key}".`);
|
|
336
|
-
}
|
|
337
|
-
if (groups.length === 1) {
|
|
338
|
-
keys.add(key);
|
|
339
|
-
return keys;
|
|
340
|
-
}
|
|
341
|
-
for (const group of groups) {
|
|
342
|
-
extrapolateGroups(key.replace(match, group.trim()), keys);
|
|
343
|
-
}
|
|
344
|
-
return keys;
|
|
345
|
-
}
|
|
346
|
-
exports.extrapolateGroups = extrapolateGroups;
|
|
347
|
-
function generateDynamic(path) {
|
|
348
|
-
const dynamic = path
|
|
349
|
-
.split('/')
|
|
350
|
-
.map((part) => {
|
|
351
|
-
if (part === '+not-found') {
|
|
352
|
-
return {
|
|
353
|
-
name: '+not-found',
|
|
354
|
-
deep: true,
|
|
355
|
-
notFound: true,
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
const deepDynamicName = (0, matchers_1.matchDeepDynamicRouteName)(part);
|
|
359
|
-
const dynamicName = deepDynamicName ?? (0, matchers_1.matchDynamicName)(part);
|
|
360
|
-
if (!dynamicName)
|
|
361
|
-
return null;
|
|
362
|
-
return { name: dynamicName, deep: !!deepDynamicName };
|
|
363
|
-
})
|
|
364
|
-
.filter((part) => !!part);
|
|
365
|
-
return dynamic.length === 0 ? null : dynamic;
|
|
366
|
-
}
|
|
367
|
-
exports.generateDynamic = generateDynamic;
|
|
368
|
-
function appendSitemapRoute(directory) {
|
|
369
|
-
if (!directory.files.has('_sitemap')) {
|
|
370
|
-
directory.files.set('_sitemap', [
|
|
371
|
-
{
|
|
372
|
-
loadRoute() {
|
|
373
|
-
const { Sitemap, getNavOptions } = require('./views/Sitemap');
|
|
374
|
-
return { default: Sitemap, getNavOptions };
|
|
375
|
-
},
|
|
376
|
-
route: '_sitemap',
|
|
377
|
-
type: 'route',
|
|
378
|
-
contextKey: 'expo-router/build/views/Sitemap.js',
|
|
379
|
-
generated: true,
|
|
380
|
-
internal: true,
|
|
381
|
-
dynamic: null,
|
|
382
|
-
children: [],
|
|
383
|
-
},
|
|
384
|
-
]);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
function appendNotFoundRoute(directory) {
|
|
388
|
-
if (!directory.files.has('+not-found')) {
|
|
389
|
-
directory.files.set('+not-found', [
|
|
390
|
-
{
|
|
391
|
-
loadRoute() {
|
|
392
|
-
return { default: require('./views/Unmatched').Unmatched };
|
|
393
|
-
},
|
|
394
|
-
type: 'route',
|
|
395
|
-
route: '+not-found',
|
|
396
|
-
contextKey: 'expo-router/build/views/Unmatched.js',
|
|
397
|
-
generated: true,
|
|
398
|
-
internal: true,
|
|
399
|
-
dynamic: [{ name: '+not-found', deep: true, notFound: true }],
|
|
400
|
-
children: [],
|
|
401
|
-
},
|
|
402
|
-
]);
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
function getLayoutNode(node, options) {
|
|
406
|
-
/**
|
|
407
|
-
* A file called `(a,b)/(c)/_layout.tsx` will generate two _layout routes: `(a)/(c)/_layout` and `(b)/(c)/_layout`.
|
|
408
|
-
* Each of these layouts will have a different initialRouteName based upon the first group name.
|
|
409
|
-
*
|
|
410
|
-
* So
|
|
411
|
-
*/
|
|
412
|
-
// We may strip loadRoute during testing
|
|
413
|
-
const groupName = (0, matchers_1.matchGroupName)(node.route);
|
|
414
|
-
const childMatchingGroup = node.children.find((child) => {
|
|
415
|
-
return child.route.replace(/\/index$/, '') === groupName;
|
|
416
|
-
});
|
|
417
|
-
let initialRouteName = childMatchingGroup?.route;
|
|
418
|
-
const loaded = node.loadRoute();
|
|
419
|
-
if (loaded?.unstable_settings) {
|
|
420
|
-
// Allow unstable_settings={ initialRouteName: '...' } to override the default initial route name.
|
|
421
|
-
initialRouteName = loaded.unstable_settings.initialRouteName ?? initialRouteName;
|
|
422
|
-
if (groupName) {
|
|
423
|
-
// Allow unstable_settings={ 'custom': { initialRouteName: '...' } } to override the less specific initial route name.
|
|
424
|
-
const groupSpecificInitialRouteName = loaded.unstable_settings?.[groupName]?.initialRouteName;
|
|
425
|
-
initialRouteName = groupSpecificInitialRouteName ?? initialRouteName;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
return {
|
|
429
|
-
...node,
|
|
430
|
-
route: node.route.replace(/\/?_layout$/, ''),
|
|
431
|
-
children: [],
|
|
432
|
-
initialRouteName,
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
function crawlAndAppendInitialRoutesAndEntryFiles(node, options, entryPoints = []) {
|
|
436
|
-
if (node.type === 'route') {
|
|
437
|
-
node.entryPoints = [...new Set([...entryPoints, node.contextKey])];
|
|
438
|
-
}
|
|
439
|
-
else if (node.type === 'layout') {
|
|
440
|
-
if (!node.children) {
|
|
441
|
-
throw new Error(`Layout "${node.contextKey}" does not contain any child routes`);
|
|
442
|
-
}
|
|
443
|
-
// Every node below this layout will have it as an entryPoint
|
|
444
|
-
entryPoints = [...entryPoints, node.contextKey];
|
|
445
|
-
/**
|
|
446
|
-
* Calculate the initialRouteNode
|
|
447
|
-
*
|
|
448
|
-
* A file called `(a,b)/(c)/_layout.tsx` will generate two _layout routes: `(a)/(c)/_layout` and `(b)/(c)/_layout`.
|
|
449
|
-
* Each of these layouts will have a different initialRouteName based upon the first group.
|
|
450
|
-
*/
|
|
451
|
-
const groupName = (0, matchers_1.matchGroupName)(node.route);
|
|
452
|
-
const childMatchingGroup = node.children.find((child) => {
|
|
453
|
-
return child.route.replace(/\/index$/, '') === groupName;
|
|
454
|
-
});
|
|
455
|
-
let initialRouteName = childMatchingGroup?.route;
|
|
456
|
-
// We may strip loadRoute during testing
|
|
457
|
-
if (!options.internal_stripLoadRoute) {
|
|
458
|
-
const loaded = node.loadRoute();
|
|
459
|
-
if (loaded?.unstable_settings) {
|
|
460
|
-
// Allow unstable_settings={ initialRouteName: '...' } to override the default initial route name.
|
|
461
|
-
initialRouteName = loaded.unstable_settings.initialRouteName ?? initialRouteName;
|
|
462
|
-
if (groupName) {
|
|
463
|
-
// Allow unstable_settings={ 'custom': { initialRouteName: '...' } } to override the less specific initial route name.
|
|
464
|
-
const groupSpecificInitialRouteName = loaded.unstable_settings?.[groupName]?.initialRouteName;
|
|
465
|
-
initialRouteName = groupSpecificInitialRouteName ?? initialRouteName;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
if (initialRouteName) {
|
|
470
|
-
const initialRoute = node.children.find((child) => child.route === initialRouteName);
|
|
471
|
-
if (!initialRoute) {
|
|
472
|
-
const validInitialRoutes = node.children
|
|
473
|
-
.filter((child) => !child.generated)
|
|
474
|
-
.map((child) => `'${child.route}'`)
|
|
475
|
-
.join(', ');
|
|
476
|
-
if (groupName) {
|
|
477
|
-
throw new Error(`Layout ${node.contextKey} has invalid initialRouteName '${initialRouteName}' for group '(${groupName})'. Valid options are: ${validInitialRoutes}`);
|
|
478
|
-
}
|
|
479
|
-
else {
|
|
480
|
-
throw new Error(`Layout ${node.contextKey} has invalid initialRouteName '${initialRouteName}'. Valid options are: ${validInitialRoutes}`);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
// Navigators can add initialsRoutes into the history, so they need to be to be included in the entryPoints
|
|
484
|
-
node.initialRouteName = initialRouteName;
|
|
485
|
-
entryPoints.push(initialRoute.contextKey);
|
|
486
|
-
}
|
|
487
|
-
for (const child of node.children) {
|
|
488
|
-
crawlAndAppendInitialRoutesAndEntryFiles(child, options, entryPoints);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
function getMostSpecific(routes) {
|
|
493
|
-
const route = routes[routes.length - 1];
|
|
494
|
-
if (!routes[0]) {
|
|
495
|
-
throw new Error(`The file ${route.contextKey} does not have a fallback sibling file without a platform extension.`);
|
|
496
|
-
}
|
|
497
|
-
// This works even tho routes is holey array (e.g it might have index 0 and 2 but not 1)
|
|
498
|
-
// `.length` includes the holes in its count
|
|
499
|
-
return routes[routes.length - 1];
|
|
500
|
-
}
|
|
78
|
+
var getRoutesCore_2 = require("./getRoutesCore");
|
|
79
|
+
Object.defineProperty(exports, "generateDynamic", { enumerable: true, get: function () { return getRoutesCore_2.generateDynamic; } });
|
|
80
|
+
Object.defineProperty(exports, "extrapolateGroups", { enumerable: true, get: function () { return getRoutesCore_2.extrapolateGroups; } });
|
|
81
|
+
Object.defineProperty(exports, "getIgnoreList", { enumerable: true, get: function () { return getRoutesCore_2.getIgnoreList; } });
|
|
501
82
|
//# sourceMappingURL=getRoutes.js.map
|