@expo/cli 54.0.22 → 54.0.24
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 +1 -1
- package/build/src/export/exportAssets.js +10 -9
- package/build/src/export/exportAssets.js.map +1 -1
- package/build/src/run/android/resolveLaunchProps.js +7 -5
- package/build/src/run/android/resolveLaunchProps.js.map +1 -1
- package/build/src/run/android/runAndroidAsync.js.map +1 -1
- package/build/src/run/ios/launchApp.js +1 -1
- package/build/src/run/ios/launchApp.js.map +1 -1
- package/build/src/start/doctor/apple/SimulatorAppPrerequisite.js +39 -2
- package/build/src/start/doctor/apple/SimulatorAppPrerequisite.js.map +1 -1
- package/build/src/start/platforms/android/AndroidPlatformManager.js.map +1 -1
- package/build/src/start/platforms/ios/ApplePlatformManager.js.map +1 -1
- package/build/src/start/server/BundlerDevServer.js +18 -4
- package/build/src/start/server/BundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js +1 -9
- package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js.map +1 -1
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +76 -13
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +1 -3
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +7 -7
package/build/bin/cli
CHANGED
|
@@ -26,16 +26,16 @@ function _fs() {
|
|
|
26
26
|
};
|
|
27
27
|
return data;
|
|
28
28
|
}
|
|
29
|
-
function
|
|
30
|
-
const data = require("
|
|
31
|
-
|
|
29
|
+
function _path() {
|
|
30
|
+
const data = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
31
|
+
_path = function() {
|
|
32
32
|
return data;
|
|
33
33
|
};
|
|
34
34
|
return data;
|
|
35
35
|
}
|
|
36
|
-
function
|
|
37
|
-
const data = /*#__PURE__*/ _interop_require_default(require("
|
|
38
|
-
|
|
36
|
+
function _picomatch() {
|
|
37
|
+
const data = /*#__PURE__*/ _interop_require_default(require("picomatch"));
|
|
38
|
+
_picomatch = function() {
|
|
39
39
|
return data;
|
|
40
40
|
};
|
|
41
41
|
return data;
|
|
@@ -132,8 +132,9 @@ function assetPatternsToBeBundled(exp) {
|
|
|
132
132
|
// needed because android doesn't support assets that start with numbers.
|
|
133
133
|
const fullPatterns = assetPatternsToBeBundled.map((p)=>_path().default.join(projectRoot, p));
|
|
134
134
|
logPatterns(fullPatterns);
|
|
135
|
+
const matches = (0, _picomatch().default)(fullPatterns);
|
|
135
136
|
const allBundledAssets = assets.map((asset)=>{
|
|
136
|
-
const shouldBundle = shouldBundleAsset(asset,
|
|
137
|
+
const shouldBundle = shouldBundleAsset(asset, matches);
|
|
137
138
|
if (shouldBundle) {
|
|
138
139
|
var _asset_files;
|
|
139
140
|
debug(`${shouldBundle ? 'Include' : 'Exclude'} asset ${(_asset_files = asset.files) == null ? void 0 : _asset_files[0]}`);
|
|
@@ -158,10 +159,10 @@ function logPatterns(patterns) {
|
|
|
158
159
|
_log.log('\nProcessing asset bundle patterns:');
|
|
159
160
|
patterns.forEach((p)=>_log.log('- ' + p));
|
|
160
161
|
}
|
|
161
|
-
function shouldBundleAsset(asset,
|
|
162
|
+
function shouldBundleAsset(asset, matcher) {
|
|
162
163
|
var _asset_files;
|
|
163
164
|
const file = (_asset_files = asset.files) == null ? void 0 : _asset_files[0];
|
|
164
|
-
return !!('__packager_asset' in asset && asset.__packager_asset && file &&
|
|
165
|
+
return !!('__packager_asset' in asset && asset.__packager_asset && file && matcher(file));
|
|
165
166
|
}
|
|
166
167
|
async function exportAssetsAsync(projectRoot, { exp, outputDir, bundles: { web, ...bundles }, baseUrl, files = new Map(), hostedNative }) {
|
|
167
168
|
var _assets_;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/export/exportAssets.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport fs from 'fs';\nimport { minimatch } from 'minimatch';\nimport path from 'path';\n\nimport { getAssetIdForLogGrouping, persistMetroAssetsAsync } from './persistMetroAssets';\nimport type { Asset, BundleAssetWithFileHashes, BundleOutput, ExportAssetMap } from './saveAssets';\nimport * as Log from '../log';\nimport { resolveGoogleServicesFile } from '../start/server/middleware/resolveAssets';\nimport { uniqBy } from '../utils/array';\n\nconst debug = require('debug')('expo:export:exportAssets') as typeof console.log;\n\nfunction mapAssetHashToAssetString(asset: Asset, hash: string) {\n return 'asset_' + hash + ('type' in asset && asset.type ? '.' + asset.type : '');\n}\n\nexport function assetPatternsToBeBundled(\n exp: ExpoConfig & { extra?: { updates?: { assetPatternsToBeBundled?: string[] } } }\n): string[] | undefined {\n // new location for this key\n if (exp.updates?.assetPatternsToBeBundled?.length) {\n return exp.updates.assetPatternsToBeBundled;\n }\n\n // old, untyped location for this key. we may want to change this to throw in a few SDK versions (deprecated as of SDK 52).\n if (exp.extra?.updates?.assetPatternsToBeBundled?.length) {\n return exp.extra.updates.assetPatternsToBeBundled;\n }\n\n return undefined;\n}\n\n/**\n * Given an asset and a set of strings representing the assets to be bundled, returns true if\n * the asset is part of the set to be bundled.\n * @param asset Asset object\n * @param bundledAssetsSet Set of strings\n * @returns true if the asset should be bundled\n */\nfunction assetShouldBeIncludedInExport(asset: Asset, bundledAssetsSet: Set<string> | undefined) {\n if (!bundledAssetsSet) {\n return true;\n }\n return (\n asset.fileHashes.filter((hash) => bundledAssetsSet.has(mapAssetHashToAssetString(asset, hash)))\n .length > 0\n );\n}\n\n/**\n * Computes a set of strings representing the assets to be bundled with an export, given an array of assets,\n * and a set of patterns to match\n * @param assets The asset array\n * @param assetPatternsToBeBundled An array of strings with glob patterns to match\n * @param projectRoot The project root\n * @returns A set of asset strings\n */\nfunction setOfAssetsToBeBundled(\n assets: Asset[],\n assetPatternsToBeBundled: string[],\n projectRoot: string\n): Set<string> | undefined {\n // Convert asset patterns to a list of asset strings that match them.\n // Assets strings are formatted as `asset_<hash>.<type>` and represent\n // the name that the file will have in the app bundle. The `asset_` prefix is\n // needed because android doesn't support assets that start with numbers.\n\n const fullPatterns: string[] = assetPatternsToBeBundled.map((p: string) =>\n path.join(projectRoot, p)\n );\n\n logPatterns(fullPatterns);\n\n const allBundledAssets = assets\n .map((asset) => {\n const shouldBundle = shouldBundleAsset(asset, fullPatterns);\n if (shouldBundle) {\n debug(`${shouldBundle ? 'Include' : 'Exclude'} asset ${asset.files?.[0]}`);\n return asset.fileHashes.map((hash) => mapAssetHashToAssetString(asset, hash));\n }\n return [];\n })\n .flat();\n\n // The assets returned by the RN packager has duplicates so make sure we\n // only bundle each once.\n return new Set(allBundledAssets);\n}\n\n/**\n * Resolves the assetBundlePatterns from the manifest and returns the set of assets to bundle.\n *\n * @modifies {exp}\n */\nexport function resolveAssetPatternsToBeBundled<T extends ExpoConfig>(\n projectRoot: string,\n exp: T,\n assets: Asset[]\n): Set<string> | undefined {\n const assetPatternsToBeBundledForConfig = assetPatternsToBeBundled(exp);\n if (!assetPatternsToBeBundledForConfig) {\n return undefined;\n }\n const bundledAssets = setOfAssetsToBeBundled(\n assets,\n assetPatternsToBeBundledForConfig,\n projectRoot\n );\n return bundledAssets;\n}\n\nfunction logPatterns(patterns: string[]) {\n // Only log the patterns in debug mode, if they aren't already defined in the app.json, then all files will be targeted.\n Log.log('\\nProcessing asset bundle patterns:');\n patterns.forEach((p) => Log.log('- ' + p));\n}\n\nfunction shouldBundleAsset(asset: Asset, patterns: string[]) {\n const file = asset.files?.[0];\n return !!(\n '__packager_asset' in asset &&\n asset.__packager_asset &&\n file &&\n patterns.some((pattern) => minimatch(file, pattern))\n );\n}\n\nexport async function exportAssetsAsync(\n projectRoot: string,\n {\n exp,\n outputDir,\n bundles: { web, ...bundles },\n baseUrl,\n files = new Map(),\n hostedNative,\n }: {\n exp: ExpoConfig;\n bundles: Partial<Record<string, BundleOutput>>;\n outputDir: string;\n baseUrl: string;\n files?: ExportAssetMap;\n hostedNative?: boolean;\n }\n): Promise<{\n exp: ExpoConfig;\n assets: BundleAssetWithFileHashes[];\n embeddedHashSet: Set<string>;\n files: ExportAssetMap;\n}> {\n const hostedAssets: BundleAssetWithFileHashes[] = web ? [...web.assets] : [];\n\n // If the native assets should be hosted like web, then we can add them to the hosted assets to export.\n if (hostedNative) {\n hostedAssets.push(...Object.values(bundles).flatMap((bundle) => bundle!.assets ?? []));\n }\n\n if (hostedAssets.length) {\n // Save assets like a typical bundler, preserving the file paths on web.\n // TODO: Update React Native Web to support loading files from asset hashes.\n await persistMetroAssetsAsync(projectRoot, hostedAssets, {\n files,\n platform: 'web',\n outputDirectory: outputDir,\n baseUrl,\n });\n }\n\n if (hostedNative) {\n // Add google services file if it exists\n await resolveGoogleServicesFile(projectRoot, exp);\n return { exp, assets: [], embeddedHashSet: new Set(), files };\n }\n\n const assets: BundleAssetWithFileHashes[] = uniqBy(\n Object.values(bundles).flatMap((bundle) => bundle!.assets),\n (asset) => asset.hash\n );\n\n let bundledAssetsSet: Set<string> | undefined = undefined;\n let filteredAssets = assets;\n const embeddedHashSet: Set<string> = new Set();\n\n if (assets[0]?.fileHashes) {\n debug(`Assets = ${JSON.stringify(assets, null, 2)}`);\n // Updates the manifest to reflect additional asset bundling + configs\n // Get only asset strings for assets we will save\n bundledAssetsSet = resolveAssetPatternsToBeBundled(projectRoot, exp, assets);\n if (bundledAssetsSet) {\n debug(`Bundled assets = ${JSON.stringify([...bundledAssetsSet], null, 2)}`);\n // Filter asset objects to only ones that include assetPatternsToBeBundled matches\n filteredAssets = assets.filter((asset) => {\n const shouldInclude = assetShouldBeIncludedInExport(asset, bundledAssetsSet);\n if (!shouldInclude) {\n embeddedHashSet.add(asset.hash);\n }\n return shouldInclude;\n });\n debug(`Filtered assets count = ${filteredAssets.length}`);\n }\n\n const hashes = new Set<string>();\n\n // Add assets to copy.\n filteredAssets.forEach((asset) => {\n const assetId = getAssetIdForLogGrouping(projectRoot, asset);\n\n asset.files.forEach((fp: string, index: number) => {\n const hash = asset.fileHashes[index];\n if (hashes.has(hash)) return;\n hashes.add(hash);\n files.set(path.join('assets', hash), {\n originFilename: path.relative(projectRoot, fp),\n contents: fs.readFileSync(fp),\n assetId,\n });\n });\n });\n }\n\n // Add google services file if it exists\n await resolveGoogleServicesFile(projectRoot, exp);\n\n return { exp, assets, embeddedHashSet, files };\n}\n"],"names":["assetPatternsToBeBundled","exportAssetsAsync","resolveAssetPatternsToBeBundled","debug","require","mapAssetHashToAssetString","asset","hash","type","exp","updates","length","extra","undefined","assetShouldBeIncludedInExport","bundledAssetsSet","fileHashes","filter","has","setOfAssetsToBeBundled","assets","projectRoot","fullPatterns","map","p","path","join","logPatterns","allBundledAssets","shouldBundle","shouldBundleAsset","files","flat","Set","assetPatternsToBeBundledForConfig","bundledAssets","patterns","Log","log","forEach","file","__packager_asset","some","pattern","minimatch","outputDir","bundles","web","baseUrl","Map","hostedNative","hostedAssets","push","Object","values","flatMap","bundle","persistMetroAssetsAsync","platform","outputDirectory","resolveGoogleServicesFile","embeddedHashSet","uniqBy","filteredAssets","JSON","stringify","shouldInclude","add","hashes","assetId","getAssetIdForLogGrouping","fp","index","set","originFilename","relative","contents","fs","readFileSync"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/export/exportAssets.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport fs from 'fs';\nimport path from 'path';\nimport picomatch from 'picomatch';\n\nimport { getAssetIdForLogGrouping, persistMetroAssetsAsync } from './persistMetroAssets';\nimport type { Asset, BundleAssetWithFileHashes, BundleOutput, ExportAssetMap } from './saveAssets';\nimport * as Log from '../log';\nimport { resolveGoogleServicesFile } from '../start/server/middleware/resolveAssets';\nimport { uniqBy } from '../utils/array';\n\nconst debug = require('debug')('expo:export:exportAssets') as typeof console.log;\n\nfunction mapAssetHashToAssetString(asset: Asset, hash: string) {\n return 'asset_' + hash + ('type' in asset && asset.type ? '.' + asset.type : '');\n}\n\nexport function assetPatternsToBeBundled(\n exp: ExpoConfig & { extra?: { updates?: { assetPatternsToBeBundled?: string[] } } }\n): string[] | undefined {\n // new location for this key\n if (exp.updates?.assetPatternsToBeBundled?.length) {\n return exp.updates.assetPatternsToBeBundled;\n }\n\n // old, untyped location for this key. we may want to change this to throw in a few SDK versions (deprecated as of SDK 52).\n if (exp.extra?.updates?.assetPatternsToBeBundled?.length) {\n return exp.extra.updates.assetPatternsToBeBundled;\n }\n\n return undefined;\n}\n\n/**\n * Given an asset and a set of strings representing the assets to be bundled, returns true if\n * the asset is part of the set to be bundled.\n * @param asset Asset object\n * @param bundledAssetsSet Set of strings\n * @returns true if the asset should be bundled\n */\nfunction assetShouldBeIncludedInExport(asset: Asset, bundledAssetsSet: Set<string> | undefined) {\n if (!bundledAssetsSet) {\n return true;\n }\n return (\n asset.fileHashes.filter((hash) => bundledAssetsSet.has(mapAssetHashToAssetString(asset, hash)))\n .length > 0\n );\n}\n\n/**\n * Computes a set of strings representing the assets to be bundled with an export, given an array of assets,\n * and a set of patterns to match\n * @param assets The asset array\n * @param assetPatternsToBeBundled An array of strings with glob patterns to match\n * @param projectRoot The project root\n * @returns A set of asset strings\n */\nfunction setOfAssetsToBeBundled(\n assets: Asset[],\n assetPatternsToBeBundled: string[],\n projectRoot: string\n): Set<string> | undefined {\n // Convert asset patterns to a list of asset strings that match them.\n // Assets strings are formatted as `asset_<hash>.<type>` and represent\n // the name that the file will have in the app bundle. The `asset_` prefix is\n // needed because android doesn't support assets that start with numbers.\n\n const fullPatterns: string[] = assetPatternsToBeBundled.map((p: string) =>\n path.join(projectRoot, p)\n );\n\n logPatterns(fullPatterns);\n const matches = picomatch(fullPatterns);\n const allBundledAssets = assets\n .map((asset) => {\n const shouldBundle = shouldBundleAsset(asset, matches);\n if (shouldBundle) {\n debug(`${shouldBundle ? 'Include' : 'Exclude'} asset ${asset.files?.[0]}`);\n return asset.fileHashes.map((hash) => mapAssetHashToAssetString(asset, hash));\n }\n return [];\n })\n .flat();\n\n // The assets returned by the RN packager has duplicates so make sure we\n // only bundle each once.\n return new Set(allBundledAssets);\n}\n\n/**\n * Resolves the assetBundlePatterns from the manifest and returns the set of assets to bundle.\n *\n * @modifies {exp}\n */\nexport function resolveAssetPatternsToBeBundled<T extends ExpoConfig>(\n projectRoot: string,\n exp: T,\n assets: Asset[]\n): Set<string> | undefined {\n const assetPatternsToBeBundledForConfig = assetPatternsToBeBundled(exp);\n if (!assetPatternsToBeBundledForConfig) {\n return undefined;\n }\n const bundledAssets = setOfAssetsToBeBundled(\n assets,\n assetPatternsToBeBundledForConfig,\n projectRoot\n );\n return bundledAssets;\n}\n\nfunction logPatterns(patterns: string[]) {\n // Only log the patterns in debug mode, if they aren't already defined in the app.json, then all files will be targeted.\n Log.log('\\nProcessing asset bundle patterns:');\n patterns.forEach((p) => Log.log('- ' + p));\n}\n\nfunction shouldBundleAsset(asset: Asset, matcher: picomatch.Matcher) {\n const file = asset.files?.[0];\n return !!('__packager_asset' in asset && asset.__packager_asset && file && matcher(file));\n}\n\nexport async function exportAssetsAsync(\n projectRoot: string,\n {\n exp,\n outputDir,\n bundles: { web, ...bundles },\n baseUrl,\n files = new Map(),\n hostedNative,\n }: {\n exp: ExpoConfig;\n bundles: Partial<Record<string, BundleOutput>>;\n outputDir: string;\n baseUrl: string;\n files?: ExportAssetMap;\n hostedNative?: boolean;\n }\n): Promise<{\n exp: ExpoConfig;\n assets: BundleAssetWithFileHashes[];\n embeddedHashSet: Set<string>;\n files: ExportAssetMap;\n}> {\n const hostedAssets: BundleAssetWithFileHashes[] = web ? [...web.assets] : [];\n\n // If the native assets should be hosted like web, then we can add them to the hosted assets to export.\n if (hostedNative) {\n hostedAssets.push(...Object.values(bundles).flatMap((bundle) => bundle!.assets ?? []));\n }\n\n if (hostedAssets.length) {\n // Save assets like a typical bundler, preserving the file paths on web.\n // TODO: Update React Native Web to support loading files from asset hashes.\n await persistMetroAssetsAsync(projectRoot, hostedAssets, {\n files,\n platform: 'web',\n outputDirectory: outputDir,\n baseUrl,\n });\n }\n\n if (hostedNative) {\n // Add google services file if it exists\n await resolveGoogleServicesFile(projectRoot, exp);\n return { exp, assets: [], embeddedHashSet: new Set(), files };\n }\n\n const assets: BundleAssetWithFileHashes[] = uniqBy(\n Object.values(bundles).flatMap((bundle) => bundle!.assets),\n (asset) => asset.hash\n );\n\n let bundledAssetsSet: Set<string> | undefined = undefined;\n let filteredAssets = assets;\n const embeddedHashSet: Set<string> = new Set();\n\n if (assets[0]?.fileHashes) {\n debug(`Assets = ${JSON.stringify(assets, null, 2)}`);\n // Updates the manifest to reflect additional asset bundling + configs\n // Get only asset strings for assets we will save\n bundledAssetsSet = resolveAssetPatternsToBeBundled(projectRoot, exp, assets);\n if (bundledAssetsSet) {\n debug(`Bundled assets = ${JSON.stringify([...bundledAssetsSet], null, 2)}`);\n // Filter asset objects to only ones that include assetPatternsToBeBundled matches\n filteredAssets = assets.filter((asset) => {\n const shouldInclude = assetShouldBeIncludedInExport(asset, bundledAssetsSet);\n if (!shouldInclude) {\n embeddedHashSet.add(asset.hash);\n }\n return shouldInclude;\n });\n debug(`Filtered assets count = ${filteredAssets.length}`);\n }\n\n const hashes = new Set<string>();\n\n // Add assets to copy.\n filteredAssets.forEach((asset) => {\n const assetId = getAssetIdForLogGrouping(projectRoot, asset);\n\n asset.files.forEach((fp: string, index: number) => {\n const hash = asset.fileHashes[index];\n if (hashes.has(hash)) return;\n hashes.add(hash);\n files.set(path.join('assets', hash), {\n originFilename: path.relative(projectRoot, fp),\n contents: fs.readFileSync(fp),\n assetId,\n });\n });\n });\n }\n\n // Add google services file if it exists\n await resolveGoogleServicesFile(projectRoot, exp);\n\n return { exp, assets, embeddedHashSet, files };\n}\n"],"names":["assetPatternsToBeBundled","exportAssetsAsync","resolveAssetPatternsToBeBundled","debug","require","mapAssetHashToAssetString","asset","hash","type","exp","updates","length","extra","undefined","assetShouldBeIncludedInExport","bundledAssetsSet","fileHashes","filter","has","setOfAssetsToBeBundled","assets","projectRoot","fullPatterns","map","p","path","join","logPatterns","matches","picomatch","allBundledAssets","shouldBundle","shouldBundleAsset","files","flat","Set","assetPatternsToBeBundledForConfig","bundledAssets","patterns","Log","log","forEach","matcher","file","__packager_asset","outputDir","bundles","web","baseUrl","Map","hostedNative","hostedAssets","push","Object","values","flatMap","bundle","persistMetroAssetsAsync","platform","outputDirectory","resolveGoogleServicesFile","embeddedHashSet","uniqBy","filteredAssets","JSON","stringify","shouldInclude","add","hashes","assetId","getAssetIdForLogGrouping","fp","index","set","originFilename","relative","contents","fs","readFileSync"],"mappings":"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"}
|
|
@@ -20,13 +20,15 @@ const _errors = require("../../utils/errors");
|
|
|
20
20
|
async function getMainActivityAsync(projectRoot) {
|
|
21
21
|
const filePath = await _configplugins().AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);
|
|
22
22
|
const androidManifest = await _configplugins().AndroidConfig.Manifest.readAndroidManifestAsync(filePath);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
const runnableActivity = _configplugins().AndroidConfig.Manifest.getRunnableActivity(androidManifest);
|
|
24
|
+
if (runnableActivity) {
|
|
25
|
+
return runnableActivity.$['android:name'];
|
|
26
|
+
}
|
|
27
|
+
const mainActivity = _configplugins().AndroidConfig.Manifest.getMainActivity(androidManifest);
|
|
28
|
+
if (!mainActivity) {
|
|
26
29
|
throw new _errors.CommandError('ANDROID_MALFORMED', `${filePath} is missing a runnable activity element.`);
|
|
27
30
|
}
|
|
28
|
-
|
|
29
|
-
return activity.$['android:name'];
|
|
31
|
+
return mainActivity.$['android:name'];
|
|
30
32
|
}
|
|
31
33
|
async function resolveLaunchPropsAsync(projectRoot, options) {
|
|
32
34
|
const mainActivity = await getMainActivityAsync(projectRoot);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/run/android/resolveLaunchProps.ts"],"sourcesContent":["import { AndroidConfig } from '@expo/config-plugins';\n\nimport { AndroidAppIdResolver } from '../../start/platforms/android/AndroidAppIdResolver';\nimport { CommandError } from '../../utils/errors';\n\nexport interface LaunchProps {\n /**\n * The \"common\" Android package name, configured through the app manifest.\n * @see https://source.android.com/docs/core/architecture/hidl/code-style#package-names\n */\n packageName: string;\n /**\n * Optional customized application ID, used in product flavors.\n * @see https://developer.android.com/build/build-variants#change-app-id\n */\n customAppId?: string;\n /**\n * The main activity to launch, by default this is `.MainActivity`.\n * @see https://github.com/expo/expo/blob/c0aec226a43c0f186258a063a6145c3e52246f8a/templates/expo-template-bare-minimum/android/app/src/main/AndroidManifest.xml#L22\n */\n mainActivity: string;\n /**\n * The full launch activity reference used in the app intent to launch the app with `adb am start -n <launchActivity>`.\n * Usually, this is structured as `<package-name>/.<activity-name>`.\n * For product flavors, this is structured as `<custom-app-id>/<package-name>.<activity-name>`.\n * @see https://developer.android.com/studio/command-line/adb#IntentSpec\n */\n launchActivity: string;\n}\n\nasync function getMainActivityAsync(projectRoot: string): Promise<string> {\n const filePath = await AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);\n const androidManifest = await AndroidConfig.Manifest.readAndroidManifestAsync(filePath);\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/run/android/resolveLaunchProps.ts"],"sourcesContent":["import { AndroidConfig } from '@expo/config-plugins';\n\nimport { AndroidAppIdResolver } from '../../start/platforms/android/AndroidAppIdResolver';\nimport { CommandError } from '../../utils/errors';\n\nexport interface LaunchProps {\n /**\n * The \"common\" Android package name, configured through the app manifest.\n * @see https://source.android.com/docs/core/architecture/hidl/code-style#package-names\n */\n packageName: string;\n /**\n * Optional customized application ID, used in product flavors.\n * @see https://developer.android.com/build/build-variants#change-app-id\n */\n customAppId?: string;\n /**\n * The main activity to launch, by default this is `.MainActivity`.\n * @see https://github.com/expo/expo/blob/c0aec226a43c0f186258a063a6145c3e52246f8a/templates/expo-template-bare-minimum/android/app/src/main/AndroidManifest.xml#L22\n */\n mainActivity: string;\n /**\n * The full launch activity reference used in the app intent to launch the app with `adb am start -n <launchActivity>`.\n * Usually, this is structured as `<package-name>/.<activity-name>`.\n * For product flavors, this is structured as `<custom-app-id>/<package-name>.<activity-name>`.\n * @see https://developer.android.com/studio/command-line/adb#IntentSpec\n */\n launchActivity: string;\n}\n\nasync function getMainActivityAsync(projectRoot: string): Promise<string> {\n const filePath = await AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);\n const androidManifest = await AndroidConfig.Manifest.readAndroidManifestAsync(filePath);\n const runnableActivity = AndroidConfig.Manifest.getRunnableActivity(androidManifest);\n if (runnableActivity) {\n return runnableActivity.$['android:name'];\n }\n const mainActivity = AndroidConfig.Manifest.getMainActivity(androidManifest);\n if (!mainActivity) {\n throw new CommandError(\n 'ANDROID_MALFORMED',\n `${filePath} is missing a runnable activity element.`\n );\n }\n return mainActivity.$['android:name'];\n}\n\nexport async function resolveLaunchPropsAsync(\n projectRoot: string,\n options: { appId?: string }\n): Promise<LaunchProps> {\n const mainActivity = await getMainActivityAsync(projectRoot);\n const packageName = await new AndroidAppIdResolver(projectRoot).getAppIdFromNativeAsync();\n const customAppId = options.appId;\n\n const launchActivity =\n customAppId && customAppId !== packageName\n ? `${customAppId}/${packageName}${mainActivity}`\n : `${packageName}/${mainActivity}`;\n\n return {\n mainActivity,\n launchActivity,\n packageName,\n customAppId,\n };\n}\n"],"names":["resolveLaunchPropsAsync","getMainActivityAsync","projectRoot","filePath","AndroidConfig","Paths","getAndroidManifestAsync","androidManifest","Manifest","readAndroidManifestAsync","runnableActivity","getRunnableActivity","$","mainActivity","getMainActivity","CommandError","options","packageName","AndroidAppIdResolver","getAppIdFromNativeAsync","customAppId","appId","launchActivity"],"mappings":";;;;+BA+CsBA;;;eAAAA;;;;yBA/CQ;;;;;;sCAEO;wBACR;AA2B7B,eAAeC,qBAAqBC,WAAmB;IACrD,MAAMC,WAAW,MAAMC,8BAAa,CAACC,KAAK,CAACC,uBAAuB,CAACJ;IACnE,MAAMK,kBAAkB,MAAMH,8BAAa,CAACI,QAAQ,CAACC,wBAAwB,CAACN;IAC9E,MAAMO,mBAAmBN,8BAAa,CAACI,QAAQ,CAACG,mBAAmB,CAACJ;IACpE,IAAIG,kBAAkB;QACpB,OAAOA,iBAAiBE,CAAC,CAAC,eAAe;IAC3C;IACA,MAAMC,eAAeT,8BAAa,CAACI,QAAQ,CAACM,eAAe,CAACP;IAC5D,IAAI,CAACM,cAAc;QACjB,MAAM,IAAIE,oBAAY,CACpB,qBACA,GAAGZ,SAAS,wCAAwC,CAAC;IAEzD;IACA,OAAOU,aAAaD,CAAC,CAAC,eAAe;AACvC;AAEO,eAAeZ,wBACpBE,WAAmB,EACnBc,OAA2B;IAE3B,MAAMH,eAAe,MAAMZ,qBAAqBC;IAChD,MAAMe,cAAc,MAAM,IAAIC,0CAAoB,CAAChB,aAAaiB,uBAAuB;IACvF,MAAMC,cAAcJ,QAAQK,KAAK;IAEjC,MAAMC,iBACJF,eAAeA,gBAAgBH,cAC3B,GAAGG,YAAY,CAAC,EAAEH,cAAcJ,cAAc,GAC9C,GAAGI,YAAY,CAAC,EAAEJ,cAAc;IAEtC,OAAO;QACLA;QACAS;QACAL;QACAG;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/run/android/runAndroidAsync.ts"],"sourcesContent":["import chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { resolveInstallApkNameAsync } from './resolveInstallApkName';\nimport { Options, ResolvedOptions, resolveOptionsAsync } from './resolveOptions';\nimport { exportEagerAsync } from '../../export/embed/exportEager';\nimport { Log } from '../../log';\nimport type { AndroidOpenInCustomProps } from '../../start/platforms/android/AndroidPlatformManager';\nimport { assembleAsync, installAsync } from '../../start/platforms/android/gradle';\nimport { resolveBuildCache, uploadBuildCache } from '../../utils/build-cache-providers';\nimport { CommandError } from '../../utils/errors';\nimport { setNodeEnv } from '../../utils/nodeEnv';\nimport { ensurePortAvailabilityAsync } from '../../utils/port';\nimport { getSchemesForAndroidAsync } from '../../utils/scheme';\nimport { ensureNativeProjectAsync } from '../ensureNativeProject';\nimport { logProjectLogsLocation } from '../hints';\nimport { startBundlerAsync } from '../startBundler';\n\nconst debug = require('debug')('expo:run:android');\n\nexport async function runAndroidAsync(projectRoot: string, { install, ...options }: Options) {\n // NOTE: This is a guess, the developer can overwrite with `NODE_ENV`.\n const isProduction = options.variant?.toLowerCase().endsWith('release');\n setNodeEnv(isProduction ? 'production' : 'development');\n require('@expo/env').load(projectRoot);\n\n await ensureNativeProjectAsync(projectRoot, { platform: 'android', install });\n\n const props = await resolveOptionsAsync(projectRoot, options);\n\n if (!options.binary && props.buildCacheProvider) {\n const localPath = await resolveBuildCache({\n projectRoot,\n platform: 'android',\n provider: props.buildCacheProvider,\n runOptions: options,\n });\n if (localPath) {\n options.binary = localPath;\n }\n }\n\n debug('Package name: ' + props.packageName);\n Log.log('› Building app...');\n\n const androidProjectRoot = path.join(projectRoot, 'android');\n\n let shouldUpdateBuildCache = false;\n if (!options.binary) {\n let eagerBundleOptions: string | undefined;\n\n if (isProduction) {\n eagerBundleOptions = JSON.stringify(\n await exportEagerAsync(projectRoot, {\n dev: false,\n platform: 'android',\n })\n );\n }\n\n await assembleAsync(androidProjectRoot, {\n variant: props.variant,\n port: props.port,\n appName: props.appName,\n buildCache: props.buildCache,\n architectures: props.architectures,\n eagerBundleOptions,\n });\n shouldUpdateBuildCache = true;\n\n // Ensure the port hasn't become busy during the build.\n if (props.shouldStartBundler && !(await ensurePortAvailabilityAsync(projectRoot, props))) {\n props.shouldStartBundler = false;\n }\n }\n\n const manager = await startBundlerAsync(projectRoot, {\n port: props.port,\n // If a scheme is specified then use that instead of the package name.\n scheme: (await getSchemesForAndroidAsync(projectRoot))?.[0],\n headless: !props.shouldStartBundler,\n });\n\n if (!options.binary) {\n // Find the APK file path\n const apkFile = await resolveInstallApkNameAsync(props.device.device, props);\n if (apkFile) {\n // Attempt to install the APK from the file path\n options.binary = path.join(props.apkVariantDirectory, apkFile);\n }\n }\n\n if (options.binary) {\n // Attempt to install the APK from the file path\n const binaryPath = path.join(options.binary);\n\n if (!fs.existsSync(binaryPath)) {\n throw new CommandError(`The path to the custom Android binary does not exist: ${binaryPath}`);\n }\n Log.log(chalk.gray`\\u203A Installing ${binaryPath}`);\n await props.device.installAppAsync(binaryPath);\n } else {\n await installAppAsync(androidProjectRoot, props);\n }\n\n await manager.getDefaultDevServer().openCustomRuntimeAsync
|
|
1
|
+
{"version":3,"sources":["../../../../src/run/android/runAndroidAsync.ts"],"sourcesContent":["import chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { resolveInstallApkNameAsync } from './resolveInstallApkName';\nimport { Options, ResolvedOptions, resolveOptionsAsync } from './resolveOptions';\nimport { exportEagerAsync } from '../../export/embed/exportEager';\nimport { Log } from '../../log';\nimport type { AndroidOpenInCustomProps } from '../../start/platforms/android/AndroidPlatformManager';\nimport { assembleAsync, installAsync } from '../../start/platforms/android/gradle';\nimport { resolveBuildCache, uploadBuildCache } from '../../utils/build-cache-providers';\nimport { CommandError } from '../../utils/errors';\nimport { setNodeEnv } from '../../utils/nodeEnv';\nimport { ensurePortAvailabilityAsync } from '../../utils/port';\nimport { getSchemesForAndroidAsync } from '../../utils/scheme';\nimport { ensureNativeProjectAsync } from '../ensureNativeProject';\nimport { logProjectLogsLocation } from '../hints';\nimport { startBundlerAsync } from '../startBundler';\n\nconst debug = require('debug')('expo:run:android');\n\nexport async function runAndroidAsync(projectRoot: string, { install, ...options }: Options) {\n // NOTE: This is a guess, the developer can overwrite with `NODE_ENV`.\n const isProduction = options.variant?.toLowerCase().endsWith('release');\n setNodeEnv(isProduction ? 'production' : 'development');\n require('@expo/env').load(projectRoot);\n\n await ensureNativeProjectAsync(projectRoot, { platform: 'android', install });\n\n const props = await resolveOptionsAsync(projectRoot, options);\n\n if (!options.binary && props.buildCacheProvider) {\n const localPath = await resolveBuildCache({\n projectRoot,\n platform: 'android',\n provider: props.buildCacheProvider,\n runOptions: options,\n });\n if (localPath) {\n options.binary = localPath;\n }\n }\n\n debug('Package name: ' + props.packageName);\n Log.log('› Building app...');\n\n const androidProjectRoot = path.join(projectRoot, 'android');\n\n let shouldUpdateBuildCache = false;\n if (!options.binary) {\n let eagerBundleOptions: string | undefined;\n\n if (isProduction) {\n eagerBundleOptions = JSON.stringify(\n await exportEagerAsync(projectRoot, {\n dev: false,\n platform: 'android',\n })\n );\n }\n\n await assembleAsync(androidProjectRoot, {\n variant: props.variant,\n port: props.port,\n appName: props.appName,\n buildCache: props.buildCache,\n architectures: props.architectures,\n eagerBundleOptions,\n });\n shouldUpdateBuildCache = true;\n\n // Ensure the port hasn't become busy during the build.\n if (props.shouldStartBundler && !(await ensurePortAvailabilityAsync(projectRoot, props))) {\n props.shouldStartBundler = false;\n }\n }\n\n const manager = await startBundlerAsync(projectRoot, {\n port: props.port,\n // If a scheme is specified then use that instead of the package name.\n scheme: (await getSchemesForAndroidAsync(projectRoot))?.[0],\n headless: !props.shouldStartBundler,\n });\n\n if (!options.binary) {\n // Find the APK file path\n const apkFile = await resolveInstallApkNameAsync(props.device.device, props);\n if (apkFile) {\n // Attempt to install the APK from the file path\n options.binary = path.join(props.apkVariantDirectory, apkFile);\n }\n }\n\n if (options.binary) {\n // Attempt to install the APK from the file path\n const binaryPath = path.join(options.binary);\n\n if (!fs.existsSync(binaryPath)) {\n throw new CommandError(`The path to the custom Android binary does not exist: ${binaryPath}`);\n }\n Log.log(chalk.gray`\\u203A Installing ${binaryPath}`);\n await props.device.installAppAsync(binaryPath);\n } else {\n await installAppAsync(androidProjectRoot, props);\n }\n\n await manager.getDefaultDevServer().openCustomRuntimeAsync(\n 'emulator',\n {\n applicationId: props.packageName,\n customAppId: props.customAppId,\n launchActivity: props.launchActivity,\n },\n { device: props.device.device }\n );\n\n if (props.shouldStartBundler) {\n logProjectLogsLocation();\n } else {\n await manager.stopAsync();\n }\n\n if (options.binary && shouldUpdateBuildCache && props.buildCacheProvider) {\n await uploadBuildCache({\n projectRoot,\n platform: 'android',\n provider: props.buildCacheProvider,\n buildPath: options.binary,\n runOptions: options,\n });\n }\n}\n\nasync function installAppAsync(androidProjectRoot: string, props: ResolvedOptions) {\n // If we cannot resolve the APK file path then we can attempt to install using Gradle.\n // This offers more advanced resolution that we may not have first class support for.\n Log.log('› Failed to locate binary file, installing with Gradle...');\n await installAsync(androidProjectRoot, {\n variant: props.variant ?? 'debug',\n appName: props.appName ?? 'app',\n port: props.port,\n });\n}\n"],"names":["runAndroidAsync","debug","require","projectRoot","install","options","isProduction","variant","toLowerCase","endsWith","setNodeEnv","load","ensureNativeProjectAsync","platform","props","resolveOptionsAsync","binary","buildCacheProvider","localPath","resolveBuildCache","provider","runOptions","packageName","Log","log","androidProjectRoot","path","join","shouldUpdateBuildCache","eagerBundleOptions","JSON","stringify","exportEagerAsync","dev","assembleAsync","port","appName","buildCache","architectures","shouldStartBundler","ensurePortAvailabilityAsync","manager","startBundlerAsync","scheme","getSchemesForAndroidAsync","headless","apkFile","resolveInstallApkNameAsync","device","apkVariantDirectory","binaryPath","fs","existsSync","CommandError","chalk","gray","installAppAsync","getDefaultDevServer","openCustomRuntimeAsync","applicationId","customAppId","launchActivity","logProjectLogsLocation","stopAsync","uploadBuildCache","buildPath","installAsync"],"mappings":"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"}
|
|
@@ -115,7 +115,7 @@ async function launchAppAsync(binaryPath, manager, props, appId) {
|
|
|
115
115
|
await manager.getDefaultDevServer().openCustomRuntimeAsync('simulator', {
|
|
116
116
|
applicationId: appId
|
|
117
117
|
}, {
|
|
118
|
-
device
|
|
118
|
+
device: device.device
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
121
|
async function getLaunchInfoForBinaryAsync(binaryPath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/run/ios/launchApp.ts"],"sourcesContent":["import chalk from 'chalk';\nimport path from 'path';\n\nimport * as XcodeBuild from './XcodeBuild';\nimport { BuildProps } from './XcodeBuild.types';\nimport { getAppDeltaDirectory, installOnDeviceAsync } from './appleDevice/installOnDeviceAsync';\nimport { Log } from '../../log';\nimport { AppleDeviceManager } from '../../start/platforms/ios/AppleDeviceManager';\nimport { launchBinaryOnMacAsync } from '../../start/platforms/ios/devicectl';\nimport { SimulatorLogStreamer } from '../../start/platforms/ios/simctlLogging';\nimport { DevServerManager } from '../../start/server/DevServerManager';\nimport { parsePlistAsync } from '../../utils/plist';\nimport { profile } from '../../utils/profile';\n\ntype BinaryLaunchInfo = {\n bundleId: string;\n schemes: string[];\n};\n\n/** Install and launch the app binary on a device. */\nexport async function launchAppAsync(\n binaryPath: string,\n manager: DevServerManager,\n props: Pick<BuildProps, 'isSimulator' | 'device' | 'shouldStartBundler'>,\n appId?: string\n) {\n appId ??= (await profile(getLaunchInfoForBinaryAsync)(binaryPath)).bundleId;\n\n Log.log(chalk.gray`\\u203A Installing ${binaryPath}`);\n if (!props.isSimulator) {\n if (props.device.osType === 'macOS') {\n await launchBinaryOnMacAsync(appId, binaryPath);\n } else {\n await profile(installOnDeviceAsync)({\n bundleIdentifier: appId,\n bundle: binaryPath,\n appDeltaDirectory: getAppDeltaDirectory(appId),\n udid: props.device.udid,\n deviceName: props.device.name,\n });\n }\n\n return;\n }\n\n XcodeBuild.logPrettyItem(chalk`{bold Installing} on ${props.device.name}`);\n\n const device = await AppleDeviceManager.resolveAsync({ device: props.device });\n await device.installAppAsync(binaryPath);\n\n XcodeBuild.logPrettyItem(chalk`{bold Opening} on ${device.name} {dim (${appId})}`);\n\n if (props.shouldStartBundler) {\n await SimulatorLogStreamer.getStreamer(device.device, {\n appId,\n }).attachAsync();\n }\n\n await manager.getDefaultDevServer().openCustomRuntimeAsync(\n 'simulator',\n {\n applicationId: appId,\n },\n { device }\n );\n}\n\nexport async function getLaunchInfoForBinaryAsync(binaryPath: string): Promise<BinaryLaunchInfo> {\n const builtInfoPlistPath = path.join(binaryPath, 'Info.plist');\n const { CFBundleIdentifier, CFBundleURLTypes } = await parsePlistAsync(builtInfoPlistPath);\n\n let schemes: string[] = [];\n\n if (Array.isArray(CFBundleURLTypes)) {\n schemes =\n CFBundleURLTypes.reduce<string[]>((acc, urlType: unknown) => {\n if (\n urlType &&\n typeof urlType === 'object' &&\n 'CFBundleURLSchemes' in urlType &&\n Array.isArray(urlType.CFBundleURLSchemes)\n ) {\n return [...acc, ...urlType.CFBundleURLSchemes];\n }\n return acc;\n }, []) ?? [];\n }\n\n return { bundleId: CFBundleIdentifier, schemes };\n}\n"],"names":["getLaunchInfoForBinaryAsync","launchAppAsync","binaryPath","manager","props","appId","profile","bundleId","Log","log","chalk","gray","isSimulator","device","osType","launchBinaryOnMacAsync","installOnDeviceAsync","bundleIdentifier","bundle","appDeltaDirectory","getAppDeltaDirectory","udid","deviceName","name","XcodeBuild","logPrettyItem","AppleDeviceManager","resolveAsync","installAppAsync","shouldStartBundler","SimulatorLogStreamer","getStreamer","attachAsync","getDefaultDevServer","openCustomRuntimeAsync","applicationId","builtInfoPlistPath","path","join","CFBundleIdentifier","CFBundleURLTypes","parsePlistAsync","schemes","Array","isArray","reduce","acc","urlType","CFBundleURLSchemes"],"mappings":";;;;;;;;;;;IAmEsBA,2BAA2B;eAA3BA;;IA/CAC,cAAc;eAAdA;;;;gEApBJ;;;;;;;gEACD;;;;;;oEAEW;sCAE+B;qBACvC;oCACe;2BACI;+BACF;uBAEL;yBACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQjB,eAAeA,eACpBC,UAAkB,EAClBC,OAAyB,EACzBC,KAAwE,EACxEC,KAAc;IAEdA,UAAU,AAAC,CAAA,MAAMC,IAAAA,gBAAO,EAACN,6BAA6BE,WAAU,EAAGK,QAAQ;IAE3EC,QAAG,CAACC,GAAG,CAACC,gBAAK,CAACC,IAAI,CAAC,kBAAkB,EAAET,WAAW,CAAC;IACnD,IAAI,CAACE,MAAMQ,WAAW,EAAE;QACtB,IAAIR,MAAMS,MAAM,CAACC,MAAM,KAAK,SAAS;YACnC,MAAMC,IAAAA,iCAAsB,EAACV,OAAOH;QACtC,OAAO;YACL,MAAMI,IAAAA,gBAAO,EAACU,0CAAoB,EAAE;gBAClCC,kBAAkBZ;gBAClBa,QAAQhB;gBACRiB,mBAAmBC,IAAAA,0CAAoB,EAACf;gBACxCgB,MAAMjB,MAAMS,MAAM,CAACQ,IAAI;gBACvBC,YAAYlB,MAAMS,MAAM,CAACU,IAAI;YAC/B;QACF;QAEA;IACF;IAEAC,YAAWC,aAAa,CAACf,IAAAA,gBAAK,CAAA,CAAC,qBAAqB,EAAEN,MAAMS,MAAM,CAACU,IAAI,CAAC,CAAC;IAEzE,MAAMV,SAAS,MAAMa,sCAAkB,CAACC,YAAY,CAAC;QAAEd,QAAQT,MAAMS,MAAM;IAAC;IAC5E,MAAMA,OAAOe,eAAe,CAAC1B;IAE7BsB,YAAWC,aAAa,CAACf,IAAAA,gBAAK,CAAA,CAAC,kBAAkB,EAAEG,OAAOU,IAAI,CAAC,OAAO,EAAElB,MAAM,EAAE,CAAC;IAEjF,IAAID,MAAMyB,kBAAkB,EAAE;QAC5B,MAAMC,mCAAoB,CAACC,WAAW,CAAClB,OAAOA,MAAM,EAAE;YACpDR;QACF,GAAG2B,WAAW;IAChB;IAEA,MAAM7B,QAAQ8B,mBAAmB,GAAGC,sBAAsB,CACxD,aACA;QACEC,eAAe9B;IACjB,GACA;QAAEQ;
|
|
1
|
+
{"version":3,"sources":["../../../../src/run/ios/launchApp.ts"],"sourcesContent":["import chalk from 'chalk';\nimport path from 'path';\n\nimport * as XcodeBuild from './XcodeBuild';\nimport { BuildProps } from './XcodeBuild.types';\nimport { getAppDeltaDirectory, installOnDeviceAsync } from './appleDevice/installOnDeviceAsync';\nimport { Log } from '../../log';\nimport { AppleDeviceManager } from '../../start/platforms/ios/AppleDeviceManager';\nimport { launchBinaryOnMacAsync } from '../../start/platforms/ios/devicectl';\nimport { SimulatorLogStreamer } from '../../start/platforms/ios/simctlLogging';\nimport { DevServerManager } from '../../start/server/DevServerManager';\nimport { parsePlistAsync } from '../../utils/plist';\nimport { profile } from '../../utils/profile';\n\ntype BinaryLaunchInfo = {\n bundleId: string;\n schemes: string[];\n};\n\n/** Install and launch the app binary on a device. */\nexport async function launchAppAsync(\n binaryPath: string,\n manager: DevServerManager,\n props: Pick<BuildProps, 'isSimulator' | 'device' | 'shouldStartBundler'>,\n appId?: string\n) {\n appId ??= (await profile(getLaunchInfoForBinaryAsync)(binaryPath)).bundleId;\n\n Log.log(chalk.gray`\\u203A Installing ${binaryPath}`);\n if (!props.isSimulator) {\n if (props.device.osType === 'macOS') {\n await launchBinaryOnMacAsync(appId, binaryPath);\n } else {\n await profile(installOnDeviceAsync)({\n bundleIdentifier: appId,\n bundle: binaryPath,\n appDeltaDirectory: getAppDeltaDirectory(appId),\n udid: props.device.udid,\n deviceName: props.device.name,\n });\n }\n\n return;\n }\n\n XcodeBuild.logPrettyItem(chalk`{bold Installing} on ${props.device.name}`);\n\n const device = await AppleDeviceManager.resolveAsync({ device: props.device });\n await device.installAppAsync(binaryPath);\n\n XcodeBuild.logPrettyItem(chalk`{bold Opening} on ${device.name} {dim (${appId})}`);\n\n if (props.shouldStartBundler) {\n await SimulatorLogStreamer.getStreamer(device.device, {\n appId,\n }).attachAsync();\n }\n\n await manager.getDefaultDevServer().openCustomRuntimeAsync(\n 'simulator',\n {\n applicationId: appId,\n },\n { device: device.device }\n );\n}\n\nexport async function getLaunchInfoForBinaryAsync(binaryPath: string): Promise<BinaryLaunchInfo> {\n const builtInfoPlistPath = path.join(binaryPath, 'Info.plist');\n const { CFBundleIdentifier, CFBundleURLTypes } = await parsePlistAsync(builtInfoPlistPath);\n\n let schemes: string[] = [];\n\n if (Array.isArray(CFBundleURLTypes)) {\n schemes =\n CFBundleURLTypes.reduce<string[]>((acc, urlType: unknown) => {\n if (\n urlType &&\n typeof urlType === 'object' &&\n 'CFBundleURLSchemes' in urlType &&\n Array.isArray(urlType.CFBundleURLSchemes)\n ) {\n return [...acc, ...urlType.CFBundleURLSchemes];\n }\n return acc;\n }, []) ?? [];\n }\n\n return { bundleId: CFBundleIdentifier, schemes };\n}\n"],"names":["getLaunchInfoForBinaryAsync","launchAppAsync","binaryPath","manager","props","appId","profile","bundleId","Log","log","chalk","gray","isSimulator","device","osType","launchBinaryOnMacAsync","installOnDeviceAsync","bundleIdentifier","bundle","appDeltaDirectory","getAppDeltaDirectory","udid","deviceName","name","XcodeBuild","logPrettyItem","AppleDeviceManager","resolveAsync","installAppAsync","shouldStartBundler","SimulatorLogStreamer","getStreamer","attachAsync","getDefaultDevServer","openCustomRuntimeAsync","applicationId","builtInfoPlistPath","path","join","CFBundleIdentifier","CFBundleURLTypes","parsePlistAsync","schemes","Array","isArray","reduce","acc","urlType","CFBundleURLSchemes"],"mappings":";;;;;;;;;;;IAmEsBA,2BAA2B;eAA3BA;;IA/CAC,cAAc;eAAdA;;;;gEApBJ;;;;;;;gEACD;;;;;;oEAEW;sCAE+B;qBACvC;oCACe;2BACI;+BACF;uBAEL;yBACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQjB,eAAeA,eACpBC,UAAkB,EAClBC,OAAyB,EACzBC,KAAwE,EACxEC,KAAc;IAEdA,UAAU,AAAC,CAAA,MAAMC,IAAAA,gBAAO,EAACN,6BAA6BE,WAAU,EAAGK,QAAQ;IAE3EC,QAAG,CAACC,GAAG,CAACC,gBAAK,CAACC,IAAI,CAAC,kBAAkB,EAAET,WAAW,CAAC;IACnD,IAAI,CAACE,MAAMQ,WAAW,EAAE;QACtB,IAAIR,MAAMS,MAAM,CAACC,MAAM,KAAK,SAAS;YACnC,MAAMC,IAAAA,iCAAsB,EAACV,OAAOH;QACtC,OAAO;YACL,MAAMI,IAAAA,gBAAO,EAACU,0CAAoB,EAAE;gBAClCC,kBAAkBZ;gBAClBa,QAAQhB;gBACRiB,mBAAmBC,IAAAA,0CAAoB,EAACf;gBACxCgB,MAAMjB,MAAMS,MAAM,CAACQ,IAAI;gBACvBC,YAAYlB,MAAMS,MAAM,CAACU,IAAI;YAC/B;QACF;QAEA;IACF;IAEAC,YAAWC,aAAa,CAACf,IAAAA,gBAAK,CAAA,CAAC,qBAAqB,EAAEN,MAAMS,MAAM,CAACU,IAAI,CAAC,CAAC;IAEzE,MAAMV,SAAS,MAAMa,sCAAkB,CAACC,YAAY,CAAC;QAAEd,QAAQT,MAAMS,MAAM;IAAC;IAC5E,MAAMA,OAAOe,eAAe,CAAC1B;IAE7BsB,YAAWC,aAAa,CAACf,IAAAA,gBAAK,CAAA,CAAC,kBAAkB,EAAEG,OAAOU,IAAI,CAAC,OAAO,EAAElB,MAAM,EAAE,CAAC;IAEjF,IAAID,MAAMyB,kBAAkB,EAAE;QAC5B,MAAMC,mCAAoB,CAACC,WAAW,CAAClB,OAAOA,MAAM,EAAE;YACpDR;QACF,GAAG2B,WAAW;IAChB;IAEA,MAAM7B,QAAQ8B,mBAAmB,GAAGC,sBAAsB,CACxD,aACA;QACEC,eAAe9B;IACjB,GACA;QAAEQ,QAAQA,OAAOA,MAAM;IAAC;AAE5B;AAEO,eAAeb,4BAA4BE,UAAkB;IAClE,MAAMkC,qBAAqBC,eAAI,CAACC,IAAI,CAACpC,YAAY;IACjD,MAAM,EAAEqC,kBAAkB,EAAEC,gBAAgB,EAAE,GAAG,MAAMC,IAAAA,sBAAe,EAACL;IAEvE,IAAIM,UAAoB,EAAE;IAE1B,IAAIC,MAAMC,OAAO,CAACJ,mBAAmB;QACnCE,UACEF,iBAAiBK,MAAM,CAAW,CAACC,KAAKC;YACtC,IACEA,WACA,OAAOA,YAAY,YACnB,wBAAwBA,WACxBJ,MAAMC,OAAO,CAACG,QAAQC,kBAAkB,GACxC;gBACA,OAAO;uBAAIF;uBAAQC,QAAQC,kBAAkB;iBAAC;YAChD;YACA,OAAOF;QACT,GAAG,EAAE,KAAK,EAAE;IAChB;IAEA,OAAO;QAAEvC,UAAUgC;QAAoBG;IAAQ;AACjD"}
|
|
@@ -22,6 +22,13 @@ function _spawnasync() {
|
|
|
22
22
|
};
|
|
23
23
|
return data;
|
|
24
24
|
}
|
|
25
|
+
function _path() {
|
|
26
|
+
const data = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
27
|
+
_path = function() {
|
|
28
|
+
return data;
|
|
29
|
+
};
|
|
30
|
+
return data;
|
|
31
|
+
}
|
|
25
32
|
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../../../log"));
|
|
26
33
|
const _Prerequisite = require("../Prerequisite");
|
|
27
34
|
function _interop_require_default(obj) {
|
|
@@ -71,14 +78,44 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
71
78
|
return newObj;
|
|
72
79
|
}
|
|
73
80
|
const debug = require('debug')('expo:doctor:apple:simulatorApp');
|
|
74
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Get the bundle ID of the Simulator.app via AppleScript / LaunchServices.
|
|
83
|
+
* May return null if the Simulator.app is not registered in LaunchServices
|
|
84
|
+
* (e.g. when Xcode lives on an external or renamed volume).
|
|
85
|
+
*/ async function getSimulatorAppIdViaAppleScriptAsync() {
|
|
75
86
|
try {
|
|
76
87
|
return (await (0, _osascript().execAsync)('id of app "Simulator"')).trim();
|
|
77
88
|
} catch {
|
|
78
|
-
// This error may occur in CI where the
|
|
89
|
+
// This error may occur in CI where the user intends to install just the simulators but no
|
|
90
|
+
// Xcode, or when Simulator.app is not registered in LaunchServices (e.g. Xcode on an
|
|
91
|
+
// external or renamed volume).
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Fallback: locate Simulator.app via the active Xcode developer directory and read its
|
|
97
|
+
* CFBundleIdentifier directly from the app bundle's Info.plist.
|
|
98
|
+
* This works even when LaunchServices hasn't indexed Simulator.app.
|
|
99
|
+
*/ async function getSimulatorAppIdFromBundleAsync() {
|
|
100
|
+
try {
|
|
101
|
+
const { stdout: developerDir } = await (0, _spawnasync().default)('xcode-select', [
|
|
102
|
+
'--print-path'
|
|
103
|
+
]);
|
|
104
|
+
const simulatorInfoPlist = _path().default.join(developerDir.trim(), 'Applications', 'Simulator.app', 'Contents', 'Info.plist');
|
|
105
|
+
const { stdout: bundleId } = await (0, _spawnasync().default)('defaults', [
|
|
106
|
+
'read',
|
|
107
|
+
simulatorInfoPlist,
|
|
108
|
+
'CFBundleIdentifier'
|
|
109
|
+
]);
|
|
110
|
+
return bundleId.trim() || null;
|
|
111
|
+
} catch {
|
|
112
|
+
// Simulator.app not found at the expected path or xcode-select is unavailable.
|
|
79
113
|
}
|
|
80
114
|
return null;
|
|
81
115
|
}
|
|
116
|
+
async function getSimulatorAppIdAsync() {
|
|
117
|
+
return await getSimulatorAppIdViaAppleScriptAsync() ?? await getSimulatorAppIdFromBundleAsync();
|
|
118
|
+
}
|
|
82
119
|
class SimulatorAppPrerequisite extends _Prerequisite.Prerequisite {
|
|
83
120
|
static #_ = this.instance = new SimulatorAppPrerequisite();
|
|
84
121
|
async assertImplementation() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/doctor/apple/SimulatorAppPrerequisite.ts"],"sourcesContent":["import { execAsync } from '@expo/osascript';\nimport spawnAsync from '@expo/spawn-async';\n\nimport * as Log from '../../../log';\nimport { Prerequisite, PrerequisiteCommandError } from '../Prerequisite';\n\nconst debug = require('debug')('expo:doctor:apple:simulatorApp') as typeof console.log;\n\nasync function
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/doctor/apple/SimulatorAppPrerequisite.ts"],"sourcesContent":["import { execAsync } from '@expo/osascript';\nimport spawnAsync from '@expo/spawn-async';\nimport path from 'path';\n\nimport * as Log from '../../../log';\nimport { Prerequisite, PrerequisiteCommandError } from '../Prerequisite';\n\nconst debug = require('debug')('expo:doctor:apple:simulatorApp') as typeof console.log;\n\n/**\n * Get the bundle ID of the Simulator.app via AppleScript / LaunchServices.\n * May return null if the Simulator.app is not registered in LaunchServices\n * (e.g. when Xcode lives on an external or renamed volume).\n */\nasync function getSimulatorAppIdViaAppleScriptAsync(): Promise<string | null> {\n try {\n return (await execAsync('id of app \"Simulator\"')).trim();\n } catch {\n // This error may occur in CI where the user intends to install just the simulators but no\n // Xcode, or when Simulator.app is not registered in LaunchServices (e.g. Xcode on an\n // external or renamed volume).\n }\n return null;\n}\n\n/**\n * Fallback: locate Simulator.app via the active Xcode developer directory and read its\n * CFBundleIdentifier directly from the app bundle's Info.plist.\n * This works even when LaunchServices hasn't indexed Simulator.app.\n */\nasync function getSimulatorAppIdFromBundleAsync(): Promise<string | null> {\n try {\n const { stdout: developerDir } = await spawnAsync('xcode-select', ['--print-path']);\n const simulatorInfoPlist = path.join(\n developerDir.trim(),\n 'Applications',\n 'Simulator.app',\n 'Contents',\n 'Info.plist'\n );\n const { stdout: bundleId } = await spawnAsync('defaults', [\n 'read',\n simulatorInfoPlist,\n 'CFBundleIdentifier',\n ]);\n return bundleId.trim() || null;\n } catch {\n // Simulator.app not found at the expected path or xcode-select is unavailable.\n }\n return null;\n}\n\nasync function getSimulatorAppIdAsync(): Promise<string | null> {\n return (\n (await getSimulatorAppIdViaAppleScriptAsync()) ?? (await getSimulatorAppIdFromBundleAsync())\n );\n}\n\nexport class SimulatorAppPrerequisite extends Prerequisite {\n static instance = new SimulatorAppPrerequisite();\n\n async assertImplementation(): Promise<void> {\n const result = await getSimulatorAppIdAsync();\n if (!result) {\n // This error may occur in CI where the users intends to install just the simulators but no Xcode.\n throw new PrerequisiteCommandError(\n 'SIMULATOR_APP',\n \"Can't determine id of Simulator app; the Simulator is most likely not installed on this machine. Run `sudo xcode-select -s /Applications/Xcode.app`\"\n );\n }\n if (\n result !== 'com.apple.iphonesimulator' &&\n result !== 'com.apple.CoreSimulator.SimulatorTrampoline'\n ) {\n throw new PrerequisiteCommandError(\n 'SIMULATOR_APP',\n \"Simulator is installed but is identified as '\" + result + \"'; don't know what that is.\"\n );\n }\n debug(`Simulator app id: ${result}`);\n\n try {\n // make sure we can run simctl\n await spawnAsync('xcrun', ['simctl', 'help']);\n } catch (error: any) {\n Log.warn(`Unable to run simctl:\\n${error.toString()}`);\n throw new PrerequisiteCommandError(\n 'SIMCTL',\n 'xcrun is not configured correctly. Ensure `sudo xcode-select --reset` works before running this command again.'\n );\n }\n }\n}\n"],"names":["SimulatorAppPrerequisite","debug","require","getSimulatorAppIdViaAppleScriptAsync","execAsync","trim","getSimulatorAppIdFromBundleAsync","stdout","developerDir","spawnAsync","simulatorInfoPlist","path","join","bundleId","getSimulatorAppIdAsync","Prerequisite","instance","assertImplementation","result","PrerequisiteCommandError","error","Log","warn","toString"],"mappings":";;;;+BA0DaA;;;eAAAA;;;;yBA1Da;;;;;;;gEACH;;;;;;;gEACN;;;;;;6DAEI;8BACkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEvD,MAAMC,QAAQC,QAAQ,SAAS;AAE/B;;;;CAIC,GACD,eAAeC;IACb,IAAI;QACF,OAAO,AAAC,CAAA,MAAMC,IAAAA,sBAAS,EAAC,wBAAuB,EAAGC,IAAI;IACxD,EAAE,OAAM;IACN,0FAA0F;IAC1F,qFAAqF;IACrF,+BAA+B;IACjC;IACA,OAAO;AACT;AAEA;;;;CAIC,GACD,eAAeC;IACb,IAAI;QACF,MAAM,EAAEC,QAAQC,YAAY,EAAE,GAAG,MAAMC,IAAAA,qBAAU,EAAC,gBAAgB;YAAC;SAAe;QAClF,MAAMC,qBAAqBC,eAAI,CAACC,IAAI,CAClCJ,aAAaH,IAAI,IACjB,gBACA,iBACA,YACA;QAEF,MAAM,EAAEE,QAAQM,QAAQ,EAAE,GAAG,MAAMJ,IAAAA,qBAAU,EAAC,YAAY;YACxD;YACAC;YACA;SACD;QACD,OAAOG,SAASR,IAAI,MAAM;IAC5B,EAAE,OAAM;IACN,+EAA+E;IACjF;IACA,OAAO;AACT;AAEA,eAAeS;IACb,OACE,AAAC,MAAMX,0CAA4C,MAAMG;AAE7D;AAEO,MAAMN,iCAAiCe,0BAAY;qBACjDC,WAAW,IAAIhB;IAEtB,MAAMiB,uBAAsC;QAC1C,MAAMC,SAAS,MAAMJ;QACrB,IAAI,CAACI,QAAQ;YACX,kGAAkG;YAClG,MAAM,IAAIC,sCAAwB,CAChC,iBACA;QAEJ;QACA,IACED,WAAW,+BACXA,WAAW,+CACX;YACA,MAAM,IAAIC,sCAAwB,CAChC,iBACA,kDAAkDD,SAAS;QAE/D;QACAjB,MAAM,CAAC,kBAAkB,EAAEiB,QAAQ;QAEnC,IAAI;YACF,8BAA8B;YAC9B,MAAMT,IAAAA,qBAAU,EAAC,SAAS;gBAAC;gBAAU;aAAO;QAC9C,EAAE,OAAOW,OAAY;YACnBC,KAAIC,IAAI,CAAC,CAAC,uBAAuB,EAAEF,MAAMG,QAAQ,IAAI;YACrD,MAAM,IAAIJ,sCAAwB,CAChC,UACA;QAEJ;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/platforms/android/AndroidPlatformManager.ts"],"sourcesContent":["import { AndroidAppIdResolver } from './AndroidAppIdResolver';\nimport { AndroidDeviceManager } from './AndroidDeviceManager';\nimport { Device } from './adb';\nimport { startAdbReverseAsync } from './adbReverse';\nimport { CommandError } from '../../../utils/errors';\nimport { memoize } from '../../../utils/fn';\nimport { learnMore } from '../../../utils/link';\nimport { hasDirectDevClientDependency } from '../../detectDevClient';\nimport { AppIdResolver } from '../AppIdResolver';\nimport { BaseOpenInCustomProps, BaseResolveDeviceProps, PlatformManager } from '../PlatformManager';\n\nconst debug = require('debug')(\n 'expo:start:platforms:platformManager:android'\n) as typeof console.log;\n\nexport interface AndroidOpenInCustomProps extends BaseOpenInCustomProps {\n /**\n * The Android app intent to launch through `adb shell am start -n <launchActivity>`.\n */\n launchActivity?: string;\n /**\n * The custom app id to launch, provided through `--app-id`.\n * By default, the app id is identical to the package name.\n * When using product flavors, the app id might be customized.\n */\n customAppId?: string;\n}\n\nexport class AndroidPlatformManager extends PlatformManager<Device, AndroidOpenInCustomProps> {\n /** The last used custom launch props, should be reused whenever launching custom runtime without launch props */\n private lastCustomRuntimeLaunchProps?: AndroidOpenInCustomProps;\n /** Memoized method to detect if dev client is installed */\n private hasDevClientInstalled: () => boolean;\n\n constructor(\n protected projectRoot: string,\n protected port: number,\n options: {\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL */\n getExpoGoUrl: () => string;\n /** Get redirect URL for native disambiguation. */\n getRedirectUrl: () => string | null;\n /** Dev Client URL. */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n }\n ) {\n super(projectRoot, {\n platform: 'android',\n ...options,\n resolveDeviceAsync: AndroidDeviceManager.resolveAsync,\n });\n\n this.hasDevClientInstalled = memoize(hasDirectDevClientDependency.bind(this, projectRoot));\n }\n\n async openAsync(\n options:\n | { runtime: 'expo' | 'web' }\n | { runtime: 'custom'; props?: Partial<AndroidOpenInCustomProps> },\n resolveSettings?:
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/platforms/android/AndroidPlatformManager.ts"],"sourcesContent":["import { AndroidAppIdResolver } from './AndroidAppIdResolver';\nimport { AndroidDeviceManager } from './AndroidDeviceManager';\nimport { Device } from './adb';\nimport { startAdbReverseAsync } from './adbReverse';\nimport { CommandError } from '../../../utils/errors';\nimport { memoize } from '../../../utils/fn';\nimport { learnMore } from '../../../utils/link';\nimport { hasDirectDevClientDependency } from '../../detectDevClient';\nimport { AppIdResolver } from '../AppIdResolver';\nimport { BaseOpenInCustomProps, BaseResolveDeviceProps, PlatformManager } from '../PlatformManager';\n\nconst debug = require('debug')(\n 'expo:start:platforms:platformManager:android'\n) as typeof console.log;\n\nexport interface AndroidOpenInCustomProps extends BaseOpenInCustomProps {\n /**\n * The Android app intent to launch through `adb shell am start -n <launchActivity>`.\n */\n launchActivity?: string;\n /**\n * The custom app id to launch, provided through `--app-id`.\n * By default, the app id is identical to the package name.\n * When using product flavors, the app id might be customized.\n */\n customAppId?: string;\n}\n\nexport class AndroidPlatformManager extends PlatformManager<Device, AndroidOpenInCustomProps> {\n /** The last used custom launch props, should be reused whenever launching custom runtime without launch props */\n private lastCustomRuntimeLaunchProps?: AndroidOpenInCustomProps;\n /** Memoized method to detect if dev client is installed */\n private hasDevClientInstalled: () => boolean;\n\n constructor(\n protected projectRoot: string,\n protected port: number,\n options: {\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL */\n getExpoGoUrl: () => string;\n /** Get redirect URL for native disambiguation. */\n getRedirectUrl: () => string | null;\n /** Dev Client URL. */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n }\n ) {\n super(projectRoot, {\n platform: 'android',\n ...options,\n resolveDeviceAsync: AndroidDeviceManager.resolveAsync,\n });\n\n this.hasDevClientInstalled = memoize(hasDirectDevClientDependency.bind(this, projectRoot));\n }\n\n async openAsync(\n options:\n | { runtime: 'expo' | 'web' }\n | { runtime: 'custom'; props?: Partial<AndroidOpenInCustomProps> },\n resolveSettings?: BaseResolveDeviceProps<Device>\n ): Promise<{ url: string }> {\n await startAdbReverseAsync([this.port]);\n\n if (options.runtime === 'custom') {\n // Store the resolved launch properties for future \"openAsync\" request.\n // This reuses the same launch properties when opening through the CLI interface (pressing `a`).\n if (options.props) {\n this.lastCustomRuntimeLaunchProps = options.props;\n } else if (!options.props && this.lastCustomRuntimeLaunchProps) {\n options.props = this.lastCustomRuntimeLaunchProps;\n }\n\n // Handle projects that need to launch with a custom app id and launch activity\n return this.openProjectInCustomRuntimeWithCustomAppIdAsync(options, resolveSettings);\n }\n\n return super.openAsync(options, resolveSettings);\n }\n\n /**\n * Launch the custom runtime project, using the provided custom app id and launch activity.\n * Instead of \"open url\", this will launch the activity directly.\n * If dev client is installed, it will also pass the dev client URL to the activity.\n */\n async openProjectInCustomRuntimeWithCustomAppIdAsync(\n options: { runtime: 'custom'; props?: Partial<AndroidOpenInCustomProps> },\n resolveSettings?: Partial<BaseResolveDeviceProps<Device>>\n ) {\n // Fall back to default dev client URL open behavior if no custom app id or launch activity is provided\n if (!options.props?.customAppId || !options.props?.launchActivity) {\n return super.openProjectInCustomRuntimeAsync(resolveSettings, options.props);\n }\n\n const { customAppId, launchActivity } = options.props;\n const url = this.hasDevClientInstalled()\n ? (this.props.getCustomRuntimeUrl({ scheme: options.props.scheme }) ?? undefined)\n : undefined;\n\n debug(`Opening custom runtime using launch activity: ${launchActivity} --`, options.props);\n\n const deviceManager = (await this.props.resolveDeviceAsync(\n resolveSettings\n )) as AndroidDeviceManager;\n\n if (!(await deviceManager.isAppInstalledAndIfSoReturnContainerPathForIOSAsync(customAppId))) {\n throw new CommandError(\n `No development build (${customAppId}) for this project is installed. ` +\n `Install a development build on the target device and try again.\\n${learnMore(\n 'https://docs.expo.dev/development/build/'\n )}`\n );\n }\n\n deviceManager.logOpeningUrl(url ?? launchActivity);\n await deviceManager.activateWindowAsync();\n await deviceManager.launchActivityAsync(launchActivity, url);\n\n return { url: url ?? launchActivity };\n }\n\n _getAppIdResolver(): AppIdResolver {\n return new AndroidAppIdResolver(this.projectRoot);\n }\n\n _resolveAlternativeLaunchUrl(\n applicationId: string,\n props?: Partial<AndroidOpenInCustomProps>\n ): string {\n return props?.launchActivity ?? `${applicationId}/.MainActivity`;\n }\n}\n"],"names":["AndroidPlatformManager","debug","require","PlatformManager","constructor","projectRoot","port","options","platform","resolveDeviceAsync","AndroidDeviceManager","resolveAsync","hasDevClientInstalled","memoize","hasDirectDevClientDependency","bind","openAsync","resolveSettings","startAdbReverseAsync","runtime","props","lastCustomRuntimeLaunchProps","openProjectInCustomRuntimeWithCustomAppIdAsync","customAppId","launchActivity","openProjectInCustomRuntimeAsync","url","getCustomRuntimeUrl","scheme","undefined","deviceManager","isAppInstalledAndIfSoReturnContainerPathForIOSAsync","CommandError","learnMore","logOpeningUrl","activateWindowAsync","launchActivityAsync","_getAppIdResolver","AndroidAppIdResolver","_resolveAlternativeLaunchUrl","applicationId"],"mappings":";;;;+BA4BaA;;;eAAAA;;;sCA5BwB;sCACA;4BAEA;wBACR;oBACL;sBACE;iCACmB;iCAEkC;AAE/E,MAAMC,QAAQC,QAAQ,SACpB;AAgBK,MAAMF,+BAA+BG,gCAAe;IAMzDC,YACE,AAAUC,WAAmB,EAC7B,AAAUC,IAAY,EACtBC,OASC,CACD;QACA,KAAK,CAACF,aAAa;YACjBG,UAAU;YACV,GAAGD,OAAO;YACVE,oBAAoBC,0CAAoB,CAACC,YAAY;QACvD,SAjBUN,cAAAA,kBACAC,OAAAA;QAkBV,IAAI,CAACM,qBAAqB,GAAGC,IAAAA,WAAO,EAACC,6CAA4B,CAACC,IAAI,CAAC,IAAI,EAAEV;IAC/E;IAEA,MAAMW,UACJT,OAEoE,EACpEU,eAAgD,EACtB;QAC1B,MAAMC,IAAAA,gCAAoB,EAAC;YAAC,IAAI,CAACZ,IAAI;SAAC;QAEtC,IAAIC,QAAQY,OAAO,KAAK,UAAU;YAChC,uEAAuE;YACvE,gGAAgG;YAChG,IAAIZ,QAAQa,KAAK,EAAE;gBACjB,IAAI,CAACC,4BAA4B,GAAGd,QAAQa,KAAK;YACnD,OAAO,IAAI,CAACb,QAAQa,KAAK,IAAI,IAAI,CAACC,4BAA4B,EAAE;gBAC9Dd,QAAQa,KAAK,GAAG,IAAI,CAACC,4BAA4B;YACnD;YAEA,+EAA+E;YAC/E,OAAO,IAAI,CAACC,8CAA8C,CAACf,SAASU;QACtE;QAEA,OAAO,KAAK,CAACD,UAAUT,SAASU;IAClC;IAEA;;;;GAIC,GACD,MAAMK,+CACJf,OAAyE,EACzEU,eAAyD,EACzD;YAEKV,gBAA+BA;QADpC,uGAAuG;QACvG,IAAI,GAACA,iBAAAA,QAAQa,KAAK,qBAAbb,eAAegB,WAAW,KAAI,GAAChB,kBAAAA,QAAQa,KAAK,qBAAbb,gBAAeiB,cAAc,GAAE;YACjE,OAAO,KAAK,CAACC,gCAAgCR,iBAAiBV,QAAQa,KAAK;QAC7E;QAEA,MAAM,EAAEG,WAAW,EAAEC,cAAc,EAAE,GAAGjB,QAAQa,KAAK;QACrD,MAAMM,MAAM,IAAI,CAACd,qBAAqB,KACjC,IAAI,CAACQ,KAAK,CAACO,mBAAmB,CAAC;YAAEC,QAAQrB,QAAQa,KAAK,CAACQ,MAAM;QAAC,MAAMC,YACrEA;QAEJ5B,MAAM,CAAC,8CAA8C,EAAEuB,eAAe,GAAG,CAAC,EAAEjB,QAAQa,KAAK;QAEzF,MAAMU,gBAAiB,MAAM,IAAI,CAACV,KAAK,CAACX,kBAAkB,CACxDQ;QAGF,IAAI,CAAE,MAAMa,cAAcC,mDAAmD,CAACR,cAAe;YAC3F,MAAM,IAAIS,oBAAY,CACpB,CAAC,sBAAsB,EAAET,YAAY,iCAAiC,CAAC,GACrE,CAAC,iEAAiE,EAAEU,IAAAA,eAAS,EAC3E,6CACC;QAET;QAEAH,cAAcI,aAAa,CAACR,OAAOF;QACnC,MAAMM,cAAcK,mBAAmB;QACvC,MAAML,cAAcM,mBAAmB,CAACZ,gBAAgBE;QAExD,OAAO;YAAEA,KAAKA,OAAOF;QAAe;IACtC;IAEAa,oBAAmC;QACjC,OAAO,IAAIC,0CAAoB,CAAC,IAAI,CAACjC,WAAW;IAClD;IAEAkC,6BACEC,aAAqB,EACrBpB,KAAyC,EACjC;QACR,OAAOA,CAAAA,yBAAAA,MAAOI,cAAc,KAAI,GAAGgB,cAAc,cAAc,CAAC;IAClE;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/platforms/ios/ApplePlatformManager.ts"],"sourcesContent":["import { AppleAppIdResolver } from './AppleAppIdResolver';\nimport { AppleDeviceManager } from './AppleDeviceManager';\nimport { Device } from './simctl';\nimport { AppIdResolver } from '../AppIdResolver';\nimport { BaseOpenInCustomProps, PlatformManager } from '../PlatformManager';\n\n/** Manages launching apps on Apple simulators. */\nexport class ApplePlatformManager extends PlatformManager<Device> {\n constructor(\n protected projectRoot: string,\n protected port: number,\n options: {\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL. */\n getExpoGoUrl: () => string;\n /** Get redirect URL for native disambiguation. */\n getRedirectUrl: () => string | null;\n /** Dev Client */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n }\n ) {\n super(projectRoot, {\n platform: 'ios',\n ...options,\n resolveDeviceAsync: AppleDeviceManager.resolveAsync,\n });\n }\n\n async openAsync(\n options:\n | { runtime: 'expo' | 'web' }\n | { runtime: 'custom'; props?: Partial<BaseOpenInCustomProps> },\n resolveSettings?:
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/platforms/ios/ApplePlatformManager.ts"],"sourcesContent":["import { AppleAppIdResolver } from './AppleAppIdResolver';\nimport { AppleDeviceManager } from './AppleDeviceManager';\nimport { Device } from './simctl';\nimport { AppIdResolver } from '../AppIdResolver';\nimport { BaseOpenInCustomProps, BaseResolveDeviceProps, PlatformManager } from '../PlatformManager';\n\n/** Manages launching apps on Apple simulators. */\nexport class ApplePlatformManager extends PlatformManager<Device> {\n constructor(\n protected projectRoot: string,\n protected port: number,\n options: {\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL. */\n getExpoGoUrl: () => string;\n /** Get redirect URL for native disambiguation. */\n getRedirectUrl: () => string | null;\n /** Dev Client */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n }\n ) {\n super(projectRoot, {\n platform: 'ios',\n ...options,\n resolveDeviceAsync: AppleDeviceManager.resolveAsync,\n });\n }\n\n async openAsync(\n options:\n | { runtime: 'expo' | 'web' }\n | { runtime: 'custom'; props?: Partial<BaseOpenInCustomProps> },\n resolveSettings?: BaseResolveDeviceProps<Device>\n ): Promise<{ url: string }> {\n await AppleDeviceManager.assertSystemRequirementsAsync();\n return super.openAsync(options, resolveSettings);\n }\n\n _getAppIdResolver(): AppIdResolver {\n return new AppleAppIdResolver(this.projectRoot);\n }\n\n _resolveAlternativeLaunchUrl(\n applicationId: string,\n props?: Partial<BaseOpenInCustomProps>\n ): string {\n return applicationId;\n }\n}\n"],"names":["ApplePlatformManager","PlatformManager","constructor","projectRoot","port","options","platform","resolveDeviceAsync","AppleDeviceManager","resolveAsync","openAsync","resolveSettings","assertSystemRequirementsAsync","_getAppIdResolver","AppleAppIdResolver","_resolveAlternativeLaunchUrl","applicationId","props"],"mappings":";;;;+BAOaA;;;eAAAA;;;oCAPsB;oCACA;iCAG4C;AAGxE,MAAMA,6BAA6BC,gCAAe;IACvDC,YACE,AAAUC,WAAmB,EAC7B,AAAUC,IAAY,EACtBC,OASC,CACD;QACA,KAAK,CAACF,aAAa;YACjBG,UAAU;YACV,GAAGD,OAAO;YACVE,oBAAoBC,sCAAkB,CAACC,YAAY;QACrD,SAjBUN,cAAAA,kBACAC,OAAAA;IAiBZ;IAEA,MAAMM,UACJL,OAEiE,EACjEM,eAAgD,EACtB;QAC1B,MAAMH,sCAAkB,CAACI,6BAA6B;QACtD,OAAO,KAAK,CAACF,UAAUL,SAASM;IAClC;IAEAE,oBAAmC;QACjC,OAAO,IAAIC,sCAAkB,CAAC,IAAI,CAACX,WAAW;IAChD;IAEAY,6BACEC,aAAqB,EACrBC,KAAsC,EAC9B;QACR,OAAOD;IACT;AACF"}
|
|
@@ -360,23 +360,37 @@ class BundlerDevServer {
|
|
|
360
360
|
}
|
|
361
361
|
return this.getUrlCreator().constructLoadingUrl({}, platform === 'emulator' ? 'android' : platform === 'simulator' ? 'ios' : null) ?? null;
|
|
362
362
|
}
|
|
363
|
-
async getPlatformManagerAsync(
|
|
363
|
+
async getPlatformManagerAsync(ofPlatform) {
|
|
364
|
+
const platform = ofPlatform;
|
|
364
365
|
if (!this.platformManagers[platform]) {
|
|
365
366
|
var _this_getInstance;
|
|
366
|
-
const Manager = PLATFORM_MANAGERS[platform]();
|
|
367
367
|
const port = (_this_getInstance = this.getInstance()) == null ? void 0 : _this_getInstance.location.port;
|
|
368
368
|
if (!port || !this.urlCreator) {
|
|
369
369
|
throw new _errors.CommandError('DEV_SERVER', 'Cannot interact with native platforms until dev server has started');
|
|
370
370
|
}
|
|
371
371
|
debug(`Creating platform manager (platform: ${platform}, port: ${port})`);
|
|
372
|
-
|
|
372
|
+
const managerParams = {
|
|
373
373
|
getCustomRuntimeUrl: this.urlCreator.constructDevClientUrl.bind(this.urlCreator),
|
|
374
374
|
getExpoGoUrl: this.getExpoGoUrl.bind(this),
|
|
375
375
|
getRedirectUrl: this.getRedirectUrl.bind(this, platform),
|
|
376
376
|
getDevServerUrl: this.getDevServerUrl.bind(this, {
|
|
377
377
|
hostType: 'localhost'
|
|
378
378
|
})
|
|
379
|
-
}
|
|
379
|
+
};
|
|
380
|
+
switch(platform){
|
|
381
|
+
case 'simulator':
|
|
382
|
+
{
|
|
383
|
+
const Manager = PLATFORM_MANAGERS[platform]();
|
|
384
|
+
this.platformManagers[platform] = new Manager(this.projectRoot, port, managerParams);
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
case 'emulator':
|
|
388
|
+
{
|
|
389
|
+
const Manager = PLATFORM_MANAGERS[platform]();
|
|
390
|
+
this.platformManagers[platform] = new Manager(this.projectRoot, port, managerParams);
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
380
394
|
}
|
|
381
395
|
return this.platformManagers[platform];
|
|
382
396
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/server/BundlerDevServer.ts"],"sourcesContent":["import assert from 'assert';\nimport resolveFrom from 'resolve-from';\n\nimport { AsyncNgrok } from './AsyncNgrok';\nimport { AsyncWsTunnel } from './AsyncWsTunnel';\nimport DevToolsPluginManager from './DevToolsPluginManager';\nimport { DevelopmentSession } from './DevelopmentSession';\nimport { CreateURLOptions, UrlCreator } from './UrlCreator';\nimport { PlatformBundlers } from './platformBundlers';\nimport * as Log from '../../log';\nimport { FileNotifier } from '../../utils/FileNotifier';\nimport { resolveWithTimeout } from '../../utils/delay';\nimport { env, envIsWebcontainer } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { openBrowserAsync } from '../../utils/open';\nimport {\n BaseOpenInCustomProps,\n BaseResolveDeviceProps,\n PlatformManager,\n} from '../platforms/PlatformManager';\n\nconst debug = require('debug')('expo:start:server:devServer') as typeof console.log;\n\nexport type MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\nexport type ServerLike = {\n close(callback?: (err?: Error) => void): void;\n addListener?(event: string, listener: (...args: any[]) => void): unknown;\n};\n\nexport type DevServerInstance = {\n /** Bundler dev server instance. */\n server: ServerLike;\n /** Dev server URL location properties. */\n location: {\n url: string;\n port: number;\n protocol: 'http' | 'https';\n host?: string;\n };\n /** Additional middleware that's attached to the `server`. */\n middleware: any;\n /** Message socket for communicating with the runtime. */\n messageSocket: MessageSocket;\n};\n\nexport interface BundlerStartOptions {\n /** Should the dev server use `https` protocol. */\n https?: boolean;\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Is dev client enabled. */\n devClient?: boolean;\n /** Should run dev servers with clean caches. */\n resetDevServer?: boolean;\n /** Code signing private key path (defaults to same directory as certificate) */\n privateKeyPath?: string;\n\n /** Max amount of workers (threads) to use with Metro bundler, defaults to undefined for max workers. */\n maxWorkers?: number;\n /** Port to start the dev server on. */\n port?: number;\n\n /** Should start a headless dev server e.g. mock representation to approximate info from a server running in a different process. */\n headless?: boolean;\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n\n /** Will the bundler be used for exporting. NOTE: This is an odd option to pass to the dev server. */\n isExporting?: boolean;\n\n // Webpack options\n /** Should modify and create PWA icons. */\n isImageEditingEnabled?: boolean;\n\n location: CreateURLOptions;\n}\n\nconst PLATFORM_MANAGERS = {\n simulator: () =>\n require('../platforms/ios/ApplePlatformManager')\n .ApplePlatformManager as typeof import('../platforms/ios/ApplePlatformManager').ApplePlatformManager,\n emulator: () =>\n require('../platforms/android/AndroidPlatformManager')\n .AndroidPlatformManager as typeof import('../platforms/android/AndroidPlatformManager').AndroidPlatformManager,\n};\n\nexport abstract class BundlerDevServer {\n /** Name of the bundler. */\n abstract get name(): string;\n\n /** Tunnel instance for managing tunnel connections. */\n protected tunnel: AsyncNgrok | AsyncWsTunnel | null = null;\n /** Interfaces with the Expo 'Development Session' API. */\n protected devSession: DevelopmentSession | null = null;\n /** Http server and related info. */\n protected instance: DevServerInstance | null = null;\n /** Native platform interfaces for opening projects. */\n private platformManagers: Record<string, PlatformManager<any>> = {};\n /** Manages the creation of dev server URLs. */\n protected urlCreator?: UrlCreator | null = null;\n\n private notifier: FileNotifier | null = null;\n protected readonly devToolsPluginManager: DevToolsPluginManager;\n public isDevClient: boolean;\n\n constructor(\n /** Project root folder. */\n public projectRoot: string,\n /** A mapping of bundlers to platforms. */\n public platformBundlers: PlatformBundlers,\n /** Advanced options */\n options?: {\n /**\n * The instance of DevToolsPluginManager\n * @default new DevToolsPluginManager(projectRoot)\n */\n devToolsPluginManager?: DevToolsPluginManager;\n // TODO: Replace with custom scheme maybe...\n isDevClient?: boolean;\n }\n ) {\n this.devToolsPluginManager =\n options?.devToolsPluginManager ?? new DevToolsPluginManager(projectRoot);\n this.isDevClient = options?.isDevClient ?? false;\n }\n\n protected setInstance(instance: DevServerInstance) {\n this.instance = instance;\n }\n\n /** Get the manifest middleware function. */\n protected async getManifestMiddlewareAsync(\n options: Pick<BundlerStartOptions, 'minify' | 'mode' | 'privateKeyPath'> = {}\n ) {\n const Middleware = require('./middleware/ExpoGoManifestHandlerMiddleware')\n .ExpoGoManifestHandlerMiddleware as typeof import('./middleware/ExpoGoManifestHandlerMiddleware').ExpoGoManifestHandlerMiddleware;\n\n const urlCreator = this.getUrlCreator();\n const middleware = new Middleware(this.projectRoot, {\n constructUrl: urlCreator.constructUrl.bind(urlCreator),\n mode: options.mode,\n minify: options.minify,\n isNativeWebpack: this.name === 'webpack' && this.isTargetingNative(),\n privateKeyPath: options.privateKeyPath,\n });\n return middleware;\n }\n\n /** Start the dev server using settings defined in the start command. */\n public async startAsync(options: BundlerStartOptions): Promise<DevServerInstance> {\n await this.stopAsync();\n\n let instance: DevServerInstance;\n if (options.headless) {\n instance = await this.startHeadlessAsync(options);\n } else {\n instance = await this.startImplementationAsync(options);\n }\n\n this.setInstance(instance);\n await this.postStartAsync(options);\n return instance;\n }\n\n protected abstract startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance>;\n\n public async waitForTypeScriptAsync(): Promise<boolean> {\n return false;\n }\n\n public abstract startTypeScriptServices(): Promise<void>;\n\n public async watchEnvironmentVariables(): Promise<void> {\n // noop -- We've only implemented this functionality in Metro.\n }\n\n /**\n * Creates a mock server representation that can be used to estimate URLs for a server started in another process.\n * This is used for the run commands where you can reuse the server from a previous run.\n */\n private async startHeadlessAsync(options: BundlerStartOptions): Promise<DevServerInstance> {\n if (!options.port)\n throw new CommandError('HEADLESS_SERVER', 'headless dev server requires a port option');\n this.urlCreator = this.getUrlCreator(options);\n\n return {\n // Create a mock server\n server: {\n close: (callback: () => void) => {\n this.instance = null;\n callback?.();\n },\n addListener() {},\n },\n location: {\n // The port is the main thing we want to send back.\n port: options.port,\n // localhost isn't always correct.\n host: 'localhost',\n // http is the only supported protocol on native.\n url: `http://localhost:${options.port}`,\n protocol: 'http',\n },\n middleware: {},\n messageSocket: {\n broadcast: () => {\n throw new CommandError('HEADLESS_SERVER', 'Cannot broadcast messages to headless server');\n },\n },\n };\n }\n\n /**\n * Runs after the `startAsync` function, performing any additional common operations.\n * You can assume the dev server is started by the time this function is called.\n */\n protected async postStartAsync(options: BundlerStartOptions) {\n if (\n options.location.hostType === 'tunnel' &&\n !env.EXPO_OFFLINE &&\n // This is a hack to prevent using tunnel on web since we block it upstream for some reason.\n this.isTargetingNative()\n ) {\n await this._startTunnelAsync();\n } else if (envIsWebcontainer()) {\n await this._startTunnelAsync();\n }\n\n if (!options.isExporting) {\n await this.startDevSessionAsync();\n this.watchConfig();\n }\n }\n\n protected abstract getConfigModuleIds(): string[];\n\n protected watchConfig() {\n this.notifier?.stopObserving();\n this.notifier = new FileNotifier(this.projectRoot, this.getConfigModuleIds());\n this.notifier.startObserving();\n }\n\n /** Create ngrok instance and start the tunnel server. Exposed for testing. */\n public async _startTunnelAsync(): Promise<AsyncNgrok | AsyncWsTunnel | null> {\n const port = this.getInstance()?.location.port;\n if (!port) return null;\n debug('[tunnel] connect to port: ' + port);\n this.tunnel = envIsWebcontainer()\n ? new AsyncWsTunnel(this.projectRoot, port)\n : new AsyncNgrok(this.projectRoot, port);\n await this.tunnel.startAsync();\n return this.tunnel;\n }\n\n protected async startDevSessionAsync() {\n // This is used to make Expo Go open the project in either Expo Go, or the web browser.\n // Must come after ngrok (`startTunnelAsync`) setup.\n this.devSession = new DevelopmentSession(\n this.projectRoot,\n // This URL will be used on external devices so the computer IP won't be relevant.\n this.isTargetingNative()\n ? this.getNativeRuntimeUrl()\n : this.getDevServerUrl({ hostType: 'localhost' })\n );\n\n await this.devSession.startAsync({\n runtime: this.isTargetingNative() ? 'native' : 'web',\n });\n }\n\n public isTargetingNative() {\n // Temporary hack while we implement multi-bundler dev server proxy.\n return true;\n }\n\n public isTargetingWeb() {\n return this.platformBundlers.web === this.name;\n }\n\n /**\n * Sends a message over web sockets to any connected device,\n * does nothing when the dev server is not running.\n *\n * @param method name of the command. In RN projects `reload`, and `devMenu` are available. In Expo Go, `sendDevCommand` is available.\n * @param params\n */\n public broadcastMessage(\n method: 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ) {\n this.getInstance()?.messageSocket.broadcast(method, params);\n }\n\n /** Get the running dev server instance. */\n public getInstance() {\n return this.instance;\n }\n\n /** Stop the running dev server instance. */\n async stopAsync() {\n // Stop file watching.\n this.notifier?.stopObserving();\n\n // Stop the dev session timer and tell Expo API to remove dev session.\n await this.devSession?.closeAsync();\n\n // Stop tunnel if running.\n await this.tunnel?.stopAsync().catch((e) => {\n Log.error(`Error stopping tunnel:`);\n Log.exception(e);\n });\n\n return resolveWithTimeout(\n () =>\n new Promise<void>((resolve, reject) => {\n // Close the server.\n debug(`Stopping dev server (bundler: ${this.name})`);\n\n if (this.instance?.server) {\n // Check if server is even running.\n this.instance.server.close((error) => {\n debug(`Stopped dev server (bundler: ${this.name})`);\n this.instance = null;\n if (error) {\n if ('code' in error && error.code === 'ERR_SERVER_NOT_RUNNING') {\n resolve();\n } else {\n reject(error);\n }\n } else {\n resolve();\n }\n });\n } else {\n debug(`Stopped dev server (bundler: ${this.name})`);\n this.instance = null;\n resolve();\n }\n }),\n {\n // NOTE(Bacon): Metro dev server doesn't seem to be closing in time.\n timeout: 1000,\n errorMessage: `Timeout waiting for '${this.name}' dev server to close`,\n }\n );\n }\n\n public getUrlCreator(options: Partial<Pick<BundlerStartOptions, 'port' | 'location'>> = {}) {\n if (!this.urlCreator) {\n assert(options?.port, 'Dev server instance not found');\n this.urlCreator = new UrlCreator(options.location, {\n port: options.port,\n getTunnelUrl: this.getTunnelUrl.bind(this),\n });\n }\n return this.urlCreator;\n }\n\n public getNativeRuntimeUrl(opts: Partial<CreateURLOptions> = {}) {\n return this.isDevClient\n ? (this.getUrlCreator().constructDevClientUrl(opts) ?? this.getDevServerUrl())\n : this.getUrlCreator().constructUrl({ ...opts, scheme: 'exp' });\n }\n\n /** Get the URL for the running instance of the dev server. */\n public getDevServerUrl(options: { hostType?: 'localhost' } = {}): string | null {\n const instance = this.getInstance();\n if (!instance?.location) {\n return null;\n }\n\n // If we have an active WS tunnel instance, we always need to return the tunnel location.\n if (this.tunnel && this.tunnel instanceof AsyncWsTunnel) {\n return this.getUrlCreator().constructUrl();\n }\n\n const { location } = instance;\n if (options.hostType === 'localhost') {\n return `${location.protocol}://localhost:${location.port}`;\n }\n\n return location.url ?? null;\n }\n\n public getDevServerUrlOrAssert(options: { hostType?: 'localhost' } = {}): string {\n const instance = this.getDevServerUrl(options);\n if (!instance) {\n throw new CommandError(\n 'DEV_SERVER',\n `Cannot get the dev server URL before the server has started - bundler[${this.name}]`\n );\n }\n\n return instance;\n }\n\n /** Get the base URL for JS inspector */\n public getJsInspectorBaseUrl(): string {\n if (this.name !== 'metro') {\n throw new CommandError(\n 'DEV_SERVER',\n `Cannot get the JS inspector base url - bundler[${this.name}]`\n );\n }\n return this.getUrlCreator().constructUrl({ scheme: 'http' });\n }\n\n /** Get the tunnel URL from the tunnel. */\n public getTunnelUrl(): string | null {\n return this.tunnel?.getActiveUrl() ?? null;\n }\n\n /** Open the dev server in a runtime. */\n public async openPlatformAsync(\n launchTarget: keyof typeof PLATFORM_MANAGERS | 'desktop',\n resolver: BaseResolveDeviceProps<any> = {}\n ) {\n if (launchTarget === 'desktop') {\n const serverUrl = this.getDevServerUrl({ hostType: 'localhost' });\n // Allow opening the tunnel URL when using Metro web.\n const url = this.name === 'metro' ? (this.getTunnelUrl() ?? serverUrl) : serverUrl;\n await openBrowserAsync(url!);\n return { url };\n }\n\n const runtime = this.isTargetingNative() ? (this.isDevClient ? 'custom' : 'expo') : 'web';\n const manager = await this.getPlatformManagerAsync(launchTarget);\n return manager.openAsync({ runtime }, resolver);\n }\n\n /** Open the dev server in a runtime. */\n public async openCustomRuntimeAsync<T extends BaseOpenInCustomProps = BaseOpenInCustomProps>(\n launchTarget: keyof typeof PLATFORM_MANAGERS,\n launchProps: Partial<T> = {},\n resolver: BaseResolveDeviceProps<any> = {}\n ) {\n const runtime = this.isTargetingNative() ? (this.isDevClient ? 'custom' : 'expo') : 'web';\n if (runtime !== 'custom') {\n throw new CommandError(\n `dev server cannot open custom runtimes either because it does not target native platforms or because it is not targeting dev clients. (target: ${runtime})`\n );\n }\n\n const manager = await this.getPlatformManagerAsync(launchTarget);\n return manager.openAsync({ runtime: 'custom', props: launchProps }, resolver);\n }\n\n /** Get the URL for opening in Expo Go. */\n protected getExpoGoUrl(): string {\n return this.getUrlCreator().constructUrl({ scheme: 'exp' });\n }\n\n /** Should use the interstitial page for selecting which runtime to use. */\n protected isRedirectPageEnabled(): boolean {\n return (\n !env.EXPO_NO_REDIRECT_PAGE &&\n // if user passed --dev-client flag, skip interstitial page\n !this.isDevClient &&\n // Checks if dev client is installed.\n !!resolveFrom.silent(this.projectRoot, 'expo-dev-client')\n );\n }\n\n /** Get the redirect URL when redirecting is enabled. */\n public getRedirectUrl(platform: keyof typeof PLATFORM_MANAGERS | null = null): string | null {\n if (!this.isRedirectPageEnabled()) {\n debug('Redirect page is disabled');\n return null;\n }\n\n return (\n this.getUrlCreator().constructLoadingUrl(\n {},\n platform === 'emulator' ? 'android' : platform === 'simulator' ? 'ios' : null\n ) ?? null\n );\n }\n\n protected async getPlatformManagerAsync(platform: keyof typeof PLATFORM_MANAGERS) {\n if (!this.platformManagers[platform]) {\n const Manager = PLATFORM_MANAGERS[platform]();\n const port = this.getInstance()?.location.port;\n if (!port || !this.urlCreator) {\n throw new CommandError(\n 'DEV_SERVER',\n 'Cannot interact with native platforms until dev server has started'\n );\n }\n debug(`Creating platform manager (platform: ${platform}, port: ${port})`);\n this.platformManagers[platform] = new Manager(this.projectRoot, port, {\n getCustomRuntimeUrl: this.urlCreator.constructDevClientUrl.bind(this.urlCreator),\n getExpoGoUrl: this.getExpoGoUrl.bind(this),\n getRedirectUrl: this.getRedirectUrl.bind(this, platform),\n getDevServerUrl: this.getDevServerUrl.bind(this, { hostType: 'localhost' }),\n });\n }\n return this.platformManagers[platform];\n }\n}\n"],"names":["BundlerDevServer","debug","require","PLATFORM_MANAGERS","simulator","ApplePlatformManager","emulator","AndroidPlatformManager","constructor","projectRoot","platformBundlers","options","tunnel","devSession","instance","platformManagers","urlCreator","notifier","devToolsPluginManager","DevToolsPluginManager","isDevClient","setInstance","getManifestMiddlewareAsync","Middleware","ExpoGoManifestHandlerMiddleware","getUrlCreator","middleware","constructUrl","bind","mode","minify","isNativeWebpack","name","isTargetingNative","privateKeyPath","startAsync","stopAsync","headless","startHeadlessAsync","startImplementationAsync","postStartAsync","waitForTypeScriptAsync","watchEnvironmentVariables","port","CommandError","server","close","callback","addListener","location","host","url","protocol","messageSocket","broadcast","hostType","env","EXPO_OFFLINE","_startTunnelAsync","envIsWebcontainer","isExporting","startDevSessionAsync","watchConfig","stopObserving","FileNotifier","getConfigModuleIds","startObserving","getInstance","AsyncWsTunnel","AsyncNgrok","DevelopmentSession","getNativeRuntimeUrl","getDevServerUrl","runtime","isTargetingWeb","web","broadcastMessage","method","params","closeAsync","catch","e","Log","error","exception","resolveWithTimeout","Promise","resolve","reject","code","timeout","errorMessage","assert","UrlCreator","getTunnelUrl","opts","constructDevClientUrl","scheme","getDevServerUrlOrAssert","getJsInspectorBaseUrl","getActiveUrl","openPlatformAsync","launchTarget","resolver","serverUrl","openBrowserAsync","manager","getPlatformManagerAsync","openAsync","openCustomRuntimeAsync","launchProps","props","getExpoGoUrl","isRedirectPageEnabled","EXPO_NO_REDIRECT_PAGE","resolveFrom","silent","getRedirectUrl","platform","constructLoadingUrl","Manager","getCustomRuntimeUrl"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/server/BundlerDevServer.ts"],"sourcesContent":["import assert from 'assert';\nimport resolveFrom from 'resolve-from';\n\nimport { AsyncNgrok } from './AsyncNgrok';\nimport { AsyncWsTunnel } from './AsyncWsTunnel';\nimport DevToolsPluginManager from './DevToolsPluginManager';\nimport { DevelopmentSession } from './DevelopmentSession';\nimport { CreateURLOptions, UrlCreator } from './UrlCreator';\nimport { PlatformBundlers } from './platformBundlers';\nimport * as Log from '../../log';\nimport { FileNotifier } from '../../utils/FileNotifier';\nimport { resolveWithTimeout } from '../../utils/delay';\nimport { env, envIsWebcontainer } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { openBrowserAsync } from '../../utils/open';\nimport {\n BaseOpenInCustomProps,\n BaseResolveDeviceProps,\n PlatformManager,\n} from '../platforms/PlatformManager';\n\nconst debug = require('debug')('expo:start:server:devServer') as typeof console.log;\n\nexport type MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\nexport type ServerLike = {\n close(callback?: (err?: Error) => void): void;\n addListener?(event: string, listener: (...args: any[]) => void): unknown;\n};\n\nexport type DevServerInstance = {\n /** Bundler dev server instance. */\n server: ServerLike;\n /** Dev server URL location properties. */\n location: {\n url: string;\n port: number;\n protocol: 'http' | 'https';\n host?: string;\n };\n /** Additional middleware that's attached to the `server`. */\n middleware: any;\n /** Message socket for communicating with the runtime. */\n messageSocket: MessageSocket;\n};\n\nexport interface BundlerStartOptions {\n /** Should the dev server use `https` protocol. */\n https?: boolean;\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Is dev client enabled. */\n devClient?: boolean;\n /** Should run dev servers with clean caches. */\n resetDevServer?: boolean;\n /** Code signing private key path (defaults to same directory as certificate) */\n privateKeyPath?: string;\n\n /** Max amount of workers (threads) to use with Metro bundler, defaults to undefined for max workers. */\n maxWorkers?: number;\n /** Port to start the dev server on. */\n port?: number;\n\n /** Should start a headless dev server e.g. mock representation to approximate info from a server running in a different process. */\n headless?: boolean;\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n\n /** Will the bundler be used for exporting. NOTE: This is an odd option to pass to the dev server. */\n isExporting?: boolean;\n\n // Webpack options\n /** Should modify and create PWA icons. */\n isImageEditingEnabled?: boolean;\n\n location: CreateURLOptions;\n}\n\nconst PLATFORM_MANAGERS = {\n simulator: () =>\n require('../platforms/ios/ApplePlatformManager')\n .ApplePlatformManager as typeof import('../platforms/ios/ApplePlatformManager').ApplePlatformManager,\n emulator: () =>\n require('../platforms/android/AndroidPlatformManager')\n .AndroidPlatformManager as typeof import('../platforms/android/AndroidPlatformManager').AndroidPlatformManager,\n};\n\ntype PlatformManagers = {\n [K in keyof typeof PLATFORM_MANAGERS]: InstanceType<ReturnType<(typeof PLATFORM_MANAGERS)[K]>>;\n};\n\ntype PlatformDevice<Platform extends keyof PlatformManagers> =\n PlatformManagers[Platform] extends PlatformManager<infer Device, any> ? Device : never;\n\ntype PlatformLaunchProps<Platform extends keyof PlatformManagers> =\n PlatformManagers[Platform] extends PlatformManager<any, infer LaunchProps> ? LaunchProps : never;\n\nexport abstract class BundlerDevServer {\n /** Name of the bundler. */\n abstract get name(): string;\n\n /** Tunnel instance for managing tunnel connections. */\n protected tunnel: AsyncNgrok | AsyncWsTunnel | null = null;\n /** Interfaces with the Expo 'Development Session' API. */\n protected devSession: DevelopmentSession | null = null;\n /** Http server and related info. */\n protected instance: DevServerInstance | null = null;\n /** Native platform interfaces for opening projects. */\n private platformManagers: { [K in keyof PlatformManagers]?: PlatformManagers[K] | undefined } =\n {};\n /** Manages the creation of dev server URLs. */\n protected urlCreator?: UrlCreator | null = null;\n\n private notifier: FileNotifier | null = null;\n protected readonly devToolsPluginManager: DevToolsPluginManager;\n public isDevClient: boolean;\n\n constructor(\n /** Project root folder. */\n public projectRoot: string,\n /** A mapping of bundlers to platforms. */\n public platformBundlers: PlatformBundlers,\n /** Advanced options */\n options?: {\n /**\n * The instance of DevToolsPluginManager\n * @default new DevToolsPluginManager(projectRoot)\n */\n devToolsPluginManager?: DevToolsPluginManager;\n // TODO: Replace with custom scheme maybe...\n isDevClient?: boolean;\n }\n ) {\n this.devToolsPluginManager =\n options?.devToolsPluginManager ?? new DevToolsPluginManager(projectRoot);\n this.isDevClient = options?.isDevClient ?? false;\n }\n\n protected setInstance(instance: DevServerInstance) {\n this.instance = instance;\n }\n\n /** Get the manifest middleware function. */\n protected async getManifestMiddlewareAsync(\n options: Pick<BundlerStartOptions, 'minify' | 'mode' | 'privateKeyPath'> = {}\n ) {\n const Middleware = require('./middleware/ExpoGoManifestHandlerMiddleware')\n .ExpoGoManifestHandlerMiddleware as typeof import('./middleware/ExpoGoManifestHandlerMiddleware').ExpoGoManifestHandlerMiddleware;\n\n const urlCreator = this.getUrlCreator();\n const middleware = new Middleware(this.projectRoot, {\n constructUrl: urlCreator.constructUrl.bind(urlCreator),\n mode: options.mode,\n minify: options.minify,\n isNativeWebpack: this.name === 'webpack' && this.isTargetingNative(),\n privateKeyPath: options.privateKeyPath,\n });\n return middleware;\n }\n\n /** Start the dev server using settings defined in the start command. */\n public async startAsync(options: BundlerStartOptions): Promise<DevServerInstance> {\n await this.stopAsync();\n\n let instance: DevServerInstance;\n if (options.headless) {\n instance = await this.startHeadlessAsync(options);\n } else {\n instance = await this.startImplementationAsync(options);\n }\n\n this.setInstance(instance);\n await this.postStartAsync(options);\n return instance;\n }\n\n protected abstract startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance>;\n\n public async waitForTypeScriptAsync(): Promise<boolean> {\n return false;\n }\n\n public abstract startTypeScriptServices(): Promise<void>;\n\n public async watchEnvironmentVariables(): Promise<void> {\n // noop -- We've only implemented this functionality in Metro.\n }\n\n /**\n * Creates a mock server representation that can be used to estimate URLs for a server started in another process.\n * This is used for the run commands where you can reuse the server from a previous run.\n */\n private async startHeadlessAsync(options: BundlerStartOptions): Promise<DevServerInstance> {\n if (!options.port)\n throw new CommandError('HEADLESS_SERVER', 'headless dev server requires a port option');\n this.urlCreator = this.getUrlCreator(options);\n\n return {\n // Create a mock server\n server: {\n close: (callback: () => void) => {\n this.instance = null;\n callback?.();\n },\n addListener() {},\n },\n location: {\n // The port is the main thing we want to send back.\n port: options.port,\n // localhost isn't always correct.\n host: 'localhost',\n // http is the only supported protocol on native.\n url: `http://localhost:${options.port}`,\n protocol: 'http',\n },\n middleware: {},\n messageSocket: {\n broadcast: () => {\n throw new CommandError('HEADLESS_SERVER', 'Cannot broadcast messages to headless server');\n },\n },\n };\n }\n\n /**\n * Runs after the `startAsync` function, performing any additional common operations.\n * You can assume the dev server is started by the time this function is called.\n */\n protected async postStartAsync(options: BundlerStartOptions) {\n if (\n options.location.hostType === 'tunnel' &&\n !env.EXPO_OFFLINE &&\n // This is a hack to prevent using tunnel on web since we block it upstream for some reason.\n this.isTargetingNative()\n ) {\n await this._startTunnelAsync();\n } else if (envIsWebcontainer()) {\n await this._startTunnelAsync();\n }\n\n if (!options.isExporting) {\n await this.startDevSessionAsync();\n this.watchConfig();\n }\n }\n\n protected abstract getConfigModuleIds(): string[];\n\n protected watchConfig() {\n this.notifier?.stopObserving();\n this.notifier = new FileNotifier(this.projectRoot, this.getConfigModuleIds());\n this.notifier.startObserving();\n }\n\n /** Create ngrok instance and start the tunnel server. Exposed for testing. */\n public async _startTunnelAsync(): Promise<AsyncNgrok | AsyncWsTunnel | null> {\n const port = this.getInstance()?.location.port;\n if (!port) return null;\n debug('[tunnel] connect to port: ' + port);\n this.tunnel = envIsWebcontainer()\n ? new AsyncWsTunnel(this.projectRoot, port)\n : new AsyncNgrok(this.projectRoot, port);\n await this.tunnel.startAsync();\n return this.tunnel;\n }\n\n protected async startDevSessionAsync() {\n // This is used to make Expo Go open the project in either Expo Go, or the web browser.\n // Must come after ngrok (`startTunnelAsync`) setup.\n this.devSession = new DevelopmentSession(\n this.projectRoot,\n // This URL will be used on external devices so the computer IP won't be relevant.\n this.isTargetingNative()\n ? this.getNativeRuntimeUrl()\n : this.getDevServerUrl({ hostType: 'localhost' })\n );\n\n await this.devSession.startAsync({\n runtime: this.isTargetingNative() ? 'native' : 'web',\n });\n }\n\n public isTargetingNative() {\n // Temporary hack while we implement multi-bundler dev server proxy.\n return true;\n }\n\n public isTargetingWeb() {\n return this.platformBundlers.web === this.name;\n }\n\n /**\n * Sends a message over web sockets to any connected device,\n * does nothing when the dev server is not running.\n *\n * @param method name of the command. In RN projects `reload`, and `devMenu` are available. In Expo Go, `sendDevCommand` is available.\n * @param params\n */\n public broadcastMessage(\n method: 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ) {\n this.getInstance()?.messageSocket.broadcast(method, params);\n }\n\n /** Get the running dev server instance. */\n public getInstance() {\n return this.instance;\n }\n\n /** Stop the running dev server instance. */\n async stopAsync() {\n // Stop file watching.\n this.notifier?.stopObserving();\n\n // Stop the dev session timer and tell Expo API to remove dev session.\n await this.devSession?.closeAsync();\n\n // Stop tunnel if running.\n await this.tunnel?.stopAsync().catch((e) => {\n Log.error(`Error stopping tunnel:`);\n Log.exception(e);\n });\n\n return resolveWithTimeout(\n () =>\n new Promise<void>((resolve, reject) => {\n // Close the server.\n debug(`Stopping dev server (bundler: ${this.name})`);\n\n if (this.instance?.server) {\n // Check if server is even running.\n this.instance.server.close((error) => {\n debug(`Stopped dev server (bundler: ${this.name})`);\n this.instance = null;\n if (error) {\n if ('code' in error && error.code === 'ERR_SERVER_NOT_RUNNING') {\n resolve();\n } else {\n reject(error);\n }\n } else {\n resolve();\n }\n });\n } else {\n debug(`Stopped dev server (bundler: ${this.name})`);\n this.instance = null;\n resolve();\n }\n }),\n {\n // NOTE(Bacon): Metro dev server doesn't seem to be closing in time.\n timeout: 1000,\n errorMessage: `Timeout waiting for '${this.name}' dev server to close`,\n }\n );\n }\n\n public getUrlCreator(options: Partial<Pick<BundlerStartOptions, 'port' | 'location'>> = {}) {\n if (!this.urlCreator) {\n assert(options?.port, 'Dev server instance not found');\n this.urlCreator = new UrlCreator(options.location, {\n port: options.port,\n getTunnelUrl: this.getTunnelUrl.bind(this),\n });\n }\n return this.urlCreator;\n }\n\n public getNativeRuntimeUrl(opts: Partial<CreateURLOptions> = {}) {\n return this.isDevClient\n ? (this.getUrlCreator().constructDevClientUrl(opts) ?? this.getDevServerUrl())\n : this.getUrlCreator().constructUrl({ ...opts, scheme: 'exp' });\n }\n\n /** Get the URL for the running instance of the dev server. */\n public getDevServerUrl(options: { hostType?: 'localhost' } = {}): string | null {\n const instance = this.getInstance();\n if (!instance?.location) {\n return null;\n }\n\n // If we have an active WS tunnel instance, we always need to return the tunnel location.\n if (this.tunnel && this.tunnel instanceof AsyncWsTunnel) {\n return this.getUrlCreator().constructUrl();\n }\n\n const { location } = instance;\n if (options.hostType === 'localhost') {\n return `${location.protocol}://localhost:${location.port}`;\n }\n\n return location.url ?? null;\n }\n\n public getDevServerUrlOrAssert(options: { hostType?: 'localhost' } = {}): string {\n const instance = this.getDevServerUrl(options);\n if (!instance) {\n throw new CommandError(\n 'DEV_SERVER',\n `Cannot get the dev server URL before the server has started - bundler[${this.name}]`\n );\n }\n\n return instance;\n }\n\n /** Get the base URL for JS inspector */\n public getJsInspectorBaseUrl(): string {\n if (this.name !== 'metro') {\n throw new CommandError(\n 'DEV_SERVER',\n `Cannot get the JS inspector base url - bundler[${this.name}]`\n );\n }\n return this.getUrlCreator().constructUrl({ scheme: 'http' });\n }\n\n /** Get the tunnel URL from the tunnel. */\n public getTunnelUrl(): string | null {\n return this.tunnel?.getActiveUrl() ?? null;\n }\n\n /** Open the dev server in a runtime. */\n public async openPlatformAsync(\n launchTarget: keyof PlatformManagers | 'desktop',\n resolver: BaseResolveDeviceProps<any> = {}\n ) {\n if (launchTarget === 'desktop') {\n const serverUrl = this.getDevServerUrl({ hostType: 'localhost' });\n // Allow opening the tunnel URL when using Metro web.\n const url = this.name === 'metro' ? (this.getTunnelUrl() ?? serverUrl) : serverUrl;\n await openBrowserAsync(url!);\n return { url };\n }\n\n const runtime = this.isTargetingNative() ? (this.isDevClient ? 'custom' : 'expo') : 'web';\n const manager = await this.getPlatformManagerAsync(launchTarget);\n return manager.openAsync({ runtime }, resolver);\n }\n\n /** Open the dev server in a runtime. */\n public async openCustomRuntimeAsync<Platform extends keyof PlatformManagers>(\n launchTarget: Platform,\n launchProps: Partial<PlatformLaunchProps<Platform>> = {},\n resolver: BaseResolveDeviceProps<PlatformDevice<Platform>> = {}\n ) {\n const runtime = this.isTargetingNative() ? (this.isDevClient ? 'custom' : 'expo') : 'web';\n if (runtime !== 'custom') {\n throw new CommandError(\n `dev server cannot open custom runtimes either because it does not target native platforms or because it is not targeting dev clients. (target: ${runtime})`\n );\n }\n\n const manager = await this.getPlatformManagerAsync(launchTarget);\n return manager.openAsync(\n { runtime: 'custom', props: launchProps },\n resolver as BaseResolveDeviceProps<any>\n );\n }\n\n /** Get the URL for opening in Expo Go. */\n protected getExpoGoUrl(): string {\n return this.getUrlCreator().constructUrl({ scheme: 'exp' });\n }\n\n /** Should use the interstitial page for selecting which runtime to use. */\n protected isRedirectPageEnabled(): boolean {\n return (\n !env.EXPO_NO_REDIRECT_PAGE &&\n // if user passed --dev-client flag, skip interstitial page\n !this.isDevClient &&\n // Checks if dev client is installed.\n !!resolveFrom.silent(this.projectRoot, 'expo-dev-client')\n );\n }\n\n /** Get the redirect URL when redirecting is enabled. */\n public getRedirectUrl(platform: keyof PlatformManagers | null = null): string | null {\n if (!this.isRedirectPageEnabled()) {\n debug('Redirect page is disabled');\n return null;\n }\n\n return (\n this.getUrlCreator().constructLoadingUrl(\n {},\n platform === 'emulator' ? 'android' : platform === 'simulator' ? 'ios' : null\n ) ?? null\n );\n }\n\n protected async getPlatformManagerAsync<Platform extends keyof PlatformManagers>(\n ofPlatform: Platform\n ): Promise<PlatformManagers[Platform]> {\n const platform: keyof PlatformManagers = ofPlatform;\n if (!this.platformManagers[platform]) {\n const port = this.getInstance()?.location.port;\n if (!port || !this.urlCreator) {\n throw new CommandError(\n 'DEV_SERVER',\n 'Cannot interact with native platforms until dev server has started'\n );\n }\n debug(`Creating platform manager (platform: ${platform}, port: ${port})`);\n const managerParams = {\n getCustomRuntimeUrl: this.urlCreator.constructDevClientUrl.bind(this.urlCreator),\n getExpoGoUrl: this.getExpoGoUrl.bind(this),\n getRedirectUrl: this.getRedirectUrl.bind(this, platform),\n getDevServerUrl: this.getDevServerUrl.bind(this, { hostType: 'localhost' }),\n };\n switch (platform) {\n case 'simulator': {\n const Manager = PLATFORM_MANAGERS[platform]();\n this.platformManagers[platform] = new Manager(this.projectRoot, port, managerParams);\n break;\n }\n case 'emulator': {\n const Manager = PLATFORM_MANAGERS[platform]();\n this.platformManagers[platform] = new Manager(this.projectRoot, port, managerParams);\n break;\n }\n }\n }\n return this.platformManagers[platform] as PlatformManagers[Platform];\n }\n}\n"],"names":["BundlerDevServer","debug","require","PLATFORM_MANAGERS","simulator","ApplePlatformManager","emulator","AndroidPlatformManager","constructor","projectRoot","platformBundlers","options","tunnel","devSession","instance","platformManagers","urlCreator","notifier","devToolsPluginManager","DevToolsPluginManager","isDevClient","setInstance","getManifestMiddlewareAsync","Middleware","ExpoGoManifestHandlerMiddleware","getUrlCreator","middleware","constructUrl","bind","mode","minify","isNativeWebpack","name","isTargetingNative","privateKeyPath","startAsync","stopAsync","headless","startHeadlessAsync","startImplementationAsync","postStartAsync","waitForTypeScriptAsync","watchEnvironmentVariables","port","CommandError","server","close","callback","addListener","location","host","url","protocol","messageSocket","broadcast","hostType","env","EXPO_OFFLINE","_startTunnelAsync","envIsWebcontainer","isExporting","startDevSessionAsync","watchConfig","stopObserving","FileNotifier","getConfigModuleIds","startObserving","getInstance","AsyncWsTunnel","AsyncNgrok","DevelopmentSession","getNativeRuntimeUrl","getDevServerUrl","runtime","isTargetingWeb","web","broadcastMessage","method","params","closeAsync","catch","e","Log","error","exception","resolveWithTimeout","Promise","resolve","reject","code","timeout","errorMessage","assert","UrlCreator","getTunnelUrl","opts","constructDevClientUrl","scheme","getDevServerUrlOrAssert","getJsInspectorBaseUrl","getActiveUrl","openPlatformAsync","launchTarget","resolver","serverUrl","openBrowserAsync","manager","getPlatformManagerAsync","openAsync","openCustomRuntimeAsync","launchProps","props","getExpoGoUrl","isRedirectPageEnabled","EXPO_NO_REDIRECT_PAGE","resolveFrom","silent","getRedirectUrl","platform","constructLoadingUrl","ofPlatform","managerParams","getCustomRuntimeUrl","Manager"],"mappings":"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"}
|
|
@@ -15,19 +15,11 @@ function _ws() {
|
|
|
15
15
|
};
|
|
16
16
|
return data;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
function createDevToolsPluginWebsocketEndpoint({ serverBaseUrl }) {
|
|
18
|
+
function createDevToolsPluginWebsocketEndpoint() {
|
|
20
19
|
const wss = new (_ws()).WebSocketServer({
|
|
21
20
|
noServer: true
|
|
22
21
|
});
|
|
23
22
|
wss.on('connection', (ws, request)=>{
|
|
24
|
-
// Explicitly limit devtools websocket to loopback requests
|
|
25
|
-
if (!(0, _net.isLocalSocket)(request.socket) || !(0, _net.isMatchingOrigin)(request, serverBaseUrl)) {
|
|
26
|
-
// NOTE: `socket.close` nicely closes the websocket, which will still allow incoming messages
|
|
27
|
-
// `socket.terminate` instead forcefully closes down the socket
|
|
28
|
-
ws.terminate();
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
23
|
ws.on('message', (message, isBinary)=>{
|
|
32
24
|
// Broadcast the received message to all other connected clients
|
|
33
25
|
wss.clients.forEach((client)=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/DevToolsPluginWebsocketEndpoint.ts"],"sourcesContent":["import { WebSocket, WebSocketServer } from 'ws';\n\
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/DevToolsPluginWebsocketEndpoint.ts"],"sourcesContent":["import { WebSocket, WebSocketServer } from 'ws';\n\nexport function createDevToolsPluginWebsocketEndpoint(): Record<string, WebSocketServer> {\n const wss = new WebSocketServer({ noServer: true });\n\n wss.on('connection', (ws, request) => {\n ws.on('message', (message, isBinary) => {\n // Broadcast the received message to all other connected clients\n wss.clients.forEach((client) => {\n if (client !== ws && client.readyState === WebSocket.OPEN) {\n client.send(message, { binary: isBinary });\n }\n });\n });\n });\n\n return { '/expo-dev-plugins/broadcast': wss };\n}\n"],"names":["createDevToolsPluginWebsocketEndpoint","wss","WebSocketServer","noServer","on","ws","request","message","isBinary","clients","forEach","client","readyState","WebSocket","OPEN","send","binary"],"mappings":";;;;+BAEgBA;;;eAAAA;;;;yBAF2B;;;;;;AAEpC,SAASA;IACd,MAAMC,MAAM,IAAIC,CAAAA,KAAc,iBAAC,CAAC;QAAEC,UAAU;IAAK;IAEjDF,IAAIG,EAAE,CAAC,cAAc,CAACC,IAAIC;QACxBD,GAAGD,EAAE,CAAC,WAAW,CAACG,SAASC;YACzB,gEAAgE;YAChEP,IAAIQ,OAAO,CAACC,OAAO,CAAC,CAACC;gBACnB,IAAIA,WAAWN,MAAMM,OAAOC,UAAU,KAAKC,eAAS,CAACC,IAAI,EAAE;oBACzDH,OAAOI,IAAI,CAACR,SAAS;wBAAES,QAAQR;oBAAS;gBAC1C;YACF;QACF;IACF;IAEA,OAAO;QAAE,+BAA+BP;IAAI;AAC9C"}
|
|
@@ -8,6 +8,13 @@ Object.defineProperty(exports, "createMetroMiddleware", {
|
|
|
8
8
|
return createMetroMiddleware;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
function _paths() {
|
|
12
|
+
const data = require("@expo/config/paths");
|
|
13
|
+
_paths = function() {
|
|
14
|
+
return data;
|
|
15
|
+
};
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
11
18
|
function _connect() {
|
|
12
19
|
const data = /*#__PURE__*/ _interop_require_default(require("connect"));
|
|
13
20
|
_connect = function() {
|
|
@@ -15,6 +22,20 @@ function _connect() {
|
|
|
15
22
|
};
|
|
16
23
|
return data;
|
|
17
24
|
}
|
|
25
|
+
function _nodefs() {
|
|
26
|
+
const data = /*#__PURE__*/ _interop_require_default(require("node:fs"));
|
|
27
|
+
_nodefs = function() {
|
|
28
|
+
return data;
|
|
29
|
+
};
|
|
30
|
+
return data;
|
|
31
|
+
}
|
|
32
|
+
function _nodepath() {
|
|
33
|
+
const data = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
34
|
+
_nodepath = function() {
|
|
35
|
+
return data;
|
|
36
|
+
};
|
|
37
|
+
return data;
|
|
38
|
+
}
|
|
18
39
|
const _compression = require("./compression");
|
|
19
40
|
const _createEventSocket = require("./createEventSocket");
|
|
20
41
|
const _createMessageSocket = require("./createMessageSocket");
|
|
@@ -31,7 +52,7 @@ function createMetroMiddleware(metroConfig) {
|
|
|
31
52
|
});
|
|
32
53
|
const events = (0, _createEventSocket.createEventsSocket)(messages);
|
|
33
54
|
const middleware = (0, _connect().default)().use(noCacheMiddleware).use(_compression.compression)// Support opening stack frames from clients directly in the editor
|
|
34
|
-
.use('/open-stack-frame', rawBodyMiddleware).use('/open-stack-frame',
|
|
55
|
+
.use('/open-stack-frame', rawBodyMiddleware).use('/open-stack-frame', createMetroOpenStackFrameMiddleware(metroConfig))// Support the symbolication endpoint of Metro
|
|
35
56
|
// See: https://github.com/facebook/metro/blob/a792d85ffde3c21c3fbf64ac9404ab0afe5ff957/packages/metro/src/Server.js#L1266
|
|
36
57
|
.use('/symbolicate', rawBodyMiddleware)// Support status check to detect if the packager needs to be started from the native side
|
|
37
58
|
.use('/status', createMetroStatusMiddleware(metroConfig));
|
|
@@ -45,7 +66,7 @@ function createMetroMiddleware(metroConfig) {
|
|
|
45
66
|
}
|
|
46
67
|
};
|
|
47
68
|
}
|
|
48
|
-
const noCacheMiddleware = (
|
|
69
|
+
const noCacheMiddleware = (_req, res, next)=>{
|
|
49
70
|
res.setHeader('Surrogate-Control', 'no-store');
|
|
50
71
|
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
|
51
72
|
res.setHeader('Pragma', 'no-cache');
|
|
@@ -59,22 +80,64 @@ const rawBodyMiddleware = (req, _res, next)=>{
|
|
|
59
80
|
reqWithBody.on('data', (chunk)=>reqWithBody.rawBody += chunk);
|
|
60
81
|
reqWithBody.on('end', next);
|
|
61
82
|
};
|
|
62
|
-
const metroOpenStackFrameMiddleware = (req, res, next)=>{
|
|
63
|
-
// Only accept POST requests
|
|
64
|
-
if (req.method !== 'POST') return next();
|
|
65
|
-
// Only handle requests with a raw body
|
|
66
|
-
if (!('rawBody' in req) || !req.rawBody) {
|
|
67
|
-
res.statusCode = 406;
|
|
68
|
-
return res.end('Open stack frame requires the JSON stack frame as request body');
|
|
69
|
-
}
|
|
70
|
-
const frame = JSON.parse(req.rawBody);
|
|
71
|
-
(0, _editor.openInEditorAsync)(frame.file, frame.lineNumber).finally(()=>res.end('OK'));
|
|
72
|
-
};
|
|
73
83
|
function createMetroStatusMiddleware(metroConfig) {
|
|
74
84
|
return (_req, res)=>{
|
|
75
85
|
res.setHeader('X-React-Native-Project-Root', encodeURI(metroConfig.projectRoot));
|
|
76
86
|
res.end('packager-status:running');
|
|
77
87
|
};
|
|
78
88
|
}
|
|
89
|
+
function createMetroOpenStackFrameMiddleware(metroConfig) {
|
|
90
|
+
return async (req, res, next)=>{
|
|
91
|
+
if (req.method !== 'POST') {
|
|
92
|
+
return next();
|
|
93
|
+
}
|
|
94
|
+
if (!('rawBody' in req) || !req.rawBody) {
|
|
95
|
+
res.statusCode = 406;
|
|
96
|
+
return res.end('Open stack frame requires the JSON stack frame as request body');
|
|
97
|
+
}
|
|
98
|
+
let frame;
|
|
99
|
+
try {
|
|
100
|
+
const json = JSON.parse(req.rawBody);
|
|
101
|
+
if (typeof json === 'object' && json != null && typeof json.file === 'string') {
|
|
102
|
+
frame = {
|
|
103
|
+
file: json.file,
|
|
104
|
+
lineNumber: typeof json.lineNumber === 'number' && Number.isSafeInteger(json.lineNumber) ? json.lineNumber : undefined
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
} catch {}
|
|
108
|
+
if (!frame) {
|
|
109
|
+
res.statusCode = 400;
|
|
110
|
+
return res.end('Open stack frame requires the JSON stack frame as request body');
|
|
111
|
+
}
|
|
112
|
+
const root = (0, _paths().getMetroServerRoot)(metroConfig.projectRoot);
|
|
113
|
+
const file = await ensureFileInRootDirectory(root, frame.file);
|
|
114
|
+
if (!file) {
|
|
115
|
+
res.statusCode = 400;
|
|
116
|
+
return res.end('Open stack frame requires target file to be in server root');
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
await (0, _editor.openInEditorAsync)(file, frame.lineNumber);
|
|
120
|
+
return res.end('OK');
|
|
121
|
+
} catch {
|
|
122
|
+
res.statusCode = 5006;
|
|
123
|
+
return res.end('Open stack frame failed to open local editor');
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const ensureFileInRootDirectory = async (root, file)=>{
|
|
128
|
+
try {
|
|
129
|
+
file = _nodepath().default.resolve(root, file);
|
|
130
|
+
file = await _nodefs().default.promises.realpath(file);
|
|
131
|
+
// Cannot be accessed using Metro's server API, we need to move the file
|
|
132
|
+
// into the project root and try again.
|
|
133
|
+
if (!_nodepath().default.relative(root, file).startsWith('..' + _nodepath().default.sep)) {
|
|
134
|
+
return file;
|
|
135
|
+
} else {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
} catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
79
142
|
|
|
80
143
|
//# sourceMappingURL=createMetroMiddleware.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/start/server/metro/dev-server/createMetroMiddleware.ts"],"sourcesContent":["import type { MetroConfig } from '@expo/metro/metro';\nimport connect from 'connect';\n\nimport { compression } from './compression';\nimport { createEventsSocket } from './createEventSocket';\nimport { createMessagesSocket } from './createMessageSocket';\nimport { Log } from '../../../../log';\nimport { openInEditorAsync } from '../../../../utils/editor';\n\nexport function createMetroMiddleware(metroConfig: Pick<MetroConfig, 'projectRoot'>) {\n const messages = createMessagesSocket({ logger: Log });\n const events = createEventsSocket(messages);\n\n const middleware = connect()\n .use(noCacheMiddleware)\n .use(compression)\n // Support opening stack frames from clients directly in the editor\n .use('/open-stack-frame', rawBodyMiddleware)\n .use('/open-stack-frame',
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/start/server/metro/dev-server/createMetroMiddleware.ts"],"sourcesContent":["import { getMetroServerRoot } from '@expo/config/paths';\nimport type { MetroConfig } from '@expo/metro/metro';\nimport connect from 'connect';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { compression } from './compression';\nimport { createEventsSocket } from './createEventSocket';\nimport { createMessagesSocket } from './createMessageSocket';\nimport { Log } from '../../../../log';\nimport { openInEditorAsync } from '../../../../utils/editor';\n\ninterface StackFrame {\n file: string;\n lineNumber?: number | undefined;\n}\n\nexport function createMetroMiddleware(metroConfig: Pick<MetroConfig, 'projectRoot'>) {\n const messages = createMessagesSocket({ logger: Log });\n const events = createEventsSocket(messages);\n\n const middleware = connect()\n .use(noCacheMiddleware)\n .use(compression)\n // Support opening stack frames from clients directly in the editor\n .use('/open-stack-frame', rawBodyMiddleware)\n .use('/open-stack-frame', createMetroOpenStackFrameMiddleware(metroConfig))\n // Support the symbolication endpoint of Metro\n // See: https://github.com/facebook/metro/blob/a792d85ffde3c21c3fbf64ac9404ab0afe5ff957/packages/metro/src/Server.js#L1266\n .use('/symbolicate', rawBodyMiddleware)\n // Support status check to detect if the packager needs to be started from the native side\n .use('/status', createMetroStatusMiddleware(metroConfig));\n\n return {\n middleware,\n messagesSocket: messages,\n eventsSocket: events,\n websocketEndpoints: {\n [messages.endpoint]: messages.server,\n [events.endpoint]: events.server,\n },\n };\n}\n\nconst noCacheMiddleware: connect.NextHandleFunction = (_req, res, next) => {\n res.setHeader('Surrogate-Control', 'no-store');\n res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');\n res.setHeader('Pragma', 'no-cache');\n res.setHeader('Expires', '0');\n next();\n};\n\nconst rawBodyMiddleware: connect.NextHandleFunction = (req, _res, next) => {\n const reqWithBody = req as typeof req & { rawBody: string };\n reqWithBody.setEncoding('utf8');\n reqWithBody.rawBody = '';\n reqWithBody.on('data', (chunk) => (reqWithBody.rawBody += chunk));\n reqWithBody.on('end', next);\n};\n\nfunction createMetroStatusMiddleware(\n metroConfig: Pick<MetroConfig, 'projectRoot'>\n): connect.NextHandleFunction {\n return (_req, res) => {\n res.setHeader('X-React-Native-Project-Root', encodeURI(metroConfig.projectRoot!));\n res.end('packager-status:running');\n };\n}\n\nfunction createMetroOpenStackFrameMiddleware(\n metroConfig: Pick<MetroConfig, 'projectRoot'>\n): connect.NextHandleFunction {\n return async (req, res, next) => {\n if (req.method !== 'POST') {\n return next();\n }\n\n if (!('rawBody' in req) || !req.rawBody) {\n res.statusCode = 406;\n return res.end('Open stack frame requires the JSON stack frame as request body');\n }\n\n let frame: StackFrame | undefined;\n try {\n const json = JSON.parse(req.rawBody as string);\n if (typeof json === 'object' && json != null && typeof json.file === 'string') {\n frame = {\n file: json.file,\n lineNumber:\n typeof json.lineNumber === 'number' && Number.isSafeInteger(json.lineNumber)\n ? json.lineNumber\n : undefined,\n };\n }\n } catch {}\n if (!frame) {\n res.statusCode = 400;\n return res.end('Open stack frame requires the JSON stack frame as request body');\n }\n\n const root = getMetroServerRoot(metroConfig.projectRoot!);\n const file = await ensureFileInRootDirectory(root, frame.file);\n if (!file) {\n res.statusCode = 400;\n return res.end('Open stack frame requires target file to be in server root');\n }\n\n try {\n await openInEditorAsync(file, frame.lineNumber);\n return res.end('OK');\n } catch {\n res.statusCode = 5006;\n return res.end('Open stack frame failed to open local editor');\n }\n };\n}\n\nconst ensureFileInRootDirectory = async (root: string, file: string): Promise<string | null> => {\n try {\n file = path.resolve(root, file);\n file = await fs.promises.realpath(file);\n // Cannot be accessed using Metro's server API, we need to move the file\n // into the project root and try again.\n if (!path.relative(root, file).startsWith('..' + path.sep)) {\n return file;\n } else {\n return null;\n }\n } catch {\n return null;\n }\n};\n"],"names":["createMetroMiddleware","metroConfig","messages","createMessagesSocket","logger","Log","events","createEventsSocket","middleware","connect","use","noCacheMiddleware","compression","rawBodyMiddleware","createMetroOpenStackFrameMiddleware","createMetroStatusMiddleware","messagesSocket","eventsSocket","websocketEndpoints","endpoint","server","_req","res","next","setHeader","req","_res","reqWithBody","setEncoding","rawBody","on","chunk","encodeURI","projectRoot","end","method","statusCode","frame","json","JSON","parse","file","lineNumber","Number","isSafeInteger","undefined","root","getMetroServerRoot","ensureFileInRootDirectory","openInEditorAsync","path","resolve","fs","promises","realpath","relative","startsWith","sep"],"mappings":"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"}
|
|
@@ -262,9 +262,7 @@ async function instantiateMetroAsync(metroBundler, options, { isExporting, exp =
|
|
|
262
262
|
}
|
|
263
263
|
return middleware.use(metroMiddleware);
|
|
264
264
|
};
|
|
265
|
-
const devtoolsWebsocketEndpoints = (0, _DevToolsPluginWebsocketEndpoint.createDevToolsPluginWebsocketEndpoint)(
|
|
266
|
-
serverBaseUrl
|
|
267
|
-
});
|
|
265
|
+
const devtoolsWebsocketEndpoints = (0, _DevToolsPluginWebsocketEndpoint.createDevToolsPluginWebsocketEndpoint)();
|
|
268
266
|
Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);
|
|
269
267
|
}
|
|
270
268
|
// Attach Expo Atlas if enabled
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/instantiateMetro.ts"],"sourcesContent":["import { type ExpoConfig, getConfig } from '@expo/config';\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport type { Reporter } from '@expo/metro/metro';\nimport type Bundler from '@expo/metro/metro/Bundler';\nimport type { ReadOnlyGraph } from '@expo/metro/metro/DeltaBundler';\nimport type { TransformOptions } from '@expo/metro/metro/DeltaBundler/Worker';\nimport MetroHmrServer, { Client as MetroHmrClient } from '@expo/metro/metro/HmrServer';\nimport RevisionNotFoundError from '@expo/metro/metro/IncrementalBundler/RevisionNotFoundError';\nimport type MetroServer from '@expo/metro/metro/Server';\nimport formatBundlingError from '@expo/metro/metro/lib/formatBundlingError';\nimport { mergeConfig, resolveConfig, type ConfigT } from '@expo/metro/metro-config';\nimport { Terminal } from '@expo/metro/metro-core';\nimport { getDefaultConfig } from '@expo/metro-config';\nimport chalk from 'chalk';\nimport http from 'http';\nimport path from 'path';\n\nimport { createDevToolsPluginWebsocketEndpoint } from './DevToolsPluginWebsocketEndpoint';\nimport { MetroBundlerDevServer } from './MetroBundlerDevServer';\nimport { MetroTerminalReporter } from './MetroTerminalReporter';\nimport { attachAtlasAsync } from './debugging/attachAtlas';\nimport { createDebugMiddleware } from './debugging/createDebugMiddleware';\nimport { createMetroMiddleware } from './dev-server/createMetroMiddleware';\nimport { runServer } from './runServer-fork';\nimport { withMetroMultiPlatformAsync } from './withMetroMultiPlatform';\nimport { Log } from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { createCorsMiddleware } from '../middleware/CorsMiddleware';\nimport { createJsInspectorMiddleware } from '../middleware/inspector/createJsInspectorMiddleware';\nimport { prependMiddleware } from '../middleware/mutations';\nimport { getPlatformBundlers } from '../platformBundlers';\n\n// From expo/dev-server but with ability to use custom logger.\ntype MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\n// Wrap terminal and polyfill console.log so we can log during bundling without breaking the indicator.\nclass LogRespectingTerminal extends Terminal {\n constructor(stream: import('node:net').Socket | import('node:stream').Writable) {\n super(stream, { ttyPrint: true });\n\n const sendLog = (...msg: any[]) => {\n if (!msg.length) {\n this.log('');\n } else {\n const [format, ...args] = msg;\n this.log(format, ...args);\n }\n // Flush the logs to the terminal immediately so logs at the end of the process are not lost.\n this.flush();\n };\n\n console.log = sendLog;\n console.info = sendLog;\n }\n}\n\n// Share one instance of Terminal for all instances of Metro.\nconst terminal = new LogRespectingTerminal(process.stdout);\n\ninterface LoadMetroConfigOptions {\n maxWorkers?: number;\n port?: number;\n reporter?: Reporter;\n resetCache?: boolean;\n}\n\nexport async function loadMetroConfigAsync(\n projectRoot: string,\n options: LoadMetroConfigOptions,\n {\n exp,\n isExporting,\n getMetroBundler,\n }: { exp: ExpoConfig; isExporting: boolean; getMetroBundler: () => Bundler }\n) {\n let reportEvent: ((event: any) => void) | undefined;\n\n const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? env.EXPO_USE_STICKY_RESOLVER;\n\n const serverActionsEnabled =\n exp.experiments?.reactServerFunctions ?? env.EXPO_UNSTABLE_SERVER_FUNCTIONS;\n\n if (serverActionsEnabled) {\n process.env.EXPO_UNSTABLE_SERVER_FUNCTIONS = '1';\n }\n\n // NOTE: Enable all the experimental Metro flags when RSC is enabled.\n if (exp.experiments?.reactServerComponentRoutes || serverActionsEnabled) {\n process.env.EXPO_USE_METRO_REQUIRE = '1';\n }\n\n const isReactCanaryEnabled =\n (exp.experiments?.reactServerComponentRoutes ||\n serverActionsEnabled ||\n exp.experiments?.reactCanary) ??\n false;\n\n const serverRoot = getMetroServerRoot(projectRoot);\n const terminalReporter = new MetroTerminalReporter(serverRoot, terminal);\n\n // NOTE: Allow external tools to override the metro config. This is considered internal and unstable\n const configPath = env.EXPO_OVERRIDE_METRO_CONFIG ?? undefined;\n const resolvedConfig = await resolveConfig(configPath, projectRoot);\n const defaultConfig = getDefaultConfig(projectRoot);\n\n let config: ConfigT = resolvedConfig.isEmpty\n ? defaultConfig\n : await mergeConfig(defaultConfig, resolvedConfig.config);\n\n // Set the watchfolders to include the projectRoot, as Metro assumes this\n // Force-override the reporter\n config = {\n ...config,\n\n // See: `overrideConfigWithArguments` https://github.com/facebook/metro/blob/5059e26/packages/metro-config/src/loadConfig.js#L274-L339\n // Compare to `LoadOptions` type (disregard `reporter` as we don't expose this)\n resetCache: !!options.resetCache,\n maxWorkers: options.maxWorkers ?? config.maxWorkers,\n server: {\n ...config.server,\n port: options.port ?? config.server.port,\n },\n\n watchFolders: !config.watchFolders.includes(config.projectRoot)\n ? [config.projectRoot, ...config.watchFolders]\n : config.watchFolders,\n reporter: {\n update(event) {\n terminalReporter.update(event);\n if (reportEvent) {\n reportEvent(event);\n }\n },\n },\n };\n\n // @ts-expect-error: Set the global require cycle ignore patterns for SSR bundles. This won't work with custom global prefixes, but we don't use those.\n globalThis.__requireCycleIgnorePatterns = config.resolver?.requireCycleIgnorePatterns;\n\n if (isExporting) {\n // This token will be used in the asset plugin to ensure the path is correct for writing locally.\n // @ts-expect-error: typed as readonly.\n config.transformer.publicPath = `/assets?export_path=${\n (exp.experiments?.baseUrl ?? '') + '/assets'\n }`;\n } else {\n // @ts-expect-error: typed as readonly\n config.transformer.publicPath = '/assets/?unstable_path=.';\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n if (exp.experiments?.reactCompiler) {\n Log.log(chalk.gray`React Compiler enabled`);\n }\n\n if (env.EXPO_UNSTABLE_TREE_SHAKING && !env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n throw new CommandError(\n 'EXPO_UNSTABLE_TREE_SHAKING requires EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH to be enabled.'\n );\n }\n\n if (env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental fast resolver is enabled.`);\n }\n if (env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n Log.warn(`Experimental bundle optimization is enabled.`);\n }\n if (env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental tree shaking is enabled.`);\n }\n if (autolinkingModuleResolutionEnabled) {\n Log.warn(`Experimental Expo Autolinking module resolver is enabled.`);\n }\n\n if (serverActionsEnabled) {\n Log.warn(\n `React Server Functions (beta) are enabled. Route rendering mode: ${exp.experiments?.reactServerComponentRoutes ? 'server' : 'client'}`\n );\n }\n\n config = await withMetroMultiPlatformAsync(projectRoot, {\n config,\n exp,\n platformBundlers,\n isTsconfigPathsEnabled: exp.experiments?.tsconfigPaths ?? true,\n isAutolinkingResolverEnabled: autolinkingModuleResolutionEnabled,\n isFastResolverEnabled: env.EXPO_USE_FAST_RESOLVER,\n isExporting,\n isReactCanaryEnabled,\n isNamedRequiresEnabled: env.EXPO_USE_METRO_REQUIRE,\n isReactServerComponentsEnabled: !!exp.experiments?.reactServerComponentRoutes,\n getMetroBundler,\n });\n\n return {\n config,\n setEventReporter: (logger: (event: any) => void) => (reportEvent = logger),\n reporter: terminalReporter,\n };\n}\n\n/** The most generic possible setup for Metro bundler. */\nexport async function instantiateMetroAsync(\n metroBundler: MetroBundlerDevServer,\n options: LoadMetroConfigOptions,\n {\n isExporting,\n exp = getConfig(metroBundler.projectRoot, {\n skipSDKVersionRequirement: true,\n }).exp,\n }: { isExporting: boolean; exp?: ExpoConfig }\n): Promise<{\n metro: MetroServer;\n hmrServer: MetroHmrServer<MetroHmrClient> | null;\n server: http.Server;\n middleware: any;\n messageSocket: MessageSocket;\n}> {\n const projectRoot = metroBundler.projectRoot;\n\n const {\n config: metroConfig,\n setEventReporter,\n reporter,\n } = await loadMetroConfigAsync(projectRoot, options, {\n exp,\n isExporting,\n getMetroBundler() {\n return metro.getBundler().getBundler();\n },\n });\n\n // Create the core middleware stack for Metro, including websocket listeners\n const { middleware, messagesSocket, eventsSocket, websocketEndpoints } =\n createMetroMiddleware(metroConfig);\n\n // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)\n const serverBaseUrl = metroBundler\n .getUrlCreator()\n .constructUrl({ scheme: 'http', hostType: 'localhost' });\n\n if (!isExporting) {\n // Enable correct CORS headers for Expo Router features\n prependMiddleware(middleware, createCorsMiddleware(exp));\n\n // Enable debug middleware for CDP-related debugging\n const { debugMiddleware, debugWebsocketEndpoints } = createDebugMiddleware({\n projectRoot: metroBundler.projectRoot,\n serverBaseUrl,\n reporter,\n });\n Object.assign(websocketEndpoints, debugWebsocketEndpoints);\n middleware.use(debugMiddleware);\n middleware.use('/_expo/debugger', createJsInspectorMiddleware());\n\n // TODO(cedric): `enhanceMiddleware` is deprecated, but is currently used to unify the middleware stacks\n // See: https://github.com/facebook/metro/commit/22e85fde85ec454792a1b70eba4253747a2587a9\n // See: https://github.com/facebook/metro/commit/d0d554381f119bb80ab09dbd6a1d310b54737e52\n const customEnhanceMiddleware = metroConfig.server.enhanceMiddleware;\n // @ts-expect-error: can't mutate readonly config\n metroConfig.server.enhanceMiddleware = (metroMiddleware: any, server: MetroServer) => {\n if (customEnhanceMiddleware) {\n metroMiddleware = customEnhanceMiddleware(metroMiddleware, server);\n }\n return middleware.use(metroMiddleware);\n };\n\n const devtoolsWebsocketEndpoints = createDevToolsPluginWebsocketEndpoint({ serverBaseUrl });\n Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);\n }\n\n // Attach Expo Atlas if enabled\n await attachAtlasAsync({\n isExporting,\n exp,\n projectRoot,\n middleware,\n metroConfig,\n // NOTE(cedric): reset the Atlas file once, and reuse it for static exports\n resetAtlasFile: isExporting,\n });\n\n const { server, hmrServer, metro } = await runServer(\n metroBundler,\n metroConfig,\n {\n websocketEndpoints,\n watch: !isExporting && isWatchEnabled(),\n },\n {\n mockServer: isExporting,\n }\n );\n\n // Patch transform file to remove inconvenient customTransformOptions which are only used in single well-known files.\n const originalTransformFile = metro\n .getBundler()\n .getBundler()\n .transformFile.bind(metro.getBundler().getBundler());\n\n metro.getBundler().getBundler().transformFile = async function (\n filePath: string,\n transformOptions: TransformOptions,\n fileBuffer?: Buffer\n ) {\n return originalTransformFile(\n filePath,\n pruneCustomTransformOptions(\n filePath,\n // Clone the options so we don't mutate the original.\n {\n ...transformOptions,\n customTransformOptions: {\n __proto__: null,\n ...transformOptions.customTransformOptions,\n },\n }\n ),\n fileBuffer\n );\n };\n\n setEventReporter(eventsSocket.reportMetroEvent);\n\n // This function ensures that modules in source maps are sorted in the same\n // order as in a plain JS bundle.\n metro._getSortedModules = function (this: MetroServer, graph: ReadOnlyGraph) {\n const modules = [...graph.dependencies.values()];\n\n const ctx = {\n platform: graph.transformOptions.platform,\n environment: graph.transformOptions.customTransformOptions?.environment,\n };\n // Assign IDs to modules in a consistent order\n for (const module of modules) {\n // @ts-expect-error\n this._createModuleId(module.path, ctx);\n }\n // Sort by IDs\n return modules.sort(\n // @ts-expect-error\n (a, b) => this._createModuleId(a.path, ctx) - this._createModuleId(b.path, ctx)\n );\n };\n\n if (hmrServer) {\n let hmrJSBundle:\n | typeof import('@expo/metro-config/build/serializer/fork/hmrJSBundle').default\n | typeof import('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle').default;\n\n try {\n hmrJSBundle = require('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n } catch {\n // TODO: Add fallback for monorepo tests up until the fork is merged.\n Log.warn('Failed to load HMR serializer from @expo/metro-config, using fallback version.');\n hmrJSBundle = require('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle');\n }\n\n // Patch HMR Server to send more info to the `_createModuleId` function for deterministic module IDs and add support for serializing HMR updates the same as all other bundles.\n hmrServer._prepareMessage = async function (\n this: MetroHmrServer<MetroHmrClient>,\n group,\n options,\n changeEvent\n ) {\n // Fork of https://github.com/facebook/metro/blob/3b3e0aaf725cfa6907bf2c8b5fbc0da352d29efe/packages/metro/src/HmrServer.js#L327-L393\n // with patch for `_createModuleId`.\n const logger = !options.isInitialUpdate ? changeEvent?.logger : null;\n try {\n const revPromise = this._bundler.getRevision(group.revisionId);\n if (!revPromise) {\n return {\n type: 'error',\n body: formatBundlingError(new RevisionNotFoundError(group.revisionId)),\n };\n }\n logger?.point('updateGraph_start');\n const { revision, delta } = await this._bundler.updateGraph(await revPromise, false);\n logger?.point('updateGraph_end');\n this._clientGroups.delete(group.revisionId);\n group.revisionId = revision.id;\n for (const client of group.clients) {\n client.revisionIds = client.revisionIds.filter(\n (revisionId) => revisionId !== group.revisionId\n );\n client.revisionIds.push(revision.id);\n }\n this._clientGroups.set(group.revisionId, group);\n logger?.point('serialize_start');\n // NOTE(EvanBacon): This is the patch\n const moduleIdContext = {\n platform: revision.graph.transformOptions.platform,\n environment: revision.graph.transformOptions.customTransformOptions?.environment,\n };\n const hmrUpdate = hmrJSBundle(delta, revision.graph, {\n clientUrl: group.clientUrl,\n // NOTE(EvanBacon): This is also the patch\n createModuleId: (moduleId: string) => {\n // @ts-expect-error\n return this._createModuleId(moduleId, moduleIdContext);\n },\n includeAsyncPaths: group.graphOptions.lazy,\n projectRoot: this._config.projectRoot,\n serverRoot: this._config.server.unstable_serverRoot ?? this._config.projectRoot,\n });\n logger?.point('serialize_end');\n return {\n type: 'update',\n body: {\n revisionId: revision.id,\n isInitialUpdate: options.isInitialUpdate,\n ...hmrUpdate,\n },\n };\n } catch (error: any) {\n const formattedError = formatBundlingError(error);\n this._config.reporter.update({\n type: 'bundling_error',\n error,\n });\n return {\n type: 'error',\n body: formattedError,\n };\n }\n };\n }\n\n return {\n metro,\n hmrServer,\n server,\n middleware,\n messageSocket: messagesSocket,\n };\n}\n\n// TODO: Fork the entire transform function so we can simply regex the file contents for keywords instead.\nfunction pruneCustomTransformOptions(\n filePath: string,\n transformOptions: TransformOptions\n): TransformOptions {\n // Normalize the filepath for cross platform checking.\n filePath = filePath.split(path.sep).join('/');\n\n if (\n transformOptions.customTransformOptions?.dom &&\n // The only generated file that needs the dom root is `expo/dom/entry.js`\n !filePath.match(/expo\\/dom\\/entry\\.js$/)\n ) {\n // Clear the dom root option if we aren't transforming the magic entry file, this ensures\n // that cached artifacts from other DOM component bundles can be reused.\n transformOptions.customTransformOptions.dom = 'true';\n }\n\n if (\n transformOptions.customTransformOptions?.routerRoot &&\n // The router root is used all over expo-router (`process.env.EXPO_ROUTER_ABS_APP_ROOT`, `process.env.EXPO_ROUTER_APP_ROOT`) so we'll just ignore the entire package.\n !(filePath.match(/\\/expo-router\\/_ctx/) || filePath.match(/\\/expo-router\\/build\\//))\n ) {\n // Set to the default value.\n transformOptions.customTransformOptions.routerRoot = 'app';\n }\n\n if (\n transformOptions.customTransformOptions?.asyncRoutes &&\n // The async routes settings are also used in `expo-router/_ctx.ios.js` (and other platform variants) via `process.env.EXPO_ROUTER_IMPORT_MODE`\n !(filePath.match(/\\/expo-router\\/_ctx/) || filePath.match(/\\/expo-router\\/build\\//))\n ) {\n delete transformOptions.customTransformOptions.asyncRoutes;\n }\n\n if (\n transformOptions.customTransformOptions?.clientBoundaries &&\n // The client boundaries are only used in `expo/virtual/rsc.js` for production RSC exports.\n !filePath.match(/\\/expo\\/virtual\\/rsc\\.js$/)\n ) {\n delete transformOptions.customTransformOptions.clientBoundaries;\n }\n\n return transformOptions;\n}\n\n/**\n * Simplify and communicate if Metro is running without watching file updates,.\n * Exposed for testing.\n */\nexport function isWatchEnabled() {\n if (env.CI) {\n Log.log(\n chalk`Metro is running in CI mode, reloads are disabled. Remove {bold CI=true} to enable watch mode.`\n );\n }\n\n return !env.CI;\n}\n"],"names":["instantiateMetroAsync","isWatchEnabled","loadMetroConfigAsync","LogRespectingTerminal","Terminal","constructor","stream","ttyPrint","sendLog","msg","length","log","format","args","flush","console","info","terminal","process","stdout","projectRoot","options","exp","isExporting","getMetroBundler","config","reportEvent","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","env","EXPO_USE_STICKY_RESOLVER","serverActionsEnabled","reactServerFunctions","EXPO_UNSTABLE_SERVER_FUNCTIONS","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","isReactCanaryEnabled","reactCanary","serverRoot","getMetroServerRoot","terminalReporter","MetroTerminalReporter","configPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resolvedConfig","resolveConfig","defaultConfig","getDefaultConfig","isEmpty","mergeConfig","resetCache","maxWorkers","server","port","watchFolders","includes","reporter","update","event","globalThis","__requireCycleIgnorePatterns","resolver","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reactCompiler","Log","chalk","gray","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","warn","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isAutolinkingResolverEnabled","isFastResolverEnabled","EXPO_USE_FAST_RESOLVER","isNamedRequiresEnabled","isReactServerComponentsEnabled","setEventReporter","logger","metroBundler","getConfig","skipSDKVersionRequirement","metroConfig","metro","getBundler","middleware","messagesSocket","eventsSocket","websocketEndpoints","createMetroMiddleware","serverBaseUrl","getUrlCreator","constructUrl","scheme","hostType","prependMiddleware","createCorsMiddleware","debugMiddleware","debugWebsocketEndpoints","createDebugMiddleware","Object","assign","use","createJsInspectorMiddleware","customEnhanceMiddleware","enhanceMiddleware","metroMiddleware","devtoolsWebsocketEndpoints","createDevToolsPluginWebsocketEndpoint","attachAtlasAsync","resetAtlasFile","hmrServer","runServer","watch","mockServer","originalTransformFile","transformFile","bind","filePath","transformOptions","fileBuffer","pruneCustomTransformOptions","customTransformOptions","__proto__","reportMetroEvent","_getSortedModules","graph","modules","dependencies","values","ctx","platform","environment","module","_createModuleId","path","sort","a","b","hmrJSBundle","require","default","_prepareMessage","group","changeEvent","isInitialUpdate","revision","revPromise","_bundler","getRevision","revisionId","type","body","formatBundlingError","RevisionNotFoundError","point","delta","updateGraph","_clientGroups","delete","id","client","clients","revisionIds","filter","push","set","moduleIdContext","hmrUpdate","clientUrl","createModuleId","moduleId","includeAsyncPaths","graphOptions","lazy","_config","unstable_serverRoot","error","formattedError","messageSocket","split","sep","join","dom","match","routerRoot","asyncRoutes","clientBoundaries","CI"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/instantiateMetro.ts"],"sourcesContent":["import { type ExpoConfig, getConfig } from '@expo/config';\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport type { Reporter } from '@expo/metro/metro';\nimport type Bundler from '@expo/metro/metro/Bundler';\nimport type { ReadOnlyGraph } from '@expo/metro/metro/DeltaBundler';\nimport type { TransformOptions } from '@expo/metro/metro/DeltaBundler/Worker';\nimport MetroHmrServer, { Client as MetroHmrClient } from '@expo/metro/metro/HmrServer';\nimport RevisionNotFoundError from '@expo/metro/metro/IncrementalBundler/RevisionNotFoundError';\nimport type MetroServer from '@expo/metro/metro/Server';\nimport formatBundlingError from '@expo/metro/metro/lib/formatBundlingError';\nimport { mergeConfig, resolveConfig, type ConfigT } from '@expo/metro/metro-config';\nimport { Terminal } from '@expo/metro/metro-core';\nimport { getDefaultConfig } from '@expo/metro-config';\nimport chalk from 'chalk';\nimport http from 'http';\nimport path from 'path';\n\nimport { createDevToolsPluginWebsocketEndpoint } from './DevToolsPluginWebsocketEndpoint';\nimport { MetroBundlerDevServer } from './MetroBundlerDevServer';\nimport { MetroTerminalReporter } from './MetroTerminalReporter';\nimport { attachAtlasAsync } from './debugging/attachAtlas';\nimport { createDebugMiddleware } from './debugging/createDebugMiddleware';\nimport { createMetroMiddleware } from './dev-server/createMetroMiddleware';\nimport { runServer } from './runServer-fork';\nimport { withMetroMultiPlatformAsync } from './withMetroMultiPlatform';\nimport { Log } from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { createCorsMiddleware } from '../middleware/CorsMiddleware';\nimport { createJsInspectorMiddleware } from '../middleware/inspector/createJsInspectorMiddleware';\nimport { prependMiddleware } from '../middleware/mutations';\nimport { getPlatformBundlers } from '../platformBundlers';\n\n// From expo/dev-server but with ability to use custom logger.\ntype MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\n// Wrap terminal and polyfill console.log so we can log during bundling without breaking the indicator.\nclass LogRespectingTerminal extends Terminal {\n constructor(stream: import('node:net').Socket | import('node:stream').Writable) {\n super(stream, { ttyPrint: true });\n\n const sendLog = (...msg: any[]) => {\n if (!msg.length) {\n this.log('');\n } else {\n const [format, ...args] = msg;\n this.log(format, ...args);\n }\n // Flush the logs to the terminal immediately so logs at the end of the process are not lost.\n this.flush();\n };\n\n console.log = sendLog;\n console.info = sendLog;\n }\n}\n\n// Share one instance of Terminal for all instances of Metro.\nconst terminal = new LogRespectingTerminal(process.stdout);\n\ninterface LoadMetroConfigOptions {\n maxWorkers?: number;\n port?: number;\n reporter?: Reporter;\n resetCache?: boolean;\n}\n\nexport async function loadMetroConfigAsync(\n projectRoot: string,\n options: LoadMetroConfigOptions,\n {\n exp,\n isExporting,\n getMetroBundler,\n }: { exp: ExpoConfig; isExporting: boolean; getMetroBundler: () => Bundler }\n) {\n let reportEvent: ((event: any) => void) | undefined;\n\n const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? env.EXPO_USE_STICKY_RESOLVER;\n\n const serverActionsEnabled =\n exp.experiments?.reactServerFunctions ?? env.EXPO_UNSTABLE_SERVER_FUNCTIONS;\n\n if (serverActionsEnabled) {\n process.env.EXPO_UNSTABLE_SERVER_FUNCTIONS = '1';\n }\n\n // NOTE: Enable all the experimental Metro flags when RSC is enabled.\n if (exp.experiments?.reactServerComponentRoutes || serverActionsEnabled) {\n process.env.EXPO_USE_METRO_REQUIRE = '1';\n }\n\n const isReactCanaryEnabled =\n (exp.experiments?.reactServerComponentRoutes ||\n serverActionsEnabled ||\n exp.experiments?.reactCanary) ??\n false;\n\n const serverRoot = getMetroServerRoot(projectRoot);\n const terminalReporter = new MetroTerminalReporter(serverRoot, terminal);\n\n // NOTE: Allow external tools to override the metro config. This is considered internal and unstable\n const configPath = env.EXPO_OVERRIDE_METRO_CONFIG ?? undefined;\n const resolvedConfig = await resolveConfig(configPath, projectRoot);\n const defaultConfig = getDefaultConfig(projectRoot);\n\n let config: ConfigT = resolvedConfig.isEmpty\n ? defaultConfig\n : await mergeConfig(defaultConfig, resolvedConfig.config);\n\n // Set the watchfolders to include the projectRoot, as Metro assumes this\n // Force-override the reporter\n config = {\n ...config,\n\n // See: `overrideConfigWithArguments` https://github.com/facebook/metro/blob/5059e26/packages/metro-config/src/loadConfig.js#L274-L339\n // Compare to `LoadOptions` type (disregard `reporter` as we don't expose this)\n resetCache: !!options.resetCache,\n maxWorkers: options.maxWorkers ?? config.maxWorkers,\n server: {\n ...config.server,\n port: options.port ?? config.server.port,\n },\n\n watchFolders: !config.watchFolders.includes(config.projectRoot)\n ? [config.projectRoot, ...config.watchFolders]\n : config.watchFolders,\n reporter: {\n update(event) {\n terminalReporter.update(event);\n if (reportEvent) {\n reportEvent(event);\n }\n },\n },\n };\n\n // @ts-expect-error: Set the global require cycle ignore patterns for SSR bundles. This won't work with custom global prefixes, but we don't use those.\n globalThis.__requireCycleIgnorePatterns = config.resolver?.requireCycleIgnorePatterns;\n\n if (isExporting) {\n // This token will be used in the asset plugin to ensure the path is correct for writing locally.\n // @ts-expect-error: typed as readonly.\n config.transformer.publicPath = `/assets?export_path=${\n (exp.experiments?.baseUrl ?? '') + '/assets'\n }`;\n } else {\n // @ts-expect-error: typed as readonly\n config.transformer.publicPath = '/assets/?unstable_path=.';\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n if (exp.experiments?.reactCompiler) {\n Log.log(chalk.gray`React Compiler enabled`);\n }\n\n if (env.EXPO_UNSTABLE_TREE_SHAKING && !env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n throw new CommandError(\n 'EXPO_UNSTABLE_TREE_SHAKING requires EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH to be enabled.'\n );\n }\n\n if (env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental fast resolver is enabled.`);\n }\n if (env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n Log.warn(`Experimental bundle optimization is enabled.`);\n }\n if (env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental tree shaking is enabled.`);\n }\n if (autolinkingModuleResolutionEnabled) {\n Log.warn(`Experimental Expo Autolinking module resolver is enabled.`);\n }\n\n if (serverActionsEnabled) {\n Log.warn(\n `React Server Functions (beta) are enabled. Route rendering mode: ${exp.experiments?.reactServerComponentRoutes ? 'server' : 'client'}`\n );\n }\n\n config = await withMetroMultiPlatformAsync(projectRoot, {\n config,\n exp,\n platformBundlers,\n isTsconfigPathsEnabled: exp.experiments?.tsconfigPaths ?? true,\n isAutolinkingResolverEnabled: autolinkingModuleResolutionEnabled,\n isFastResolverEnabled: env.EXPO_USE_FAST_RESOLVER,\n isExporting,\n isReactCanaryEnabled,\n isNamedRequiresEnabled: env.EXPO_USE_METRO_REQUIRE,\n isReactServerComponentsEnabled: !!exp.experiments?.reactServerComponentRoutes,\n getMetroBundler,\n });\n\n return {\n config,\n setEventReporter: (logger: (event: any) => void) => (reportEvent = logger),\n reporter: terminalReporter,\n };\n}\n\n/** The most generic possible setup for Metro bundler. */\nexport async function instantiateMetroAsync(\n metroBundler: MetroBundlerDevServer,\n options: LoadMetroConfigOptions,\n {\n isExporting,\n exp = getConfig(metroBundler.projectRoot, {\n skipSDKVersionRequirement: true,\n }).exp,\n }: { isExporting: boolean; exp?: ExpoConfig }\n): Promise<{\n metro: MetroServer;\n hmrServer: MetroHmrServer<MetroHmrClient> | null;\n server: http.Server;\n middleware: any;\n messageSocket: MessageSocket;\n}> {\n const projectRoot = metroBundler.projectRoot;\n\n const {\n config: metroConfig,\n setEventReporter,\n reporter,\n } = await loadMetroConfigAsync(projectRoot, options, {\n exp,\n isExporting,\n getMetroBundler() {\n return metro.getBundler().getBundler();\n },\n });\n\n // Create the core middleware stack for Metro, including websocket listeners\n const { middleware, messagesSocket, eventsSocket, websocketEndpoints } =\n createMetroMiddleware(metroConfig);\n\n // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)\n const serverBaseUrl = metroBundler\n .getUrlCreator()\n .constructUrl({ scheme: 'http', hostType: 'localhost' });\n\n if (!isExporting) {\n // Enable correct CORS headers for Expo Router features\n prependMiddleware(middleware, createCorsMiddleware(exp));\n\n // Enable debug middleware for CDP-related debugging\n const { debugMiddleware, debugWebsocketEndpoints } = createDebugMiddleware({\n projectRoot: metroBundler.projectRoot,\n serverBaseUrl,\n reporter,\n });\n Object.assign(websocketEndpoints, debugWebsocketEndpoints);\n middleware.use(debugMiddleware);\n middleware.use('/_expo/debugger', createJsInspectorMiddleware());\n\n // TODO(cedric): `enhanceMiddleware` is deprecated, but is currently used to unify the middleware stacks\n // See: https://github.com/facebook/metro/commit/22e85fde85ec454792a1b70eba4253747a2587a9\n // See: https://github.com/facebook/metro/commit/d0d554381f119bb80ab09dbd6a1d310b54737e52\n const customEnhanceMiddleware = metroConfig.server.enhanceMiddleware;\n // @ts-expect-error: can't mutate readonly config\n metroConfig.server.enhanceMiddleware = (metroMiddleware: any, server: MetroServer) => {\n if (customEnhanceMiddleware) {\n metroMiddleware = customEnhanceMiddleware(metroMiddleware, server);\n }\n return middleware.use(metroMiddleware);\n };\n\n const devtoolsWebsocketEndpoints = createDevToolsPluginWebsocketEndpoint();\n Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);\n }\n\n // Attach Expo Atlas if enabled\n await attachAtlasAsync({\n isExporting,\n exp,\n projectRoot,\n middleware,\n metroConfig,\n // NOTE(cedric): reset the Atlas file once, and reuse it for static exports\n resetAtlasFile: isExporting,\n });\n\n const { server, hmrServer, metro } = await runServer(\n metroBundler,\n metroConfig,\n {\n websocketEndpoints,\n watch: !isExporting && isWatchEnabled(),\n },\n {\n mockServer: isExporting,\n }\n );\n\n // Patch transform file to remove inconvenient customTransformOptions which are only used in single well-known files.\n const originalTransformFile = metro\n .getBundler()\n .getBundler()\n .transformFile.bind(metro.getBundler().getBundler());\n\n metro.getBundler().getBundler().transformFile = async function (\n filePath: string,\n transformOptions: TransformOptions,\n fileBuffer?: Buffer\n ) {\n return originalTransformFile(\n filePath,\n pruneCustomTransformOptions(\n filePath,\n // Clone the options so we don't mutate the original.\n {\n ...transformOptions,\n customTransformOptions: {\n __proto__: null,\n ...transformOptions.customTransformOptions,\n },\n }\n ),\n fileBuffer\n );\n };\n\n setEventReporter(eventsSocket.reportMetroEvent);\n\n // This function ensures that modules in source maps are sorted in the same\n // order as in a plain JS bundle.\n metro._getSortedModules = function (this: MetroServer, graph: ReadOnlyGraph) {\n const modules = [...graph.dependencies.values()];\n\n const ctx = {\n platform: graph.transformOptions.platform,\n environment: graph.transformOptions.customTransformOptions?.environment,\n };\n // Assign IDs to modules in a consistent order\n for (const module of modules) {\n // @ts-expect-error\n this._createModuleId(module.path, ctx);\n }\n // Sort by IDs\n return modules.sort(\n // @ts-expect-error\n (a, b) => this._createModuleId(a.path, ctx) - this._createModuleId(b.path, ctx)\n );\n };\n\n if (hmrServer) {\n let hmrJSBundle:\n | typeof import('@expo/metro-config/build/serializer/fork/hmrJSBundle').default\n | typeof import('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle').default;\n\n try {\n hmrJSBundle = require('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n } catch {\n // TODO: Add fallback for monorepo tests up until the fork is merged.\n Log.warn('Failed to load HMR serializer from @expo/metro-config, using fallback version.');\n hmrJSBundle = require('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle');\n }\n\n // Patch HMR Server to send more info to the `_createModuleId` function for deterministic module IDs and add support for serializing HMR updates the same as all other bundles.\n hmrServer._prepareMessage = async function (\n this: MetroHmrServer<MetroHmrClient>,\n group,\n options,\n changeEvent\n ) {\n // Fork of https://github.com/facebook/metro/blob/3b3e0aaf725cfa6907bf2c8b5fbc0da352d29efe/packages/metro/src/HmrServer.js#L327-L393\n // with patch for `_createModuleId`.\n const logger = !options.isInitialUpdate ? changeEvent?.logger : null;\n try {\n const revPromise = this._bundler.getRevision(group.revisionId);\n if (!revPromise) {\n return {\n type: 'error',\n body: formatBundlingError(new RevisionNotFoundError(group.revisionId)),\n };\n }\n logger?.point('updateGraph_start');\n const { revision, delta } = await this._bundler.updateGraph(await revPromise, false);\n logger?.point('updateGraph_end');\n this._clientGroups.delete(group.revisionId);\n group.revisionId = revision.id;\n for (const client of group.clients) {\n client.revisionIds = client.revisionIds.filter(\n (revisionId) => revisionId !== group.revisionId\n );\n client.revisionIds.push(revision.id);\n }\n this._clientGroups.set(group.revisionId, group);\n logger?.point('serialize_start');\n // NOTE(EvanBacon): This is the patch\n const moduleIdContext = {\n platform: revision.graph.transformOptions.platform,\n environment: revision.graph.transformOptions.customTransformOptions?.environment,\n };\n const hmrUpdate = hmrJSBundle(delta, revision.graph, {\n clientUrl: group.clientUrl,\n // NOTE(EvanBacon): This is also the patch\n createModuleId: (moduleId: string) => {\n // @ts-expect-error\n return this._createModuleId(moduleId, moduleIdContext);\n },\n includeAsyncPaths: group.graphOptions.lazy,\n projectRoot: this._config.projectRoot,\n serverRoot: this._config.server.unstable_serverRoot ?? this._config.projectRoot,\n });\n logger?.point('serialize_end');\n return {\n type: 'update',\n body: {\n revisionId: revision.id,\n isInitialUpdate: options.isInitialUpdate,\n ...hmrUpdate,\n },\n };\n } catch (error: any) {\n const formattedError = formatBundlingError(error);\n this._config.reporter.update({\n type: 'bundling_error',\n error,\n });\n return {\n type: 'error',\n body: formattedError,\n };\n }\n };\n }\n\n return {\n metro,\n hmrServer,\n server,\n middleware,\n messageSocket: messagesSocket,\n };\n}\n\n// TODO: Fork the entire transform function so we can simply regex the file contents for keywords instead.\nfunction pruneCustomTransformOptions(\n filePath: string,\n transformOptions: TransformOptions\n): TransformOptions {\n // Normalize the filepath for cross platform checking.\n filePath = filePath.split(path.sep).join('/');\n\n if (\n transformOptions.customTransformOptions?.dom &&\n // The only generated file that needs the dom root is `expo/dom/entry.js`\n !filePath.match(/expo\\/dom\\/entry\\.js$/)\n ) {\n // Clear the dom root option if we aren't transforming the magic entry file, this ensures\n // that cached artifacts from other DOM component bundles can be reused.\n transformOptions.customTransformOptions.dom = 'true';\n }\n\n if (\n transformOptions.customTransformOptions?.routerRoot &&\n // The router root is used all over expo-router (`process.env.EXPO_ROUTER_ABS_APP_ROOT`, `process.env.EXPO_ROUTER_APP_ROOT`) so we'll just ignore the entire package.\n !(filePath.match(/\\/expo-router\\/_ctx/) || filePath.match(/\\/expo-router\\/build\\//))\n ) {\n // Set to the default value.\n transformOptions.customTransformOptions.routerRoot = 'app';\n }\n\n if (\n transformOptions.customTransformOptions?.asyncRoutes &&\n // The async routes settings are also used in `expo-router/_ctx.ios.js` (and other platform variants) via `process.env.EXPO_ROUTER_IMPORT_MODE`\n !(filePath.match(/\\/expo-router\\/_ctx/) || filePath.match(/\\/expo-router\\/build\\//))\n ) {\n delete transformOptions.customTransformOptions.asyncRoutes;\n }\n\n if (\n transformOptions.customTransformOptions?.clientBoundaries &&\n // The client boundaries are only used in `expo/virtual/rsc.js` for production RSC exports.\n !filePath.match(/\\/expo\\/virtual\\/rsc\\.js$/)\n ) {\n delete transformOptions.customTransformOptions.clientBoundaries;\n }\n\n return transformOptions;\n}\n\n/**\n * Simplify and communicate if Metro is running without watching file updates,.\n * Exposed for testing.\n */\nexport function isWatchEnabled() {\n if (env.CI) {\n Log.log(\n chalk`Metro is running in CI mode, reloads are disabled. Remove {bold CI=true} to enable watch mode.`\n );\n }\n\n return !env.CI;\n}\n"],"names":["instantiateMetroAsync","isWatchEnabled","loadMetroConfigAsync","LogRespectingTerminal","Terminal","constructor","stream","ttyPrint","sendLog","msg","length","log","format","args","flush","console","info","terminal","process","stdout","projectRoot","options","exp","isExporting","getMetroBundler","config","reportEvent","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","env","EXPO_USE_STICKY_RESOLVER","serverActionsEnabled","reactServerFunctions","EXPO_UNSTABLE_SERVER_FUNCTIONS","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","isReactCanaryEnabled","reactCanary","serverRoot","getMetroServerRoot","terminalReporter","MetroTerminalReporter","configPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resolvedConfig","resolveConfig","defaultConfig","getDefaultConfig","isEmpty","mergeConfig","resetCache","maxWorkers","server","port","watchFolders","includes","reporter","update","event","globalThis","__requireCycleIgnorePatterns","resolver","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reactCompiler","Log","chalk","gray","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","warn","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isAutolinkingResolverEnabled","isFastResolverEnabled","EXPO_USE_FAST_RESOLVER","isNamedRequiresEnabled","isReactServerComponentsEnabled","setEventReporter","logger","metroBundler","getConfig","skipSDKVersionRequirement","metroConfig","metro","getBundler","middleware","messagesSocket","eventsSocket","websocketEndpoints","createMetroMiddleware","serverBaseUrl","getUrlCreator","constructUrl","scheme","hostType","prependMiddleware","createCorsMiddleware","debugMiddleware","debugWebsocketEndpoints","createDebugMiddleware","Object","assign","use","createJsInspectorMiddleware","customEnhanceMiddleware","enhanceMiddleware","metroMiddleware","devtoolsWebsocketEndpoints","createDevToolsPluginWebsocketEndpoint","attachAtlasAsync","resetAtlasFile","hmrServer","runServer","watch","mockServer","originalTransformFile","transformFile","bind","filePath","transformOptions","fileBuffer","pruneCustomTransformOptions","customTransformOptions","__proto__","reportMetroEvent","_getSortedModules","graph","modules","dependencies","values","ctx","platform","environment","module","_createModuleId","path","sort","a","b","hmrJSBundle","require","default","_prepareMessage","group","changeEvent","isInitialUpdate","revision","revPromise","_bundler","getRevision","revisionId","type","body","formatBundlingError","RevisionNotFoundError","point","delta","updateGraph","_clientGroups","delete","id","client","clients","revisionIds","filter","push","set","moduleIdContext","hmrUpdate","clientUrl","createModuleId","moduleId","includeAsyncPaths","graphOptions","lazy","_config","unstable_serverRoot","error","formattedError","messageSocket","split","sep","join","dom","match","routerRoot","asyncRoutes","clientBoundaries","CI"],"mappings":"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"}
|
|
@@ -33,7 +33,7 @@ class FetchClient {
|
|
|
33
33
|
this.headers = {
|
|
34
34
|
accept: 'application/json',
|
|
35
35
|
'content-type': 'application/json',
|
|
36
|
-
'user-agent': `expo-cli/${"54.0.
|
|
36
|
+
'user-agent': `expo-cli/${"54.0.24"}`,
|
|
37
37
|
authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
|
|
38
38
|
};
|
|
39
39
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/cli",
|
|
3
|
-
"version": "54.0.
|
|
3
|
+
"version": "54.0.24",
|
|
4
4
|
"description": "The Expo CLI",
|
|
5
5
|
"main": "build/bin/cli",
|
|
6
6
|
"bin": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@expo/image-utils": "^0.8.8",
|
|
51
51
|
"@expo/json-file": "^10.0.8",
|
|
52
52
|
"@expo/metro": "~54.2.0",
|
|
53
|
-
"@expo/metro-config": "~54.0.
|
|
53
|
+
"@expo/metro-config": "~54.0.15",
|
|
54
54
|
"@expo/osascript": "^2.3.8",
|
|
55
55
|
"@expo/package-manager": "^1.9.10",
|
|
56
56
|
"@expo/plist": "^0.4.8",
|
|
@@ -73,16 +73,16 @@
|
|
|
73
73
|
"connect": "^3.7.0",
|
|
74
74
|
"debug": "^4.3.4",
|
|
75
75
|
"env-editor": "^0.4.1",
|
|
76
|
-
"expo-server": "^1.0.
|
|
76
|
+
"expo-server": "^1.0.6",
|
|
77
77
|
"freeport-async": "^2.0.0",
|
|
78
78
|
"getenv": "^2.0.0",
|
|
79
79
|
"glob": "^13.0.0",
|
|
80
|
-
"lan-network": "^0.1
|
|
80
|
+
"lan-network": "^0.2.1",
|
|
81
81
|
"minimatch": "^9.0.0",
|
|
82
82
|
"node-forge": "^1.3.3",
|
|
83
83
|
"npm-package-arg": "^11.0.0",
|
|
84
84
|
"ora": "^3.4.0",
|
|
85
|
-
"picomatch": "^
|
|
85
|
+
"picomatch": "^4.0.3",
|
|
86
86
|
"pretty-bytes": "^5.6.0",
|
|
87
87
|
"pretty-format": "^29.7.0",
|
|
88
88
|
"progress": "^2.0.3",
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"@types/klaw-sync": "^6.0.0",
|
|
145
145
|
"@types/node": "^22.14.0",
|
|
146
146
|
"@types/npm-package-arg": "^6.1.0",
|
|
147
|
-
"@types/picomatch": "^
|
|
147
|
+
"@types/picomatch": "^4.0.2",
|
|
148
148
|
"@types/progress": "^2.0.5",
|
|
149
149
|
"@types/prompts": "^2.0.6",
|
|
150
150
|
"@types/resolve": "^1.20.2",
|
|
@@ -169,5 +169,5 @@
|
|
|
169
169
|
"tree-kill": "^1.2.2",
|
|
170
170
|
"tsd": "^0.28.1"
|
|
171
171
|
},
|
|
172
|
-
"gitHead": "
|
|
172
|
+
"gitHead": "dd4e87727c4ef32ac5d8a7b5a42fd80da254140f"
|
|
173
173
|
}
|