@expo/cli 0.10.10 → 0.11.0
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/bin/cli +2 -2
- package/build/src/api/endpoint.js +10 -0
- package/build/src/api/endpoint.js.map +1 -1
- package/build/src/api/graphql/queries/UserQuery.js +2 -1
- package/build/src/api/graphql/queries/UserQuery.js.map +1 -1
- package/build/src/api/user/UserSettings.js.map +1 -1
- package/build/src/api/user/actions.js +6 -1
- package/build/src/api/user/actions.js.map +1 -1
- package/build/src/api/user/expoSsoLauncher.js +127 -0
- package/build/src/api/user/expoSsoLauncher.js.map +1 -0
- package/build/src/api/user/user.js +46 -18
- package/build/src/api/user/user.js.map +1 -1
- package/build/src/export/index.js +3 -1
- package/build/src/export/index.js.map +1 -1
- package/build/src/export/resolveOptions.js +28 -29
- package/build/src/export/resolveOptions.js.map +1 -1
- package/build/src/graphql/generated.js +25 -1
- package/build/src/graphql/generated.js.map +1 -1
- package/build/src/login/index.js +7 -2
- package/build/src/login/index.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +35 -3
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/MetroTerminalReporter.js +9 -1
- package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/metroWatchTypeScriptFiles.js +1 -1
- package/build/src/start/server/metro/metroWatchTypeScriptFiles.js.map +1 -1
- package/build/src/start/server/metro/withMetroMultiPlatform.js +2 -2
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/metro/withMetroResolvers.js +166 -16
- package/build/src/start/server/metro/withMetroResolvers.js.map +1 -1
- package/build/src/start/server/middleware/ClassicManifestMiddleware.js +1 -1
- package/build/src/start/server/middleware/ManifestMiddleware.js +23 -6
- package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
- package/build/src/start/server/type-generation/__typetests__/fixtures/basic.js.map +1 -1
- package/build/src/start/server/type-generation/__typetests__/route.test.js +20 -9
- package/build/src/start/server/type-generation/__typetests__/route.test.js.map +1 -1
- package/build/src/start/server/type-generation/routes.js +120 -50
- package/build/src/start/server/type-generation/routes.js.map +1 -1
- package/build/src/utils/analytics/metroDebuggerMiddleware.js +9 -4
- package/build/src/utils/analytics/metroDebuggerMiddleware.js.map +1 -1
- package/build/src/utils/analytics/rudderstackClient.js +2 -2
- package/build/src/utils/env.js +3 -0
- package/build/src/utils/env.js.map +1 -1
- package/build/src/utils/port.js +2 -0
- package/build/src/utils/port.js.map +1 -1
- package/package.json +8 -8
- package/static/react-devtools-page/index.html +1 -1
|
@@ -4,8 +4,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
exports.getDefaultMetroResolver = getDefaultMetroResolver;
|
|
6
6
|
exports.withMetroResolvers = withMetroResolvers;
|
|
7
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
|
9
|
+
var _env = require("../../../utils/env");
|
|
7
10
|
var _metroErrors = require("./metroErrors");
|
|
8
11
|
var _resolveFromProject = require("./resolveFromProject");
|
|
12
|
+
function _interopRequireDefault(obj) {
|
|
13
|
+
return obj && obj.__esModule ? obj : {
|
|
14
|
+
default: obj
|
|
15
|
+
};
|
|
16
|
+
}
|
|
9
17
|
const debug = require("debug")("expo:metro:withMetroResolvers");
|
|
10
18
|
function getDefaultMetroResolver(projectRoot) {
|
|
11
19
|
const { resolve } = (0, _resolveFromProject).importMetroResolverFromProject(projectRoot);
|
|
@@ -13,32 +21,174 @@ function getDefaultMetroResolver(projectRoot) {
|
|
|
13
21
|
return resolve(context, moduleName, platform);
|
|
14
22
|
};
|
|
15
23
|
}
|
|
24
|
+
function optionsKeyForContext(context) {
|
|
25
|
+
const canonicalize = require("metro-core/src/canonicalize");
|
|
26
|
+
var _customResolverOptions, ref;
|
|
27
|
+
// Compound key for the resolver cache
|
|
28
|
+
return (ref = JSON.stringify((_customResolverOptions = context.customResolverOptions) != null ? _customResolverOptions : {}, canonicalize)) != null ? ref : "";
|
|
29
|
+
}
|
|
16
30
|
function withMetroResolvers(config, projectRoot, resolvers) {
|
|
17
31
|
debug(`Appending ${resolvers.length} custom resolvers to Metro config. (has custom resolver: ${!!config.resolver.resolveRequest})`);
|
|
18
32
|
const originalResolveRequest = config.resolver.resolveRequest || getDefaultMetroResolver(projectRoot);
|
|
33
|
+
function mutateResolutionError(error, context, moduleName, platform) {
|
|
34
|
+
var ref;
|
|
35
|
+
if (!_env.env.EXPO_METRO_UNSTABLE_ERRORS || !platform) {
|
|
36
|
+
debug("Cannot mutate resolution error");
|
|
37
|
+
return error;
|
|
38
|
+
}
|
|
39
|
+
const mapByOrigin = depGraph.get(optionsKeyForContext(context));
|
|
40
|
+
const mapByPlatform = mapByOrigin == null ? void 0 : mapByOrigin.get(platform);
|
|
41
|
+
if (!mapByPlatform) {
|
|
42
|
+
return error;
|
|
43
|
+
}
|
|
44
|
+
// collect all references inversely using some expensive lookup
|
|
45
|
+
const getReferences = (origin)=>{
|
|
46
|
+
const inverseOrigin = [];
|
|
47
|
+
if (!mapByPlatform) {
|
|
48
|
+
return inverseOrigin;
|
|
49
|
+
}
|
|
50
|
+
for (const [originKey, mapByTarget] of mapByPlatform){
|
|
51
|
+
// search comparing origin to path
|
|
52
|
+
const found = [
|
|
53
|
+
...mapByTarget.values()
|
|
54
|
+
].find((resolution)=>resolution.path === origin
|
|
55
|
+
);
|
|
56
|
+
if (found) {
|
|
57
|
+
inverseOrigin.push({
|
|
58
|
+
origin,
|
|
59
|
+
previous: originKey,
|
|
60
|
+
request: found.request
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return inverseOrigin;
|
|
65
|
+
};
|
|
66
|
+
const pad = (num)=>{
|
|
67
|
+
return new Array(num).fill(" ").join("");
|
|
68
|
+
};
|
|
69
|
+
var ref1, ref2;
|
|
70
|
+
const root = (ref2 = (ref1 = (ref = config.server) == null ? void 0 : ref.unstable_serverRoot) != null ? ref1 : config.projectRoot) != null ? ref2 : projectRoot;
|
|
71
|
+
const recurseBackWithLimit = (req, limit, count = 0)=>{
|
|
72
|
+
const results = {
|
|
73
|
+
origin: req.origin,
|
|
74
|
+
request: req.request,
|
|
75
|
+
previous: []
|
|
76
|
+
};
|
|
77
|
+
if (count >= limit) {
|
|
78
|
+
return results;
|
|
79
|
+
}
|
|
80
|
+
const inverse = getReferences(req.origin);
|
|
81
|
+
for (const match of inverse){
|
|
82
|
+
// Use more qualified name if possible
|
|
83
|
+
// results.origin = match.origin;
|
|
84
|
+
// Found entry point
|
|
85
|
+
if (req.origin === match.previous) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
results.previous.push(recurseBackWithLimit({
|
|
89
|
+
origin: match.previous,
|
|
90
|
+
request: match.request
|
|
91
|
+
}, limit, count + 1));
|
|
92
|
+
}
|
|
93
|
+
return results;
|
|
94
|
+
};
|
|
95
|
+
const inverseTree = recurseBackWithLimit({
|
|
96
|
+
origin: context.originModulePath,
|
|
97
|
+
request: moduleName
|
|
98
|
+
}, // TODO: Do we need to expose this?
|
|
99
|
+
35);
|
|
100
|
+
if (inverseTree.previous.length > 0) {
|
|
101
|
+
debug("Found inverse graph:", JSON.stringify(inverseTree, null, 2));
|
|
102
|
+
let extraMessage = _chalk.default.bold("Import stack:");
|
|
103
|
+
const printRecursive = (tree, depth = 0)=>{
|
|
104
|
+
let filename = _path.default.relative(root, tree.origin);
|
|
105
|
+
if (filename.match(/\?ctx=[\w\d]+$/)) {
|
|
106
|
+
filename = filename.replace(/\?ctx=[\w\d]+$/, _chalk.default.dim(" (require.context)"));
|
|
107
|
+
} else {
|
|
108
|
+
let formattedRequest = _chalk.default.green(`"${tree.request}"`);
|
|
109
|
+
if (// If bundling for web and the import is pulling internals from outside of react-native
|
|
110
|
+
// then mark it as an invalid import.
|
|
111
|
+
platform === "web" && !/^(node_modules\/)?react-native\//.test(filename) && tree.request.match(/^react-native\/.*/)) {
|
|
112
|
+
formattedRequest = formattedRequest + _chalk.default`\n {yellow Importing react-native internals is not supported on web.}`;
|
|
113
|
+
}
|
|
114
|
+
filename = filename + _chalk.default`\n{gray |} {cyan import} ${formattedRequest}\n`;
|
|
115
|
+
}
|
|
116
|
+
let line = "\n" + pad(depth) + _chalk.default.gray(" ") + filename;
|
|
117
|
+
if (filename.match(/node_modules/)) {
|
|
118
|
+
line = _chalk.default.gray(// Bold the node module name
|
|
119
|
+
line.replace(/node_modules\/([^/]+)/, (_match, p1)=>{
|
|
120
|
+
return "node_modules/" + _chalk.default.bold(p1);
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
extraMessage += line;
|
|
124
|
+
for (const child of tree.previous){
|
|
125
|
+
printRecursive(child, // Only add depth if there are multiple children
|
|
126
|
+
tree.previous.length > 1 ? depth + 1 : depth);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
printRecursive(inverseTree);
|
|
130
|
+
// @ts-expect-error
|
|
131
|
+
error._expoImportStack = extraMessage;
|
|
132
|
+
} else {
|
|
133
|
+
debug("Found no inverse tree for:", context.originModulePath);
|
|
134
|
+
}
|
|
135
|
+
return error;
|
|
136
|
+
}
|
|
137
|
+
const depGraph = new Map();
|
|
19
138
|
return {
|
|
20
139
|
...config,
|
|
21
140
|
resolver: {
|
|
22
141
|
...config.resolver,
|
|
23
|
-
resolveRequest (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
142
|
+
resolveRequest (context, moduleName, platform) {
|
|
143
|
+
const storeResult = (res)=>{
|
|
144
|
+
if (!_env.env.EXPO_METRO_UNSTABLE_ERRORS || !platform) return;
|
|
145
|
+
const key = optionsKeyForContext(context);
|
|
146
|
+
if (!depGraph.has(key)) depGraph.set(key, new Map());
|
|
147
|
+
const mapByTarget = depGraph.get(key);
|
|
148
|
+
if (!mapByTarget.has(platform)) mapByTarget.set(platform, new Map());
|
|
149
|
+
const mapByPlatform = mapByTarget.get(platform);
|
|
150
|
+
if (!mapByPlatform.has(context.originModulePath)) mapByPlatform.set(context.originModulePath, new Set());
|
|
151
|
+
const setForModule = mapByPlatform.get(context.originModulePath);
|
|
152
|
+
const qualifiedModuleName = (res == null ? void 0 : res.type) === "sourceFile" ? res.filePath : moduleName;
|
|
153
|
+
setForModule.add({
|
|
154
|
+
path: qualifiedModuleName,
|
|
155
|
+
request: moduleName
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
const universalContext = {
|
|
159
|
+
...context,
|
|
160
|
+
preferNativePlatform: platform !== "web"
|
|
161
|
+
};
|
|
162
|
+
try {
|
|
163
|
+
for (const resolver of resolvers){
|
|
164
|
+
try {
|
|
165
|
+
const resolution = resolver(universalContext, moduleName, platform);
|
|
166
|
+
if (resolution) {
|
|
167
|
+
storeResult(resolution);
|
|
168
|
+
return resolution;
|
|
169
|
+
}
|
|
170
|
+
} catch (error) {
|
|
171
|
+
// If no user-defined resolver, use Expo's default behavior.
|
|
172
|
+
// This prevents extraneous resolution attempts on failure.
|
|
173
|
+
if (!config.resolver.resolveRequest) {
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
// If the error is directly related to a resolver not being able to resolve a module, then
|
|
177
|
+
// we can ignore the error and try the next resolver. Otherwise, we should throw the error.
|
|
178
|
+
const isResolutionError = (0, _metroErrors).isFailedToResolveNameError(error) || (0, _metroErrors).isFailedToResolvePathError(error);
|
|
179
|
+
if (!isResolutionError) {
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
debug(`Custom resolver threw: ${error.constructor.name}. (module: ${moduleName}, platform: ${platform})`);
|
|
36
183
|
}
|
|
37
|
-
debug(`Custom resolver threw: ${error.constructor.name}. (module: ${args[1]}, platform: ${args[2]})`);
|
|
38
184
|
}
|
|
185
|
+
// If we haven't returned by now, use the original resolver or upstream resolver.
|
|
186
|
+
const res = originalResolveRequest(universalContext, moduleName, platform);
|
|
187
|
+
storeResult(res);
|
|
188
|
+
return res;
|
|
189
|
+
} catch (error) {
|
|
190
|
+
throw mutateResolutionError(error, universalContext, moduleName, platform);
|
|
39
191
|
}
|
|
40
|
-
// If we haven't returned by now, use the original resolver or upstream resolver.
|
|
41
|
-
return originalResolveRequest(...args);
|
|
42
192
|
}
|
|
43
193
|
}
|
|
44
194
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/withMetroResolvers.ts"],"sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { ConfigT as MetroConfig } from 'metro-config';\nimport { ResolutionContext } from 'metro-resolver';\n\nimport { isFailedToResolveNameError, isFailedToResolvePathError } from './metroErrors';\nimport { importMetroResolverFromProject } from './resolveFromProject';\n\nconst debug = require('debug')('expo:metro:withMetroResolvers') as typeof console.log;\n\nexport type MetroResolver = NonNullable<MetroConfig['resolver']['resolveRequest']>;\n\n/** Expo Metro Resolvers can return `null` to skip without throwing an error. Metro Resolvers will throw either a `FailedToResolveNameError` or `FailedToResolvePathError`. */\nexport type ExpoCustomMetroResolver = (\n ...args: Parameters<MetroResolver>\n) => ReturnType<MetroResolver> | null;\n\n/** @returns `MetroResolver` utilizing the upstream `resolve` method. */\nexport function getDefaultMetroResolver(projectRoot: string): MetroResolver {\n const { resolve } = importMetroResolverFromProject(projectRoot);\n return (context: ResolutionContext, moduleName: string, platform: string | null) => {\n return resolve(context, moduleName, platform);\n };\n}\n\n/**\n * Extend the Metro config `resolver.resolveRequest` method with additional resolvers that can\n * exit early by returning a `Resolution` or skip to the next resolver by returning `null`.\n *\n * @param config Metro config.\n * @param projectRoot path to the project root used to resolve the default Metro resolver.\n * @param resolvers custom MetroResolver to chain.\n * @returns a new `MetroConfig` with the `resolver.resolveRequest` method chained.\n */\nexport function withMetroResolvers(\n config: MetroConfig,\n projectRoot: string,\n resolvers: ExpoCustomMetroResolver[]\n): MetroConfig {\n debug(\n `Appending ${\n resolvers.length\n } custom resolvers to Metro config. (has custom resolver: ${!!config.resolver.resolveRequest})`\n );\n const originalResolveRequest =\n config.resolver.resolveRequest || getDefaultMetroResolver(projectRoot);\n\n return {\n ...config,\n resolver: {\n ...config.resolver,\n resolveRequest(...args: Parameters<MetroResolver>) {\n for (const resolver of resolvers) {\n try {\n const resolution = resolver(...args);\n if (resolution) {\n return resolution;\n }\n } catch (error: any) {\n // If the error is directly related to a resolver not being able to resolve a module, then\n // we can ignore the error and try the next resolver. Otherwise, we should throw the error.\n const isResolutionError =\n isFailedToResolveNameError(error) || isFailedToResolvePathError(error);\n if (!isResolutionError) {\n throw error;\n }\n debug(\n `Custom resolver threw: ${error.constructor.name}. (module: ${args[1]}, platform: ${args[2]})`\n );\n }\n }\n // If we haven't returned by now, use the original resolver or upstream resolver.\n return originalResolveRequest(...args);\n },\n },\n };\n}\n"],"names":["getDefaultMetroResolver","withMetroResolvers","debug","require","projectRoot","resolve","importMetroResolverFromProject","context","moduleName","platform","config","resolvers","length","resolver","resolveRequest","originalResolveRequest","args","resolution","error","isResolutionError","isFailedToResolveNameError","isFailedToResolvePathError","constructor","name"],"mappings":"AAMA;;;;QAgBgBA,uBAAuB,GAAvBA,uBAAuB;QAgBvBC,kBAAkB,GAAlBA,kBAAkB;AA7BqC,IAAA,YAAe,WAAf,eAAe,CAAA;AACvC,IAAA,mBAAsB,WAAtB,sBAAsB,CAAA;AAErE,MAAMC,KAAK,GAAGC,OAAO,CAAC,OAAO,CAAC,CAAC,+BAA+B,CAAC,AAAsB,AAAC;AAU/E,SAASH,uBAAuB,CAACI,WAAmB,EAAiB;IAC1E,MAAM,EAAEC,OAAO,CAAA,EAAE,GAAGC,CAAAA,GAAAA,mBAA8B,AAAa,CAAA,+BAAb,CAACF,WAAW,CAAC,AAAC;IAChE,OAAO,CAACG,OAA0B,EAAEC,UAAkB,EAAEC,QAAuB,GAAK;QAClF,OAAOJ,OAAO,CAACE,OAAO,EAAEC,UAAU,EAAEC,QAAQ,CAAC,CAAC;KAC/C,CAAC;CACH;AAWM,SAASR,kBAAkB,CAChCS,MAAmB,EACnBN,WAAmB,EACnBO,SAAoC,EACvB;IACbT,KAAK,CACH,CAAC,UAAU,EACTS,SAAS,CAACC,MAAM,CACjB,yDAAyD,EAAE,CAAC,CAACF,MAAM,CAACG,QAAQ,CAACC,cAAc,CAAC,CAAC,CAAC,CAChG,CAAC;IACF,MAAMC,sBAAsB,GAC1BL,MAAM,CAACG,QAAQ,CAACC,cAAc,IAAId,uBAAuB,CAACI,WAAW,CAAC,AAAC;IAEzE,OAAO;QACL,GAAGM,MAAM;QACTG,QAAQ,EAAE;YACR,GAAGH,MAAM,CAACG,QAAQ;YAClBC,cAAc,EAAC,GAAGE,IAAI,AAA2B,EAAE;gBACjD,KAAK,MAAMH,QAAQ,IAAIF,SAAS,CAAE;oBAChC,IAAI;wBACF,MAAMM,UAAU,GAAGJ,QAAQ,IAAIG,IAAI,CAAC,AAAC;wBACrC,IAAIC,UAAU,EAAE;4BACd,OAAOA,UAAU,CAAC;yBACnB;qBACF,CAAC,OAAOC,KAAK,EAAO;wBACnB,0FAA0F;wBAC1F,2FAA2F;wBAC3F,MAAMC,iBAAiB,GACrBC,CAAAA,GAAAA,YAA0B,AAAO,CAAA,2BAAP,CAACF,KAAK,CAAC,IAAIG,CAAAA,GAAAA,YAA0B,AAAO,CAAA,2BAAP,CAACH,KAAK,CAAC,AAAC;wBACzE,IAAI,CAACC,iBAAiB,EAAE;4BACtB,MAAMD,KAAK,CAAC;yBACb;wBACDhB,KAAK,CACH,CAAC,uBAAuB,EAAEgB,KAAK,CAACI,WAAW,CAACC,IAAI,CAAC,WAAW,EAAEP,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,EAAEA,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC/F,CAAC;qBACH;iBACF;gBACD,iFAAiF;gBACjF,OAAOD,sBAAsB,IAAIC,IAAI,CAAC,CAAC;aACxC;SACF;KACF,CAAC;CACH"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/withMetroResolvers.ts"],"sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport chalk from 'chalk';\nimport { ConfigT as MetroConfig } from 'metro-config';\nimport { ResolutionContext } from 'metro-resolver';\nimport path from 'path';\n\nimport { env } from '../../../utils/env';\nimport { isFailedToResolveNameError, isFailedToResolvePathError } from './metroErrors';\nimport { importMetroResolverFromProject } from './resolveFromProject';\n\nconst debug = require('debug')('expo:metro:withMetroResolvers') as typeof console.log;\n\nexport type MetroResolver = NonNullable<MetroConfig['resolver']['resolveRequest']>;\n\n/** Expo Metro Resolvers can return `null` to skip without throwing an error. Metro Resolvers will throw either a `FailedToResolveNameError` or `FailedToResolvePathError`. */\nexport type ExpoCustomMetroResolver = (\n ...args: Parameters<MetroResolver>\n) => ReturnType<MetroResolver> | null;\n\n/** @returns `MetroResolver` utilizing the upstream `resolve` method. */\nexport function getDefaultMetroResolver(projectRoot: string): MetroResolver {\n const { resolve } = importMetroResolverFromProject(projectRoot);\n return (context: ResolutionContext, moduleName: string, platform: string | null) => {\n return resolve(context, moduleName, platform);\n };\n}\n\nfunction optionsKeyForContext(context: ResolutionContext) {\n const canonicalize = require('metro-core/src/canonicalize');\n\n // Compound key for the resolver cache\n return JSON.stringify(context.customResolverOptions ?? {}, canonicalize) ?? '';\n}\n\n/**\n * Extend the Metro config `resolver.resolveRequest` method with additional resolvers that can\n * exit early by returning a `Resolution` or skip to the next resolver by returning `null`.\n *\n * @param config Metro config.\n * @param projectRoot path to the project root used to resolve the default Metro resolver.\n * @param resolvers custom MetroResolver to chain.\n * @returns a new `MetroConfig` with the `resolver.resolveRequest` method chained.\n */\nexport function withMetroResolvers(\n config: MetroConfig,\n projectRoot: string,\n resolvers: ExpoCustomMetroResolver[]\n): MetroConfig {\n debug(\n `Appending ${\n resolvers.length\n } custom resolvers to Metro config. (has custom resolver: ${!!config.resolver.resolveRequest})`\n );\n const originalResolveRequest =\n config.resolver.resolveRequest || getDefaultMetroResolver(projectRoot);\n\n function mutateResolutionError(\n error: Error,\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n if (!env.EXPO_METRO_UNSTABLE_ERRORS || !platform) {\n debug('Cannot mutate resolution error');\n return error;\n }\n\n const mapByOrigin = depGraph.get(optionsKeyForContext(context));\n const mapByPlatform = mapByOrigin?.get(platform);\n\n if (!mapByPlatform) {\n return error;\n }\n\n // collect all references inversely using some expensive lookup\n\n const getReferences = (origin: string) => {\n const inverseOrigin: { origin: string; previous: string; request: string }[] = [];\n\n if (!mapByPlatform) {\n return inverseOrigin;\n }\n\n for (const [originKey, mapByTarget] of mapByPlatform) {\n // search comparing origin to path\n\n const found = [...mapByTarget.values()].find((resolution) => resolution.path === origin);\n if (found) {\n inverseOrigin.push({\n origin,\n previous: originKey,\n request: found.request,\n });\n }\n }\n\n return inverseOrigin;\n };\n\n const pad = (num: number) => {\n return new Array(num).fill(' ').join('');\n };\n\n const root = config.server?.unstable_serverRoot ?? config.projectRoot ?? projectRoot;\n\n type InverseDepResult = {\n origin: string;\n request: string;\n previous: InverseDepResult[];\n };\n const recurseBackWithLimit = (\n req: { origin: string; request: string },\n limit: number,\n count: number = 0\n ) => {\n const results: InverseDepResult = {\n origin: req.origin,\n request: req.request,\n previous: [],\n };\n\n if (count >= limit) {\n return results;\n }\n\n const inverse = getReferences(req.origin);\n for (const match of inverse) {\n // Use more qualified name if possible\n // results.origin = match.origin;\n // Found entry point\n if (req.origin === match.previous) {\n continue;\n }\n results.previous.push(\n recurseBackWithLimit({ origin: match.previous, request: match.request }, limit, count + 1)\n );\n }\n return results;\n };\n\n const inverseTree = recurseBackWithLimit(\n { origin: context.originModulePath, request: moduleName },\n // TODO: Do we need to expose this?\n 35\n );\n\n if (inverseTree.previous.length > 0) {\n debug('Found inverse graph:', JSON.stringify(inverseTree, null, 2));\n let extraMessage = chalk.bold('Import stack:');\n const printRecursive = (tree: InverseDepResult, depth: number = 0) => {\n let filename = path.relative(root, tree.origin);\n if (filename.match(/\\?ctx=[\\w\\d]+$/)) {\n filename = filename.replace(/\\?ctx=[\\w\\d]+$/, chalk.dim(' (require.context)'));\n } else {\n let formattedRequest = chalk.green(`\"${tree.request}\"`);\n\n if (\n // If bundling for web and the import is pulling internals from outside of react-native\n // then mark it as an invalid import.\n platform === 'web' &&\n !/^(node_modules\\/)?react-native\\//.test(filename) &&\n tree.request.match(/^react-native\\/.*/)\n ) {\n formattedRequest =\n formattedRequest +\n chalk`\\n {yellow Importing react-native internals is not supported on web.}`;\n }\n\n filename = filename + chalk`\\n{gray |} {cyan import} ${formattedRequest}\\n`;\n }\n let line = '\\n' + pad(depth) + chalk.gray(' ') + filename;\n if (filename.match(/node_modules/)) {\n line = chalk.gray(\n // Bold the node module name\n line.replace(/node_modules\\/([^/]+)/, (_match, p1) => {\n return 'node_modules/' + chalk.bold(p1);\n })\n );\n }\n extraMessage += line;\n for (const child of tree.previous) {\n printRecursive(\n child,\n // Only add depth if there are multiple children\n tree.previous.length > 1 ? depth + 1 : depth\n );\n }\n };\n printRecursive(inverseTree);\n\n // @ts-expect-error\n error._expoImportStack = extraMessage;\n } else {\n debug('Found no inverse tree for:', context.originModulePath);\n }\n\n return error;\n }\n\n const depGraph: Map<\n // custom options\n string,\n Map<\n // platform\n string,\n Map<\n // origin module name\n string,\n Set<{\n // required module name\n path: string;\n // This isn't entirely accurate since a module can be imported multiple times in a file,\n // and use different names. But it's good enough for now.\n request: string;\n }>\n >\n >\n > = new Map();\n\n return {\n ...config,\n resolver: {\n ...config.resolver,\n resolveRequest(context, moduleName, platform) {\n const storeResult = (res: NonNullable<ReturnType<ExpoCustomMetroResolver>>) => {\n if (!env.EXPO_METRO_UNSTABLE_ERRORS || !platform) return;\n\n const key = optionsKeyForContext(context);\n if (!depGraph.has(key)) depGraph.set(key, new Map());\n const mapByTarget = depGraph.get(key);\n if (!mapByTarget!.has(platform)) mapByTarget!.set(platform, new Map());\n const mapByPlatform = mapByTarget!.get(platform);\n if (!mapByPlatform!.has(context.originModulePath))\n mapByPlatform!.set(context.originModulePath, new Set());\n const setForModule = mapByPlatform!.get(context.originModulePath)!;\n\n const qualifiedModuleName = res?.type === 'sourceFile' ? res.filePath : moduleName;\n setForModule.add({ path: qualifiedModuleName, request: moduleName });\n };\n\n const universalContext = {\n ...context,\n preferNativePlatform: platform !== 'web',\n };\n\n try {\n for (const resolver of resolvers) {\n try {\n const resolution = resolver(universalContext, moduleName, platform);\n if (resolution) {\n storeResult(resolution);\n return resolution;\n }\n } catch (error: any) {\n // If no user-defined resolver, use Expo's default behavior.\n // This prevents extraneous resolution attempts on failure.\n if (!config.resolver.resolveRequest) {\n throw error;\n }\n\n // If the error is directly related to a resolver not being able to resolve a module, then\n // we can ignore the error and try the next resolver. Otherwise, we should throw the error.\n const isResolutionError =\n isFailedToResolveNameError(error) || isFailedToResolvePathError(error);\n if (!isResolutionError) {\n throw error;\n }\n debug(\n `Custom resolver threw: ${error.constructor.name}. (module: ${moduleName}, platform: ${platform})`\n );\n }\n }\n // If we haven't returned by now, use the original resolver or upstream resolver.\n const res = originalResolveRequest(universalContext, moduleName, platform);\n storeResult(res);\n return res;\n } catch (error: any) {\n throw mutateResolutionError(error, universalContext, moduleName, platform);\n }\n },\n },\n };\n}\n"],"names":["getDefaultMetroResolver","withMetroResolvers","debug","require","projectRoot","resolve","importMetroResolverFromProject","context","moduleName","platform","optionsKeyForContext","canonicalize","JSON","stringify","customResolverOptions","config","resolvers","length","resolver","resolveRequest","originalResolveRequest","mutateResolutionError","error","env","EXPO_METRO_UNSTABLE_ERRORS","mapByOrigin","depGraph","get","mapByPlatform","getReferences","origin","inverseOrigin","originKey","mapByTarget","found","values","find","resolution","path","push","previous","request","pad","num","Array","fill","join","root","server","unstable_serverRoot","recurseBackWithLimit","req","limit","count","results","inverse","match","inverseTree","originModulePath","extraMessage","chalk","bold","printRecursive","tree","depth","filename","relative","replace","dim","formattedRequest","green","test","line","gray","_match","p1","child","_expoImportStack","Map","storeResult","res","key","has","set","Set","setForModule","qualifiedModuleName","type","filePath","add","universalContext","preferNativePlatform","isResolutionError","isFailedToResolveNameError","isFailedToResolvePathError","constructor","name"],"mappings":"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"}
|
|
@@ -138,7 +138,7 @@ async function createHostInfoAsync() {
|
|
|
138
138
|
host: await _userSettings.default.getAnonymousIdentifierAsync(),
|
|
139
139
|
server: "expo",
|
|
140
140
|
// Defined in the build step
|
|
141
|
-
serverVersion: "0.
|
|
141
|
+
serverVersion: "0.11.0",
|
|
142
142
|
serverDriver: _manifestMiddleware.DEVELOPER_TOOL,
|
|
143
143
|
serverOS: _os.default.platform(),
|
|
144
144
|
serverOSVersion: _os.default.release()
|
|
@@ -6,11 +6,13 @@ exports.getWorkspaceRoot = getWorkspaceRoot;
|
|
|
6
6
|
exports.getEntryWithServerRoot = getEntryWithServerRoot;
|
|
7
7
|
exports.getMetroServerRoot = getMetroServerRoot;
|
|
8
8
|
exports.resolveMainModuleName = resolveMainModuleName;
|
|
9
|
+
exports.shouldEnableAsyncImports = shouldEnableAsyncImports;
|
|
9
10
|
exports.createBundleUrlPath = createBundleUrlPath;
|
|
10
11
|
exports.DEVELOPER_TOOL = void 0;
|
|
11
12
|
var _config = require("@expo/config");
|
|
12
13
|
var _findYarnWorkspaceRoot = _interopRequireDefault(require("find-yarn-workspace-root"));
|
|
13
14
|
var _path = _interopRequireDefault(require("path"));
|
|
15
|
+
var _resolveFrom = _interopRequireDefault(require("resolve-from"));
|
|
14
16
|
var _url = require("url");
|
|
15
17
|
var Log = _interopRequireWildcard(require("../../../log"));
|
|
16
18
|
var _env = require("../../../utils/env");
|
|
@@ -74,14 +76,26 @@ function resolveMainModuleName(projectRoot, projectConfig, platform) {
|
|
|
74
76
|
debug(`Resolved entry point: ${entryPoint} (project root: ${projectRoot})`);
|
|
75
77
|
return (0, _url1).stripExtension(entryPoint, "js");
|
|
76
78
|
}
|
|
77
|
-
function
|
|
79
|
+
function shouldEnableAsyncImports(projectRoot) {
|
|
80
|
+
if (_env.env.EXPO_NO_METRO_LAZY) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
// `@expo/metro-runtime` includes support for the fetch + eval runtime code required
|
|
84
|
+
// to support async imports. If it's not installed, we can't support async imports.
|
|
85
|
+
// If it is installed, the user MUST import it somewhere in their project.
|
|
86
|
+
// Expo Router automatically pulls this in, so we can check for it.
|
|
87
|
+
return _resolveFrom.default.silent(projectRoot, "@expo/metro-runtime") != null;
|
|
88
|
+
}
|
|
89
|
+
function createBundleUrlPath({ platform , mainModuleName , mode , minify =mode === "production" , environment , serializerOutput , lazy }) {
|
|
78
90
|
const queryParams = new URLSearchParams({
|
|
79
91
|
platform: encodeURIComponent(platform),
|
|
80
92
|
dev: String(mode !== "production"),
|
|
81
93
|
// TODO: Is this still needed?
|
|
82
|
-
hot: String(false)
|
|
83
|
-
lazy: String(!_env.env.EXPO_NO_METRO_LAZY)
|
|
94
|
+
hot: String(false)
|
|
84
95
|
});
|
|
96
|
+
if (lazy) {
|
|
97
|
+
queryParams.append("lazy", String(lazy));
|
|
98
|
+
}
|
|
85
99
|
if (minify) {
|
|
86
100
|
queryParams.append("minify", String(minify));
|
|
87
101
|
}
|
|
@@ -165,7 +179,8 @@ class ManifestMiddleware extends _expoMiddleware.ExpoMiddleware {
|
|
|
165
179
|
mode: (_mode = this.options.mode) != null ? _mode : "development",
|
|
166
180
|
minify: this.options.minify,
|
|
167
181
|
platform,
|
|
168
|
-
mainModuleName
|
|
182
|
+
mainModuleName,
|
|
183
|
+
lazy: shouldEnableAsyncImports(this.projectRoot)
|
|
169
184
|
});
|
|
170
185
|
return this.options.constructUrl({
|
|
171
186
|
scheme: "http",
|
|
@@ -178,9 +193,11 @@ class ManifestMiddleware extends _expoMiddleware.ExpoMiddleware {
|
|
|
178
193
|
platform: encodeURIComponent(platform),
|
|
179
194
|
dev: String(this.options.mode !== "production"),
|
|
180
195
|
// TODO: Is this still needed?
|
|
181
|
-
hot: String(false)
|
|
182
|
-
lazy: String(!_env.env.EXPO_NO_METRO_LAZY)
|
|
196
|
+
hot: String(false)
|
|
183
197
|
});
|
|
198
|
+
if (shouldEnableAsyncImports(this.projectRoot)) {
|
|
199
|
+
queryParams.append("lazy", String(true));
|
|
200
|
+
}
|
|
184
201
|
if (this.options.minify) {
|
|
185
202
|
queryParams.append("minify", String(this.options.minify));
|
|
186
203
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/middleware/ManifestMiddleware.ts"],"sourcesContent":["import { ExpoConfig, ExpoGoConfig, getConfig, ProjectConfig } from '@expo/config';\nimport findWorkspaceRoot from 'find-yarn-workspace-root';\nimport path from 'path';\nimport { resolve } from 'url';\n\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport { stripExtension } from '../../../utils/url';\nimport * as ProjectDevices from '../../project/devices';\nimport { UrlCreator } from '../UrlCreator';\nimport { getPlatformBundlers } from '../platformBundlers';\nimport { createTemplateHtmlFromExpoConfigAsync } from '../webTemplate';\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport { resolveGoogleServicesFile, resolveManifestAssets } from './resolveAssets';\nimport { resolveAbsoluteEntryPoint } from './resolveEntryPoint';\nimport { parsePlatformHeader, RuntimePlatform } from './resolvePlatform';\nimport { ServerHeaders, ServerNext, ServerRequest, ServerResponse } from './server.types';\n\nconst debug = require('debug')('expo:start:server:middleware:manifest') as typeof console.log;\n\n/** Wraps `findWorkspaceRoot` and guards against having an empty `package.json` file in an upper directory. */\nexport function getWorkspaceRoot(projectRoot: string): string | null {\n try {\n return findWorkspaceRoot(projectRoot);\n } catch (error: any) {\n if (error.message.includes('Unexpected end of JSON input')) {\n return null;\n }\n throw error;\n }\n}\n\nexport function getEntryWithServerRoot(\n projectRoot: string,\n projectConfig: ProjectConfig,\n platform: string\n) {\n return path.relative(\n getMetroServerRoot(projectRoot),\n resolveAbsoluteEntryPoint(projectRoot, platform, projectConfig)\n );\n}\n\nexport function getMetroServerRoot(projectRoot: string) {\n if (env.EXPO_USE_METRO_WORKSPACE_ROOT) {\n return getWorkspaceRoot(projectRoot) ?? projectRoot;\n }\n\n return projectRoot;\n}\n\n/** Get the main entry module ID (file) relative to the project root. */\nexport function resolveMainModuleName(\n projectRoot: string,\n projectConfig: ProjectConfig,\n platform: string\n): string {\n const entryPoint = getEntryWithServerRoot(projectRoot, projectConfig, platform);\n\n debug(`Resolved entry point: ${entryPoint} (project root: ${projectRoot})`);\n\n return stripExtension(entryPoint, 'js');\n}\n\nexport function createBundleUrlPath({\n platform,\n mainModuleName,\n mode,\n minify = mode === 'production',\n environment,\n serializerOutput,\n}: {\n platform: string;\n mainModuleName: string;\n mode: string;\n minify?: boolean;\n environment?: string;\n serializerOutput?: 'static';\n}): string {\n const queryParams = new URLSearchParams({\n platform: encodeURIComponent(platform),\n dev: String(mode !== 'production'),\n // TODO: Is this still needed?\n hot: String(false),\n lazy: String(!env.EXPO_NO_METRO_LAZY),\n });\n\n if (minify) {\n queryParams.append('minify', String(minify));\n }\n if (environment) {\n queryParams.append('resolver.environment', environment);\n queryParams.append('transform.environment', environment);\n }\n if (serializerOutput) {\n queryParams.append('serializer.output', serializerOutput);\n }\n\n return `/${encodeURI(mainModuleName)}.bundle?${queryParams.toString()}`;\n}\n\n/** Info about the computer hosting the dev server. */\nexport interface HostInfo {\n host: string;\n server: 'expo';\n serverVersion: string;\n serverDriver: string | null;\n serverOS: NodeJS.Platform;\n serverOSVersion: string;\n}\n\n/** Parsed values from the supported request headers. */\nexport interface ManifestRequestInfo {\n /** Platform to serve. */\n platform: RuntimePlatform;\n /** Requested host name. */\n hostname?: string | null;\n}\n\n/** Project related info. */\nexport type ResponseProjectSettings = {\n expoGoConfig: ExpoGoConfig;\n hostUri: string;\n bundleUrl: string;\n exp: ExpoConfig;\n};\n\nexport const DEVELOPER_TOOL = 'expo-cli';\n\nexport type ManifestMiddlewareOptions = {\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n constructUrl: UrlCreator['constructUrl'];\n isNativeWebpack?: boolean;\n privateKeyPath?: string;\n};\n\n/** Base middleware creator for serving the Expo manifest (like the index.html but for native runtimes). */\nexport abstract class ManifestMiddleware<\n TManifestRequestInfo extends ManifestRequestInfo\n> extends ExpoMiddleware {\n private initialProjectConfig: ProjectConfig;\n\n constructor(protected projectRoot: string, protected options: ManifestMiddlewareOptions) {\n super(\n projectRoot,\n /**\n * Only support `/`, `/manifest`, `/index.exp` for the manifest middleware.\n */\n ['/', '/manifest', '/index.exp']\n );\n this.initialProjectConfig = getConfig(projectRoot);\n }\n\n /** Exposed for testing. */\n public async _resolveProjectSettingsAsync({\n platform,\n hostname,\n }: Pick<TManifestRequestInfo, 'hostname' | 'platform'>): Promise<ResponseProjectSettings> {\n // Read the config\n const projectConfig = getConfig(this.projectRoot);\n\n // Read from headers\n const mainModuleName = this.resolveMainModuleName(projectConfig, platform);\n\n // Create the manifest and set fields within it\n const expoGoConfig = this.getExpoGoConfig({\n mainModuleName,\n hostname,\n });\n\n const hostUri = this.options.constructUrl({ scheme: '', hostname });\n\n const bundleUrl = this._getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n });\n\n // Resolve all assets and set them on the manifest as URLs\n await this.mutateManifestWithAssetsAsync(projectConfig.exp, bundleUrl);\n\n return {\n expoGoConfig,\n hostUri,\n bundleUrl,\n exp: projectConfig.exp,\n };\n }\n\n /** Get the main entry module ID (file) relative to the project root. */\n private resolveMainModuleName(projectConfig: ProjectConfig, platform: string): string {\n let entryPoint = getEntryWithServerRoot(this.projectRoot, projectConfig, platform);\n\n debug(`Resolved entry point: ${entryPoint} (project root: ${this.projectRoot})`);\n\n // NOTE(Bacon): Webpack is currently hardcoded to index.bundle on native\n // in the future (TODO) we should move this logic into a Webpack plugin and use\n // a generated file name like we do on web.\n // const server = getDefaultDevServer();\n // // TODO: Move this into BundlerDevServer and read this info from self.\n // const isNativeWebpack = server instanceof WebpackBundlerDevServer && server.isTargetingNative();\n if (this.options.isNativeWebpack) {\n entryPoint = 'index.js';\n }\n\n return stripExtension(entryPoint, 'js');\n }\n\n /** Parse request headers into options. */\n public abstract getParsedHeaders(req: ServerRequest): TManifestRequestInfo;\n\n /** Store device IDs that were sent in the request headers. */\n private async saveDevicesAsync(req: ServerRequest) {\n const deviceIds = req.headers?.['expo-dev-client-id'];\n if (deviceIds) {\n await ProjectDevices.saveDevicesAsync(this.projectRoot, deviceIds).catch((e) =>\n Log.exception(e)\n );\n }\n }\n\n /** Create the bundle URL (points to the single JS entry file). Exposed for testing. */\n public _getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n }: {\n platform: string;\n hostname?: string | null;\n mainModuleName: string;\n }): string {\n const path = createBundleUrlPath({\n mode: this.options.mode ?? 'development',\n minify: this.options.minify,\n platform,\n mainModuleName,\n });\n\n return (\n this.options.constructUrl({\n scheme: 'http',\n // hostType: this.options.location.hostType,\n hostname,\n }) + path\n );\n }\n\n public _getBundleUrlPath({\n platform,\n mainModuleName,\n }: {\n platform: string;\n mainModuleName: string;\n }): string {\n const queryParams = new URLSearchParams({\n platform: encodeURIComponent(platform),\n dev: String(this.options.mode !== 'production'),\n // TODO: Is this still needed?\n hot: String(false),\n lazy: String(!env.EXPO_NO_METRO_LAZY),\n });\n\n if (this.options.minify) {\n queryParams.append('minify', String(this.options.minify));\n }\n\n return `/${encodeURI(mainModuleName)}.bundle?${queryParams.toString()}`;\n }\n\n /** Log telemetry. */\n protected abstract trackManifest(version?: string): void;\n\n /** Get the manifest response to return to the runtime. This file contains info regarding where the assets can be loaded from. Exposed for testing. */\n public abstract _getManifestResponseAsync(options: TManifestRequestInfo): Promise<{\n body: string;\n version: string;\n headers: ServerHeaders;\n }>;\n\n private getExpoGoConfig({\n mainModuleName,\n hostname,\n }: {\n mainModuleName: string;\n hostname?: string | null;\n }): ExpoGoConfig {\n return {\n // localhost:8081\n debuggerHost: this.options.constructUrl({ scheme: '', hostname }),\n // http://localhost:8081/logs -- used to send logs to the CLI for displaying in the terminal.\n // This is deprecated in favor of the WebSocket connection setup in Metro.\n logUrl: this.options.constructUrl({ scheme: 'http', hostname }) + '/logs',\n // Required for Expo Go to function.\n developer: {\n tool: DEVELOPER_TOOL,\n projectRoot: this.projectRoot,\n },\n packagerOpts: {\n // Required for dev client.\n dev: this.options.mode !== 'production',\n },\n // Indicates the name of the main bundle.\n mainModuleName,\n // Add this string to make Flipper register React Native / Metro as \"running\".\n // Can be tested by running:\n // `METRO_SERVER_PORT=8081 open -a flipper.app`\n // Where 8081 is the port where the Expo project is being hosted.\n __flipperHack: 'React Native packager is running',\n };\n }\n\n /** Resolve all assets and set them on the manifest as URLs */\n private async mutateManifestWithAssetsAsync(manifest: ExpoConfig, bundleUrl: string) {\n await resolveManifestAssets(this.projectRoot, {\n manifest,\n resolver: async (path) => {\n if (this.options.isNativeWebpack) {\n // When using our custom dev server, just do assets normally\n // without the `assets/` subpath redirect.\n return resolve(bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0], path);\n }\n return bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0] + 'assets/' + path;\n },\n });\n // The server normally inserts this but if we're offline we'll do it here\n await resolveGoogleServicesFile(this.projectRoot, manifest);\n }\n\n public getWebBundleUrl() {\n const platform = 'web';\n // Read from headers\n const mainModuleName = this.resolveMainModuleName(this.initialProjectConfig, platform);\n return this._getBundleUrlPath({\n platform,\n mainModuleName,\n });\n }\n\n /**\n * Web platforms should create an index.html response using the same script resolution as native.\n *\n * Instead of adding a `bundleUrl` to a `manifest.json` (native) we'll add a `<script src=\"\">`\n * to an `index.html`, this enables the web platform to load JavaScript from the server.\n */\n private async handleWebRequestAsync(req: ServerRequest, res: ServerResponse) {\n // Read from headers\n const bundleUrl = this.getWebBundleUrl();\n\n res.setHeader('Content-Type', 'text/html');\n\n res.end(\n await createTemplateHtmlFromExpoConfigAsync(this.projectRoot, {\n exp: this.initialProjectConfig.exp,\n scripts: [bundleUrl],\n })\n );\n }\n\n /** Exposed for testing. */\n async checkBrowserRequestAsync(req: ServerRequest, res: ServerResponse, next: ServerNext) {\n // Read the config\n const bundlers = getPlatformBundlers(this.initialProjectConfig.exp);\n if (bundlers.web === 'metro') {\n // NOTE(EvanBacon): This effectively disables the safety check we do on custom runtimes to ensure\n // the `expo-platform` header is included. When `web.bundler=web`, if the user has non-standard Expo\n // code loading then they'll get a web bundle without a clear assertion of platform support.\n const platform = parsePlatformHeader(req);\n // On web, serve the public folder\n if (!platform || platform === 'web') {\n if (this.initialProjectConfig.exp.web?.output === 'static') {\n // Skip the spa-styled index.html when static generation is enabled.\n next();\n return true;\n } else {\n await this.handleWebRequestAsync(req, res);\n return true;\n }\n }\n }\n return false;\n }\n\n async handleRequestAsync(\n req: ServerRequest,\n res: ServerResponse,\n next: ServerNext\n ): Promise<void> {\n // First check for standard JavaScript runtimes (aka legacy browsers like Chrome).\n if (await this.checkBrowserRequestAsync(req, res, next)) {\n return;\n }\n\n // Save device IDs for dev client.\n await this.saveDevicesAsync(req);\n\n // Read from headers\n const options = this.getParsedHeaders(req);\n const { body, version, headers } = await this._getManifestResponseAsync(options);\n for (const [headerName, headerValue] of headers) {\n res.setHeader(headerName, headerValue);\n }\n res.end(body);\n\n // Log analytics\n this.trackManifest(version ?? null);\n }\n}\n"],"names":["getWorkspaceRoot","getEntryWithServerRoot","getMetroServerRoot","resolveMainModuleName","createBundleUrlPath","Log","ProjectDevices","debug","require","projectRoot","findWorkspaceRoot","error","message","includes","projectConfig","platform","path","relative","resolveAbsoluteEntryPoint","env","EXPO_USE_METRO_WORKSPACE_ROOT","entryPoint","stripExtension","mainModuleName","mode","minify","environment","serializerOutput","queryParams","URLSearchParams","encodeURIComponent","dev","String","hot","lazy","EXPO_NO_METRO_LAZY","append","encodeURI","toString","DEVELOPER_TOOL","ManifestMiddleware","ExpoMiddleware","constructor","options","initialProjectConfig","getConfig","_resolveProjectSettingsAsync","hostname","expoGoConfig","getExpoGoConfig","hostUri","constructUrl","scheme","bundleUrl","_getBundleUrl","mutateManifestWithAssetsAsync","exp","isNativeWebpack","saveDevicesAsync","req","deviceIds","headers","catch","e","exception","_getBundleUrlPath","debuggerHost","logUrl","developer","tool","packagerOpts","__flipperHack","manifest","resolveManifestAssets","resolver","resolve","match","resolveGoogleServicesFile","getWebBundleUrl","handleWebRequestAsync","res","setHeader","end","createTemplateHtmlFromExpoConfigAsync","scripts","checkBrowserRequestAsync","next","bundlers","getPlatformBundlers","web","parsePlatformHeader","output","handleRequestAsync","getParsedHeaders","body","version","_getManifestResponseAsync","headerName","headerValue","trackManifest"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/middleware/ManifestMiddleware.ts"],"sourcesContent":["import { ExpoConfig, ExpoGoConfig, getConfig, ProjectConfig } from '@expo/config';\nimport findWorkspaceRoot from 'find-yarn-workspace-root';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\nimport { resolve } from 'url';\n\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport { stripExtension } from '../../../utils/url';\nimport * as ProjectDevices from '../../project/devices';\nimport { UrlCreator } from '../UrlCreator';\nimport { getPlatformBundlers } from '../platformBundlers';\nimport { createTemplateHtmlFromExpoConfigAsync } from '../webTemplate';\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport { resolveGoogleServicesFile, resolveManifestAssets } from './resolveAssets';\nimport { resolveAbsoluteEntryPoint } from './resolveEntryPoint';\nimport { parsePlatformHeader, RuntimePlatform } from './resolvePlatform';\nimport { ServerHeaders, ServerNext, ServerRequest, ServerResponse } from './server.types';\n\nconst debug = require('debug')('expo:start:server:middleware:manifest') as typeof console.log;\n\n/** Wraps `findWorkspaceRoot` and guards against having an empty `package.json` file in an upper directory. */\nexport function getWorkspaceRoot(projectRoot: string): string | null {\n try {\n return findWorkspaceRoot(projectRoot);\n } catch (error: any) {\n if (error.message.includes('Unexpected end of JSON input')) {\n return null;\n }\n throw error;\n }\n}\n\nexport function getEntryWithServerRoot(\n projectRoot: string,\n projectConfig: ProjectConfig,\n platform: string\n) {\n return path.relative(\n getMetroServerRoot(projectRoot),\n resolveAbsoluteEntryPoint(projectRoot, platform, projectConfig)\n );\n}\n\nexport function getMetroServerRoot(projectRoot: string) {\n if (env.EXPO_USE_METRO_WORKSPACE_ROOT) {\n return getWorkspaceRoot(projectRoot) ?? projectRoot;\n }\n\n return projectRoot;\n}\n\n/** Get the main entry module ID (file) relative to the project root. */\nexport function resolveMainModuleName(\n projectRoot: string,\n projectConfig: ProjectConfig,\n platform: string\n): string {\n const entryPoint = getEntryWithServerRoot(projectRoot, projectConfig, platform);\n\n debug(`Resolved entry point: ${entryPoint} (project root: ${projectRoot})`);\n\n return stripExtension(entryPoint, 'js');\n}\n\nexport function shouldEnableAsyncImports(projectRoot: string): boolean {\n if (env.EXPO_NO_METRO_LAZY) {\n return false;\n }\n\n // `@expo/metro-runtime` includes support for the fetch + eval runtime code required\n // to support async imports. If it's not installed, we can't support async imports.\n // If it is installed, the user MUST import it somewhere in their project.\n // Expo Router automatically pulls this in, so we can check for it.\n return resolveFrom.silent(projectRoot, '@expo/metro-runtime') != null;\n}\n\nexport function createBundleUrlPath({\n platform,\n mainModuleName,\n mode,\n minify = mode === 'production',\n environment,\n serializerOutput,\n lazy,\n}: {\n platform: string;\n mainModuleName: string;\n mode: string;\n minify?: boolean;\n environment?: string;\n serializerOutput?: 'static';\n lazy?: boolean;\n}): string {\n const queryParams = new URLSearchParams({\n platform: encodeURIComponent(platform),\n dev: String(mode !== 'production'),\n // TODO: Is this still needed?\n hot: String(false),\n });\n\n if (lazy) {\n queryParams.append('lazy', String(lazy));\n }\n\n if (minify) {\n queryParams.append('minify', String(minify));\n }\n if (environment) {\n queryParams.append('resolver.environment', environment);\n queryParams.append('transform.environment', environment);\n }\n if (serializerOutput) {\n queryParams.append('serializer.output', serializerOutput);\n }\n\n return `/${encodeURI(mainModuleName)}.bundle?${queryParams.toString()}`;\n}\n\n/** Info about the computer hosting the dev server. */\nexport interface HostInfo {\n host: string;\n server: 'expo';\n serverVersion: string;\n serverDriver: string | null;\n serverOS: NodeJS.Platform;\n serverOSVersion: string;\n}\n\n/** Parsed values from the supported request headers. */\nexport interface ManifestRequestInfo {\n /** Platform to serve. */\n platform: RuntimePlatform;\n /** Requested host name. */\n hostname?: string | null;\n}\n\n/** Project related info. */\nexport type ResponseProjectSettings = {\n expoGoConfig: ExpoGoConfig;\n hostUri: string;\n bundleUrl: string;\n exp: ExpoConfig;\n};\n\nexport const DEVELOPER_TOOL = 'expo-cli';\n\nexport type ManifestMiddlewareOptions = {\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n constructUrl: UrlCreator['constructUrl'];\n isNativeWebpack?: boolean;\n privateKeyPath?: string;\n};\n\n/** Base middleware creator for serving the Expo manifest (like the index.html but for native runtimes). */\nexport abstract class ManifestMiddleware<\n TManifestRequestInfo extends ManifestRequestInfo\n> extends ExpoMiddleware {\n private initialProjectConfig: ProjectConfig;\n\n constructor(protected projectRoot: string, protected options: ManifestMiddlewareOptions) {\n super(\n projectRoot,\n /**\n * Only support `/`, `/manifest`, `/index.exp` for the manifest middleware.\n */\n ['/', '/manifest', '/index.exp']\n );\n this.initialProjectConfig = getConfig(projectRoot);\n }\n\n /** Exposed for testing. */\n public async _resolveProjectSettingsAsync({\n platform,\n hostname,\n }: Pick<TManifestRequestInfo, 'hostname' | 'platform'>): Promise<ResponseProjectSettings> {\n // Read the config\n const projectConfig = getConfig(this.projectRoot);\n\n // Read from headers\n const mainModuleName = this.resolveMainModuleName(projectConfig, platform);\n\n // Create the manifest and set fields within it\n const expoGoConfig = this.getExpoGoConfig({\n mainModuleName,\n hostname,\n });\n\n const hostUri = this.options.constructUrl({ scheme: '', hostname });\n\n const bundleUrl = this._getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n });\n\n // Resolve all assets and set them on the manifest as URLs\n await this.mutateManifestWithAssetsAsync(projectConfig.exp, bundleUrl);\n\n return {\n expoGoConfig,\n hostUri,\n bundleUrl,\n exp: projectConfig.exp,\n };\n }\n\n /** Get the main entry module ID (file) relative to the project root. */\n private resolveMainModuleName(projectConfig: ProjectConfig, platform: string): string {\n let entryPoint = getEntryWithServerRoot(this.projectRoot, projectConfig, platform);\n\n debug(`Resolved entry point: ${entryPoint} (project root: ${this.projectRoot})`);\n\n // NOTE(Bacon): Webpack is currently hardcoded to index.bundle on native\n // in the future (TODO) we should move this logic into a Webpack plugin and use\n // a generated file name like we do on web.\n // const server = getDefaultDevServer();\n // // TODO: Move this into BundlerDevServer and read this info from self.\n // const isNativeWebpack = server instanceof WebpackBundlerDevServer && server.isTargetingNative();\n if (this.options.isNativeWebpack) {\n entryPoint = 'index.js';\n }\n\n return stripExtension(entryPoint, 'js');\n }\n\n /** Parse request headers into options. */\n public abstract getParsedHeaders(req: ServerRequest): TManifestRequestInfo;\n\n /** Store device IDs that were sent in the request headers. */\n private async saveDevicesAsync(req: ServerRequest) {\n const deviceIds = req.headers?.['expo-dev-client-id'];\n if (deviceIds) {\n await ProjectDevices.saveDevicesAsync(this.projectRoot, deviceIds).catch((e) =>\n Log.exception(e)\n );\n }\n }\n\n /** Create the bundle URL (points to the single JS entry file). Exposed for testing. */\n public _getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n }: {\n platform: string;\n hostname?: string | null;\n mainModuleName: string;\n }): string {\n const path = createBundleUrlPath({\n mode: this.options.mode ?? 'development',\n minify: this.options.minify,\n platform,\n mainModuleName,\n lazy: shouldEnableAsyncImports(this.projectRoot),\n });\n\n return (\n this.options.constructUrl({\n scheme: 'http',\n // hostType: this.options.location.hostType,\n hostname,\n }) + path\n );\n }\n\n public _getBundleUrlPath({\n platform,\n mainModuleName,\n }: {\n platform: string;\n mainModuleName: string;\n }): string {\n const queryParams = new URLSearchParams({\n platform: encodeURIComponent(platform),\n dev: String(this.options.mode !== 'production'),\n // TODO: Is this still needed?\n hot: String(false),\n });\n if (shouldEnableAsyncImports(this.projectRoot)) {\n queryParams.append('lazy', String(true));\n }\n\n if (this.options.minify) {\n queryParams.append('minify', String(this.options.minify));\n }\n\n return `/${encodeURI(mainModuleName)}.bundle?${queryParams.toString()}`;\n }\n\n /** Log telemetry. */\n protected abstract trackManifest(version?: string): void;\n\n /** Get the manifest response to return to the runtime. This file contains info regarding where the assets can be loaded from. Exposed for testing. */\n public abstract _getManifestResponseAsync(options: TManifestRequestInfo): Promise<{\n body: string;\n version: string;\n headers: ServerHeaders;\n }>;\n\n private getExpoGoConfig({\n mainModuleName,\n hostname,\n }: {\n mainModuleName: string;\n hostname?: string | null;\n }): ExpoGoConfig {\n return {\n // localhost:8081\n debuggerHost: this.options.constructUrl({ scheme: '', hostname }),\n // http://localhost:8081/logs -- used to send logs to the CLI for displaying in the terminal.\n // This is deprecated in favor of the WebSocket connection setup in Metro.\n logUrl: this.options.constructUrl({ scheme: 'http', hostname }) + '/logs',\n // Required for Expo Go to function.\n developer: {\n tool: DEVELOPER_TOOL,\n projectRoot: this.projectRoot,\n },\n packagerOpts: {\n // Required for dev client.\n dev: this.options.mode !== 'production',\n },\n // Indicates the name of the main bundle.\n mainModuleName,\n // Add this string to make Flipper register React Native / Metro as \"running\".\n // Can be tested by running:\n // `METRO_SERVER_PORT=8081 open -a flipper.app`\n // Where 8081 is the port where the Expo project is being hosted.\n __flipperHack: 'React Native packager is running',\n };\n }\n\n /** Resolve all assets and set them on the manifest as URLs */\n private async mutateManifestWithAssetsAsync(manifest: ExpoConfig, bundleUrl: string) {\n await resolveManifestAssets(this.projectRoot, {\n manifest,\n resolver: async (path) => {\n if (this.options.isNativeWebpack) {\n // When using our custom dev server, just do assets normally\n // without the `assets/` subpath redirect.\n return resolve(bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0], path);\n }\n return bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0] + 'assets/' + path;\n },\n });\n // The server normally inserts this but if we're offline we'll do it here\n await resolveGoogleServicesFile(this.projectRoot, manifest);\n }\n\n public getWebBundleUrl() {\n const platform = 'web';\n // Read from headers\n const mainModuleName = this.resolveMainModuleName(this.initialProjectConfig, platform);\n return this._getBundleUrlPath({\n platform,\n mainModuleName,\n });\n }\n\n /**\n * Web platforms should create an index.html response using the same script resolution as native.\n *\n * Instead of adding a `bundleUrl` to a `manifest.json` (native) we'll add a `<script src=\"\">`\n * to an `index.html`, this enables the web platform to load JavaScript from the server.\n */\n private async handleWebRequestAsync(req: ServerRequest, res: ServerResponse) {\n // Read from headers\n const bundleUrl = this.getWebBundleUrl();\n\n res.setHeader('Content-Type', 'text/html');\n\n res.end(\n await createTemplateHtmlFromExpoConfigAsync(this.projectRoot, {\n exp: this.initialProjectConfig.exp,\n scripts: [bundleUrl],\n })\n );\n }\n\n /** Exposed for testing. */\n async checkBrowserRequestAsync(req: ServerRequest, res: ServerResponse, next: ServerNext) {\n // Read the config\n const bundlers = getPlatformBundlers(this.initialProjectConfig.exp);\n if (bundlers.web === 'metro') {\n // NOTE(EvanBacon): This effectively disables the safety check we do on custom runtimes to ensure\n // the `expo-platform` header is included. When `web.bundler=web`, if the user has non-standard Expo\n // code loading then they'll get a web bundle without a clear assertion of platform support.\n const platform = parsePlatformHeader(req);\n // On web, serve the public folder\n if (!platform || platform === 'web') {\n if (this.initialProjectConfig.exp.web?.output === 'static') {\n // Skip the spa-styled index.html when static generation is enabled.\n next();\n return true;\n } else {\n await this.handleWebRequestAsync(req, res);\n return true;\n }\n }\n }\n return false;\n }\n\n async handleRequestAsync(\n req: ServerRequest,\n res: ServerResponse,\n next: ServerNext\n ): Promise<void> {\n // First check for standard JavaScript runtimes (aka legacy browsers like Chrome).\n if (await this.checkBrowserRequestAsync(req, res, next)) {\n return;\n }\n\n // Save device IDs for dev client.\n await this.saveDevicesAsync(req);\n\n // Read from headers\n const options = this.getParsedHeaders(req);\n const { body, version, headers } = await this._getManifestResponseAsync(options);\n for (const [headerName, headerValue] of headers) {\n res.setHeader(headerName, headerValue);\n }\n res.end(body);\n\n // Log analytics\n this.trackManifest(version ?? null);\n }\n}\n"],"names":["getWorkspaceRoot","getEntryWithServerRoot","getMetroServerRoot","resolveMainModuleName","shouldEnableAsyncImports","createBundleUrlPath","Log","ProjectDevices","debug","require","projectRoot","findWorkspaceRoot","error","message","includes","projectConfig","platform","path","relative","resolveAbsoluteEntryPoint","env","EXPO_USE_METRO_WORKSPACE_ROOT","entryPoint","stripExtension","EXPO_NO_METRO_LAZY","resolveFrom","silent","mainModuleName","mode","minify","environment","serializerOutput","lazy","queryParams","URLSearchParams","encodeURIComponent","dev","String","hot","append","encodeURI","toString","DEVELOPER_TOOL","ManifestMiddleware","ExpoMiddleware","constructor","options","initialProjectConfig","getConfig","_resolveProjectSettingsAsync","hostname","expoGoConfig","getExpoGoConfig","hostUri","constructUrl","scheme","bundleUrl","_getBundleUrl","mutateManifestWithAssetsAsync","exp","isNativeWebpack","saveDevicesAsync","req","deviceIds","headers","catch","e","exception","_getBundleUrlPath","debuggerHost","logUrl","developer","tool","packagerOpts","__flipperHack","manifest","resolveManifestAssets","resolver","resolve","match","resolveGoogleServicesFile","getWebBundleUrl","handleWebRequestAsync","res","setHeader","end","createTemplateHtmlFromExpoConfigAsync","scripts","checkBrowserRequestAsync","next","bundlers","getPlatformBundlers","web","parsePlatformHeader","output","handleRequestAsync","getParsedHeaders","body","version","_getManifestResponseAsync","headerName","headerValue","trackManifest"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../src/start/server/type-generation/__typetests__/fixtures/basic.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable import/export */\n/* eslint-disable @typescript-eslint/ban-types */\n\nimport type { LinkProps as OriginalLinkProps } from 'expo-router/build/link/Link';\nexport * from 'expo-router/build';\n\n// prettier-ignore\ntype StaticRoutes = `/apple` | `/banana`;\n// prettier-ignore\ntype DynamicRoutes<T extends string> = `/colors/${SingleRoutePart<T>}` | `/animals/${CatchAllRoutePart<T>}` | `/mix/${SingleRoutePart<T>}/${SingleRoutePart<T>}/${CatchAllRoutePart<T>}`;\n// prettier-ignore\ntype DynamicRouteTemplate = `/colors/[color]` | `/animals/[...animal]` | `/mix/[fruit]/[color]/[...animals]`;\n\ntype RelativePathString = `./${string}` | `../${string}` | '..';\ntype AbsoluteRoute = DynamicRouteTemplate | StaticRoutes;\ntype ExternalPathString = `http${string}`;\ntype ExpoRouterRoutes = DynamicRouteTemplate | StaticRoutes | RelativePathString;\ntype AllRoutes = ExpoRouterRoutes | ExternalPathString;\n\n/****************\n * Route Utils *\n ****************/\n\ntype SearchOrHash = `?${string}` | `#${string}`;\n\n/**\n * Return only the RoutePart of a string. If the string has multiple parts return never\n *\n * string | type\n * ---------|------\n * 123 | 123\n * /123/abc | never\n * 123?abc | never\n * ./123 | never\n * /123 | never\n * 123/../ | never\n */\ntype SingleRoutePart<S extends string> = S extends `${string}/${string}`\n ? never\n : S extends `${string}${SearchOrHash}`\n ? never\n : S extends ''\n ? never\n : S;\n\n/**\n * Return only the CatchAll router part. If the string has search parameters or a hash return never\n */\ntype CatchAllRoutePart<S extends string> = S extends `${string}${SearchOrHash}`\n ? never\n : S extends ''\n ? never\n : S;\n\n// type OptionalCatchAllRoutePart<S extends string> = S extends `${string}${SearchOrHash}` ? never : S\n\n/**\n * Return the name of a route parameter\n * '[test]' -> 'test'\n * 'test' -> never\n * '[...test]' -> '...test'\n */\ntype IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never;\n\n/**\n * Return a union of all parameter names. If there are no names return never\n *\n * /[test] -> 'test'\n * /[abc]/[...def] -> 'abc'|'...def'\n */\ntype ParameterNames<Path> = Path extends `${infer PartA}/${infer PartB}`\n ? IsParameter<PartA> | ParameterNames<PartB>\n : IsParameter<Path>;\n\n/**\n * Returns all segements of a route.\n *\n * /(group)/123/abc/[id]/[...rest] -> ['(group)', '123', 'abc', '[id]', '[...rest]'\n */\ntype RouteSegments<Path> = Path extends `${infer PartA}/${infer PartB}`\n ? PartA extends '' | '.'\n ? [...RouteSegments<PartB>]\n : [PartA, ...RouteSegments<PartB>]\n : Path extends ''\n ? []\n : [Path];\n\n/**\n * Returns a Record of the routes parameters as strings and CatchAll parameters as string
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/start/server/type-generation/__typetests__/fixtures/basic.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable import/export */\n/* eslint-disable @typescript-eslint/ban-types */\n\nimport type { LinkProps as OriginalLinkProps } from 'expo-router/build/link/Link';\nimport type { Router as OriginalRouter } from 'expo-router/src/types';\nexport * from 'expo-router/build';\n\n// prettier-ignore\ntype StaticRoutes = `/apple` | `/banana`;\n// prettier-ignore\ntype DynamicRoutes<T extends string> = `/colors/${SingleRoutePart<T>}` | `/animals/${CatchAllRoutePart<T>}` | `/mix/${SingleRoutePart<T>}/${SingleRoutePart<T>}/${CatchAllRoutePart<T>}`;\n// prettier-ignore\ntype DynamicRouteTemplate = `/colors/[color]` | `/animals/[...animal]` | `/mix/[fruit]/[color]/[...animals]`;\n\ntype RelativePathString = `./${string}` | `../${string}` | '..';\ntype AbsoluteRoute = DynamicRouteTemplate | StaticRoutes;\ntype ExternalPathString = `http${string}`;\ntype ExpoRouterRoutes = DynamicRouteTemplate | StaticRoutes | RelativePathString;\ntype AllRoutes = ExpoRouterRoutes | ExternalPathString;\n\n/****************\n * Route Utils *\n ****************/\n\ntype SearchOrHash = `?${string}` | `#${string}`;\ntype UnknownInputParams = Record<string, string | number | (string | number)[]>;\ntype UnknownOutputParams = Record<string, string | string[]>;\n\n/**\n * Return only the RoutePart of a string. If the string has multiple parts return never\n *\n * string | type\n * ---------|------\n * 123 | 123\n * /123/abc | never\n * 123?abc | never\n * ./123 | never\n * /123 | never\n * 123/../ | never\n */\ntype SingleRoutePart<S extends string> = S extends `${string}/${string}`\n ? never\n : S extends `${string}${SearchOrHash}`\n ? never\n : S extends ''\n ? never\n : S extends `(${string})`\n ? never\n : S extends `[${string}]`\n ? never\n : S;\n\n/**\n * Return only the CatchAll router part. If the string has search parameters or a hash return never\n */\ntype CatchAllRoutePart<S extends string> = S extends `${string}${SearchOrHash}`\n ? never\n : S extends ''\n ? never\n : S extends `${string}(${string})${string}`\n ? never\n : S extends `${string}[${string}]${string}`\n ? never\n : S;\n\n// type OptionalCatchAllRoutePart<S extends string> = S extends `${string}${SearchOrHash}` ? never : S\n\n/**\n * Return the name of a route parameter\n * '[test]' -> 'test'\n * 'test' -> never\n * '[...test]' -> '...test'\n */\ntype IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never;\n\n/**\n * Return a union of all parameter names. If there are no names return never\n *\n * /[test] -> 'test'\n * /[abc]/[...def] -> 'abc'|'...def'\n */\ntype ParameterNames<Path> = Path extends `${infer PartA}/${infer PartB}`\n ? IsParameter<PartA> | ParameterNames<PartB>\n : IsParameter<Path>;\n\n/**\n * Returns all segements of a route.\n *\n * /(group)/123/abc/[id]/[...rest] -> ['(group)', '123', 'abc', '[id]', '[...rest]'\n */\ntype RouteSegments<Path> = Path extends `${infer PartA}/${infer PartB}`\n ? PartA extends '' | '.'\n ? [...RouteSegments<PartB>]\n : [PartA, ...RouteSegments<PartB>]\n : Path extends ''\n ? []\n : [Path];\n\n/**\n * Returns a Record of the routes parameters as strings and CatchAll parameters\n *\n * There are two versions, input and output, as you can input 'string | number' but\n * the output will always be 'string'\n *\n * /[id]/[...rest] -> { id: string, rest: string[] }\n * /no-params -> {}\n */\ntype InputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends `...${infer Name}`\n ? Name\n : Key]: Key extends `...${string}` ? (string | number)[] : string | number;\n} & UnknownInputParams;\n\ntype OutputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends `...${infer Name}`\n ? Name\n : Key]: Key extends `...${string}` ? string[] : string;\n} & UnknownOutputParams;\n\n/**\n * Returns the search parameters for a route.\n */\nexport type SearchParams<T extends AllRoutes> = T extends DynamicRouteTemplate\n ? OutputRouteParams<T>\n : T extends StaticRoutes\n ? never\n : UnknownOutputParams;\n\n/**\n * Route is mostly used as part of Href to ensure that a valid route is provided\n *\n * Given a dynamic route, this will return never. This is helpful for conditional logic\n *\n * /test -> /test, /test2, etc\n * /test/[abc] -> never\n * /test/resolve -> /test, /test2, etc\n *\n * Note that if we provide a value for [abc] then the route is allowed\n *\n * This is named Route to prevent confusion, as users they will often see it in tooltips\n */\nexport type Route<T> = T extends string\n ? T extends DynamicRouteTemplate\n ? never\n :\n | StaticRoutes\n | RelativePathString\n | ExternalPathString\n | (T extends `${infer P}${SearchOrHash}`\n ? P extends DynamicRoutes<infer _>\n ? T\n : never\n : T extends DynamicRoutes<infer _>\n ? T\n : never)\n : never;\n\n/*********\n * Href *\n *********/\n\nexport type Href<T> = T extends Record<'pathname', string> ? HrefObject<T> : Route<T>;\n\nexport type HrefObject<\n R extends Record<'pathname', string>,\n P = R['pathname']\n> = P extends DynamicRouteTemplate\n ? { pathname: P; params: InputRouteParams<P> }\n : P extends Route<P>\n ? { pathname: Route<P> | DynamicRouteTemplate; params?: never | InputRouteParams<never> }\n : never;\n\n/***********************\n * Expo Router Exports *\n ***********************/\n\nexport type Router = Omit<OriginalRouter, 'push' | 'replace' | 'setParams'> & {\n /** Navigate to the provided href. */\n push: <T>(href: Href<T>) => void;\n /** Navigate to route without appending to the history. */\n replace: <T>(href: Href<T>) => void;\n /** Update the current route query params. */\n setParams: <T = ''>(params?: T extends '' ? Record<string, string> : InputRouteParams<T>) => void;\n};\n\n/** The imperative router. */\nexport declare const router: Router;\n\n/************\n * <Link /> *\n ************/\nexport interface LinkProps<T> extends OriginalLinkProps {\n href: Href<T>;\n}\n\nexport interface LinkComponent {\n <T>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: <T>(href: Href<T>) => string;\n}\n\n/**\n * Component to render link to another route using a path.\n * Uses an anchor tag on the web.\n *\n * @param props.href Absolute path to route (e.g. `/feeds/hot`).\n * @param props.replace Should replace the current route without adding to the history.\n * @param props.asChild Forward props to child component. Useful for custom buttons.\n * @param props.children Child elements to render the content.\n */\nexport declare const Link: LinkComponent;\n\n/** Redirects to the href as soon as the component is mounted. */\nexport declare const Redirect: <T>(\n props: React.PropsWithChildren<{ href: Href<T> }>\n) => JSX.Element;\n\n/************\n * Hooks *\n ************/\nexport declare function useRouter(): Router;\n\nexport declare function useLocalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams\n>(): T extends AllRoutes ? SearchParams<T> : T;\n\n/** @deprecated renamed to `useGlobalSearchParams` */\nexport declare function useSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams\n>(): T extends AllRoutes ? SearchParams<T> : T;\n\nexport declare function useGlobalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams\n>(): T extends AllRoutes ? SearchParams<T> : T;\n\nexport declare function useSegments<\n T extends AbsoluteRoute | RouteSegments<AbsoluteRoute> | RelativePathString\n>(): T extends AbsoluteRoute ? RouteSegments<T> : T extends string ? string[] : T;\n"],"names":[],"mappings":"AAIA;;;;6CAEc,mBAAmB;AAAjC,YAAA,MAAkC;;2CAAlC,MAAkC;;;;mBAAlC,MAAkC;;;EAAA"}
|
|
@@ -39,11 +39,6 @@ describe("router.push()", ()=>{
|
|
|
39
39
|
it("can accept any external url", ()=>{
|
|
40
40
|
(0, _tsdLite).expectType(router.push("http://expo.dev"));
|
|
41
41
|
});
|
|
42
|
-
it("throws if using inline search params", ()=>{
|
|
43
|
-
// While this is allowed in Expo Router, the Typed Routes version throws as we cannot type it
|
|
44
|
-
(0, _tsdLite).expectError(router.push("/colors?color=blue"));
|
|
45
|
-
(0, _tsdLite).expectError(router.push("/animals/bear?color=blue"));
|
|
46
|
-
});
|
|
47
42
|
});
|
|
48
43
|
describe("HrefObject", ()=>{
|
|
49
44
|
it("will error on non-urls", ()=>{
|
|
@@ -100,6 +95,19 @@ describe("router.push()", ()=>{
|
|
|
100
95
|
}
|
|
101
96
|
}));
|
|
102
97
|
});
|
|
98
|
+
it("allows numeric inputs", ()=>{
|
|
99
|
+
(0, _tsdLite).expectType(router.push({
|
|
100
|
+
pathname: "/mix/[fruit]/[color]/[...animals]",
|
|
101
|
+
params: {
|
|
102
|
+
color: 1,
|
|
103
|
+
fruit: "apple",
|
|
104
|
+
animals: [
|
|
105
|
+
2,
|
|
106
|
+
"cat"
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
}));
|
|
110
|
+
});
|
|
103
111
|
it("requires an array for catch all routes", ()=>{
|
|
104
112
|
(0, _tsdLite).expectError(router.push({
|
|
105
113
|
pathname: "/animals/[...animal]",
|
|
@@ -114,10 +122,7 @@ describe("router.push()", ()=>{
|
|
|
114
122
|
params: {
|
|
115
123
|
color: "red",
|
|
116
124
|
fruit: "apple",
|
|
117
|
-
animals: [
|
|
118
|
-
"cat",
|
|
119
|
-
"dog"
|
|
120
|
-
]
|
|
125
|
+
animals: []
|
|
121
126
|
}
|
|
122
127
|
}));
|
|
123
128
|
});
|
|
@@ -141,6 +146,12 @@ describe("useSearchParams", ()=>{
|
|
|
141
146
|
(0, _tsdLite).expectError((0, _basic).useSearchParams());
|
|
142
147
|
(0, _tsdLite).expectError((0, _basic).useSearchParams());
|
|
143
148
|
});
|
|
149
|
+
describe("useLocalSearchParams", ()=>{
|
|
150
|
+
(0, _tsdLite).expectType((0, _basic).useLocalSearchParams());
|
|
151
|
+
(0, _tsdLite).expectType((0, _basic).useLocalSearchParams());
|
|
152
|
+
(0, _tsdLite).expectError((0, _basic).useSearchParams());
|
|
153
|
+
(0, _tsdLite).expectError((0, _basic).useSearchParams());
|
|
154
|
+
});
|
|
144
155
|
describe("useGlobalSearchParams", ()=>{
|
|
145
156
|
(0, _tsdLite).expectType((0, _basic).useGlobalSearchParams());
|
|
146
157
|
(0, _tsdLite).expectType((0, _basic).useGlobalSearchParams());
|