@expo/cli 0.23.1 → 0.23.3

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 CHANGED
@@ -123,7 +123,7 @@ const args = (0, _arg().default)({
123
123
  });
124
124
  if (args['--version']) {
125
125
  // Version is added in the build script.
126
- console.log("0.23.1");
126
+ console.log("0.23.3");
127
127
  process.exit(0);
128
128
  }
129
129
  if (args['--non-interactive']) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/export/persistMetroAssets.ts"],"sourcesContent":["/**\n * Copyright © 2023 650 Industries.\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * Based on the community asset persisting for Metro but with base path and web support:\n * https://github.com/facebook/react-native/blob/d6e0bc714ad4d215ede4949d3c4f44af6dea5dd3/packages/community-cli-plugin/src/commands/bundle/saveAssets.js#L1\n */\nimport fs from 'fs';\nimport type { AssetData } from 'metro';\nimport path from 'path';\n\nimport { drawableFileTypes, getAssetLocalPath } from './metroAssetLocalPath';\nimport { ExportAssetMap } from './saveAssets';\nimport { Log } from '../log';\n\nfunction cleanAssetCatalog(catalogDir: string): void {\n const files = fs.readdirSync(catalogDir).filter((file) => file.endsWith('.imageset'));\n for (const file of files) {\n fs.rmSync(path.join(catalogDir, file));\n }\n}\n\nexport async function persistMetroAssetsAsync(\n projectRoot: string,\n assets: readonly AssetData[],\n {\n platform,\n outputDirectory,\n baseUrl,\n iosAssetCatalogDirectory,\n files,\n }: {\n platform: string;\n outputDirectory: string;\n baseUrl?: string;\n iosAssetCatalogDirectory?: string;\n files?: ExportAssetMap;\n }\n) {\n if (outputDirectory == null) {\n Log.warn('Assets destination folder is not set, skipping...');\n return;\n }\n\n // For iOS, we need to ensure that the outputDirectory exists.\n // The bundle code and images build phase script always tries to access this folder\n if (platform === 'ios' && !fs.existsSync(outputDirectory)) {\n fs.mkdirSync(outputDirectory, { recursive: true });\n }\n\n let assetsToCopy: AssetData[] = [];\n\n // TODO: Use `files` as below to defer writing files\n if (platform === 'ios' && iosAssetCatalogDirectory != null) {\n // Use iOS Asset Catalog for images. This will allow Apple app thinning to\n // remove unused scales from the optimized bundle.\n const catalogDir = path.join(iosAssetCatalogDirectory, 'RNAssets.xcassets');\n if (!fs.existsSync(catalogDir)) {\n Log.error(\n `Could not find asset catalog 'RNAssets.xcassets' in ${iosAssetCatalogDirectory}. Make sure to create it if it does not exist.`\n );\n return;\n }\n\n Log.log('Adding images to asset catalog', catalogDir);\n cleanAssetCatalog(catalogDir);\n for (const asset of assets) {\n if (isCatalogAsset(asset)) {\n const imageSet = getImageSet(\n catalogDir,\n asset,\n filterPlatformAssetScales(platform, asset.scales)\n );\n writeImageSet(imageSet);\n } else {\n assetsToCopy.push(asset);\n }\n }\n Log.log('Done adding images to asset catalog');\n } else {\n assetsToCopy = [...assets];\n }\n if (platform === 'android') {\n await createKeepFileAsync(assetsToCopy, outputDirectory);\n }\n\n const batches: Record<string, string> = {};\n\n for (const asset of assetsToCopy) {\n const validScales = new Set(filterPlatformAssetScales(platform, asset.scales));\n for (let idx = 0; idx < asset.scales.length; idx++) {\n const scale = asset.scales[idx];\n if (validScales.has(scale)) {\n const src = asset.files[idx];\n const dest = getAssetLocalPath(asset, { platform, scale, baseUrl });\n if (files) {\n const data = await fs.promises.readFile(src);\n files.set(dest, {\n contents: data,\n assetId: getAssetIdForLogGrouping(projectRoot, asset),\n targetDomain: platform === 'web' ? 'client' : undefined,\n });\n } else {\n batches[src] = path.join(outputDirectory, dest);\n }\n }\n }\n }\n\n if (!files) {\n await copyInBatchesAsync(batches);\n }\n}\n\nexport async function createKeepFileAsync(\n assets: AssetData[],\n outputDirectory: string\n): Promise<void> {\n if (!assets.length) {\n return;\n }\n const assetsList = [];\n for (const asset of assets) {\n const prefix = drawableFileTypes.has(asset.type) ? 'drawable' : 'raw';\n assetsList.push(`@${prefix}/${getResourceIdentifier(asset)}`);\n }\n const keepPath = path.join(outputDirectory, 'raw/keep.xml');\n const content = `<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:keep=\"${assetsList.join(',')}\" />`;\n await fs.promises.mkdir(path.dirname(keepPath), { recursive: true });\n await fs.promises.writeFile(keepPath, content);\n}\n\nexport function getAssetIdForLogGrouping(\n projectRoot: string,\n asset: Partial<Pick<AssetData, 'fileSystemLocation' | 'name' | 'type'>>\n): string | undefined {\n return 'fileSystemLocation' in asset && asset.fileSystemLocation != null && asset.name != null\n ? path.relative(projectRoot, path.join(asset.fileSystemLocation, asset.name)) +\n (asset.type ? '.' + asset.type : '')\n : undefined;\n}\n\nfunction writeImageSet(imageSet: ImageSet): void {\n fs.mkdirSync(imageSet.baseUrl, { recursive: true });\n\n for (const file of imageSet.files) {\n const dest = path.join(imageSet.baseUrl, file.name);\n fs.copyFileSync(file.src, dest);\n }\n\n fs.writeFileSync(\n path.join(imageSet.baseUrl, 'Contents.json'),\n JSON.stringify({\n images: imageSet.files.map((file) => ({\n filename: file.name,\n idiom: 'universal',\n scale: `${file.scale}x`,\n })),\n info: {\n author: 'expo',\n version: 1,\n },\n })\n );\n}\n\nfunction isCatalogAsset(asset: Pick<AssetData, 'type'>): boolean {\n return asset.type === 'png' || asset.type === 'jpg' || asset.type === 'jpeg';\n}\n\ntype ImageSet = {\n baseUrl: string;\n files: { name: string; src: string; scale: number }[];\n};\n\nfunction getImageSet(\n catalogDir: string,\n asset: Pick<AssetData, 'httpServerLocation' | 'name' | 'type' | 'files'>,\n scales: number[]\n): ImageSet {\n const fileName = getResourceIdentifier(asset);\n return {\n baseUrl: path.join(catalogDir, `${fileName}.imageset`),\n files: scales.map((scale, idx) => {\n const suffix = scale === 1 ? '' : `@${scale}x`;\n return {\n name: `${fileName + suffix}.${asset.type}`,\n scale,\n src: asset.files[idx],\n };\n }),\n };\n}\n\nexport function copyInBatchesAsync(filesToCopy: Record<string, string>) {\n const queue = Object.keys(filesToCopy);\n if (queue.length === 0) {\n return;\n }\n\n Log.log(`Copying ${queue.length} asset files`);\n return new Promise<void>((resolve, reject) => {\n const copyNext = (error?: NodeJS.ErrnoException) => {\n if (error) {\n return reject(error);\n }\n if (queue.length) {\n // queue.length === 0 is checked in previous branch, so this is string\n const src = queue.shift() as string;\n const dest = filesToCopy[src];\n copy(src, dest, copyNext);\n } else {\n resolve();\n }\n };\n copyNext();\n });\n}\n\nfunction copy(src: string, dest: string, callback: (error: NodeJS.ErrnoException) => void): void {\n fs.mkdir(path.dirname(dest), { recursive: true }, (err?) => {\n if (err) {\n callback(err);\n return;\n }\n fs.createReadStream(src).pipe(fs.createWriteStream(dest)).on('finish', callback);\n });\n}\n\nconst ALLOWED_SCALES: { [key: string]: number[] } = {\n ios: [1, 2, 3],\n};\n\nexport function filterPlatformAssetScales(platform: string, scales: number[]): number[] {\n const whitelist: number[] = ALLOWED_SCALES[platform];\n if (!whitelist) {\n return scales;\n }\n const result = scales.filter((scale) => whitelist.includes(scale));\n if (!result.length && scales.length) {\n // No matching scale found, but there are some available. Ideally we don't\n // want to be in this situation and should throw, but for now as a fallback\n // let's just use the closest larger image\n const maxScale = whitelist[whitelist.length - 1];\n for (const scale of scales) {\n if (scale > maxScale) {\n result.push(scale);\n break;\n }\n }\n\n // There is no larger scales available, use the largest we have\n if (!result.length) {\n result.push(scales[scales.length - 1]);\n }\n }\n return result;\n}\n\nfunction getResourceIdentifier(asset: Pick<AssetData, 'httpServerLocation' | 'name'>): string {\n const folderPath = getBaseUrl(asset);\n return `${folderPath}/${asset.name}`\n .toLowerCase()\n .replace(/\\//g, '_') // Encode folder structure in file name\n .replace(/([^a-z0-9_])/g, '') // Remove illegal chars\n .replace(/^assets_/, ''); // Remove \"assets_\" prefix\n}\n\nfunction getBaseUrl(asset: Pick<AssetData, 'httpServerLocation'>): string {\n let baseUrl = asset.httpServerLocation;\n if (baseUrl[0] === '/') {\n baseUrl = baseUrl.substring(1);\n }\n return baseUrl;\n}\n"],"names":["copyInBatchesAsync","createKeepFileAsync","filterPlatformAssetScales","getAssetIdForLogGrouping","persistMetroAssetsAsync","cleanAssetCatalog","catalogDir","files","fs","readdirSync","filter","file","endsWith","rmSync","path","join","projectRoot","assets","platform","outputDirectory","baseUrl","iosAssetCatalogDirectory","Log","warn","existsSync","mkdirSync","recursive","assetsToCopy","error","log","asset","isCatalogAsset","imageSet","getImageSet","scales","writeImageSet","push","batches","validScales","Set","idx","length","scale","has","src","dest","getAssetLocalPath","data","promises","readFile","set","contents","assetId","targetDomain","undefined","assetsList","prefix","drawableFileTypes","type","getResourceIdentifier","keepPath","content","mkdir","dirname","writeFile","fileSystemLocation","name","relative","copyFileSync","writeFileSync","JSON","stringify","images","map","filename","idiom","info","author","version","fileName","suffix","filesToCopy","queue","Object","keys","Promise","resolve","reject","copyNext","shift","copy","callback","err","createReadStream","pipe","createWriteStream","on","ALLOWED_SCALES","ios","whitelist","result","includes","maxScale","folderPath","getBaseUrl","toLowerCase","replace","httpServerLocation","substring"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/export/persistMetroAssets.ts"],"sourcesContent":["/**\n * Copyright © 2023 650 Industries.\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * Based on the community asset persisting for Metro but with base path and web support:\n * https://github.com/facebook/react-native/blob/d6e0bc714ad4d215ede4949d3c4f44af6dea5dd3/packages/community-cli-plugin/src/commands/bundle/saveAssets.js#L1\n */\nimport fs from 'fs';\nimport type { AssetData } from 'metro';\nimport path from 'path';\n\nimport { drawableFileTypes, getAssetLocalPath } from './metroAssetLocalPath';\nimport { ExportAssetMap } from './saveAssets';\nimport { Log } from '../log';\n\nfunction cleanAssetCatalog(catalogDir: string): void {\n const files = fs.readdirSync(catalogDir).filter((file) => file.endsWith('.imageset'));\n for (const file of files) {\n fs.rmSync(path.join(catalogDir, file));\n }\n}\n\nexport async function persistMetroAssetsAsync(\n projectRoot: string,\n assets: readonly AssetData[],\n {\n platform,\n outputDirectory,\n baseUrl,\n iosAssetCatalogDirectory,\n files,\n }: {\n platform: string;\n outputDirectory: string;\n baseUrl?: string;\n iosAssetCatalogDirectory?: string;\n files?: ExportAssetMap;\n }\n) {\n if (outputDirectory == null) {\n Log.warn('Assets destination folder is not set, skipping...');\n return;\n }\n\n // For iOS, we need to ensure that the outputDirectory exists.\n // The bundle code and images build phase script always tries to access this folder\n if (platform === 'ios' && !fs.existsSync(outputDirectory)) {\n fs.mkdirSync(outputDirectory, { recursive: true });\n }\n\n let assetsToCopy: AssetData[] = [];\n\n // TODO: Use `files` as below to defer writing files\n if (platform === 'ios' && iosAssetCatalogDirectory != null) {\n // Use iOS Asset Catalog for images. This will allow Apple app thinning to\n // remove unused scales from the optimized bundle.\n const catalogDir = path.join(iosAssetCatalogDirectory, 'RNAssets.xcassets');\n if (!fs.existsSync(catalogDir)) {\n Log.error(\n `Could not find asset catalog 'RNAssets.xcassets' in ${iosAssetCatalogDirectory}. Make sure to create it if it does not exist.`\n );\n return;\n }\n\n Log.log('Adding images to asset catalog', catalogDir);\n cleanAssetCatalog(catalogDir);\n for (const asset of assets) {\n if (isCatalogAsset(asset)) {\n const imageSet = getImageSet(\n catalogDir,\n asset,\n filterPlatformAssetScales(platform, asset.scales)\n );\n writeImageSet(imageSet);\n } else {\n assetsToCopy.push(asset);\n }\n }\n Log.log('Done adding images to asset catalog');\n } else {\n assetsToCopy = [...assets];\n }\n if (platform === 'android') {\n await createKeepFileAsync(assetsToCopy, outputDirectory);\n }\n\n const batches: Record<string, string> = {};\n\n for (const asset of assetsToCopy) {\n const validScales = new Set(filterPlatformAssetScales(platform, asset.scales));\n for (let idx = 0; idx < asset.scales.length; idx++) {\n const scale = asset.scales[idx];\n if (validScales.has(scale)) {\n const src = asset.files[idx];\n const dest = getAssetLocalPath(asset, { platform, scale, baseUrl });\n if (files) {\n const data = await fs.promises.readFile(src);\n files.set(dest, {\n contents: data,\n assetId: getAssetIdForLogGrouping(projectRoot, asset),\n targetDomain: platform === 'web' ? 'client' : undefined,\n });\n } else {\n batches[src] = path.join(outputDirectory, dest);\n }\n }\n }\n }\n\n if (!files) {\n await copyInBatchesAsync(batches);\n }\n}\n\nexport async function createKeepFileAsync(\n assets: AssetData[],\n outputDirectory: string\n): Promise<void> {\n if (!assets.length) {\n return;\n }\n const assetsList = [];\n for (const asset of assets) {\n const prefix = drawableFileTypes.has(asset.type) ? 'drawable' : 'raw';\n assetsList.push(`@${prefix}/${getResourceIdentifier(asset)}`);\n }\n const keepPath = path.join(outputDirectory, 'raw/keep.xml');\n const content = `<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:keep=\"${assetsList.join(',')}\" />`;\n await fs.promises.mkdir(path.dirname(keepPath), { recursive: true });\n await fs.promises.writeFile(keepPath, content);\n}\n\nexport function getAssetIdForLogGrouping(\n projectRoot: string,\n asset: Partial<Pick<AssetData, 'fileSystemLocation' | 'name' | 'type'>>\n): string | undefined {\n return 'fileSystemLocation' in asset && asset.fileSystemLocation != null && asset.name != null\n ? path.relative(projectRoot, path.join(asset.fileSystemLocation, asset.name)) +\n (asset.type ? '.' + asset.type : '')\n : undefined;\n}\n\nfunction writeImageSet(imageSet: ImageSet): void {\n fs.mkdirSync(imageSet.baseUrl, { recursive: true });\n\n for (const file of imageSet.files) {\n const dest = path.join(imageSet.baseUrl, file.name);\n fs.copyFileSync(file.src, dest);\n }\n\n fs.writeFileSync(\n path.join(imageSet.baseUrl, 'Contents.json'),\n JSON.stringify({\n images: imageSet.files.map((file) => ({\n filename: file.name,\n idiom: 'universal',\n scale: `${file.scale}x`,\n })),\n info: {\n author: 'expo',\n version: 1,\n },\n })\n );\n}\n\nfunction isCatalogAsset(asset: Pick<AssetData, 'type'>): boolean {\n return asset.type === 'png' || asset.type === 'jpg' || asset.type === 'jpeg';\n}\n\ntype ImageSet = {\n baseUrl: string;\n files: { name: string; src: string; scale: number }[];\n};\n\nfunction getImageSet(\n catalogDir: string,\n asset: Pick<AssetData, 'httpServerLocation' | 'name' | 'type' | 'files'>,\n scales: number[]\n): ImageSet {\n const fileName = getResourceIdentifier(asset);\n return {\n baseUrl: path.join(catalogDir, `${fileName}.imageset`),\n files: scales.map((scale, idx) => {\n const suffix = scale === 1 ? '' : `@${scale}x`;\n return {\n name: `${fileName + suffix}.${asset.type}`,\n scale,\n src: asset.files[idx],\n };\n }),\n };\n}\n\nexport function copyInBatchesAsync(filesToCopy: Record<string, string>) {\n const queue = Object.keys(filesToCopy);\n if (queue.length === 0) {\n return;\n }\n\n Log.log(`Copying ${queue.length} asset files`);\n return new Promise<void>((resolve, reject) => {\n const copyNext = (error?: NodeJS.ErrnoException) => {\n if (error) {\n return reject(error);\n }\n if (queue.length) {\n // queue.length === 0 is checked in previous branch, so this is string\n const src = queue.shift() as string;\n const dest = filesToCopy[src];\n copy(src, dest, copyNext);\n } else {\n resolve();\n }\n };\n copyNext();\n });\n}\n\nfunction copy(src: string, dest: string, callback: (error?: NodeJS.ErrnoException) => void): void {\n fs.mkdir(path.dirname(dest), { recursive: true }, (err?) => {\n if (err) {\n callback(err);\n return;\n }\n fs.createReadStream(src).pipe(fs.createWriteStream(dest)).on('finish', callback);\n });\n}\n\nconst ALLOWED_SCALES: { [key: string]: number[] } = {\n ios: [1, 2, 3],\n};\n\nexport function filterPlatformAssetScales(platform: string, scales: number[]): number[] {\n const whitelist: number[] = ALLOWED_SCALES[platform];\n if (!whitelist) {\n return scales;\n }\n const result = scales.filter((scale) => whitelist.includes(scale));\n if (!result.length && scales.length) {\n // No matching scale found, but there are some available. Ideally we don't\n // want to be in this situation and should throw, but for now as a fallback\n // let's just use the closest larger image\n const maxScale = whitelist[whitelist.length - 1];\n for (const scale of scales) {\n if (scale > maxScale) {\n result.push(scale);\n break;\n }\n }\n\n // There is no larger scales available, use the largest we have\n if (!result.length) {\n result.push(scales[scales.length - 1]);\n }\n }\n return result;\n}\n\nfunction getResourceIdentifier(asset: Pick<AssetData, 'httpServerLocation' | 'name'>): string {\n const folderPath = getBaseUrl(asset);\n return `${folderPath}/${asset.name}`\n .toLowerCase()\n .replace(/\\//g, '_') // Encode folder structure in file name\n .replace(/([^a-z0-9_])/g, '') // Remove illegal chars\n .replace(/^assets_/, ''); // Remove \"assets_\" prefix\n}\n\nfunction getBaseUrl(asset: Pick<AssetData, 'httpServerLocation'>): string {\n let baseUrl = asset.httpServerLocation;\n if (baseUrl[0] === '/') {\n baseUrl = baseUrl.substring(1);\n }\n return baseUrl;\n}\n"],"names":["copyInBatchesAsync","createKeepFileAsync","filterPlatformAssetScales","getAssetIdForLogGrouping","persistMetroAssetsAsync","cleanAssetCatalog","catalogDir","files","fs","readdirSync","filter","file","endsWith","rmSync","path","join","projectRoot","assets","platform","outputDirectory","baseUrl","iosAssetCatalogDirectory","Log","warn","existsSync","mkdirSync","recursive","assetsToCopy","error","log","asset","isCatalogAsset","imageSet","getImageSet","scales","writeImageSet","push","batches","validScales","Set","idx","length","scale","has","src","dest","getAssetLocalPath","data","promises","readFile","set","contents","assetId","targetDomain","undefined","assetsList","prefix","drawableFileTypes","type","getResourceIdentifier","keepPath","content","mkdir","dirname","writeFile","fileSystemLocation","name","relative","copyFileSync","writeFileSync","JSON","stringify","images","map","filename","idiom","info","author","version","fileName","suffix","filesToCopy","queue","Object","keys","Promise","resolve","reject","copyNext","shift","copy","callback","err","createReadStream","pipe","createWriteStream","on","ALLOWED_SCALES","ios","whitelist","result","includes","maxScale","folderPath","getBaseUrl","toLowerCase","replace","httpServerLocation","substring"],"mappings":"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"}
@@ -8,6 +8,13 @@ Object.defineProperty(exports, "runAndroidAsync", {
8
8
  return runAndroidAsync;
9
9
  }
10
10
  });
11
+ function _config() {
12
+ const data = require("@expo/config");
13
+ _config = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
11
18
  function _chalk() {
12
19
  const data = /*#__PURE__*/ _interop_require_default(require("chalk"));
13
20
  _chalk = function() {
@@ -40,6 +47,7 @@ const _port = require("../../utils/port");
40
47
  const _scheme = require("../../utils/scheme");
41
48
  const _ensureNativeProject = require("../ensureNativeProject");
42
49
  const _hints = require("../hints");
50
+ const _remoteBuildCache = require("../remoteBuildCache");
43
51
  const _startBundler = require("../startBundler");
44
52
  function _interop_require_default(obj) {
45
53
  return obj && obj.__esModule ? obj : {
@@ -48,11 +56,22 @@ function _interop_require_default(obj) {
48
56
  }
49
57
  const debug = require('debug')('expo:run:android');
50
58
  async function runAndroidAsync(projectRoot, { install, ...options }) {
51
- var _options_variant, _this;
59
+ var _options_variant, _projectConfig_exp_experiments, _this, _projectConfig_exp_experiments1;
52
60
  // NOTE: This is a guess, the developer can overwrite with `NODE_ENV`.
53
61
  const isProduction = (_options_variant = options.variant) == null ? void 0 : _options_variant.toLowerCase().endsWith('release');
54
62
  (0, _nodeEnv.setNodeEnv)(isProduction ? 'production' : 'development');
55
63
  require('@expo/env').load(projectRoot);
64
+ const projectConfig = (0, _config().getConfig)(projectRoot);
65
+ if (!options.binary && ((_projectConfig_exp_experiments = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments.remoteBuildCache)) {
66
+ var _projectConfig_exp_experiments2;
67
+ const localPath = await (0, _remoteBuildCache.resolveRemoteBuildCache)(projectRoot, {
68
+ platform: 'android',
69
+ provider: (_projectConfig_exp_experiments2 = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments2.remoteBuildCache.provider
70
+ });
71
+ if (localPath) {
72
+ options.binary = localPath;
73
+ }
74
+ }
56
75
  await (0, _ensureNativeProject.ensureNativeProjectAsync)(projectRoot, {
57
76
  platform: 'android',
58
77
  install
@@ -61,6 +80,7 @@ async function runAndroidAsync(projectRoot, { install, ...options }) {
61
80
  debug('Package name: ' + props.packageName);
62
81
  _log.Log.log('› Building app...');
63
82
  const androidProjectRoot = _path().default.join(projectRoot, 'android');
83
+ let shouldUpdateBuildCache = false;
64
84
  if (!options.binary) {
65
85
  let eagerBundleOptions;
66
86
  if (isProduction) {
@@ -77,6 +97,7 @@ async function runAndroidAsync(projectRoot, { install, ...options }) {
77
97
  architectures: props.architectures,
78
98
  eagerBundleOptions
79
99
  });
100
+ shouldUpdateBuildCache = true;
80
101
  // Ensure the port hasn't become busy during the build.
81
102
  if (props.shouldStartBundler && !await (0, _port.ensurePortAvailabilityAsync)(projectRoot, props)) {
82
103
  props.shouldStartBundler = false;
@@ -111,6 +132,13 @@ async function runAndroidAsync(projectRoot, { install, ...options }) {
111
132
  } else {
112
133
  await manager.stopAsync();
113
134
  }
135
+ if (shouldUpdateBuildCache && ((_projectConfig_exp_experiments1 = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments1.remoteBuildCache)) {
136
+ var _projectConfig_exp_experiments3;
137
+ await (0, _remoteBuildCache.uploadRemoteBuildCache)(projectRoot, {
138
+ platform: 'android',
139
+ provider: (_projectConfig_exp_experiments3 = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments3.remoteBuildCache.provider
140
+ });
141
+ }
114
142
  }
115
143
  async function installAppAsync(androidProjectRoot, props) {
116
144
  // Find the APK file path
@@ -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 { 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 debug('Package name: ' + props.packageName);\n Log.log('› Building app...');\n\n const androidProjectRoot = path.join(projectRoot, 'android');\n\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\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 // 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<AndroidOpenInCustomProps>(\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\nasync function installAppAsync(androidProjectRoot: string, props: ResolvedOptions) {\n // Find the APK file path\n const apkFile = await resolveInstallApkNameAsync(props.device.device, props);\n\n if (apkFile) {\n // Attempt to install the APK from the file path\n const binaryPath = path.join(props.apkVariantDirectory, apkFile);\n Log.log(chalk.gray`\\u203A Installing ${binaryPath}`);\n await props.device.installAppAsync(binaryPath);\n } else {\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}\n"],"names":["runAndroidAsync","debug","require","projectRoot","install","options","isProduction","variant","toLowerCase","endsWith","setNodeEnv","load","ensureNativeProjectAsync","platform","props","resolveOptionsAsync","packageName","Log","log","androidProjectRoot","path","join","binary","eagerBundleOptions","JSON","stringify","exportEagerAsync","dev","assembleAsync","port","appName","buildCache","architectures","shouldStartBundler","ensurePortAvailabilityAsync","manager","startBundlerAsync","scheme","getSchemesForAndroidAsync","headless","binaryPath","fs","existsSync","CommandError","chalk","gray","device","installAppAsync","getDefaultDevServer","openCustomRuntimeAsync","applicationId","customAppId","launchActivity","logProjectLogsLocation","stopAsync","apkFile","resolveInstallApkNameAsync","apkVariantDirectory","installAsync"],"mappings":";;;;+BAoBsBA;;;eAAAA;;;;gEApBJ;;;;;;;gEACH;;;;;;;gEACE;;;;;;uCAE0B;gCACmB;6BAC7B;qBACb;wBAEwB;wBACf;yBACF;sBACiB;wBACF;qCACD;uBACF;8BACL;;;;;;AAElC,MAAMC,QAAQC,QAAQ,SAAS;AAExB,eAAeF,gBAAgBG,WAAmB,EAAE,EAAEC,OAAO,EAAE,GAAGC,SAAkB;QAEpEA,kBA2CV;IA5CX,sEAAsE;IACtE,MAAMC,gBAAeD,mBAAAA,QAAQE,OAAO,qBAAfF,iBAAiBG,WAAW,GAAGC,QAAQ,CAAC;IAC7DC,IAAAA,mBAAU,EAACJ,eAAe,eAAe;IACzCJ,QAAQ,aAAaS,IAAI,CAACR;IAE1B,MAAMS,IAAAA,6CAAwB,EAACT,aAAa;QAAEU,UAAU;QAAWT;IAAQ;IAE3E,MAAMU,QAAQ,MAAMC,IAAAA,mCAAmB,EAACZ,aAAaE;IAErDJ,MAAM,mBAAmBa,MAAME,WAAW;IAC1CC,QAAG,CAACC,GAAG,CAAC;IAER,MAAMC,qBAAqBC,eAAI,CAACC,IAAI,CAAClB,aAAa;IAElD,IAAI,CAACE,QAAQiB,MAAM,EAAE;QACnB,IAAIC;QAEJ,IAAIjB,cAAc;YAChBiB,qBAAqBC,KAAKC,SAAS,CACjC,MAAMC,IAAAA,6BAAgB,EAACvB,aAAa;gBAClCwB,KAAK;gBACLd,UAAU;YACZ;QAEJ;QAEA,MAAMe,IAAAA,qBAAa,EAACT,oBAAoB;YACtCZ,SAASO,MAAMP,OAAO;YACtBsB,MAAMf,MAAMe,IAAI;YAChBC,SAAShB,MAAMgB,OAAO;YACtBC,YAAYjB,MAAMiB,UAAU;YAC5BC,eAAelB,MAAMkB,aAAa;YAClCT;QACF;QAEA,uDAAuD;QACvD,IAAIT,MAAMmB,kBAAkB,IAAI,CAAE,MAAMC,IAAAA,iCAA2B,EAAC/B,aAAaW,QAAS;YACxFA,MAAMmB,kBAAkB,GAAG;QAC7B;IACF;IAEA,MAAME,UAAU,MAAMC,IAAAA,+BAAiB,EAACjC,aAAa;QACnD0B,MAAMf,MAAMe,IAAI;QAChB,sEAAsE;QACtEQ,MAAM,GAAG,QAAA,MAAMC,IAAAA,iCAAyB,EAACnC,iCAAjC,AAAC,KAA+C,CAAC,EAAE;QAC3DoC,UAAU,CAACzB,MAAMmB,kBAAkB;IACrC;IAEA,IAAI5B,QAAQiB,MAAM,EAAE;QAClB,gDAAgD;QAChD,MAAMkB,aAAapB,eAAI,CAACC,IAAI,CAAChB,QAAQiB,MAAM;QAE3C,IAAI,CAACmB,aAAE,CAACC,UAAU,CAACF,aAAa;YAC9B,MAAM,IAAIG,oBAAY,CAAC,CAAC,sDAAsD,EAAEH,YAAY;QAC9F;QACAvB,QAAG,CAACC,GAAG,CAAC0B,gBAAK,CAACC,IAAI,CAAC,kBAAkB,EAAEL,WAAW,CAAC;QACnD,MAAM1B,MAAMgC,MAAM,CAACC,eAAe,CAACP;IACrC,OAAO;QACL,MAAMO,gBAAgB5B,oBAAoBL;IAC5C;IAEA,MAAMqB,QAAQa,mBAAmB,GAAGC,sBAAsB,CACxD,YACA;QACEC,eAAepC,MAAME,WAAW;QAChCmC,aAAarC,MAAMqC,WAAW;QAC9BC,gBAAgBtC,MAAMsC,cAAc;IACtC,GACA;QAAEN,QAAQhC,MAAMgC,MAAM,CAACA,MAAM;IAAC;IAGhC,IAAIhC,MAAMmB,kBAAkB,EAAE;QAC5BoB,IAAAA,6BAAsB;IACxB,OAAO;QACL,MAAMlB,QAAQmB,SAAS;IACzB;AACF;AAEA,eAAeP,gBAAgB5B,kBAA0B,EAAEL,KAAsB;IAC/E,yBAAyB;IACzB,MAAMyC,UAAU,MAAMC,IAAAA,iDAA0B,EAAC1C,MAAMgC,MAAM,CAACA,MAAM,EAAEhC;IAEtE,IAAIyC,SAAS;QACX,gDAAgD;QAChD,MAAMf,aAAapB,eAAI,CAACC,IAAI,CAACP,MAAM2C,mBAAmB,EAAEF;QACxDtC,QAAG,CAACC,GAAG,CAAC0B,gBAAK,CAACC,IAAI,CAAC,kBAAkB,EAAEL,WAAW,CAAC;QACnD,MAAM1B,MAAMgC,MAAM,CAACC,eAAe,CAACP;IACrC,OAAO;QACL,sFAAsF;QACtF,qFAAqF;QACrFvB,QAAG,CAACC,GAAG,CAAC;QACR,MAAMwC,IAAAA,oBAAY,EAACvC,oBAAoB;YACrCZ,SAASO,MAAMP,OAAO,IAAI;YAC1BuB,SAAShB,MAAMgB,OAAO,IAAI;YAC1BD,MAAMf,MAAMe,IAAI;QAClB;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../src/run/android/runAndroidAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport 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 { 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 { resolveRemoteBuildCache, uploadRemoteBuildCache } from '../remoteBuildCache';\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 const projectConfig = getConfig(projectRoot);\n if (!options.binary && projectConfig.exp.experiments?.remoteBuildCache) {\n const localPath = await resolveRemoteBuildCache(projectRoot, {\n platform: 'android',\n provider: projectConfig.exp.experiments?.remoteBuildCache.provider,\n });\n if (localPath) {\n options.binary = localPath;\n }\n }\n\n await ensureNativeProjectAsync(projectRoot, { platform: 'android', install });\n\n const props = await resolveOptionsAsync(projectRoot, options);\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 // 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<AndroidOpenInCustomProps>(\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 (shouldUpdateBuildCache && projectConfig.exp.experiments?.remoteBuildCache) {\n await uploadRemoteBuildCache(projectRoot, {\n platform: 'android',\n provider: projectConfig.exp.experiments?.remoteBuildCache.provider,\n });\n }\n}\n\nasync function installAppAsync(androidProjectRoot: string, props: ResolvedOptions) {\n // Find the APK file path\n const apkFile = await resolveInstallApkNameAsync(props.device.device, props);\n\n if (apkFile) {\n // Attempt to install the APK from the file path\n const binaryPath = path.join(props.apkVariantDirectory, apkFile);\n Log.log(chalk.gray`\\u203A Installing ${binaryPath}`);\n await props.device.installAppAsync(binaryPath);\n } else {\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}\n"],"names":["runAndroidAsync","debug","require","projectRoot","install","options","projectConfig","isProduction","variant","toLowerCase","endsWith","setNodeEnv","load","getConfig","binary","exp","experiments","remoteBuildCache","localPath","resolveRemoteBuildCache","platform","provider","ensureNativeProjectAsync","props","resolveOptionsAsync","packageName","Log","log","androidProjectRoot","path","join","shouldUpdateBuildCache","eagerBundleOptions","JSON","stringify","exportEagerAsync","dev","assembleAsync","port","appName","buildCache","architectures","shouldStartBundler","ensurePortAvailabilityAsync","manager","startBundlerAsync","scheme","getSchemesForAndroidAsync","headless","binaryPath","fs","existsSync","CommandError","chalk","gray","device","installAppAsync","getDefaultDevServer","openCustomRuntimeAsync","applicationId","customAppId","launchActivity","logProjectLogsLocation","stopAsync","uploadRemoteBuildCache","apkFile","resolveInstallApkNameAsync","apkVariantDirectory","installAsync"],"mappings":"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"}
@@ -8,6 +8,13 @@ Object.defineProperty(exports, "runIosAsync", {
8
8
  return runIosAsync;
9
9
  }
10
10
  });
11
+ function _config() {
12
+ const data = require("@expo/config");
13
+ _config = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
11
18
  function _spawnasync() {
12
19
  const data = /*#__PURE__*/ _interop_require_default(require("@expo/spawn-async"));
13
20
  _spawnasync = function() {
@@ -45,6 +52,7 @@ const _profile = require("../../utils/profile");
45
52
  const _scheme = require("../../utils/scheme");
46
53
  const _ensureNativeProject = require("../ensureNativeProject");
47
54
  const _hints = require("../hints");
55
+ const _remoteBuildCache = require("../remoteBuildCache");
48
56
  const _startBundler = require("../startBundler");
49
57
  const _XcodeBuild = /*#__PURE__*/ _interop_require_wildcard(require("./XcodeBuild"));
50
58
  const _launchApp = require("./launchApp");
@@ -101,7 +109,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
101
109
  }
102
110
  const debug = require('debug')('expo:run:ios');
103
111
  async function runIosAsync(projectRoot, options) {
104
- var _this;
112
+ var _projectConfig_exp_experiments, _this, _projectConfig_exp_experiments1;
105
113
  (0, _nodeEnv.setNodeEnv)(options.configuration === 'Release' ? 'production' : 'development');
106
114
  require('@expo/env').load(projectRoot);
107
115
  assertPlatform();
@@ -114,6 +122,17 @@ async function runIosAsync(projectRoot, options) {
114
122
  }
115
123
  // Resolve the CLI arguments into useable options.
116
124
  const props = await (0, _profile.profile)(_resolveOptions.resolveOptionsAsync)(projectRoot, options);
125
+ const projectConfig = (0, _config().getConfig)(projectRoot);
126
+ if (!options.binary && ((_projectConfig_exp_experiments = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments.remoteBuildCache) && props.isSimulator) {
127
+ var _projectConfig_exp_experiments2;
128
+ const localPath = await (0, _remoteBuildCache.resolveRemoteBuildCache)(projectRoot, {
129
+ platform: 'ios',
130
+ provider: (_projectConfig_exp_experiments2 = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments2.remoteBuildCache.provider
131
+ });
132
+ if (localPath) {
133
+ options.binary = localPath;
134
+ }
135
+ }
117
136
  if (options.rebundle) {
118
137
  _log.warn(`The --unstable-rebundle flag is experimental and may not work as expected.`);
119
138
  // Get the existing binary path to re-bundle the app.
@@ -157,6 +176,7 @@ async function runIosAsync(projectRoot, options) {
157
176
  }
158
177
  }
159
178
  let binaryPath;
179
+ let shouldUpdateBuildCache = false;
160
180
  if (options.binary) {
161
181
  binaryPath = await (0, _validateExternalBinary.getValidBinaryPathAsync)(options.binary, props);
162
182
  _log.log('Using custom binary path:', binaryPath);
@@ -176,6 +196,7 @@ async function runIosAsync(projectRoot, options) {
176
196
  // Find the path to the built app binary, this will be used to install the binary
177
197
  // on a device.
178
198
  binaryPath = await (0, _profile.profile)(_XcodeBuild.getAppBinaryPath)(buildOutput);
199
+ shouldUpdateBuildCache = true;
179
200
  }
180
201
  debug('Binary path:', binaryPath);
181
202
  // Ensure the port hasn't become busy during the build.
@@ -217,6 +238,13 @@ async function runIosAsync(projectRoot, options) {
217
238
  } else {
218
239
  await manager.stopAsync();
219
240
  }
241
+ if (shouldUpdateBuildCache && ((_projectConfig_exp_experiments1 = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments1.remoteBuildCache)) {
242
+ var _projectConfig_exp_experiments3;
243
+ await (0, _remoteBuildCache.uploadRemoteBuildCache)(projectRoot, {
244
+ platform: 'ios',
245
+ provider: (_projectConfig_exp_experiments3 = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments3.remoteBuildCache.provider
246
+ });
247
+ }
220
248
  }
221
249
  function assertPlatform() {
222
250
  if (process.platform !== 'darwin') {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/run/ios/runIosAsync.ts"],"sourcesContent":["import spawnAsync from '@expo/spawn-async';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport * as Log from '../../log';\nimport { AppleAppIdResolver } from '../../start/platforms/ios/AppleAppIdResolver';\nimport { maybePromptToSyncPodsAsync } from '../../utils/cocoapods';\nimport { setNodeEnv } from '../../utils/nodeEnv';\nimport { ensurePortAvailabilityAsync } from '../../utils/port';\nimport { profile } from '../../utils/profile';\nimport { getSchemesForIosAsync } from '../../utils/scheme';\nimport { ensureNativeProjectAsync } from '../ensureNativeProject';\nimport { logProjectLogsLocation } from '../hints';\nimport { startBundlerAsync } from '../startBundler';\nimport * as XcodeBuild from './XcodeBuild';\nimport { Options } from './XcodeBuild.types';\nimport { getLaunchInfoForBinaryAsync, launchAppAsync } from './launchApp';\nimport { resolveOptionsAsync } from './options/resolveOptions';\nimport { getValidBinaryPathAsync } from './validateExternalBinary';\nimport { exportEagerAsync } from '../../export/embed/exportEager';\nimport { getContainerPathAsync, simctlAsync } from '../../start/platforms/ios/simctl';\nimport { CommandError } from '../../utils/errors';\n\nconst debug = require('debug')('expo:run:ios');\n\nexport async function runIosAsync(projectRoot: string, options: Options) {\n setNodeEnv(options.configuration === 'Release' ? 'production' : 'development');\n require('@expo/env').load(projectRoot);\n\n assertPlatform();\n\n const install = !!options.install;\n\n if ((await ensureNativeProjectAsync(projectRoot, { platform: 'ios', install })) && install) {\n await maybePromptToSyncPodsAsync(projectRoot);\n }\n\n // Resolve the CLI arguments into useable options.\n const props = await profile(resolveOptionsAsync)(projectRoot, options);\n\n if (options.rebundle) {\n Log.warn(`The --unstable-rebundle flag is experimental and may not work as expected.`);\n // Get the existing binary path to re-bundle the app.\n\n let binaryPath: string;\n if (!options.binary) {\n if (!props.isSimulator) {\n throw new Error('Re-bundling on physical devices requires the --binary flag.');\n }\n const appId = await new AppleAppIdResolver(projectRoot).getAppIdAsync();\n const possibleBinaryPath = await getContainerPathAsync(props.device, {\n appId,\n });\n if (!possibleBinaryPath) {\n throw new CommandError(\n `Cannot rebundle because no --binary was provided and no existing binary was found on the device for ID: ${appId}.`\n );\n }\n binaryPath = possibleBinaryPath;\n Log.log('Re-using existing binary path:', binaryPath);\n // Set the binary path to the existing binary path.\n options.binary = binaryPath;\n }\n\n Log.log('Rebundling the Expo config file');\n // Re-bundle the config file the same way the app was originally bundled.\n await spawnAsync('node', [\n path.join(require.resolve('expo-constants/package.json'), '../scripts/getAppConfig.js'),\n projectRoot,\n path.join(options.binary, 'EXConstants.bundle'),\n ]);\n // Re-bundle the app.\n\n const possibleBundleOutput = path.join(options.binary, 'main.jsbundle');\n\n if (fs.existsSync(possibleBundleOutput)) {\n Log.log('Rebundling the app...');\n await exportEagerAsync(projectRoot, {\n resetCache: false,\n dev: false,\n platform: 'ios',\n assetsDest: path.join(options.binary, 'assets'),\n bundleOutput: possibleBundleOutput,\n });\n } else {\n Log.warn('Bundle output not found at expected location:', possibleBundleOutput);\n }\n }\n\n let binaryPath: string;\n if (options.binary) {\n binaryPath = await getValidBinaryPathAsync(options.binary, props);\n Log.log('Using custom binary path:', binaryPath);\n } else {\n let eagerBundleOptions: string | undefined;\n\n if (options.configuration === 'Release') {\n eagerBundleOptions = JSON.stringify(\n await exportEagerAsync(projectRoot, {\n dev: false,\n platform: 'ios',\n })\n );\n }\n\n // Spawn the `xcodebuild` process to create the app binary.\n const buildOutput = await XcodeBuild.buildAsync({\n ...props,\n eagerBundleOptions,\n });\n\n // Find the path to the built app binary, this will be used to install the binary\n // on a device.\n binaryPath = await profile(XcodeBuild.getAppBinaryPath)(buildOutput);\n }\n debug('Binary path:', binaryPath);\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 const launchInfo = await getLaunchInfoForBinaryAsync(binaryPath);\n const isCustomBinary = !!options.binary;\n\n // Always close the app before launching on a simulator. Otherwise certain cached resources like the splashscreen will not be available.\n if (props.isSimulator) {\n try {\n await simctlAsync(['terminate', props.device.udid, launchInfo.bundleId]);\n } catch (error) {\n // If we failed it's likely that the app was not running to begin with and we will get an `invalid device` error\n debug('Failed to terminate app (possibly because it was not running):', error);\n }\n }\n\n // Start the dev server which creates all of the required info for\n // launching the app on a simulator.\n const manager = await startBundlerAsync(projectRoot, {\n port: props.port,\n headless: !props.shouldStartBundler,\n // If a scheme is specified then use that instead of the package name.\n\n scheme: isCustomBinary\n ? // If launching a custom binary, use the schemes in the Info.plist.\n launchInfo.schemes[0]\n : // If a scheme is specified then use that instead of the package name.\n (await getSchemesForIosAsync(projectRoot))?.[0],\n });\n\n // Install and launch the app binary on a device.\n await launchAppAsync(\n binaryPath,\n manager,\n {\n isSimulator: props.isSimulator,\n device: props.device,\n shouldStartBundler: props.shouldStartBundler,\n },\n launchInfo.bundleId\n );\n\n // Log the location of the JS logs for the device.\n if (props.shouldStartBundler) {\n logProjectLogsLocation();\n } else {\n await manager.stopAsync();\n }\n}\n\nfunction assertPlatform() {\n if (process.platform !== 'darwin') {\n Log.exit(\n chalk`iOS apps can only be built on macOS devices. Use {cyan eas build -p ios} to build in the cloud.`\n );\n }\n}\n"],"names":["runIosAsync","debug","require","projectRoot","options","setNodeEnv","configuration","load","assertPlatform","install","ensureNativeProjectAsync","platform","maybePromptToSyncPodsAsync","props","profile","resolveOptionsAsync","rebundle","Log","warn","binaryPath","binary","isSimulator","Error","appId","AppleAppIdResolver","getAppIdAsync","possibleBinaryPath","getContainerPathAsync","device","CommandError","log","spawnAsync","path","join","resolve","possibleBundleOutput","fs","existsSync","exportEagerAsync","resetCache","dev","assetsDest","bundleOutput","getValidBinaryPathAsync","eagerBundleOptions","JSON","stringify","buildOutput","XcodeBuild","buildAsync","getAppBinaryPath","shouldStartBundler","ensurePortAvailabilityAsync","launchInfo","getLaunchInfoForBinaryAsync","isCustomBinary","simctlAsync","udid","bundleId","error","manager","startBundlerAsync","port","headless","scheme","schemes","getSchemesForIosAsync","launchAppAsync","logProjectLogsLocation","stopAsync","process","exit","chalk"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/run/ios/runIosAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport spawnAsync from '@expo/spawn-async';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport * as Log from '../../log';\nimport { AppleAppIdResolver } from '../../start/platforms/ios/AppleAppIdResolver';\nimport { maybePromptToSyncPodsAsync } from '../../utils/cocoapods';\nimport { setNodeEnv } from '../../utils/nodeEnv';\nimport { ensurePortAvailabilityAsync } from '../../utils/port';\nimport { profile } from '../../utils/profile';\nimport { getSchemesForIosAsync } from '../../utils/scheme';\nimport { ensureNativeProjectAsync } from '../ensureNativeProject';\nimport { logProjectLogsLocation } from '../hints';\nimport { uploadRemoteBuildCache, resolveRemoteBuildCache } from '../remoteBuildCache';\nimport { startBundlerAsync } from '../startBundler';\nimport * as XcodeBuild from './XcodeBuild';\nimport { Options } from './XcodeBuild.types';\nimport { getLaunchInfoForBinaryAsync, launchAppAsync } from './launchApp';\nimport { resolveOptionsAsync } from './options/resolveOptions';\nimport { getValidBinaryPathAsync } from './validateExternalBinary';\nimport { exportEagerAsync } from '../../export/embed/exportEager';\nimport { getContainerPathAsync, simctlAsync } from '../../start/platforms/ios/simctl';\nimport { CommandError } from '../../utils/errors';\n\nconst debug = require('debug')('expo:run:ios');\n\nexport async function runIosAsync(projectRoot: string, options: Options) {\n setNodeEnv(options.configuration === 'Release' ? 'production' : 'development');\n require('@expo/env').load(projectRoot);\n\n assertPlatform();\n\n const install = !!options.install;\n\n if ((await ensureNativeProjectAsync(projectRoot, { platform: 'ios', install })) && install) {\n await maybePromptToSyncPodsAsync(projectRoot);\n }\n\n // Resolve the CLI arguments into useable options.\n const props = await profile(resolveOptionsAsync)(projectRoot, options);\n\n const projectConfig = getConfig(projectRoot);\n if (!options.binary && projectConfig.exp.experiments?.remoteBuildCache && props.isSimulator) {\n const localPath = await resolveRemoteBuildCache(projectRoot, {\n platform: 'ios',\n provider: projectConfig.exp.experiments?.remoteBuildCache.provider,\n });\n if (localPath) {\n options.binary = localPath;\n }\n }\n\n if (options.rebundle) {\n Log.warn(`The --unstable-rebundle flag is experimental and may not work as expected.`);\n // Get the existing binary path to re-bundle the app.\n\n let binaryPath: string;\n if (!options.binary) {\n if (!props.isSimulator) {\n throw new Error('Re-bundling on physical devices requires the --binary flag.');\n }\n const appId = await new AppleAppIdResolver(projectRoot).getAppIdAsync();\n const possibleBinaryPath = await getContainerPathAsync(props.device, {\n appId,\n });\n if (!possibleBinaryPath) {\n throw new CommandError(\n `Cannot rebundle because no --binary was provided and no existing binary was found on the device for ID: ${appId}.`\n );\n }\n binaryPath = possibleBinaryPath;\n Log.log('Re-using existing binary path:', binaryPath);\n // Set the binary path to the existing binary path.\n options.binary = binaryPath;\n }\n\n Log.log('Rebundling the Expo config file');\n // Re-bundle the config file the same way the app was originally bundled.\n await spawnAsync('node', [\n path.join(require.resolve('expo-constants/package.json'), '../scripts/getAppConfig.js'),\n projectRoot,\n path.join(options.binary, 'EXConstants.bundle'),\n ]);\n // Re-bundle the app.\n\n const possibleBundleOutput = path.join(options.binary, 'main.jsbundle');\n\n if (fs.existsSync(possibleBundleOutput)) {\n Log.log('Rebundling the app...');\n await exportEagerAsync(projectRoot, {\n resetCache: false,\n dev: false,\n platform: 'ios',\n assetsDest: path.join(options.binary, 'assets'),\n bundleOutput: possibleBundleOutput,\n });\n } else {\n Log.warn('Bundle output not found at expected location:', possibleBundleOutput);\n }\n }\n\n let binaryPath: string;\n let shouldUpdateBuildCache = false;\n if (options.binary) {\n binaryPath = await getValidBinaryPathAsync(options.binary, props);\n Log.log('Using custom binary path:', binaryPath);\n } else {\n let eagerBundleOptions: string | undefined;\n\n if (options.configuration === 'Release') {\n eagerBundleOptions = JSON.stringify(\n await exportEagerAsync(projectRoot, {\n dev: false,\n platform: 'ios',\n })\n );\n }\n\n // Spawn the `xcodebuild` process to create the app binary.\n const buildOutput = await XcodeBuild.buildAsync({\n ...props,\n eagerBundleOptions,\n });\n\n // Find the path to the built app binary, this will be used to install the binary\n // on a device.\n binaryPath = await profile(XcodeBuild.getAppBinaryPath)(buildOutput);\n shouldUpdateBuildCache = true;\n }\n debug('Binary path:', binaryPath);\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 const launchInfo = await getLaunchInfoForBinaryAsync(binaryPath);\n const isCustomBinary = !!options.binary;\n\n // Always close the app before launching on a simulator. Otherwise certain cached resources like the splashscreen will not be available.\n if (props.isSimulator) {\n try {\n await simctlAsync(['terminate', props.device.udid, launchInfo.bundleId]);\n } catch (error) {\n // If we failed it's likely that the app was not running to begin with and we will get an `invalid device` error\n debug('Failed to terminate app (possibly because it was not running):', error);\n }\n }\n\n // Start the dev server which creates all of the required info for\n // launching the app on a simulator.\n const manager = await startBundlerAsync(projectRoot, {\n port: props.port,\n headless: !props.shouldStartBundler,\n // If a scheme is specified then use that instead of the package name.\n\n scheme: isCustomBinary\n ? // If launching a custom binary, use the schemes in the Info.plist.\n launchInfo.schemes[0]\n : // If a scheme is specified then use that instead of the package name.\n (await getSchemesForIosAsync(projectRoot))?.[0],\n });\n\n // Install and launch the app binary on a device.\n await launchAppAsync(\n binaryPath,\n manager,\n {\n isSimulator: props.isSimulator,\n device: props.device,\n shouldStartBundler: props.shouldStartBundler,\n },\n launchInfo.bundleId\n );\n\n // Log the location of the JS logs for the device.\n if (props.shouldStartBundler) {\n logProjectLogsLocation();\n } else {\n await manager.stopAsync();\n }\n\n if (shouldUpdateBuildCache && projectConfig.exp.experiments?.remoteBuildCache) {\n await uploadRemoteBuildCache(projectRoot, {\n platform: 'ios',\n provider: projectConfig.exp.experiments?.remoteBuildCache.provider,\n });\n }\n}\n\nfunction assertPlatform() {\n if (process.platform !== 'darwin') {\n Log.exit(\n chalk`iOS apps can only be built on macOS devices. Use {cyan eas build -p ios} to build in the cloud.`\n );\n }\n}\n"],"names":["runIosAsync","debug","require","projectRoot","options","projectConfig","setNodeEnv","configuration","load","assertPlatform","install","ensureNativeProjectAsync","platform","maybePromptToSyncPodsAsync","props","profile","resolveOptionsAsync","getConfig","binary","exp","experiments","remoteBuildCache","isSimulator","localPath","resolveRemoteBuildCache","provider","rebundle","Log","warn","binaryPath","Error","appId","AppleAppIdResolver","getAppIdAsync","possibleBinaryPath","getContainerPathAsync","device","CommandError","log","spawnAsync","path","join","resolve","possibleBundleOutput","fs","existsSync","exportEagerAsync","resetCache","dev","assetsDest","bundleOutput","shouldUpdateBuildCache","getValidBinaryPathAsync","eagerBundleOptions","JSON","stringify","buildOutput","XcodeBuild","buildAsync","getAppBinaryPath","shouldStartBundler","ensurePortAvailabilityAsync","launchInfo","getLaunchInfoForBinaryAsync","isCustomBinary","simctlAsync","udid","bundleId","error","manager","startBundlerAsync","port","headless","scheme","schemes","getSchemesForIosAsync","launchAppAsync","logProjectLogsLocation","stopAsync","uploadRemoteBuildCache","process","exit","chalk"],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ resolveRemoteBuildCache: function() {
13
+ return resolveRemoteBuildCache;
14
+ },
15
+ uploadRemoteBuildCache: function() {
16
+ return uploadRemoteBuildCache;
17
+ }
18
+ });
19
+ function _spawnasync() {
20
+ const data = /*#__PURE__*/ _interop_require_default(require("@expo/spawn-async"));
21
+ _spawnasync = function() {
22
+ return data;
23
+ };
24
+ return data;
25
+ }
26
+ function _fs() {
27
+ const data = /*#__PURE__*/ _interop_require_default(require("fs"));
28
+ _fs = function() {
29
+ return data;
30
+ };
31
+ return data;
32
+ }
33
+ function _path() {
34
+ const data = /*#__PURE__*/ _interop_require_default(require("path"));
35
+ _path = function() {
36
+ return data;
37
+ };
38
+ return data;
39
+ }
40
+ const _log = require("../log");
41
+ function _interop_require_default(obj) {
42
+ return obj && obj.__esModule ? obj : {
43
+ default: obj
44
+ };
45
+ }
46
+ const debug = require('debug')('expo:run:remote-build');
47
+ async function resolveRemoteBuildCache(projectRoot, { platform, provider }) {
48
+ const Fingerprint = importFingerprintForDev(projectRoot);
49
+ if (!Fingerprint) {
50
+ debug('@expo/fingerprint is not installed in the project, skip checking for remote builds');
51
+ return null;
52
+ }
53
+ const fingerprint = await Fingerprint.createFingerprintAsync(projectRoot);
54
+ if (provider === 'eas') {
55
+ const easJsonPath = _path().default.join(projectRoot, 'eas.json');
56
+ if (!_fs().default.existsSync(easJsonPath)) {
57
+ debug('eas.json not found, skip checking for remote builds');
58
+ return null;
59
+ }
60
+ _log.Log.log(`Searching builds with matching fingerprint on EAS servers`);
61
+ try {
62
+ const results = await (0, _spawnasync().default)('npx', [
63
+ 'eas-cli',
64
+ 'build:download',
65
+ `--platform=${platform}`,
66
+ `--fingerprint=${fingerprint.hash}`,
67
+ '--non-interactive',
68
+ '--dev-client',
69
+ '--json'
70
+ ], {
71
+ cwd: projectRoot
72
+ });
73
+ _log.Log.log(`Successfully downloaded cached build`);
74
+ // {
75
+ // "path": "/var/folders/03/lppcpcnn61q3mz5ckzmzd8w80000gn/T/eas-cli-nodejs/eas-build-run-cache/c0f9ba9c-0cf1-4c5c-8566-b28b7971050f_22f1bbfa-1c09-4b67-9e4a-721906546b58.app"
76
+ // }
77
+ const json = JSON.parse(results.stdout.trim());
78
+ return json == null ? void 0 : json.path;
79
+ } catch (error) {
80
+ debug('eas-cli error:', error);
81
+ return null;
82
+ }
83
+ }
84
+ return null;
85
+ }
86
+ async function uploadRemoteBuildCache(projectRoot, { platform, provider }) {
87
+ const Fingerprint = importFingerprintForDev(projectRoot);
88
+ if (!Fingerprint) {
89
+ debug('@expo/fingerprint is not installed in the project, skip checking for remote builds');
90
+ return null;
91
+ }
92
+ const fingerprint = await Fingerprint.createFingerprintAsync(projectRoot);
93
+ if (provider === 'eas') {
94
+ const easJsonPath = _path().default.join(projectRoot, 'eas.json');
95
+ if (!_fs().default.existsSync(easJsonPath)) {
96
+ debug('eas.json not found, skip checking for remote builds');
97
+ return null;
98
+ }
99
+ try {
100
+ _log.Log.log('Uploading build to remote cache');
101
+ const results = await (0, _spawnasync().default)('npx', [
102
+ 'eas-cli',
103
+ 'upload',
104
+ `--platform=${platform}`,
105
+ `--fingerprint=${fingerprint.hash}`,
106
+ '--non-interactive',
107
+ '--json'
108
+ ], {
109
+ cwd: projectRoot
110
+ });
111
+ // {
112
+ // "url": "/var/folders/03/lppcpcnn61q3mz5ckzmzd8w80000gn/T/eas-cli-nodejs/eas-build-run-cache/c0f9ba9c-0cf1-4c5c-8566-b28b7971050f_22f1bbfa-1c09-4b67-9e4a-721906546b58.app"
113
+ // }
114
+ const json = JSON.parse(results.stdout.trim());
115
+ _log.Log.log(`Build successfully uploaded: ${json == null ? void 0 : json.url}`);
116
+ } catch (error) {
117
+ debug('eas-cli error:', error);
118
+ return null;
119
+ }
120
+ }
121
+ return null;
122
+ }
123
+ function importFingerprintForDev(projectRoot) {
124
+ try {
125
+ return require(require.resolve('@expo/fingerprint', {
126
+ paths: [
127
+ projectRoot
128
+ ]
129
+ }));
130
+ } catch {
131
+ return null;
132
+ }
133
+ }
134
+
135
+ //# sourceMappingURL=remoteBuildCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/run/remoteBuildCache.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport { ModPlatform } from '@expo/config-plugins';\nimport spawnAsync from '@expo/spawn-async';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { Log } from '../log';\n\nconst debug = require('debug')('expo:run:remote-build') as typeof console.log;\n\nexport async function resolveRemoteBuildCache(\n projectRoot: string,\n {\n platform,\n provider,\n }: {\n platform: ModPlatform;\n provider?: Required<Required<ExpoConfig>['experiments']>['remoteBuildCache']['provider'];\n }\n): Promise<string | null> {\n const Fingerprint = importFingerprintForDev(projectRoot);\n if (!Fingerprint) {\n debug('@expo/fingerprint is not installed in the project, skip checking for remote builds');\n return null;\n }\n const fingerprint = await Fingerprint.createFingerprintAsync(projectRoot);\n\n if (provider === 'eas') {\n const easJsonPath = path.join(projectRoot, 'eas.json');\n if (!fs.existsSync(easJsonPath)) {\n debug('eas.json not found, skip checking for remote builds');\n return null;\n }\n\n Log.log(`Searching builds with matching fingerprint on EAS servers`);\n try {\n const results = await spawnAsync(\n 'npx',\n [\n 'eas-cli',\n 'build:download',\n `--platform=${platform}`,\n `--fingerprint=${fingerprint.hash}`,\n '--non-interactive',\n '--dev-client',\n '--json',\n ],\n {\n cwd: projectRoot,\n }\n );\n\n Log.log(`Successfully downloaded cached build`);\n // {\n // \"path\": \"/var/folders/03/lppcpcnn61q3mz5ckzmzd8w80000gn/T/eas-cli-nodejs/eas-build-run-cache/c0f9ba9c-0cf1-4c5c-8566-b28b7971050f_22f1bbfa-1c09-4b67-9e4a-721906546b58.app\"\n // }\n const json = JSON.parse(results.stdout.trim());\n return json?.path;\n } catch (error) {\n debug('eas-cli error:', error);\n return null;\n }\n }\n\n return null;\n}\n\nexport async function uploadRemoteBuildCache(\n projectRoot: string,\n {\n platform,\n provider,\n }: {\n platform: ModPlatform;\n provider?: Required<Required<ExpoConfig>['experiments']>['remoteBuildCache']['provider'];\n }\n): Promise<string | null> {\n const Fingerprint = importFingerprintForDev(projectRoot);\n if (!Fingerprint) {\n debug('@expo/fingerprint is not installed in the project, skip checking for remote builds');\n return null;\n }\n const fingerprint = await Fingerprint.createFingerprintAsync(projectRoot);\n\n if (provider === 'eas') {\n const easJsonPath = path.join(projectRoot, 'eas.json');\n if (!fs.existsSync(easJsonPath)) {\n debug('eas.json not found, skip checking for remote builds');\n return null;\n }\n\n try {\n Log.log('Uploading build to remote cache');\n const results = await spawnAsync(\n 'npx',\n [\n 'eas-cli',\n 'upload',\n `--platform=${platform}`,\n `--fingerprint=${fingerprint.hash}`,\n '--non-interactive',\n '--json',\n ],\n {\n cwd: projectRoot,\n }\n );\n // {\n // \"url\": \"/var/folders/03/lppcpcnn61q3mz5ckzmzd8w80000gn/T/eas-cli-nodejs/eas-build-run-cache/c0f9ba9c-0cf1-4c5c-8566-b28b7971050f_22f1bbfa-1c09-4b67-9e4a-721906546b58.app\"\n // }\n const json = JSON.parse(results.stdout.trim());\n Log.log(`Build successfully uploaded: ${json?.url}`);\n } catch (error) {\n debug('eas-cli error:', error);\n return null;\n }\n }\n\n return null;\n}\n\nfunction importFingerprintForDev(projectRoot: string): null | typeof import('@expo/fingerprint') {\n try {\n return require(require.resolve('@expo/fingerprint', { paths: [projectRoot] }));\n } catch {\n return null;\n }\n}\n"],"names":["resolveRemoteBuildCache","uploadRemoteBuildCache","debug","require","projectRoot","platform","provider","Fingerprint","importFingerprintForDev","fingerprint","createFingerprintAsync","easJsonPath","path","join","fs","existsSync","Log","log","results","spawnAsync","hash","cwd","json","JSON","parse","stdout","trim","error","url","resolve","paths"],"mappings":";;;;;;;;;;;IAUsBA,uBAAuB;eAAvBA;;IAyDAC,sBAAsB;eAAtBA;;;;gEAjEC;;;;;;;gEACR;;;;;;;gEACE;;;;;;qBAEG;;;;;;AAEpB,MAAMC,QAAQC,QAAQ,SAAS;AAExB,eAAeH,wBACpBI,WAAmB,EACnB,EACEC,QAAQ,EACRC,QAAQ,EAIT;IAED,MAAMC,cAAcC,wBAAwBJ;IAC5C,IAAI,CAACG,aAAa;QAChBL,MAAM;QACN,OAAO;IACT;IACA,MAAMO,cAAc,MAAMF,YAAYG,sBAAsB,CAACN;IAE7D,IAAIE,aAAa,OAAO;QACtB,MAAMK,cAAcC,eAAI,CAACC,IAAI,CAACT,aAAa;QAC3C,IAAI,CAACU,aAAE,CAACC,UAAU,CAACJ,cAAc;YAC/BT,MAAM;YACN,OAAO;QACT;QAEAc,QAAG,CAACC,GAAG,CAAC,CAAC,yDAAyD,CAAC;QACnE,IAAI;YACF,MAAMC,UAAU,MAAMC,IAAAA,qBAAU,EAC9B,OACA;gBACE;gBACA;gBACA,CAAC,WAAW,EAAEd,UAAU;gBACxB,CAAC,cAAc,EAAEI,YAAYW,IAAI,EAAE;gBACnC;gBACA;gBACA;aACD,EACD;gBACEC,KAAKjB;YACP;YAGFY,QAAG,CAACC,GAAG,CAAC,CAAC,oCAAoC,CAAC;YAC9C,IAAI;YACJ,gLAAgL;YAChL,IAAI;YACJ,MAAMK,OAAOC,KAAKC,KAAK,CAACN,QAAQO,MAAM,CAACC,IAAI;YAC3C,OAAOJ,wBAAAA,KAAMV,IAAI;QACnB,EAAE,OAAOe,OAAO;YACdzB,MAAM,kBAAkByB;YACxB,OAAO;QACT;IACF;IAEA,OAAO;AACT;AAEO,eAAe1B,uBACpBG,WAAmB,EACnB,EACEC,QAAQ,EACRC,QAAQ,EAIT;IAED,MAAMC,cAAcC,wBAAwBJ;IAC5C,IAAI,CAACG,aAAa;QAChBL,MAAM;QACN,OAAO;IACT;IACA,MAAMO,cAAc,MAAMF,YAAYG,sBAAsB,CAACN;IAE7D,IAAIE,aAAa,OAAO;QACtB,MAAMK,cAAcC,eAAI,CAACC,IAAI,CAACT,aAAa;QAC3C,IAAI,CAACU,aAAE,CAACC,UAAU,CAACJ,cAAc;YAC/BT,MAAM;YACN,OAAO;QACT;QAEA,IAAI;YACFc,QAAG,CAACC,GAAG,CAAC;YACR,MAAMC,UAAU,MAAMC,IAAAA,qBAAU,EAC9B,OACA;gBACE;gBACA;gBACA,CAAC,WAAW,EAAEd,UAAU;gBACxB,CAAC,cAAc,EAAEI,YAAYW,IAAI,EAAE;gBACnC;gBACA;aACD,EACD;gBACEC,KAAKjB;YACP;YAEF,IAAI;YACJ,+KAA+K;YAC/K,IAAI;YACJ,MAAMkB,OAAOC,KAAKC,KAAK,CAACN,QAAQO,MAAM,CAACC,IAAI;YAC3CV,QAAG,CAACC,GAAG,CAAC,CAAC,6BAA6B,EAAEK,wBAAAA,KAAMM,GAAG,EAAE;QACrD,EAAE,OAAOD,OAAO;YACdzB,MAAM,kBAAkByB;YACxB,OAAO;QACT;IACF;IAEA,OAAO;AACT;AAEA,SAASnB,wBAAwBJ,WAAmB;IAClD,IAAI;QACF,OAAOD,QAAQA,QAAQ0B,OAAO,CAAC,qBAAqB;YAAEC,OAAO;gBAAC1B;aAAY;QAAC;IAC7E,EAAE,OAAM;QACN,OAAO;IACT;AACF"}
@@ -126,7 +126,7 @@ class LogRespectingTerminal extends _metrocore().Terminal {
126
126
  // Share one instance of Terminal for all instances of Metro.
127
127
  const terminal = new LogRespectingTerminal(process.stdout);
128
128
  async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, getMetroBundler }) {
129
- var _exp_experiments, _exp_experiments1, _config_resolver, _exp_experiments2, _exp_experiments3, _exp_experiments4, _exp_experiments5, _exp_experiments6;
129
+ var _exp_experiments, _exp_experiments1, _exp_experiments2, _exp_experiments3, _config_resolver, _exp_experiments4, _exp_experiments5, _exp_experiments6;
130
130
  let reportEvent;
131
131
  const serverActionsEnabled = ((_exp_experiments = exp.experiments) == null ? void 0 : _exp_experiments.reactServerFunctions) ?? _env.env.EXPO_UNSTABLE_SERVER_FUNCTIONS;
132
132
  if (serverActionsEnabled) {
@@ -137,6 +137,11 @@ async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, ge
137
137
  process.env.EXPO_USE_METRO_REQUIRE = '1';
138
138
  process.env.EXPO_USE_FAST_RESOLVER = '1';
139
139
  }
140
+ const isReactCanaryEnabled = (((_exp_experiments2 = exp.experiments) == null ? void 0 : _exp_experiments2.reactServerComponentRoutes) || serverActionsEnabled || ((_exp_experiments3 = exp.experiments) == null ? void 0 : _exp_experiments3.reactCanary)) ?? false;
141
+ if (isReactCanaryEnabled) {
142
+ // The fast resolver is required for React canary to work as it can switch the node_modules location for react imports.
143
+ process.env.EXPO_USE_FAST_RESOLVER = '1';
144
+ }
140
145
  const serverRoot = (0, _paths().getMetroServerRoot)(projectRoot);
141
146
  const terminalReporter = new _MetroTerminalReporter.MetroTerminalReporter(serverRoot, terminal);
142
147
  const hasConfig = await (0, _metroconfig1().resolveConfig)(options.config, projectRoot);
@@ -168,7 +173,7 @@ async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, ge
168
173
  config.transformer.publicPath = '/assets/?unstable_path=.';
169
174
  }
170
175
  const platformBundlers = (0, _platformBundlers.getPlatformBundlers)(projectRoot, exp);
171
- if ((_exp_experiments2 = exp.experiments) == null ? void 0 : _exp_experiments2.reactCompiler) {
176
+ if ((_exp_experiments4 = exp.experiments) == null ? void 0 : _exp_experiments4.reactCompiler) {
172
177
  _log.Log.warn(`Experimental React Compiler is enabled.`);
173
178
  }
174
179
  if (_env.env.EXPO_UNSTABLE_TREE_SHAKING && !_env.env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {
@@ -188,10 +193,10 @@ async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, ge
188
193
  config,
189
194
  exp,
190
195
  platformBundlers,
191
- isTsconfigPathsEnabled: ((_exp_experiments3 = exp.experiments) == null ? void 0 : _exp_experiments3.tsconfigPaths) ?? true,
196
+ isTsconfigPathsEnabled: ((_exp_experiments5 = exp.experiments) == null ? void 0 : _exp_experiments5.tsconfigPaths) ?? true,
192
197
  isFastResolverEnabled: _env.env.EXPO_USE_FAST_RESOLVER,
193
198
  isExporting,
194
- isReactCanaryEnabled: (((_exp_experiments4 = exp.experiments) == null ? void 0 : _exp_experiments4.reactServerComponentRoutes) || serverActionsEnabled || ((_exp_experiments5 = exp.experiments) == null ? void 0 : _exp_experiments5.reactCanary)) ?? false,
199
+ isReactCanaryEnabled,
195
200
  isNamedRequiresEnabled: _env.env.EXPO_USE_METRO_REQUIRE,
196
201
  isReactServerComponentsEnabled: !!((_exp_experiments6 = exp.experiments) == null ? void 0 : _exp_experiments6.reactServerComponentRoutes),
197
202
  getMetroBundler
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/instantiateMetro.ts"],"sourcesContent":["import { ExpoConfig, getConfig } from '@expo/config';\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport { getDefaultConfig, LoadOptions } from '@expo/metro-config';\nimport chalk from 'chalk';\nimport http from 'http';\nimport type Metro from 'metro';\nimport { ReadOnlyGraph } from 'metro';\nimport Bundler from 'metro/src/Bundler';\nimport type { TransformOptions } from 'metro/src/DeltaBundler/Worker';\nimport MetroHmrServer from 'metro/src/HmrServer';\nimport RevisionNotFoundError from 'metro/src/IncrementalBundler/RevisionNotFoundError';\nimport formatBundlingError from 'metro/src/lib/formatBundlingError';\nimport { loadConfig, resolveConfig, ConfigT } from 'metro-config';\nimport { Terminal } from 'metro-core';\nimport util from 'node:util';\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);\n\n const sendLog = (...args: any[]) => {\n this._logLines.push(\n // format args like console.log\n util.format(...args)\n );\n this._scheduleUpdate();\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\nexport async function loadMetroConfigAsync(\n projectRoot: string,\n options: LoadOptions,\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 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 process.env.EXPO_USE_FAST_RESOLVER = '1';\n }\n\n const serverRoot = getMetroServerRoot(projectRoot);\n const terminalReporter = new MetroTerminalReporter(serverRoot, terminal);\n\n const hasConfig = await resolveConfig(options.config, projectRoot);\n let config: ConfigT = {\n ...(await loadConfig(\n { cwd: projectRoot, projectRoot, ...options },\n // If the project does not have a metro.config.js, then we use the default config.\n hasConfig.isEmpty ? getDefaultConfig(projectRoot) : undefined\n )),\n reporter: {\n update(event: any) {\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.warn(`Experimental React Compiler is 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_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\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 isFastResolverEnabled: env.EXPO_USE_FAST_RESOLVER,\n isExporting,\n isReactCanaryEnabled:\n (exp.experiments?.reactServerComponentRoutes ||\n serverActionsEnabled ||\n exp.experiments?.reactCanary) ??\n false,\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: Omit<LoadOptions, 'logger'>,\n {\n isExporting,\n exp = getConfig(metroBundler.projectRoot, {\n skipSDKVersionRequirement: true,\n }).exp,\n }: { isExporting: boolean; exp?: ExpoConfig }\n): Promise<{\n metro: Metro.Server;\n hmrServer: MetroHmrServer | 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 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 metroBundler,\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: Metro.Server) => {\n if (customEnhanceMiddleware) {\n metroMiddleware = customEnhanceMiddleware(metroMiddleware, server);\n }\n return middleware.use(metroMiddleware);\n };\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 ...websocketEndpoints,\n ...createDevToolsPluginWebsocketEndpoint(),\n },\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: Metro.Server, 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: typeof import('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n\n try {\n hmrJSBundle = require('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n } catch {\n // 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('metro/src/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 (this: MetroHmrServer, group, options, changeEvent) {\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 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/metro-runtime/src/virtual.js` for production RSC exports.\n !filePath.match(/\\/@expo\\/metro-runtime\\/rsc\\/virtual\\.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","sendLog","args","_logLines","push","util","format","_scheduleUpdate","flush","console","log","info","terminal","process","stdout","projectRoot","options","exp","isExporting","getMetroBundler","config","reportEvent","serverActionsEnabled","experiments","reactServerFunctions","env","EXPO_UNSTABLE_SERVER_FUNCTIONS","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","EXPO_USE_FAST_RESOLVER","serverRoot","getMetroServerRoot","terminalReporter","MetroTerminalReporter","hasConfig","resolveConfig","loadConfig","cwd","isEmpty","getDefaultConfig","undefined","reporter","update","event","globalThis","__requireCycleIgnorePatterns","resolver","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reactCompiler","Log","warn","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isFastResolverEnabled","isReactCanaryEnabled","reactCanary","isNamedRequiresEnabled","isReactServerComponentsEnabled","setEventReporter","logger","metroBundler","getConfig","skipSDKVersionRequirement","metroConfig","metro","getBundler","middleware","messagesSocket","eventsSocket","websocketEndpoints","createMetroMiddleware","prependMiddleware","createCorsMiddleware","debugMiddleware","debugWebsocketEndpoints","createDebugMiddleware","Object","assign","use","createJsInspectorMiddleware","customEnhanceMiddleware","server","enhanceMiddleware","metroMiddleware","attachAtlasAsync","resetAtlasFile","hmrServer","runServer","createDevToolsPluginWebsocketEndpoint","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","set","moduleIdContext","hmrUpdate","clientUrl","createModuleId","moduleId","includeAsyncPaths","graphOptions","lazy","_config","unstable_serverRoot","error","formattedError","messageSocket","split","sep","join","dom","match","routerRoot","asyncRoutes","clientBoundaries","CI","chalk"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/server/metro/instantiateMetro.ts"],"sourcesContent":["import { ExpoConfig, getConfig } from '@expo/config';\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport { getDefaultConfig, LoadOptions } from '@expo/metro-config';\nimport chalk from 'chalk';\nimport http from 'http';\nimport type Metro from 'metro';\nimport { ReadOnlyGraph } from 'metro';\nimport Bundler from 'metro/src/Bundler';\nimport type { TransformOptions } from 'metro/src/DeltaBundler/Worker';\nimport MetroHmrServer from 'metro/src/HmrServer';\nimport RevisionNotFoundError from 'metro/src/IncrementalBundler/RevisionNotFoundError';\nimport formatBundlingError from 'metro/src/lib/formatBundlingError';\nimport { loadConfig, resolveConfig, ConfigT } from 'metro-config';\nimport { Terminal } from 'metro-core';\nimport util from 'node:util';\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);\n\n const sendLog = (...args: any[]) => {\n this._logLines.push(\n // format args like console.log\n util.format(...args)\n );\n this._scheduleUpdate();\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\nexport async function loadMetroConfigAsync(\n projectRoot: string,\n options: LoadOptions,\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 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 process.env.EXPO_USE_FAST_RESOLVER = '1';\n }\n\n const isReactCanaryEnabled =\n (exp.experiments?.reactServerComponentRoutes ||\n serverActionsEnabled ||\n exp.experiments?.reactCanary) ??\n false;\n\n if (isReactCanaryEnabled) {\n // The fast resolver is required for React canary to work as it can switch the node_modules location for react imports.\n process.env.EXPO_USE_FAST_RESOLVER = '1';\n }\n\n const serverRoot = getMetroServerRoot(projectRoot);\n const terminalReporter = new MetroTerminalReporter(serverRoot, terminal);\n\n const hasConfig = await resolveConfig(options.config, projectRoot);\n let config: ConfigT = {\n ...(await loadConfig(\n { cwd: projectRoot, projectRoot, ...options },\n // If the project does not have a metro.config.js, then we use the default config.\n hasConfig.isEmpty ? getDefaultConfig(projectRoot) : undefined\n )),\n reporter: {\n update(event: any) {\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.warn(`Experimental React Compiler is 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_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\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 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: Omit<LoadOptions, 'logger'>,\n {\n isExporting,\n exp = getConfig(metroBundler.projectRoot, {\n skipSDKVersionRequirement: true,\n }).exp,\n }: { isExporting: boolean; exp?: ExpoConfig }\n): Promise<{\n metro: Metro.Server;\n hmrServer: MetroHmrServer | 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 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 metroBundler,\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: Metro.Server) => {\n if (customEnhanceMiddleware) {\n metroMiddleware = customEnhanceMiddleware(metroMiddleware, server);\n }\n return middleware.use(metroMiddleware);\n };\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 ...websocketEndpoints,\n ...createDevToolsPluginWebsocketEndpoint(),\n },\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: Metro.Server, 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: typeof import('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n\n try {\n hmrJSBundle = require('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n } catch {\n // 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('metro/src/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 (this: MetroHmrServer, group, options, changeEvent) {\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 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/metro-runtime/src/virtual.js` for production RSC exports.\n !filePath.match(/\\/@expo\\/metro-runtime\\/rsc\\/virtual\\.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","sendLog","args","_logLines","push","util","format","_scheduleUpdate","flush","console","log","info","terminal","process","stdout","projectRoot","options","exp","isExporting","getMetroBundler","config","reportEvent","serverActionsEnabled","experiments","reactServerFunctions","env","EXPO_UNSTABLE_SERVER_FUNCTIONS","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","EXPO_USE_FAST_RESOLVER","isReactCanaryEnabled","reactCanary","serverRoot","getMetroServerRoot","terminalReporter","MetroTerminalReporter","hasConfig","resolveConfig","loadConfig","cwd","isEmpty","getDefaultConfig","undefined","reporter","update","event","globalThis","__requireCycleIgnorePatterns","resolver","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reactCompiler","Log","warn","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isFastResolverEnabled","isNamedRequiresEnabled","isReactServerComponentsEnabled","setEventReporter","logger","metroBundler","getConfig","skipSDKVersionRequirement","metroConfig","metro","getBundler","middleware","messagesSocket","eventsSocket","websocketEndpoints","createMetroMiddleware","prependMiddleware","createCorsMiddleware","debugMiddleware","debugWebsocketEndpoints","createDebugMiddleware","Object","assign","use","createJsInspectorMiddleware","customEnhanceMiddleware","server","enhanceMiddleware","metroMiddleware","attachAtlasAsync","resetAtlasFile","hmrServer","runServer","createDevToolsPluginWebsocketEndpoint","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","set","moduleIdContext","hmrUpdate","clientUrl","createModuleId","moduleId","includeAsyncPaths","graphOptions","lazy","_config","unstable_serverRoot","error","formattedError","messageSocket","split","sep","join","dom","match","routerRoot","asyncRoutes","clientBoundaries","CI","chalk"],"mappings":"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"}
@@ -176,7 +176,7 @@ function getStackAsFormattedLog(projectRoot, { stack, codeFrame, error, showColl
176
176
  const stackLines = [];
177
177
  const backupStackLines = [];
178
178
  stackProps.forEach((frame)=>{
179
- const shouldShow = frame.collapse && !showCollapsedFrames;
179
+ const shouldShow = !frame.collapse || showCollapsedFrames;
180
180
  const position = _terminallink().default.isSupported ? (0, _terminallink().default)(frame.subtitle, frame.subtitle) : frame.subtitle;
181
181
  let lineItem = _chalk().default.gray(` ${frame.title} (${position})`);
182
182
  if (frame.collapse) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/metroErrorInterface.ts"],"sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport chalk from 'chalk';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\nimport { parse, StackFrame } from 'stacktrace-parser';\nimport terminalLink from 'terminal-link';\n\nimport { LogBoxLog } from './log-box/LogBoxLog';\nimport type { CodeFrame, StackFrame as MetroStackFrame } from './log-box/LogBoxSymbolication';\nimport { getStackFormattedLocation } from './log-box/formatProjectFilePath';\nimport { Log } from '../../../log';\nimport { stripAnsi } from '../../../utils/ansi';\nimport { env } from '../../../utils/env';\nimport { CommandError, SilentError } from '../../../utils/errors';\nimport { createMetroEndpointAsync } from '../getStaticRenderFunctions';\n\nfunction fill(width: number): string {\n return Array(width).join(' ');\n}\n\nfunction formatPaths(config: { filePath: string | null; line?: number; col?: number }) {\n const filePath = chalk.reset(config.filePath);\n return (\n chalk.dim('(') +\n filePath +\n chalk.dim(`:${[config.line, config.col].filter(Boolean).join(':')})`)\n );\n}\n\nexport async function logMetroErrorWithStack(\n projectRoot: string,\n {\n stack,\n codeFrame,\n error,\n }: {\n stack: MetroStackFrame[];\n codeFrame?: CodeFrame;\n error: Error;\n }\n) {\n if (error instanceof SilentError) {\n return;\n }\n\n // process.stdout.write('\\u001b[0m'); // Reset attributes\n // process.stdout.write('\\u001bc'); // Reset the terminal\n\n Log.log();\n Log.log(chalk.red('Metro error: ') + error.message);\n Log.log();\n\n if (error instanceof CommandError) {\n return;\n }\n\n Log.log(\n getStackAsFormattedLog(projectRoot, { stack, codeFrame, error, showCollapsedFrames: true })\n );\n}\n\nexport function getStackAsFormattedLog(\n projectRoot: string,\n {\n stack,\n codeFrame,\n error,\n showCollapsedFrames = env.EXPO_DEBUG,\n }: {\n stack: MetroStackFrame[];\n codeFrame?: CodeFrame;\n error?: Error;\n showCollapsedFrames?: boolean;\n }\n): string {\n const logs: string[] = [];\n let hasCodeFramePresented = false;\n if (codeFrame) {\n const maxWarningLineLength = Math.max(800, process.stdout.columns);\n\n const lineText = codeFrame.content;\n const isPreviewTooLong = codeFrame.content\n .split('\\n')\n .some((line) => line.length > maxWarningLineLength);\n const column = codeFrame.location?.column;\n // When the preview is too long, we skip reading the file and attempting to apply\n // code coloring, this is because it can get very slow.\n if (isPreviewTooLong) {\n let previewLine = '';\n let cursorLine = '';\n\n const formattedPath = formatPaths({\n filePath: codeFrame.fileName,\n line: codeFrame.location?.row,\n col: codeFrame.location?.column,\n });\n // Create a curtailed preview line like:\n // `...transition:'fade'},k._updatePropsStack=function(){clearImmediate(k._updateImmediate),k._updateImmediate...`\n // If there is no text preview or column number, we can't do anything.\n if (lineText && column != null) {\n const rangeWindow = Math.round(\n Math.max(codeFrame.fileName?.length ?? 0, Math.max(80, process.stdout.columns)) / 2\n );\n let minBounds = Math.max(0, column - rangeWindow);\n const maxBounds = Math.min(minBounds + rangeWindow * 2, lineText.length);\n previewLine = lineText.slice(minBounds, maxBounds);\n\n // If we splice content off the start, then we should append `...`.\n // This is unlikely to happen since we limit the activation size.\n if (minBounds > 0) {\n // Adjust the min bounds so the cursor is aligned after we add the \"...\"\n minBounds -= 3;\n previewLine = chalk.dim('...') + previewLine;\n }\n if (maxBounds < lineText.length) {\n previewLine += chalk.dim('...');\n }\n\n // If the column property could be found, then use that to fix the cursor location which is often broken in regex.\n cursorLine = (column == null ? '' : fill(column) + chalk.reset('^')).slice(minBounds);\n\n logs.push(formattedPath, '', previewLine, cursorLine, chalk.dim('(error truncated)'));\n hasCodeFramePresented = true;\n }\n } else {\n logs.push(codeFrame.content);\n hasCodeFramePresented = true;\n }\n }\n\n if (stack?.length) {\n const stackProps = stack.map((frame) => {\n return {\n title: frame.methodName,\n subtitle: getStackFormattedLocation(projectRoot, frame),\n collapse: frame.collapse,\n };\n });\n\n const stackLines: string[] = [];\n const backupStackLines: string[] = [];\n\n stackProps.forEach((frame) => {\n const shouldShow = frame.collapse && !showCollapsedFrames;\n\n const position = terminalLink.isSupported\n ? terminalLink(frame.subtitle, frame.subtitle)\n : frame.subtitle;\n let lineItem = chalk.gray(` ${frame.title} (${position})`);\n\n if (frame.collapse) {\n lineItem = chalk.dim(lineItem);\n }\n // Never show the internal module system.\n const isMetroRuntime =\n /\\/metro-runtime\\/src\\/polyfills\\/require\\.js/.test(frame.subtitle) ||\n /\\/metro-require\\/require\\.js/.test(frame.subtitle);\n if (!isMetroRuntime) {\n if (shouldShow) {\n stackLines.push(lineItem);\n }\n backupStackLines.push(lineItem);\n }\n });\n\n if (hasCodeFramePresented) {\n logs.push('');\n }\n logs.push(chalk.bold`Call Stack`);\n\n if (!backupStackLines.length) {\n logs.push(chalk.gray(' No stack trace available.'));\n } else {\n // If there are not stack lines then it means the error likely happened in the node modules, in this case we should fallback to showing all the\n // the stacks to give the user whatever help we can.\n const displayStack = stackLines.length ? stackLines : backupStackLines;\n logs.push(displayStack.join('\\n'));\n }\n } else if (error) {\n logs.push(chalk.gray(` ${error.stack}`));\n }\n return logs.join('\\n');\n}\n\nexport const IS_METRO_BUNDLE_ERROR_SYMBOL = Symbol('_isMetroBundleError');\nconst HAS_LOGGED_SYMBOL = Symbol('_hasLoggedInCLI');\n\nexport async function logMetroError(\n projectRoot: string,\n {\n error,\n }: {\n error: Error & {\n [HAS_LOGGED_SYMBOL]?: boolean;\n };\n }\n) {\n if (error instanceof SilentError || error[HAS_LOGGED_SYMBOL]) {\n return;\n }\n error[HAS_LOGGED_SYMBOL] = true;\n\n const stack = parseErrorStack(projectRoot, error.stack);\n\n const log = new LogBoxLog({\n level: 'static',\n message: {\n content: error.message,\n substitutions: [],\n },\n isComponentError: false,\n stack,\n category: 'static',\n componentStack: [],\n });\n\n await new Promise((res) => log.symbolicate('stack', res));\n\n logMetroErrorWithStack(projectRoot, {\n stack: log.symbolicated?.stack?.stack ?? [],\n codeFrame: log.codeFrame,\n error,\n });\n}\n\nfunction isTransformError(\n error: any\n): error is { type: 'TransformError'; filename: string; lineNumber: number; column: number } {\n return error.type === 'TransformError';\n}\n\n/** @returns the html required to render the static metro error as an SPA. */\nfunction logFromError({ error, projectRoot }: { error: Error; projectRoot: string }) {\n // Remap direct Metro Node.js errors to a format that will appear more client-friendly in the logbox UI.\n let stack: MetroStackFrame[] | undefined;\n if (isTransformError(error) && error.filename) {\n // Syntax errors in static rendering.\n stack = [\n {\n file: path.join(projectRoot, error.filename),\n methodName: '<unknown>',\n arguments: [],\n // TODO: Import stack\n lineNumber: error.lineNumber,\n column: error.column,\n },\n ];\n } else if ('originModulePath' in error && typeof error.originModulePath === 'string') {\n // TODO: Use import stack here when the error is resolution based.\n stack = [\n {\n file: error.originModulePath,\n methodName: '<unknown>',\n arguments: [],\n // TODO: Import stack\n lineNumber: 0,\n column: 0,\n },\n ];\n } else {\n stack = parseErrorStack(projectRoot, error.stack);\n }\n\n return new LogBoxLog({\n level: 'static',\n message: {\n content: error.message,\n substitutions: [],\n },\n isComponentError: false,\n stack,\n category: 'static',\n componentStack: [],\n });\n}\n\n/** @returns the html required to render the static metro error as an SPA. */\nexport async function logMetroErrorAsync({\n error,\n projectRoot,\n}: {\n error: Error;\n projectRoot: string;\n}) {\n const log = logFromError({ projectRoot, error });\n\n await new Promise<void>((res) => log.symbolicate('stack', () => res()));\n\n logMetroErrorWithStack(projectRoot, {\n stack: log.symbolicated?.stack?.stack ?? [],\n codeFrame: log.codeFrame,\n error,\n });\n}\n\n/** @returns the html required to render the static metro error as an SPA. */\nexport async function getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot,\n}: {\n error: Error;\n projectRoot: string;\n routerRoot: string;\n}) {\n const log = logFromError({ projectRoot, error });\n\n await new Promise<void>((res) => log.symbolicate('stack', () => res()));\n\n logMetroErrorWithStack(projectRoot, {\n stack: log.symbolicated?.stack?.stack ?? [],\n codeFrame: log.codeFrame,\n error,\n });\n\n if ('message' in log && 'content' in log.message && typeof log.message.content === 'string') {\n log.message.content = stripAnsi(log.message.content)!;\n }\n\n const logBoxContext = {\n selectedLogIndex: 0,\n isDisabled: false,\n logs: [log],\n };\n const html = `<html><head><style>#root,body,html{height:100%}body{overflow:hidden}#root{display:flex}</style></head><body><div id=\"root\"></div><script id=\"_expo-static-error\" type=\"application/json\">${JSON.stringify(\n logBoxContext\n )}</script></body></html>`;\n\n const errorOverlayEntry = await createMetroEndpointAsync(\n projectRoot,\n // Keep the URL relative\n '',\n resolveFrom(projectRoot, 'expo-router/_error'),\n {\n mode: 'development',\n platform: 'web',\n minify: false,\n optimize: false,\n usedExports: false,\n baseUrl: '',\n routerRoot,\n isExporting: false,\n reactCompiler: false,\n }\n );\n\n const htmlWithJs = html.replace('</body>', `<script src=${errorOverlayEntry}></script></body>`);\n return htmlWithJs;\n}\n\nfunction parseErrorStack(\n projectRoot: string,\n stack?: string\n): (StackFrame & { collapse?: boolean })[] {\n if (stack == null) {\n return [];\n }\n if (Array.isArray(stack)) {\n return stack;\n }\n\n const serverRoot = getMetroServerRoot(projectRoot);\n\n return parse(stack)\n .map((frame) => {\n // frame.file will mostly look like `http://localhost:8081/index.bundle?platform=web&dev=true&hot=false`\n\n if (frame.file) {\n // SSR will sometimes have absolute paths followed by `.bundle?...`, we need to try and make them relative paths and append a dev server URL.\n if (frame.file.startsWith('/') && frame.file.includes('bundle?') && !canParse(frame.file)) {\n // Malformed stack file from SSR. Attempt to repair.\n frame.file = 'https://localhost:8081/' + path.relative(serverRoot, frame.file);\n }\n }\n\n return {\n ...frame,\n column: frame.column != null ? frame.column - 1 : null,\n };\n })\n .filter((frame) => frame.file && !frame.file.includes('node_modules'));\n}\n\nfunction canParse(url: string): boolean {\n try {\n // eslint-disable-next-line no-new\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n"],"names":["IS_METRO_BUNDLE_ERROR_SYMBOL","getErrorOverlayHtmlAsync","getStackAsFormattedLog","logMetroError","logMetroErrorAsync","logMetroErrorWithStack","fill","width","Array","join","formatPaths","config","filePath","chalk","reset","dim","line","col","filter","Boolean","projectRoot","stack","codeFrame","error","SilentError","Log","log","red","message","CommandError","showCollapsedFrames","env","EXPO_DEBUG","logs","hasCodeFramePresented","maxWarningLineLength","Math","max","process","stdout","columns","lineText","content","isPreviewTooLong","split","some","length","column","location","previewLine","cursorLine","formattedPath","fileName","row","rangeWindow","round","minBounds","maxBounds","min","slice","push","stackProps","map","frame","title","methodName","subtitle","getStackFormattedLocation","collapse","stackLines","backupStackLines","forEach","shouldShow","position","terminalLink","isSupported","lineItem","gray","isMetroRuntime","test","bold","displayStack","Symbol","HAS_LOGGED_SYMBOL","parseErrorStack","LogBoxLog","level","substitutions","isComponentError","category","componentStack","Promise","res","symbolicate","symbolicated","isTransformError","type","logFromError","filename","file","path","arguments","lineNumber","originModulePath","routerRoot","stripAnsi","logBoxContext","selectedLogIndex","isDisabled","html","JSON","stringify","errorOverlayEntry","createMetroEndpointAsync","resolveFrom","mode","platform","minify","optimize","usedExports","baseUrl","isExporting","reactCompiler","htmlWithJs","replace","isArray","serverRoot","getMetroServerRoot","parse","startsWith","includes","canParse","relative","url","URL"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/server/metro/metroErrorInterface.ts"],"sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport chalk from 'chalk';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\nimport { parse, StackFrame } from 'stacktrace-parser';\nimport terminalLink from 'terminal-link';\n\nimport { LogBoxLog } from './log-box/LogBoxLog';\nimport type { CodeFrame, StackFrame as MetroStackFrame } from './log-box/LogBoxSymbolication';\nimport { getStackFormattedLocation } from './log-box/formatProjectFilePath';\nimport { Log } from '../../../log';\nimport { stripAnsi } from '../../../utils/ansi';\nimport { env } from '../../../utils/env';\nimport { CommandError, SilentError } from '../../../utils/errors';\nimport { createMetroEndpointAsync } from '../getStaticRenderFunctions';\n\nfunction fill(width: number): string {\n return Array(width).join(' ');\n}\n\nfunction formatPaths(config: { filePath: string | null; line?: number; col?: number }) {\n const filePath = chalk.reset(config.filePath);\n return (\n chalk.dim('(') +\n filePath +\n chalk.dim(`:${[config.line, config.col].filter(Boolean).join(':')})`)\n );\n}\n\nexport async function logMetroErrorWithStack(\n projectRoot: string,\n {\n stack,\n codeFrame,\n error,\n }: {\n stack: MetroStackFrame[];\n codeFrame?: CodeFrame;\n error: Error;\n }\n) {\n if (error instanceof SilentError) {\n return;\n }\n\n // process.stdout.write('\\u001b[0m'); // Reset attributes\n // process.stdout.write('\\u001bc'); // Reset the terminal\n\n Log.log();\n Log.log(chalk.red('Metro error: ') + error.message);\n Log.log();\n\n if (error instanceof CommandError) {\n return;\n }\n\n Log.log(\n getStackAsFormattedLog(projectRoot, { stack, codeFrame, error, showCollapsedFrames: true })\n );\n}\n\nexport function getStackAsFormattedLog(\n projectRoot: string,\n {\n stack,\n codeFrame,\n error,\n showCollapsedFrames = env.EXPO_DEBUG,\n }: {\n stack: MetroStackFrame[];\n codeFrame?: CodeFrame;\n error?: Error;\n showCollapsedFrames?: boolean;\n }\n): string {\n const logs: string[] = [];\n let hasCodeFramePresented = false;\n if (codeFrame) {\n const maxWarningLineLength = Math.max(800, process.stdout.columns);\n\n const lineText = codeFrame.content;\n const isPreviewTooLong = codeFrame.content\n .split('\\n')\n .some((line) => line.length > maxWarningLineLength);\n const column = codeFrame.location?.column;\n // When the preview is too long, we skip reading the file and attempting to apply\n // code coloring, this is because it can get very slow.\n if (isPreviewTooLong) {\n let previewLine = '';\n let cursorLine = '';\n\n const formattedPath = formatPaths({\n filePath: codeFrame.fileName,\n line: codeFrame.location?.row,\n col: codeFrame.location?.column,\n });\n // Create a curtailed preview line like:\n // `...transition:'fade'},k._updatePropsStack=function(){clearImmediate(k._updateImmediate),k._updateImmediate...`\n // If there is no text preview or column number, we can't do anything.\n if (lineText && column != null) {\n const rangeWindow = Math.round(\n Math.max(codeFrame.fileName?.length ?? 0, Math.max(80, process.stdout.columns)) / 2\n );\n let minBounds = Math.max(0, column - rangeWindow);\n const maxBounds = Math.min(minBounds + rangeWindow * 2, lineText.length);\n previewLine = lineText.slice(minBounds, maxBounds);\n\n // If we splice content off the start, then we should append `...`.\n // This is unlikely to happen since we limit the activation size.\n if (minBounds > 0) {\n // Adjust the min bounds so the cursor is aligned after we add the \"...\"\n minBounds -= 3;\n previewLine = chalk.dim('...') + previewLine;\n }\n if (maxBounds < lineText.length) {\n previewLine += chalk.dim('...');\n }\n\n // If the column property could be found, then use that to fix the cursor location which is often broken in regex.\n cursorLine = (column == null ? '' : fill(column) + chalk.reset('^')).slice(minBounds);\n\n logs.push(formattedPath, '', previewLine, cursorLine, chalk.dim('(error truncated)'));\n hasCodeFramePresented = true;\n }\n } else {\n logs.push(codeFrame.content);\n hasCodeFramePresented = true;\n }\n }\n\n if (stack?.length) {\n const stackProps = stack.map((frame) => {\n return {\n title: frame.methodName,\n subtitle: getStackFormattedLocation(projectRoot, frame),\n collapse: frame.collapse,\n };\n });\n\n const stackLines: string[] = [];\n const backupStackLines: string[] = [];\n\n stackProps.forEach((frame) => {\n const shouldShow = !frame.collapse || showCollapsedFrames;\n\n const position = terminalLink.isSupported\n ? terminalLink(frame.subtitle, frame.subtitle)\n : frame.subtitle;\n let lineItem = chalk.gray(` ${frame.title} (${position})`);\n\n if (frame.collapse) {\n lineItem = chalk.dim(lineItem);\n }\n // Never show the internal module system.\n const isMetroRuntime =\n /\\/metro-runtime\\/src\\/polyfills\\/require\\.js/.test(frame.subtitle) ||\n /\\/metro-require\\/require\\.js/.test(frame.subtitle);\n if (!isMetroRuntime) {\n if (shouldShow) {\n stackLines.push(lineItem);\n }\n backupStackLines.push(lineItem);\n }\n });\n\n if (hasCodeFramePresented) {\n logs.push('');\n }\n logs.push(chalk.bold`Call Stack`);\n\n if (!backupStackLines.length) {\n logs.push(chalk.gray(' No stack trace available.'));\n } else {\n // If there are not stack lines then it means the error likely happened in the node modules, in this case we should fallback to showing all the\n // the stacks to give the user whatever help we can.\n const displayStack = stackLines.length ? stackLines : backupStackLines;\n logs.push(displayStack.join('\\n'));\n }\n } else if (error) {\n logs.push(chalk.gray(` ${error.stack}`));\n }\n return logs.join('\\n');\n}\n\nexport const IS_METRO_BUNDLE_ERROR_SYMBOL = Symbol('_isMetroBundleError');\nconst HAS_LOGGED_SYMBOL = Symbol('_hasLoggedInCLI');\n\nexport async function logMetroError(\n projectRoot: string,\n {\n error,\n }: {\n error: Error & {\n [HAS_LOGGED_SYMBOL]?: boolean;\n };\n }\n) {\n if (error instanceof SilentError || error[HAS_LOGGED_SYMBOL]) {\n return;\n }\n error[HAS_LOGGED_SYMBOL] = true;\n\n const stack = parseErrorStack(projectRoot, error.stack);\n\n const log = new LogBoxLog({\n level: 'static',\n message: {\n content: error.message,\n substitutions: [],\n },\n isComponentError: false,\n stack,\n category: 'static',\n componentStack: [],\n });\n\n await new Promise((res) => log.symbolicate('stack', res));\n\n logMetroErrorWithStack(projectRoot, {\n stack: log.symbolicated?.stack?.stack ?? [],\n codeFrame: log.codeFrame,\n error,\n });\n}\n\nfunction isTransformError(\n error: any\n): error is { type: 'TransformError'; filename: string; lineNumber: number; column: number } {\n return error.type === 'TransformError';\n}\n\n/** @returns the html required to render the static metro error as an SPA. */\nfunction logFromError({ error, projectRoot }: { error: Error; projectRoot: string }) {\n // Remap direct Metro Node.js errors to a format that will appear more client-friendly in the logbox UI.\n let stack: MetroStackFrame[] | undefined;\n if (isTransformError(error) && error.filename) {\n // Syntax errors in static rendering.\n stack = [\n {\n file: path.join(projectRoot, error.filename),\n methodName: '<unknown>',\n arguments: [],\n // TODO: Import stack\n lineNumber: error.lineNumber,\n column: error.column,\n },\n ];\n } else if ('originModulePath' in error && typeof error.originModulePath === 'string') {\n // TODO: Use import stack here when the error is resolution based.\n stack = [\n {\n file: error.originModulePath,\n methodName: '<unknown>',\n arguments: [],\n // TODO: Import stack\n lineNumber: 0,\n column: 0,\n },\n ];\n } else {\n stack = parseErrorStack(projectRoot, error.stack);\n }\n\n return new LogBoxLog({\n level: 'static',\n message: {\n content: error.message,\n substitutions: [],\n },\n isComponentError: false,\n stack,\n category: 'static',\n componentStack: [],\n });\n}\n\n/** @returns the html required to render the static metro error as an SPA. */\nexport async function logMetroErrorAsync({\n error,\n projectRoot,\n}: {\n error: Error;\n projectRoot: string;\n}) {\n const log = logFromError({ projectRoot, error });\n\n await new Promise<void>((res) => log.symbolicate('stack', () => res()));\n\n logMetroErrorWithStack(projectRoot, {\n stack: log.symbolicated?.stack?.stack ?? [],\n codeFrame: log.codeFrame,\n error,\n });\n}\n\n/** @returns the html required to render the static metro error as an SPA. */\nexport async function getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot,\n}: {\n error: Error;\n projectRoot: string;\n routerRoot: string;\n}) {\n const log = logFromError({ projectRoot, error });\n\n await new Promise<void>((res) => log.symbolicate('stack', () => res()));\n\n logMetroErrorWithStack(projectRoot, {\n stack: log.symbolicated?.stack?.stack ?? [],\n codeFrame: log.codeFrame,\n error,\n });\n\n if ('message' in log && 'content' in log.message && typeof log.message.content === 'string') {\n log.message.content = stripAnsi(log.message.content)!;\n }\n\n const logBoxContext = {\n selectedLogIndex: 0,\n isDisabled: false,\n logs: [log],\n };\n const html = `<html><head><style>#root,body,html{height:100%}body{overflow:hidden}#root{display:flex}</style></head><body><div id=\"root\"></div><script id=\"_expo-static-error\" type=\"application/json\">${JSON.stringify(\n logBoxContext\n )}</script></body></html>`;\n\n const errorOverlayEntry = await createMetroEndpointAsync(\n projectRoot,\n // Keep the URL relative\n '',\n resolveFrom(projectRoot, 'expo-router/_error'),\n {\n mode: 'development',\n platform: 'web',\n minify: false,\n optimize: false,\n usedExports: false,\n baseUrl: '',\n routerRoot,\n isExporting: false,\n reactCompiler: false,\n }\n );\n\n const htmlWithJs = html.replace('</body>', `<script src=${errorOverlayEntry}></script></body>`);\n return htmlWithJs;\n}\n\nfunction parseErrorStack(\n projectRoot: string,\n stack?: string\n): (StackFrame & { collapse?: boolean })[] {\n if (stack == null) {\n return [];\n }\n if (Array.isArray(stack)) {\n return stack;\n }\n\n const serverRoot = getMetroServerRoot(projectRoot);\n\n return parse(stack)\n .map((frame) => {\n // frame.file will mostly look like `http://localhost:8081/index.bundle?platform=web&dev=true&hot=false`\n\n if (frame.file) {\n // SSR will sometimes have absolute paths followed by `.bundle?...`, we need to try and make them relative paths and append a dev server URL.\n if (frame.file.startsWith('/') && frame.file.includes('bundle?') && !canParse(frame.file)) {\n // Malformed stack file from SSR. Attempt to repair.\n frame.file = 'https://localhost:8081/' + path.relative(serverRoot, frame.file);\n }\n }\n\n return {\n ...frame,\n column: frame.column != null ? frame.column - 1 : null,\n };\n })\n .filter((frame) => frame.file && !frame.file.includes('node_modules'));\n}\n\nfunction canParse(url: string): boolean {\n try {\n // eslint-disable-next-line no-new\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n"],"names":["IS_METRO_BUNDLE_ERROR_SYMBOL","getErrorOverlayHtmlAsync","getStackAsFormattedLog","logMetroError","logMetroErrorAsync","logMetroErrorWithStack","fill","width","Array","join","formatPaths","config","filePath","chalk","reset","dim","line","col","filter","Boolean","projectRoot","stack","codeFrame","error","SilentError","Log","log","red","message","CommandError","showCollapsedFrames","env","EXPO_DEBUG","logs","hasCodeFramePresented","maxWarningLineLength","Math","max","process","stdout","columns","lineText","content","isPreviewTooLong","split","some","length","column","location","previewLine","cursorLine","formattedPath","fileName","row","rangeWindow","round","minBounds","maxBounds","min","slice","push","stackProps","map","frame","title","methodName","subtitle","getStackFormattedLocation","collapse","stackLines","backupStackLines","forEach","shouldShow","position","terminalLink","isSupported","lineItem","gray","isMetroRuntime","test","bold","displayStack","Symbol","HAS_LOGGED_SYMBOL","parseErrorStack","LogBoxLog","level","substitutions","isComponentError","category","componentStack","Promise","res","symbolicate","symbolicated","isTransformError","type","logFromError","filename","file","path","arguments","lineNumber","originModulePath","routerRoot","stripAnsi","logBoxContext","selectedLogIndex","isDisabled","html","JSON","stringify","errorOverlayEntry","createMetroEndpointAsync","resolveFrom","mode","platform","minify","optimize","usedExports","baseUrl","isExporting","reactCompiler","htmlWithJs","replace","isArray","serverRoot","getMetroServerRoot","parse","startsWith","includes","canParse","relative","url","URL"],"mappings":"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"}
@@ -106,7 +106,6 @@ function ensureProcessExitsAfterDelay(waitUntilExitMs = 10000, startedAtMs = Dat
106
106
  _nodeprocess().default.stdin.isTTY ? 'TTYWrap' : 'PipeWrap'
107
107
  ];
108
108
  // Check active resources, besides the TTYWrap/PipeWrap (process.stdin, process.stdout, process.stderr)
109
- // @ts-expect-error Added in v17.3.0, v16.14.0 but unavailable in v18 typings
110
109
  const activeResources = _nodeprocess().default.getActiveResourcesInfo();
111
110
  // Filter the active resource list by subtracting the expected resources, in undeterministic order
112
111
  const unexpectedActiveResources = activeResources.filter((activeResource)=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/exit.ts"],"sourcesContent":["import { ChildProcess } from 'node:child_process';\nimport process from 'node:process';\n\nimport { guardAsync } from './fn';\nimport { warn } from '../log';\n\nconst debug = require('debug')('expo:utils:exit') as typeof console.log;\n\ntype AsyncExitHook = (signal: NodeJS.Signals) => void | Promise<void>;\n\nconst PRE_EXIT_SIGNALS: NodeJS.Signals[] = ['SIGHUP', 'SIGINT', 'SIGTERM', 'SIGBREAK'];\n\n// We create a queue since Node.js throws an error if we try to append too many listeners:\n// (node:4405) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added to [process]. Use emitter.setMaxListeners() to increase limit\nconst queue: AsyncExitHook[] = [];\n\nlet unsubscribe: (() => void) | null = null;\n\n/** Add functions that run before the process exits. Returns a function for removing the listeners. */\nexport function installExitHooks(asyncExitHook: AsyncExitHook): () => void {\n // We need to instantiate the master listener the first time the queue is used.\n if (!queue.length) {\n // Track the master listener so we can remove it later.\n unsubscribe = attachMasterListener();\n }\n\n queue.push(asyncExitHook);\n\n return () => {\n const index = queue.indexOf(asyncExitHook);\n if (index >= 0) {\n queue.splice(index, 1);\n }\n // Clean up the master listener if we don't need it anymore.\n if (!queue.length) {\n unsubscribe?.();\n }\n };\n}\n\n// Create a function that runs before the process exits and guards against running multiple times.\nfunction createExitHook(signal: NodeJS.Signals) {\n return guardAsync(async () => {\n debug(`pre-exit (signal: ${signal}, queue length: ${queue.length})`);\n\n for (const [index, hookAsync] of Object.entries(queue)) {\n try {\n await hookAsync(signal);\n } catch (error: any) {\n debug(`Error in exit hook: %O (queue: ${index})`, error);\n }\n }\n\n debug(`post-exit (code: ${process.exitCode ?? 0})`);\n\n process.exit();\n });\n}\n\nfunction attachMasterListener() {\n const hooks: [NodeJS.Signals, () => any][] = [];\n for (const signal of PRE_EXIT_SIGNALS) {\n const hook = createExitHook(signal);\n hooks.push([signal, hook]);\n process.on(signal, hook);\n }\n return () => {\n for (const [signal, hook] of hooks) {\n process.removeListener(signal, hook);\n }\n };\n}\n\n/**\n * Monitor if the current process is exiting before the delay is reached.\n * If there are active resources, the process will be forced to exit after the delay is reached.\n *\n * @see https://nodejs.org/docs/latest-v18.x/api/process.html#processgetactiveresourcesinfo\n */\nexport function ensureProcessExitsAfterDelay(waitUntilExitMs = 10000, startedAtMs = Date.now()) {\n // Create a list of the expected active resources before exiting.\n // Note, the order is undeterministic\n const expectedResources = [\n process.stdout.isTTY ? 'TTYWrap' : 'PipeWrap',\n process.stderr.isTTY ? 'TTYWrap' : 'PipeWrap',\n process.stdin.isTTY ? 'TTYWrap' : 'PipeWrap',\n ];\n // Check active resources, besides the TTYWrap/PipeWrap (process.stdin, process.stdout, process.stderr)\n // @ts-expect-error Added in v17.3.0, v16.14.0 but unavailable in v18 typings\n const activeResources = process.getActiveResourcesInfo() as string[];\n // Filter the active resource list by subtracting the expected resources, in undeterministic order\n const unexpectedActiveResources = activeResources.filter((activeResource) => {\n const index = expectedResources.indexOf(activeResource);\n if (index >= 0) {\n expectedResources.splice(index, 1);\n return false;\n }\n\n return true;\n });\n\n const canExitProcess = !unexpectedActiveResources.length;\n if (canExitProcess) {\n return debug('no active resources detected, process can safely exit');\n } else {\n debug(\n `process is trying to exit, but is stuck on unexpected active resources:`,\n unexpectedActiveResources\n );\n }\n\n // Check if the process needs to be force-closed\n const elapsedTime = Date.now() - startedAtMs;\n if (elapsedTime > waitUntilExitMs) {\n debug('active handles detected past the exit delay, forcefully exiting:', activeResources);\n tryWarnActiveProcesses();\n return process.exit(0);\n }\n\n const timeoutId = setTimeout(() => {\n // Ensure the timeout is cleared before checking the active resources\n clearTimeout(timeoutId);\n // Check if the process can exit\n ensureProcessExitsAfterDelay(waitUntilExitMs, startedAtMs);\n }, 100);\n}\n\n/**\n * Try to warn the user about unexpected active processes running in the background.\n * This uses the internal `process._getActiveHandles` method, within a try-catch block.\n * If active child processes are detected, the commands of these processes are logged.\n *\n * @example ```bash\n * Done writing bundle output\n * Detected 2 processes preventing Expo from exiting, forcefully exiting now.\n * - node /Users/cedric/../node_modules/nativewind/dist/metro/tailwind/v3/child.js\n * - node /Users/cedric/../node_modules/nativewind/dist/metro/tailwind/v3/child.js\n * ```\n */\nfunction tryWarnActiveProcesses() {\n let activeProcesses: string[] = [];\n\n try {\n const children: ChildProcess[] = process\n // @ts-expect-error - This is an internal method, not designed to be exposed. It's also our only way to get this info\n ._getActiveHandles()\n .filter((handle: any) => handle instanceof ChildProcess);\n\n if (children.length) {\n activeProcesses = children.map((child) => child.spawnargs.join(' '));\n }\n } catch (error) {\n debug('failed to get active process information:', error);\n }\n\n if (!activeProcesses.length) {\n warn('Something prevented Expo from exiting, forcefully exiting now.');\n } else {\n const singularOrPlural =\n activeProcesses.length === 1 ? '1 process' : `${activeProcesses.length} processes`;\n\n warn(`Detected ${singularOrPlural} preventing Expo from exiting, forcefully exiting now.`);\n warn(' - ' + activeProcesses.join('\\n - '));\n }\n}\n"],"names":["ensureProcessExitsAfterDelay","installExitHooks","debug","require","PRE_EXIT_SIGNALS","queue","unsubscribe","asyncExitHook","length","attachMasterListener","push","index","indexOf","splice","createExitHook","signal","guardAsync","hookAsync","Object","entries","error","process","exitCode","exit","hooks","hook","on","removeListener","waitUntilExitMs","startedAtMs","Date","now","expectedResources","stdout","isTTY","stderr","stdin","activeResources","getActiveResourcesInfo","unexpectedActiveResources","filter","activeResource","canExitProcess","elapsedTime","tryWarnActiveProcesses","timeoutId","setTimeout","clearTimeout","activeProcesses","children","_getActiveHandles","handle","ChildProcess","map","child","spawnargs","join","warn","singularOrPlural"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/exit.ts"],"sourcesContent":["import { ChildProcess } from 'node:child_process';\nimport process from 'node:process';\n\nimport { guardAsync } from './fn';\nimport { warn } from '../log';\n\nconst debug = require('debug')('expo:utils:exit') as typeof console.log;\n\ntype AsyncExitHook = (signal: NodeJS.Signals) => void | Promise<void>;\n\nconst PRE_EXIT_SIGNALS: NodeJS.Signals[] = ['SIGHUP', 'SIGINT', 'SIGTERM', 'SIGBREAK'];\n\n// We create a queue since Node.js throws an error if we try to append too many listeners:\n// (node:4405) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added to [process]. Use emitter.setMaxListeners() to increase limit\nconst queue: AsyncExitHook[] = [];\n\nlet unsubscribe: (() => void) | null = null;\n\n/** Add functions that run before the process exits. Returns a function for removing the listeners. */\nexport function installExitHooks(asyncExitHook: AsyncExitHook): () => void {\n // We need to instantiate the master listener the first time the queue is used.\n if (!queue.length) {\n // Track the master listener so we can remove it later.\n unsubscribe = attachMasterListener();\n }\n\n queue.push(asyncExitHook);\n\n return () => {\n const index = queue.indexOf(asyncExitHook);\n if (index >= 0) {\n queue.splice(index, 1);\n }\n // Clean up the master listener if we don't need it anymore.\n if (!queue.length) {\n unsubscribe?.();\n }\n };\n}\n\n// Create a function that runs before the process exits and guards against running multiple times.\nfunction createExitHook(signal: NodeJS.Signals) {\n return guardAsync(async () => {\n debug(`pre-exit (signal: ${signal}, queue length: ${queue.length})`);\n\n for (const [index, hookAsync] of Object.entries(queue)) {\n try {\n await hookAsync(signal);\n } catch (error: any) {\n debug(`Error in exit hook: %O (queue: ${index})`, error);\n }\n }\n\n debug(`post-exit (code: ${process.exitCode ?? 0})`);\n\n process.exit();\n });\n}\n\nfunction attachMasterListener() {\n const hooks: [NodeJS.Signals, () => any][] = [];\n for (const signal of PRE_EXIT_SIGNALS) {\n const hook = createExitHook(signal);\n hooks.push([signal, hook]);\n process.on(signal, hook);\n }\n return () => {\n for (const [signal, hook] of hooks) {\n process.removeListener(signal, hook);\n }\n };\n}\n\n/**\n * Monitor if the current process is exiting before the delay is reached.\n * If there are active resources, the process will be forced to exit after the delay is reached.\n *\n * @see https://nodejs.org/docs/latest-v18.x/api/process.html#processgetactiveresourcesinfo\n */\nexport function ensureProcessExitsAfterDelay(waitUntilExitMs = 10000, startedAtMs = Date.now()) {\n // Create a list of the expected active resources before exiting.\n // Note, the order is undeterministic\n const expectedResources = [\n process.stdout.isTTY ? 'TTYWrap' : 'PipeWrap',\n process.stderr.isTTY ? 'TTYWrap' : 'PipeWrap',\n process.stdin.isTTY ? 'TTYWrap' : 'PipeWrap',\n ];\n // Check active resources, besides the TTYWrap/PipeWrap (process.stdin, process.stdout, process.stderr)\n const activeResources = process.getActiveResourcesInfo() as string[];\n // Filter the active resource list by subtracting the expected resources, in undeterministic order\n const unexpectedActiveResources = activeResources.filter((activeResource) => {\n const index = expectedResources.indexOf(activeResource);\n if (index >= 0) {\n expectedResources.splice(index, 1);\n return false;\n }\n\n return true;\n });\n\n const canExitProcess = !unexpectedActiveResources.length;\n if (canExitProcess) {\n return debug('no active resources detected, process can safely exit');\n } else {\n debug(\n `process is trying to exit, but is stuck on unexpected active resources:`,\n unexpectedActiveResources\n );\n }\n\n // Check if the process needs to be force-closed\n const elapsedTime = Date.now() - startedAtMs;\n if (elapsedTime > waitUntilExitMs) {\n debug('active handles detected past the exit delay, forcefully exiting:', activeResources);\n tryWarnActiveProcesses();\n return process.exit(0);\n }\n\n const timeoutId = setTimeout(() => {\n // Ensure the timeout is cleared before checking the active resources\n clearTimeout(timeoutId);\n // Check if the process can exit\n ensureProcessExitsAfterDelay(waitUntilExitMs, startedAtMs);\n }, 100);\n}\n\n/**\n * Try to warn the user about unexpected active processes running in the background.\n * This uses the internal `process._getActiveHandles` method, within a try-catch block.\n * If active child processes are detected, the commands of these processes are logged.\n *\n * @example ```bash\n * Done writing bundle output\n * Detected 2 processes preventing Expo from exiting, forcefully exiting now.\n * - node /Users/cedric/../node_modules/nativewind/dist/metro/tailwind/v3/child.js\n * - node /Users/cedric/../node_modules/nativewind/dist/metro/tailwind/v3/child.js\n * ```\n */\nfunction tryWarnActiveProcesses() {\n let activeProcesses: string[] = [];\n\n try {\n const children: ChildProcess[] = process\n // @ts-expect-error - This is an internal method, not designed to be exposed. It's also our only way to get this info\n ._getActiveHandles()\n .filter((handle: any) => handle instanceof ChildProcess);\n\n if (children.length) {\n activeProcesses = children.map((child) => child.spawnargs.join(' '));\n }\n } catch (error) {\n debug('failed to get active process information:', error);\n }\n\n if (!activeProcesses.length) {\n warn('Something prevented Expo from exiting, forcefully exiting now.');\n } else {\n const singularOrPlural =\n activeProcesses.length === 1 ? '1 process' : `${activeProcesses.length} processes`;\n\n warn(`Detected ${singularOrPlural} preventing Expo from exiting, forcefully exiting now.`);\n warn(' - ' + activeProcesses.join('\\n - '));\n }\n}\n"],"names":["ensureProcessExitsAfterDelay","installExitHooks","debug","require","PRE_EXIT_SIGNALS","queue","unsubscribe","asyncExitHook","length","attachMasterListener","push","index","indexOf","splice","createExitHook","signal","guardAsync","hookAsync","Object","entries","error","process","exitCode","exit","hooks","hook","on","removeListener","waitUntilExitMs","startedAtMs","Date","now","expectedResources","stdout","isTTY","stderr","stdin","activeResources","getActiveResourcesInfo","unexpectedActiveResources","filter","activeResource","canExitProcess","elapsedTime","tryWarnActiveProcesses","timeoutId","setTimeout","clearTimeout","activeProcesses","children","_getActiveHandles","handle","ChildProcess","map","child","spawnargs","join","warn","singularOrPlural"],"mappings":";;;;;;;;;;;IA+EgBA,4BAA4B;eAA5BA;;IA5DAC,gBAAgB;eAAhBA;;;;yBAnBa;;;;;;;gEACT;;;;;;oBAEO;qBACN;;;;;;AAErB,MAAMC,QAAQC,QAAQ,SAAS;AAI/B,MAAMC,mBAAqC;IAAC;IAAU;IAAU;IAAW;CAAW;AAEtF,0FAA0F;AAC1F,+KAA+K;AAC/K,MAAMC,QAAyB,EAAE;AAEjC,IAAIC,cAAmC;AAGhC,SAASL,iBAAiBM,aAA4B;IAC3D,+EAA+E;IAC/E,IAAI,CAACF,MAAMG,MAAM,EAAE;QACjB,uDAAuD;QACvDF,cAAcG;IAChB;IAEAJ,MAAMK,IAAI,CAACH;IAEX,OAAO;QACL,MAAMI,QAAQN,MAAMO,OAAO,CAACL;QAC5B,IAAII,SAAS,GAAG;YACdN,MAAMQ,MAAM,CAACF,OAAO;QACtB;QACA,4DAA4D;QAC5D,IAAI,CAACN,MAAMG,MAAM,EAAE;YACjBF,+BAAAA;QACF;IACF;AACF;AAEA,kGAAkG;AAClG,SAASQ,eAAeC,MAAsB;IAC5C,OAAOC,IAAAA,cAAU,EAAC;QAChBd,MAAM,CAAC,kBAAkB,EAAEa,OAAO,gBAAgB,EAAEV,MAAMG,MAAM,CAAC,CAAC,CAAC;QAEnE,KAAK,MAAM,CAACG,OAAOM,UAAU,IAAIC,OAAOC,OAAO,CAACd,OAAQ;YACtD,IAAI;gBACF,MAAMY,UAAUF;YAClB,EAAE,OAAOK,OAAY;gBACnBlB,MAAM,CAAC,+BAA+B,EAAES,MAAM,CAAC,CAAC,EAAES;YACpD;QACF;QAEAlB,MAAM,CAAC,iBAAiB,EAAEmB,sBAAO,CAACC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAElDD,sBAAO,CAACE,IAAI;IACd;AACF;AAEA,SAASd;IACP,MAAMe,QAAuC,EAAE;IAC/C,KAAK,MAAMT,UAAUX,iBAAkB;QACrC,MAAMqB,OAAOX,eAAeC;QAC5BS,MAAMd,IAAI,CAAC;YAACK;YAAQU;SAAK;QACzBJ,sBAAO,CAACK,EAAE,CAACX,QAAQU;IACrB;IACA,OAAO;QACL,KAAK,MAAM,CAACV,QAAQU,KAAK,IAAID,MAAO;YAClCH,sBAAO,CAACM,cAAc,CAACZ,QAAQU;QACjC;IACF;AACF;AAQO,SAASzB,6BAA6B4B,kBAAkB,KAAK,EAAEC,cAAcC,KAAKC,GAAG,EAAE;IAC5F,iEAAiE;IACjE,qCAAqC;IACrC,MAAMC,oBAAoB;QACxBX,sBAAO,CAACY,MAAM,CAACC,KAAK,GAAG,YAAY;QACnCb,sBAAO,CAACc,MAAM,CAACD,KAAK,GAAG,YAAY;QACnCb,sBAAO,CAACe,KAAK,CAACF,KAAK,GAAG,YAAY;KACnC;IACD,uGAAuG;IACvG,MAAMG,kBAAkBhB,sBAAO,CAACiB,sBAAsB;IACtD,kGAAkG;IAClG,MAAMC,4BAA4BF,gBAAgBG,MAAM,CAAC,CAACC;QACxD,MAAM9B,QAAQqB,kBAAkBpB,OAAO,CAAC6B;QACxC,IAAI9B,SAAS,GAAG;YACdqB,kBAAkBnB,MAAM,CAACF,OAAO;YAChC,OAAO;QACT;QAEA,OAAO;IACT;IAEA,MAAM+B,iBAAiB,CAACH,0BAA0B/B,MAAM;IACxD,IAAIkC,gBAAgB;QAClB,OAAOxC,MAAM;IACf,OAAO;QACLA,MACE,CAAC,uEAAuE,CAAC,EACzEqC;IAEJ;IAEA,gDAAgD;IAChD,MAAMI,cAAcb,KAAKC,GAAG,KAAKF;IACjC,IAAIc,cAAcf,iBAAiB;QACjC1B,MAAM,oEAAoEmC;QAC1EO;QACA,OAAOvB,sBAAO,CAACE,IAAI,CAAC;IACtB;IAEA,MAAMsB,YAAYC,WAAW;QAC3B,qEAAqE;QACrEC,aAAaF;QACb,gCAAgC;QAChC7C,6BAA6B4B,iBAAiBC;IAChD,GAAG;AACL;AAEA;;;;;;;;;;;CAWC,GACD,SAASe;IACP,IAAII,kBAA4B,EAAE;IAElC,IAAI;QACF,MAAMC,WAA2B5B,sBAAO,AACtC,qHAAqH;SACpH6B,iBAAiB,GACjBV,MAAM,CAAC,CAACW,SAAgBA,kBAAkBC,iCAAY;QAEzD,IAAIH,SAASzC,MAAM,EAAE;YACnBwC,kBAAkBC,SAASI,GAAG,CAAC,CAACC,QAAUA,MAAMC,SAAS,CAACC,IAAI,CAAC;QACjE;IACF,EAAE,OAAOpC,OAAO;QACdlB,MAAM,6CAA6CkB;IACrD;IAEA,IAAI,CAAC4B,gBAAgBxC,MAAM,EAAE;QAC3BiD,IAAAA,SAAI,EAAC;IACP,OAAO;QACL,MAAMC,mBACJV,gBAAgBxC,MAAM,KAAK,IAAI,cAAc,GAAGwC,gBAAgBxC,MAAM,CAAC,UAAU,CAAC;QAEpFiD,IAAAA,SAAI,EAAC,CAAC,SAAS,EAAEC,iBAAiB,sDAAsD,CAAC;QACzFD,IAAAA,SAAI,EAAC,SAAST,gBAAgBQ,IAAI,CAAC;IACrC;AACF"}
@@ -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/${"0.23.1"}`,
36
+ 'user-agent': `expo-cli/${"0.23.3"}`,
37
37
  authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
38
38
  };
39
39
  }
@@ -83,7 +83,7 @@ function createContext() {
83
83
  cpu: summarizeCpuInfo(),
84
84
  app: {
85
85
  name: 'expo/cli',
86
- version: "0.23.1"
86
+ version: "0.23.3"
87
87
  },
88
88
  ci: _ciinfo().isCI ? {
89
89
  name: _ciinfo().name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/cli",
3
- "version": "0.23.1",
3
+ "version": "0.23.3",
4
4
  "description": "The Expo CLI",
5
5
  "main": "build/bin/cli",
6
6
  "bin": {
@@ -42,17 +42,17 @@
42
42
  "@0no-co/graphql.web": "^1.0.8",
43
43
  "@babel/runtime": "^7.20.0",
44
44
  "@expo/code-signing-certificates": "^0.0.5",
45
- "@expo/config": "~11.0.0",
46
- "@expo/config-plugins": "~9.1.1",
45
+ "@expo/config": "~11.0.1",
46
+ "@expo/config-plugins": "~9.1.2",
47
47
  "@expo/devcert": "^1.1.2",
48
- "@expo/env": "~1.0.1",
49
- "@expo/image-utils": "^0.7.0",
50
- "@expo/json-file": "^9.1.0",
51
- "@expo/metro-config": "~0.20.1",
52
- "@expo/osascript": "^2.2.0",
53
- "@expo/package-manager": "^1.8.0",
54
- "@expo/plist": "^0.3.0",
55
- "@expo/prebuild-config": "^8.1.1",
48
+ "@expo/env": "~1.0.2",
49
+ "@expo/image-utils": "^0.7.1",
50
+ "@expo/json-file": "^9.1.1",
51
+ "@expo/metro-config": "~0.20.2",
52
+ "@expo/osascript": "^2.2.1",
53
+ "@expo/package-manager": "^1.8.1",
54
+ "@expo/plist": "^0.3.1",
55
+ "@expo/prebuild-config": "^8.1.2",
56
56
  "@expo/spawn-async": "^1.7.2",
57
57
  "@expo/ws-tunnel": "^1.0.1",
58
58
  "@expo/xcpretty": "^4.3.0",
@@ -109,7 +109,7 @@
109
109
  "devDependencies": {
110
110
  "@expo/multipart-body-parser": "^1.0.0",
111
111
  "@expo/ngrok": "4.1.3",
112
- "@expo/server": "^0.6.0",
112
+ "@expo/server": "^0.6.1",
113
113
  "@graphql-codegen/cli": "^2.16.3",
114
114
  "@graphql-codegen/typescript": "^2.8.7",
115
115
  "@graphql-codegen/typescript-operations": "^2.5.12",
@@ -125,7 +125,7 @@
125
125
  "@types/execa": "^0.9.0",
126
126
  "@types/getenv": "^1.0.0",
127
127
  "@types/klaw-sync": "^6.0.0",
128
- "@types/node": "^18.19.34",
128
+ "@types/node": "^22.14.0",
129
129
  "@types/npm-package-arg": "^6.1.0",
130
130
  "@types/picomatch": "^2.3.3",
131
131
  "@types/progress": "^2.0.5",
@@ -139,7 +139,7 @@
139
139
  "@types/ws": "^8.5.4",
140
140
  "devtools-protocol": "^0.0.1113120",
141
141
  "expo-atlas": "^0.4.0",
142
- "expo-module-scripts": "^4.1.0",
142
+ "expo-module-scripts": "^4.1.1",
143
143
  "find-process": "^1.4.7",
144
144
  "jest-runner-tsd": "^6.0.0",
145
145
  "klaw-sync": "^6.0.0",
@@ -152,5 +152,5 @@
152
152
  "tree-kill": "^1.2.2",
153
153
  "tsd": "^0.28.1"
154
154
  },
155
- "gitHead": "2487c7aa9b5ef6a7052e82bbf9a53604c2ed273f"
155
+ "gitHead": "c0356b18430ea33f7a0be93e173dfd2ca00edc88"
156
156
  }