@expo/cli 0.24.12 → 0.24.14

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.
Files changed (47) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/metro-require/require.js +6 -4
  3. package/build/src/export/exportHermes.js +2 -2
  4. package/build/src/export/exportHermes.js.map +1 -1
  5. package/build/src/prebuild/resolveTemplate.js +4 -4
  6. package/build/src/prebuild/resolveTemplate.js.map +1 -1
  7. package/build/src/run/ios/XcodeBuild.js +3 -3
  8. package/build/src/run/ios/XcodeBuild.js.map +1 -1
  9. package/build/src/start/doctor/SecurityBinPrerequisite.js +1 -1
  10. package/build/src/start/doctor/SecurityBinPrerequisite.js.map +1 -1
  11. package/build/src/start/doctor/dependencies/ensureDependenciesAsync.js +1 -1
  12. package/build/src/start/doctor/dependencies/ensureDependenciesAsync.js.map +1 -1
  13. package/build/src/start/doctor/dependencies/resolvePackages.js +1 -1
  14. package/build/src/start/doctor/dependencies/resolvePackages.js.map +1 -1
  15. package/build/src/start/doctor/ngrok/ExternalModule.js +1 -1
  16. package/build/src/start/doctor/ngrok/ExternalModule.js.map +1 -1
  17. package/build/src/start/platforms/PlatformManager.js +1 -1
  18. package/build/src/start/platforms/PlatformManager.js.map +1 -1
  19. package/build/src/start/platforms/android/AndroidPlatformManager.js +1 -1
  20. package/build/src/start/platforms/android/AndroidPlatformManager.js.map +1 -1
  21. package/build/src/start/platforms/android/getDevices.js +1 -1
  22. package/build/src/start/platforms/android/getDevices.js.map +1 -1
  23. package/build/src/start/platforms/ios/AppleDeviceManager.js +1 -1
  24. package/build/src/start/platforms/ios/AppleDeviceManager.js.map +1 -1
  25. package/build/src/start/platforms/ios/xcrun.js +1 -1
  26. package/build/src/start/platforms/ios/xcrun.js.map +1 -1
  27. package/build/src/start/server/metro/MetroTerminalReporter.js +1 -1
  28. package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
  29. package/build/src/start/server/metro/createJResolver.js +2 -2
  30. package/build/src/start/server/metro/createJResolver.js.map +1 -1
  31. package/build/src/start/server/metro/createServerComponentsMiddleware.js +0 -1
  32. package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
  33. package/build/src/start/server/metro/runServer-fork.js +1 -1
  34. package/build/src/start/server/metro/runServer-fork.js.map +1 -1
  35. package/build/src/start/server/metro/withMetroMultiPlatform.js +1 -1
  36. package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
  37. package/build/src/start/server/middleware/CorsMiddleware.js +1 -1
  38. package/build/src/start/server/middleware/CorsMiddleware.js.map +1 -1
  39. package/build/src/utils/build-cache-providers/index.js +2 -2
  40. package/build/src/utils/build-cache-providers/index.js.map +1 -1
  41. package/build/src/utils/modifyConfigAsync.js +1 -1
  42. package/build/src/utils/modifyConfigAsync.js.map +1 -1
  43. package/build/src/utils/scheme.js +1 -1
  44. package/build/src/utils/scheme.js.map +1 -1
  45. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  46. package/build/src/utils/telemetry/utils/context.js +1 -1
  47. package/package.json +8 -8
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.24.12");
126
+ console.log("0.24.14");
127
127
  process.exit(0);
128
128
  }
129
129
  if (args['--non-interactive']) {
@@ -1,8 +1,10 @@
1
1
  'use strict';
2
- global.__r = metroRequire;
3
- global[`${__METRO_GLOBAL_PREFIX__}__d`] = define;
4
- global.__c = clear;
5
- global.__registerSegment = registerSegment;
2
+ if (__DEV__ || !global[`${__METRO_GLOBAL_PREFIX__}__d`]) {
3
+ global.__r = metroRequire;
4
+ global[`${__METRO_GLOBAL_PREFIX__}__d`] = define;
5
+ global.__c = clear;
6
+ global.__registerSegment = registerSegment;
7
+ }
6
8
  var modules = clear();
7
9
  const EMPTY = {};
8
10
  const CYCLE_DETECTED = {};
@@ -115,10 +115,10 @@ function parseGradleProperties(content) {
115
115
  async function maybeThrowFromInconsistentEngineAsync(projectRoot, configFilePath, platform, isHermesManaged) {
116
116
  const configFileName = _path().default.basename(configFilePath);
117
117
  if (platform === 'android' && await maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged)) {
118
- throw new Error(`JavaScript engine configuration is inconsistent between ${configFileName} and Android native project.\n` + `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\n` + `In Android native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\n` + `Please check the following files for inconsistencies:\n` + ` - ${configFilePath}\n` + ` - ${_path().default.join(projectRoot, 'android', 'gradle.properties')}\n` + ` - ${_path().default.join(projectRoot, 'android', 'app', 'build.gradle')}\n` + 'Learn more: https://expo.fyi/hermes-android-config');
118
+ throw new Error(`JavaScript engine configuration is inconsistent between ${configFileName} and Android native project.\n` + `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\n` + `In Android native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\n` + `Check the following files for inconsistencies:\n` + ` - ${configFilePath}\n` + ` - ${_path().default.join(projectRoot, 'android', 'gradle.properties')}\n` + ` - ${_path().default.join(projectRoot, 'android', 'app', 'build.gradle')}\n` + 'Learn more: https://expo.fyi/hermes-android-config');
119
119
  }
120
120
  if (platform === 'ios' && await maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged)) {
121
- throw new Error(`JavaScript engine configuration is inconsistent between ${configFileName} and iOS native project.\n` + `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\n` + `In iOS native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\n` + `Please check the following files for inconsistencies:\n` + ` - ${configFilePath}\n` + ` - ${_path().default.join(projectRoot, 'ios', 'Podfile')}\n` + ` - ${_path().default.join(projectRoot, 'ios', 'Podfile.properties.json')}\n` + 'Learn more: https://expo.fyi/hermes-ios-config');
121
+ throw new Error(`JavaScript engine configuration is inconsistent between ${configFileName} and iOS native project.\n` + `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\n` + `In iOS native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\n` + `Check the following files for inconsistencies:\n` + ` - ${configFilePath}\n` + ` - ${_path().default.join(projectRoot, 'ios', 'Podfile')}\n` + ` - ${_path().default.join(projectRoot, 'ios', 'Podfile.properties.json')}\n` + 'Learn more: https://expo.fyi/hermes-ios-config');
122
122
  }
123
123
  }
124
124
  async function maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/export/exportHermes.ts"],"sourcesContent":["import { ExpoConfig, getConfigFilePaths, Platform } from '@expo/config';\nimport JsonFile from '@expo/json-file';\nimport fs from 'fs';\nimport path from 'path';\n\nexport async function assertEngineMismatchAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>,\n platform: Platform\n) {\n const isHermesManaged = isEnableHermesManaged(exp, platform);\n const paths = getConfigFilePaths(projectRoot);\n const configFilePath = paths.dynamicConfigPath ?? paths.staticConfigPath ?? 'app.json';\n await maybeThrowFromInconsistentEngineAsync(\n projectRoot,\n configFilePath,\n platform,\n isHermesManaged\n );\n}\n\nexport function isEnableHermesManaged(\n expoConfig: Partial<Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>>,\n platform: string\n): boolean {\n switch (platform) {\n case 'android': {\n return (expoConfig.android?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n case 'ios': {\n return (expoConfig.ios?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n default:\n return false;\n }\n}\n\nexport function parseGradleProperties(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (let line of content.split('\\n')) {\n line = line.trim();\n if (!line || line.startsWith('#')) {\n continue;\n }\n\n const sepIndex = line.indexOf('=');\n const key = line.slice(0, sepIndex);\n const value = line.slice(sepIndex + 1);\n result[key] = value;\n }\n return result;\n}\n\nexport async function maybeThrowFromInconsistentEngineAsync(\n projectRoot: string,\n configFilePath: string,\n platform: string,\n isHermesManaged: boolean\n): Promise<void> {\n const configFileName = path.basename(configFilePath);\n if (\n platform === 'android' &&\n (await maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged))\n ) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and Android native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In Android native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Please check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'android', 'gradle.properties')}\\n` +\n ` - ${path.join(projectRoot, 'android', 'app', 'build.gradle')}\\n` +\n 'Learn more: https://expo.fyi/hermes-android-config'\n );\n }\n\n if (platform === 'ios' && (await maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged))) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and iOS native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In iOS native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Please check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile')}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile.properties.json')}\\n` +\n 'Learn more: https://expo.fyi/hermes-ios-config'\n );\n }\n}\n\nexport async function maybeInconsistentEngineAndroidAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check android native project if by chance to be consistent between app config\n\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(await fs.promises.readFile(gradlePropertiesPath, 'utf8'));\n const isHermesBare = props['hermesEnabled'] === 'true';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function isHermesPossiblyEnabled(projectRoot: string): boolean | null {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for \":hermes_enabled => true\"\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = fs.readFileSync(podfilePath, 'utf8');\n const isPropsReference =\n content.search(\n /^\\s*:hermes_enabled\\s*=>\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*'hermes',?/m\n ) >= 0;\n const isHermesBare = content.search(/^\\s*:hermes_enabled\\s*=>\\s*true,?\\s+/m) >= 0;\n if (!isPropsReference && isHermesBare) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n try {\n const props = JsonFile.read(podfilePropertiesPath);\n return props['expo.jsEngine'] === 'hermes';\n } catch {\n // ignore\n }\n }\n\n return null;\n}\n\nexport async function maybeInconsistentEngineIosAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for \":hermes_enabled => true\"\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = await fs.promises.readFile(podfilePath, 'utf8');\n const isPropsReference =\n content.search(\n /^\\s*:hermes_enabled\\s*=>\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*'hermes',?/m\n ) >= 0;\n const isHermesBare = content.search(/^\\s*:hermes_enabled\\s*=>\\s*true,?\\s+/m) >= 0;\n if (!isPropsReference && isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n const props = await parsePodfilePropertiesAsync(podfilePropertiesPath);\n const isHermesBare = props['expo.jsEngine'] === 'hermes';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\n// https://github.com/facebook/hermes/blob/release-v0.5/include/hermes/BCGen/HBC/BytecodeFileFormat.h#L24-L25\nconst HERMES_MAGIC_HEADER = 'c61fbc03c103191f';\n\nexport async function isHermesBytecodeBundleAsync(file: string): Promise<boolean> {\n const header = await readHermesHeaderAsync(file);\n return header.subarray(0, 8).toString('hex') === HERMES_MAGIC_HEADER;\n}\n\nexport async function getHermesBytecodeBundleVersionAsync(file: string): Promise<number> {\n const header = await readHermesHeaderAsync(file);\n if (header.subarray(0, 8).toString('hex') !== HERMES_MAGIC_HEADER) {\n throw new Error('Invalid hermes bundle file');\n }\n return header.readUInt32LE(8);\n}\n\nasync function readHermesHeaderAsync(file: string): Promise<Buffer> {\n const fd = await fs.promises.open(file, 'r');\n const buffer = Buffer.alloc(12);\n await fd.read(buffer, 0, 12, null);\n await fd.close();\n return buffer;\n}\n\nasync function parsePodfilePropertiesAsync(\n podfilePropertiesPath: string\n): Promise<Record<string, string>> {\n try {\n return JSON.parse(await fs.promises.readFile(podfilePropertiesPath, 'utf8'));\n } catch {\n return {};\n }\n}\n\nexport function isAndroidUsingHermes(projectRoot: string) {\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(fs.readFileSync(gradlePropertiesPath, 'utf8'));\n return props['hermesEnabled'] === 'true';\n }\n\n // Assume Hermes is used by default.\n return true;\n}\n\nexport function isIosUsingHermes(projectRoot: string) {\n // If nullish, then assume Hermes is used.\n return isHermesPossiblyEnabled(projectRoot) !== false;\n}\n"],"names":["assertEngineMismatchAsync","getHermesBytecodeBundleVersionAsync","isAndroidUsingHermes","isEnableHermesManaged","isHermesBytecodeBundleAsync","isHermesPossiblyEnabled","isIosUsingHermes","maybeInconsistentEngineAndroidAsync","maybeInconsistentEngineIosAsync","maybeThrowFromInconsistentEngineAsync","parseGradleProperties","projectRoot","exp","platform","isHermesManaged","paths","getConfigFilePaths","configFilePath","dynamicConfigPath","staticConfigPath","expoConfig","android","jsEngine","ios","content","result","line","split","trim","startsWith","sepIndex","indexOf","key","slice","value","configFileName","path","basename","Error","join","gradlePropertiesPath","fs","existsSync","props","promises","readFile","isHermesBare","podfilePath","readFileSync","isPropsReference","search","podfilePropertiesPath","JsonFile","read","parsePodfilePropertiesAsync","HERMES_MAGIC_HEADER","file","header","readHermesHeaderAsync","subarray","toString","readUInt32LE","fd","open","buffer","Buffer","alloc","close","JSON","parse"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/export/exportHermes.ts"],"sourcesContent":["import { ExpoConfig, getConfigFilePaths, Platform } from '@expo/config';\nimport JsonFile from '@expo/json-file';\nimport fs from 'fs';\nimport path from 'path';\n\nexport async function assertEngineMismatchAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>,\n platform: Platform\n) {\n const isHermesManaged = isEnableHermesManaged(exp, platform);\n const paths = getConfigFilePaths(projectRoot);\n const configFilePath = paths.dynamicConfigPath ?? paths.staticConfigPath ?? 'app.json';\n await maybeThrowFromInconsistentEngineAsync(\n projectRoot,\n configFilePath,\n platform,\n isHermesManaged\n );\n}\n\nexport function isEnableHermesManaged(\n expoConfig: Partial<Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>>,\n platform: string\n): boolean {\n switch (platform) {\n case 'android': {\n return (expoConfig.android?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n case 'ios': {\n return (expoConfig.ios?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n default:\n return false;\n }\n}\n\nexport function parseGradleProperties(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (let line of content.split('\\n')) {\n line = line.trim();\n if (!line || line.startsWith('#')) {\n continue;\n }\n\n const sepIndex = line.indexOf('=');\n const key = line.slice(0, sepIndex);\n const value = line.slice(sepIndex + 1);\n result[key] = value;\n }\n return result;\n}\n\nexport async function maybeThrowFromInconsistentEngineAsync(\n projectRoot: string,\n configFilePath: string,\n platform: string,\n isHermesManaged: boolean\n): Promise<void> {\n const configFileName = path.basename(configFilePath);\n if (\n platform === 'android' &&\n (await maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged))\n ) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and Android native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In Android native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'android', 'gradle.properties')}\\n` +\n ` - ${path.join(projectRoot, 'android', 'app', 'build.gradle')}\\n` +\n 'Learn more: https://expo.fyi/hermes-android-config'\n );\n }\n\n if (platform === 'ios' && (await maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged))) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and iOS native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In iOS native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile')}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile.properties.json')}\\n` +\n 'Learn more: https://expo.fyi/hermes-ios-config'\n );\n }\n}\n\nexport async function maybeInconsistentEngineAndroidAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check android native project if by chance to be consistent between app config\n\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(await fs.promises.readFile(gradlePropertiesPath, 'utf8'));\n const isHermesBare = props['hermesEnabled'] === 'true';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function isHermesPossiblyEnabled(projectRoot: string): boolean | null {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for \":hermes_enabled => true\"\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = fs.readFileSync(podfilePath, 'utf8');\n const isPropsReference =\n content.search(\n /^\\s*:hermes_enabled\\s*=>\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*'hermes',?/m\n ) >= 0;\n const isHermesBare = content.search(/^\\s*:hermes_enabled\\s*=>\\s*true,?\\s+/m) >= 0;\n if (!isPropsReference && isHermesBare) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n try {\n const props = JsonFile.read(podfilePropertiesPath);\n return props['expo.jsEngine'] === 'hermes';\n } catch {\n // ignore\n }\n }\n\n return null;\n}\n\nexport async function maybeInconsistentEngineIosAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for \":hermes_enabled => true\"\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = await fs.promises.readFile(podfilePath, 'utf8');\n const isPropsReference =\n content.search(\n /^\\s*:hermes_enabled\\s*=>\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*'hermes',?/m\n ) >= 0;\n const isHermesBare = content.search(/^\\s*:hermes_enabled\\s*=>\\s*true,?\\s+/m) >= 0;\n if (!isPropsReference && isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n const props = await parsePodfilePropertiesAsync(podfilePropertiesPath);\n const isHermesBare = props['expo.jsEngine'] === 'hermes';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\n// https://github.com/facebook/hermes/blob/release-v0.5/include/hermes/BCGen/HBC/BytecodeFileFormat.h#L24-L25\nconst HERMES_MAGIC_HEADER = 'c61fbc03c103191f';\n\nexport async function isHermesBytecodeBundleAsync(file: string): Promise<boolean> {\n const header = await readHermesHeaderAsync(file);\n return header.subarray(0, 8).toString('hex') === HERMES_MAGIC_HEADER;\n}\n\nexport async function getHermesBytecodeBundleVersionAsync(file: string): Promise<number> {\n const header = await readHermesHeaderAsync(file);\n if (header.subarray(0, 8).toString('hex') !== HERMES_MAGIC_HEADER) {\n throw new Error('Invalid hermes bundle file');\n }\n return header.readUInt32LE(8);\n}\n\nasync function readHermesHeaderAsync(file: string): Promise<Buffer> {\n const fd = await fs.promises.open(file, 'r');\n const buffer = Buffer.alloc(12);\n await fd.read(buffer, 0, 12, null);\n await fd.close();\n return buffer;\n}\n\nasync function parsePodfilePropertiesAsync(\n podfilePropertiesPath: string\n): Promise<Record<string, string>> {\n try {\n return JSON.parse(await fs.promises.readFile(podfilePropertiesPath, 'utf8'));\n } catch {\n return {};\n }\n}\n\nexport function isAndroidUsingHermes(projectRoot: string) {\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(fs.readFileSync(gradlePropertiesPath, 'utf8'));\n return props['hermesEnabled'] === 'true';\n }\n\n // Assume Hermes is used by default.\n return true;\n}\n\nexport function isIosUsingHermes(projectRoot: string) {\n // If nullish, then assume Hermes is used.\n return isHermesPossiblyEnabled(projectRoot) !== false;\n}\n"],"names":["assertEngineMismatchAsync","getHermesBytecodeBundleVersionAsync","isAndroidUsingHermes","isEnableHermesManaged","isHermesBytecodeBundleAsync","isHermesPossiblyEnabled","isIosUsingHermes","maybeInconsistentEngineAndroidAsync","maybeInconsistentEngineIosAsync","maybeThrowFromInconsistentEngineAsync","parseGradleProperties","projectRoot","exp","platform","isHermesManaged","paths","getConfigFilePaths","configFilePath","dynamicConfigPath","staticConfigPath","expoConfig","android","jsEngine","ios","content","result","line","split","trim","startsWith","sepIndex","indexOf","key","slice","value","configFileName","path","basename","Error","join","gradlePropertiesPath","fs","existsSync","props","promises","readFile","isHermesBare","podfilePath","readFileSync","isPropsReference","search","podfilePropertiesPath","JsonFile","read","parsePodfilePropertiesAsync","HERMES_MAGIC_HEADER","file","header","readHermesHeaderAsync","subarray","toString","readUInt32LE","fd","open","buffer","Buffer","alloc","close","JSON","parse"],"mappings":"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"}
@@ -183,21 +183,21 @@ async function resolveAndDownloadRepoTemplateAsync(templateDirectory, oraInstanc
183
183
  }
184
184
  }
185
185
  if (!repoUrl) {
186
- oraInstance.fail(`Invalid URL: ${_chalk().default.red(`"${template}"`)}. Please use a valid URL and try again.`);
186
+ oraInstance.fail(`Invalid URL: ${_chalk().default.red(`"${template}"`)}. Try again with a valid URL.`);
187
187
  throw new _errors.AbortCommandError();
188
188
  }
189
189
  if (repoUrl.origin !== 'https://github.com') {
190
- oraInstance.fail(`Invalid URL: ${_chalk().default.red(`"${template}"`)}. Only GitHub repositories are supported. Please use a GitHub URL and try again.`);
190
+ oraInstance.fail(`Invalid URL: ${_chalk().default.red(`"${template}"`)}. Only GitHub repositories are supported. Try again with a valid GitHub URL.`);
191
191
  throw new _errors.AbortCommandError();
192
192
  }
193
193
  const repoInfo = await getRepoInfo(repoUrl, templatePath);
194
194
  if (!repoInfo) {
195
- oraInstance.fail(`Found invalid GitHub URL: ${_chalk().default.red(`"${template}"`)}. Please fix the URL and try again.`);
195
+ oraInstance.fail(`Found invalid GitHub URL: ${_chalk().default.red(`"${template}"`)}. Fix the URL and try again.`);
196
196
  throw new _errors.AbortCommandError();
197
197
  }
198
198
  const found = await hasRepo(repoInfo);
199
199
  if (!found) {
200
- oraInstance.fail(`Could not locate the repository for ${_chalk().default.red(`"${template}"`)}. Please check that the repository exists and try again.`);
200
+ oraInstance.fail(`Could not locate the repository for ${_chalk().default.red(`"${template}"`)}. Check that the repository exists and try again.`);
201
201
  throw new _errors.AbortCommandError();
202
202
  }
203
203
  oraInstance.text = _chalk().default.bold(`Downloading files from repo ${_chalk().default.cyan(template)}. This might take a moment.`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/prebuild/resolveTemplate.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport { Ora } from 'ora';\nimport semver from 'semver';\n\nimport { type ResolvedTemplateOption } from './resolveOptions';\nimport { fetchAsync } from '../api/rest/client';\nimport * as Log from '../log';\nimport { createGlobFilter } from '../utils/createFileTransform';\nimport { AbortCommandError } from '../utils/errors';\nimport {\n ExtractProps,\n downloadAndExtractNpmModuleAsync,\n extractLocalNpmTarballAsync,\n extractNpmTarballFromUrlAsync,\n} from '../utils/npm';\nimport { isUrlOk } from '../utils/url';\n\nconst debug = require('debug')('expo:prebuild:resolveTemplate') as typeof console.log;\n\ntype RepoInfo = {\n username: string;\n name: string;\n branch: string;\n filePath: string;\n};\n\nexport async function cloneTemplateAsync({\n templateDirectory,\n template,\n exp,\n ora,\n}: {\n templateDirectory: string;\n template?: ResolvedTemplateOption;\n exp: Pick<ExpoConfig, 'name' | 'sdkVersion'>;\n ora: Ora;\n}): Promise<string> {\n if (template) {\n const appName = exp.name;\n const { type, uri } = template;\n if (type === 'file') {\n return await extractLocalNpmTarballAsync(uri, {\n cwd: templateDirectory,\n name: appName,\n });\n } else if (type === 'npm') {\n return await downloadAndExtractNpmModuleAsync(uri, {\n cwd: templateDirectory,\n name: appName,\n });\n } else if (type === 'repository') {\n return await resolveAndDownloadRepoTemplateAsync(templateDirectory, ora, appName, uri);\n } else {\n throw new Error(`Unknown template type: ${type}`);\n }\n } else {\n const templatePackageName = await getTemplateNpmPackageName(exp.sdkVersion);\n return await downloadAndExtractNpmModuleAsync(templatePackageName, {\n cwd: templateDirectory,\n name: exp.name,\n });\n }\n}\n\n/** Given an `sdkVersion` like `44.0.0` return a fully qualified NPM package name like: `expo-template-bare-minimum@sdk-44` */\nfunction getTemplateNpmPackageName(sdkVersion?: string): string {\n // When undefined or UNVERSIONED, we use the latest version.\n if (!sdkVersion || sdkVersion === 'UNVERSIONED') {\n Log.log('Using an unspecified Expo SDK version. The latest template will be used.');\n return `expo-template-bare-minimum@latest`;\n }\n return `expo-template-bare-minimum@sdk-${semver.major(sdkVersion)}`;\n}\n\nasync function getRepoInfo(url: any, examplePath?: string): Promise<RepoInfo | undefined> {\n const [, username, name, t, _branch, ...file] = url.pathname.split('/');\n const filePath = examplePath ? examplePath.replace(/^\\//, '') : file.join('/');\n\n // Support repos whose entire purpose is to be an example, e.g.\n // https://github.com/:username/:my-cool-example-repo-name.\n if (t === undefined) {\n const infoResponse = await fetchAsync(`https://api.github.com/repos/${username}/${name}`);\n if (infoResponse.status !== 200) {\n return;\n }\n const info: any = await infoResponse.json();\n return { username, name, branch: info['default_branch'], filePath };\n }\n\n // If examplePath is available, the branch name takes the entire path\n const branch = examplePath\n ? `${_branch}/${file.join('/')}`.replace(new RegExp(`/${filePath}|/$`), '')\n : _branch;\n\n if (username && name && branch && t === 'tree') {\n return { username, name, branch, filePath };\n }\n return undefined;\n}\n\nfunction hasRepo({ username, name, branch, filePath }: RepoInfo) {\n const contentsUrl = `https://api.github.com/repos/${username}/${name}/contents`;\n const packagePath = `${filePath ? `/${filePath}` : ''}/package.json`;\n\n return isUrlOk(contentsUrl + packagePath + `?ref=${branch}`);\n}\n\nasync function downloadAndExtractRepoAsync(\n { username, name, branch, filePath }: RepoInfo,\n props: ExtractProps\n): Promise<string> {\n const url = `https://codeload.github.com/${username}/${name}/tar.gz/${branch}`;\n\n debug('Downloading tarball from:', url);\n\n // Extract the (sub)directory into non-empty path segments\n const directory = filePath.replace(/^\\//, '').split('/').filter(Boolean);\n // Remove the (sub)directory paths, and the root folder added by GitHub\n const strip = directory.length + 1;\n // Only extract the relevant (sub)directories, ignoring irrelevant files\n // The filder auto-ignores dotfiles, unless explicitly included\n const filter = createGlobFilter(\n !directory.length\n ? ['*/**', '*/ios/.xcode.env']\n : [`*/${directory.join('/')}/**`, `*/${directory.join('/')}/ios/.xcode.env`],\n {\n // Always ignore the `.xcworkspace` folder\n ignore: ['**/ios/*.xcworkspace/**'],\n }\n );\n\n return await extractNpmTarballFromUrlAsync(url, { ...props, strip, filter });\n}\n\nasync function resolveAndDownloadRepoTemplateAsync(\n templateDirectory: string,\n oraInstance: Ora,\n appName: string,\n template: string,\n templatePath?: string\n) {\n let repoUrl: URL | undefined;\n\n try {\n repoUrl = new URL(template);\n } catch (error: any) {\n if (error.code !== 'ERR_INVALID_URL') {\n oraInstance.fail(error);\n throw error;\n }\n }\n if (!repoUrl) {\n oraInstance.fail(\n `Invalid URL: ${chalk.red(`\"${template}\"`)}. Please use a valid URL and try again.`\n );\n throw new AbortCommandError();\n }\n\n if (repoUrl.origin !== 'https://github.com') {\n oraInstance.fail(\n `Invalid URL: ${chalk.red(\n `\"${template}\"`\n )}. Only GitHub repositories are supported. Please use a GitHub URL and try again.`\n );\n throw new AbortCommandError();\n }\n\n const repoInfo = await getRepoInfo(repoUrl, templatePath);\n\n if (!repoInfo) {\n oraInstance.fail(\n `Found invalid GitHub URL: ${chalk.red(`\"${template}\"`)}. Please fix the URL and try again.`\n );\n throw new AbortCommandError();\n }\n\n const found = await hasRepo(repoInfo);\n\n if (!found) {\n oraInstance.fail(\n `Could not locate the repository for ${chalk.red(\n `\"${template}\"`\n )}. Please check that the repository exists and try again.`\n );\n throw new AbortCommandError();\n }\n\n oraInstance.text = chalk.bold(\n `Downloading files from repo ${chalk.cyan(template)}. This might take a moment.`\n );\n\n return await downloadAndExtractRepoAsync(repoInfo, {\n cwd: templateDirectory,\n name: appName,\n });\n}\n"],"names":["cloneTemplateAsync","debug","require","templateDirectory","template","exp","ora","appName","name","type","uri","extractLocalNpmTarballAsync","cwd","downloadAndExtractNpmModuleAsync","resolveAndDownloadRepoTemplateAsync","Error","templatePackageName","getTemplateNpmPackageName","sdkVersion","Log","log","semver","major","getRepoInfo","url","examplePath","username","t","_branch","file","pathname","split","filePath","replace","join","undefined","infoResponse","fetchAsync","status","info","json","branch","RegExp","hasRepo","contentsUrl","packagePath","isUrlOk","downloadAndExtractRepoAsync","props","directory","filter","Boolean","strip","length","createGlobFilter","ignore","extractNpmTarballFromUrlAsync","oraInstance","templatePath","repoUrl","URL","error","code","fail","chalk","red","AbortCommandError","origin","repoInfo","found","text","bold","cyan"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/prebuild/resolveTemplate.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport { Ora } from 'ora';\nimport semver from 'semver';\n\nimport { type ResolvedTemplateOption } from './resolveOptions';\nimport { fetchAsync } from '../api/rest/client';\nimport * as Log from '../log';\nimport { createGlobFilter } from '../utils/createFileTransform';\nimport { AbortCommandError } from '../utils/errors';\nimport {\n ExtractProps,\n downloadAndExtractNpmModuleAsync,\n extractLocalNpmTarballAsync,\n extractNpmTarballFromUrlAsync,\n} from '../utils/npm';\nimport { isUrlOk } from '../utils/url';\n\nconst debug = require('debug')('expo:prebuild:resolveTemplate') as typeof console.log;\n\ntype RepoInfo = {\n username: string;\n name: string;\n branch: string;\n filePath: string;\n};\n\nexport async function cloneTemplateAsync({\n templateDirectory,\n template,\n exp,\n ora,\n}: {\n templateDirectory: string;\n template?: ResolvedTemplateOption;\n exp: Pick<ExpoConfig, 'name' | 'sdkVersion'>;\n ora: Ora;\n}): Promise<string> {\n if (template) {\n const appName = exp.name;\n const { type, uri } = template;\n if (type === 'file') {\n return await extractLocalNpmTarballAsync(uri, {\n cwd: templateDirectory,\n name: appName,\n });\n } else if (type === 'npm') {\n return await downloadAndExtractNpmModuleAsync(uri, {\n cwd: templateDirectory,\n name: appName,\n });\n } else if (type === 'repository') {\n return await resolveAndDownloadRepoTemplateAsync(templateDirectory, ora, appName, uri);\n } else {\n throw new Error(`Unknown template type: ${type}`);\n }\n } else {\n const templatePackageName = await getTemplateNpmPackageName(exp.sdkVersion);\n return await downloadAndExtractNpmModuleAsync(templatePackageName, {\n cwd: templateDirectory,\n name: exp.name,\n });\n }\n}\n\n/** Given an `sdkVersion` like `44.0.0` return a fully qualified NPM package name like: `expo-template-bare-minimum@sdk-44` */\nfunction getTemplateNpmPackageName(sdkVersion?: string): string {\n // When undefined or UNVERSIONED, we use the latest version.\n if (!sdkVersion || sdkVersion === 'UNVERSIONED') {\n Log.log('Using an unspecified Expo SDK version. The latest template will be used.');\n return `expo-template-bare-minimum@latest`;\n }\n return `expo-template-bare-minimum@sdk-${semver.major(sdkVersion)}`;\n}\n\nasync function getRepoInfo(url: any, examplePath?: string): Promise<RepoInfo | undefined> {\n const [, username, name, t, _branch, ...file] = url.pathname.split('/');\n const filePath = examplePath ? examplePath.replace(/^\\//, '') : file.join('/');\n\n // Support repos whose entire purpose is to be an example, e.g.\n // https://github.com/:username/:my-cool-example-repo-name.\n if (t === undefined) {\n const infoResponse = await fetchAsync(`https://api.github.com/repos/${username}/${name}`);\n if (infoResponse.status !== 200) {\n return;\n }\n const info: any = await infoResponse.json();\n return { username, name, branch: info['default_branch'], filePath };\n }\n\n // If examplePath is available, the branch name takes the entire path\n const branch = examplePath\n ? `${_branch}/${file.join('/')}`.replace(new RegExp(`/${filePath}|/$`), '')\n : _branch;\n\n if (username && name && branch && t === 'tree') {\n return { username, name, branch, filePath };\n }\n return undefined;\n}\n\nfunction hasRepo({ username, name, branch, filePath }: RepoInfo) {\n const contentsUrl = `https://api.github.com/repos/${username}/${name}/contents`;\n const packagePath = `${filePath ? `/${filePath}` : ''}/package.json`;\n\n return isUrlOk(contentsUrl + packagePath + `?ref=${branch}`);\n}\n\nasync function downloadAndExtractRepoAsync(\n { username, name, branch, filePath }: RepoInfo,\n props: ExtractProps\n): Promise<string> {\n const url = `https://codeload.github.com/${username}/${name}/tar.gz/${branch}`;\n\n debug('Downloading tarball from:', url);\n\n // Extract the (sub)directory into non-empty path segments\n const directory = filePath.replace(/^\\//, '').split('/').filter(Boolean);\n // Remove the (sub)directory paths, and the root folder added by GitHub\n const strip = directory.length + 1;\n // Only extract the relevant (sub)directories, ignoring irrelevant files\n // The filder auto-ignores dotfiles, unless explicitly included\n const filter = createGlobFilter(\n !directory.length\n ? ['*/**', '*/ios/.xcode.env']\n : [`*/${directory.join('/')}/**`, `*/${directory.join('/')}/ios/.xcode.env`],\n {\n // Always ignore the `.xcworkspace` folder\n ignore: ['**/ios/*.xcworkspace/**'],\n }\n );\n\n return await extractNpmTarballFromUrlAsync(url, { ...props, strip, filter });\n}\n\nasync function resolveAndDownloadRepoTemplateAsync(\n templateDirectory: string,\n oraInstance: Ora,\n appName: string,\n template: string,\n templatePath?: string\n) {\n let repoUrl: URL | undefined;\n\n try {\n repoUrl = new URL(template);\n } catch (error: any) {\n if (error.code !== 'ERR_INVALID_URL') {\n oraInstance.fail(error);\n throw error;\n }\n }\n if (!repoUrl) {\n oraInstance.fail(`Invalid URL: ${chalk.red(`\"${template}\"`)}. Try again with a valid URL.`);\n throw new AbortCommandError();\n }\n\n if (repoUrl.origin !== 'https://github.com') {\n oraInstance.fail(\n `Invalid URL: ${chalk.red(\n `\"${template}\"`\n )}. Only GitHub repositories are supported. Try again with a valid GitHub URL.`\n );\n throw new AbortCommandError();\n }\n\n const repoInfo = await getRepoInfo(repoUrl, templatePath);\n\n if (!repoInfo) {\n oraInstance.fail(\n `Found invalid GitHub URL: ${chalk.red(`\"${template}\"`)}. Fix the URL and try again.`\n );\n throw new AbortCommandError();\n }\n\n const found = await hasRepo(repoInfo);\n\n if (!found) {\n oraInstance.fail(\n `Could not locate the repository for ${chalk.red(\n `\"${template}\"`\n )}. Check that the repository exists and try again.`\n );\n throw new AbortCommandError();\n }\n\n oraInstance.text = chalk.bold(\n `Downloading files from repo ${chalk.cyan(template)}. This might take a moment.`\n );\n\n return await downloadAndExtractRepoAsync(repoInfo, {\n cwd: templateDirectory,\n name: appName,\n });\n}\n"],"names":["cloneTemplateAsync","debug","require","templateDirectory","template","exp","ora","appName","name","type","uri","extractLocalNpmTarballAsync","cwd","downloadAndExtractNpmModuleAsync","resolveAndDownloadRepoTemplateAsync","Error","templatePackageName","getTemplateNpmPackageName","sdkVersion","Log","log","semver","major","getRepoInfo","url","examplePath","username","t","_branch","file","pathname","split","filePath","replace","join","undefined","infoResponse","fetchAsync","status","info","json","branch","RegExp","hasRepo","contentsUrl","packagePath","isUrlOk","downloadAndExtractRepoAsync","props","directory","filter","Boolean","strip","length","createGlobFilter","ignore","extractNpmTarballFromUrlAsync","oraInstance","templatePath","repoUrl","URL","error","code","fail","chalk","red","AbortCommandError","origin","repoInfo","found","text","bold","cyan"],"mappings":"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"}
@@ -139,7 +139,7 @@ function matchEstimatedBinaryPath(buildOutput) {
139
139
  // Match the full path that contains `/(.*)/Developer/Xcode/DerivedData/(.*)/Build/Products/(.*)/(.*).app`
140
140
  const appBinaryPathMatch = buildOutput.match(/(\/(?:\\\s|[^ ])+\/Developer\/Xcode\/DerivedData\/(?:\\\s|[^ ])+\/Build\/Products\/(?:Debug|Release)-(?:[^\s/]+)\/(?:\\\s|[^ ])+\.app)/);
141
141
  if (!(appBinaryPathMatch == null ? void 0 : appBinaryPathMatch.length)) {
142
- throw new _errors.CommandError('XCODE_BUILD', `Malformed xcodebuild results: app binary path was not generated in build output. Please report this issue and run your project with Xcode instead.`);
142
+ throw new _errors.CommandError('XCODE_BUILD', `Malformed xcodebuild results: app binary path was not generated in build output. Report this issue and run your project with Xcode instead.`);
143
143
  } else {
144
144
  // Sort for the shortest
145
145
  const shortestPath = appBinaryPathMatch.filter((a)=>typeof a === 'string' && a).sort((a, b)=>a.length - b.length)[0].trim();
@@ -181,7 +181,7 @@ function getEscapedPath(filePath) {
181
181
  if (_fs().default.existsSync(unescapedPath)) {
182
182
  return unescapedPath;
183
183
  }
184
- throw new _errors.CommandError('XCODE_BUILD', `Unexpected: Generated app at path "${filePath}" cannot be read, the app cannot be installed. Please report this and build onto a simulator.`);
184
+ throw new _errors.CommandError('XCODE_BUILD', `Unexpected: Generated app at path "${filePath}" cannot be read, the app cannot be installed. Report this and build onto a simulator.`);
185
185
  }
186
186
  function extractEnvVariableFromBuild(buildOutput, variableName) {
187
187
  // Xcode can sometimes escape `=` with a backslash or put the value in quotes
@@ -190,7 +190,7 @@ function extractEnvVariableFromBuild(buildOutput, variableName) {
190
190
  ...buildOutput.matchAll(reg)
191
191
  ];
192
192
  if (!matched || !matched.length) {
193
- throw new _errors.CommandError('XCODE_BUILD', `Malformed xcodebuild results: "${variableName}" variable was not generated in build output. Please report this issue and run your project with Xcode instead.`);
193
+ throw new _errors.CommandError('XCODE_BUILD', `Malformed xcodebuild results: "${variableName}" variable was not generated in build output. Report this issue and run your project with Xcode instead.`);
194
194
  }
195
195
  return matched.map((value)=>value[1]).filter(Boolean);
196
196
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/run/ios/XcodeBuild.ts"],"sourcesContent":["import { ExpoRunFormatter } from '@expo/xcpretty';\nimport chalk from 'chalk';\nimport { spawn, SpawnOptionsWithoutStdio } from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\n\nimport { BuildProps, ProjectInfo } from './XcodeBuild.types';\nimport { ensureDeviceIsCodeSignedForDeploymentAsync } from './codeSigning/configureCodeSigning';\nimport { simulatorBuildRequiresCodeSigning } from './codeSigning/simulatorCodeSigning';\nimport * as Log from '../../log';\nimport { ensureDirectory } from '../../utils/dir';\nimport { env } from '../../utils/env';\nimport { AbortCommandError, CommandError } from '../../utils/errors';\nimport { getUserTerminal } from '../../utils/terminal';\nexport function logPrettyItem(message: string) {\n Log.log(chalk`{whiteBright \\u203A} ${message}`);\n}\n\nexport function matchEstimatedBinaryPath(buildOutput: string): string | null {\n // Match the full path that contains `/(.*)/Developer/Xcode/DerivedData/(.*)/Build/Products/(.*)/(.*).app`\n const appBinaryPathMatch = buildOutput.match(\n /(\\/(?:\\\\\\s|[^ ])+\\/Developer\\/Xcode\\/DerivedData\\/(?:\\\\\\s|[^ ])+\\/Build\\/Products\\/(?:Debug|Release)-(?:[^\\s/]+)\\/(?:\\\\\\s|[^ ])+\\.app)/\n );\n if (!appBinaryPathMatch?.length) {\n throw new CommandError(\n 'XCODE_BUILD',\n `Malformed xcodebuild results: app binary path was not generated in build output. Please report this issue and run your project with Xcode instead.`\n );\n } else {\n // Sort for the shortest\n const shortestPath = (appBinaryPathMatch.filter((a) => typeof a === 'string' && a) as string[])\n .sort((a: string, b: string) => a.length - b.length)[0]\n .trim();\n\n Log.debug(`Found app binary path: ${shortestPath}`);\n return shortestPath;\n }\n}\n/**\n *\n * @returns '/Users/evanbacon/Library/Developer/Xcode/DerivedData/myapp-gpgjqjodrxtervaufttwnsgimhrx/Build/Products/Debug-iphonesimulator/myapp.app'\n */\nexport function getAppBinaryPath(buildOutput: string) {\n // Matches what's used in \"Bundle React Native code and images\" script.\n // Requires that `-hideShellScriptEnvironment` is not included in the build command (extra logs).\n\n try {\n // Like `\\=/Users/evanbacon/Library/Developer/Xcode/DerivedData/Exponent-anpuosnglkxokahjhfszejloqfvo/Build/Products/Debug-iphonesimulator`\n const CONFIGURATION_BUILD_DIR = extractEnvVariableFromBuild(\n buildOutput,\n 'CONFIGURATION_BUILD_DIR'\n ).sort(\n // Longer name means more suffixes, we want the shortest possible one to be first.\n // Massive projects (like Expo Go) can sometimes print multiple different sets of environment variables.\n // This can become an issue with some\n (a, b) => a.length - b.length\n );\n // Like `Exponent.app`\n const UNLOCALIZED_RESOURCES_FOLDER_PATH = extractEnvVariableFromBuild(\n buildOutput,\n 'UNLOCALIZED_RESOURCES_FOLDER_PATH'\n );\n\n const binaryPath = path.join(\n // Use the shortest defined env variable (usually there's just one).\n CONFIGURATION_BUILD_DIR[0],\n // Use the last defined env variable.\n UNLOCALIZED_RESOURCES_FOLDER_PATH[UNLOCALIZED_RESOURCES_FOLDER_PATH.length - 1]\n );\n\n // If the app has a space in the name it'll fail because it isn't escaped properly by Xcode.\n return getEscapedPath(binaryPath);\n } catch (error) {\n if (error instanceof CommandError && error.code === 'XCODE_BUILD') {\n const possiblePath = matchEstimatedBinaryPath(buildOutput);\n if (possiblePath) {\n return possiblePath;\n }\n }\n throw error;\n }\n}\n\nexport function getEscapedPath(filePath: string): string {\n if (fs.existsSync(filePath)) {\n return filePath;\n }\n const unescapedPath = filePath.split(/\\\\ /).join(' ');\n if (fs.existsSync(unescapedPath)) {\n return unescapedPath;\n }\n throw new CommandError(\n 'XCODE_BUILD',\n `Unexpected: Generated app at path \"${filePath}\" cannot be read, the app cannot be installed. Please report this and build onto a simulator.`\n );\n}\n\nexport function extractEnvVariableFromBuild(buildOutput: string, variableName: string) {\n // Xcode can sometimes escape `=` with a backslash or put the value in quotes\n const reg = new RegExp(`export ${variableName}\\\\\\\\?=(.*)$`, 'mg');\n const matched = [...buildOutput.matchAll(reg)];\n\n if (!matched || !matched.length) {\n throw new CommandError(\n 'XCODE_BUILD',\n `Malformed xcodebuild results: \"${variableName}\" variable was not generated in build output. Please report this issue and run your project with Xcode instead.`\n );\n }\n return matched.map((value) => value[1]).filter(Boolean) as string[];\n}\n\nexport function getProcessOptions({\n packager,\n shouldSkipInitialBundling,\n terminal,\n port,\n eagerBundleOptions,\n}: {\n packager: boolean;\n shouldSkipInitialBundling?: boolean;\n terminal: string | undefined;\n port: number;\n eagerBundleOptions?: string;\n}): SpawnOptionsWithoutStdio {\n const SKIP_BUNDLING = shouldSkipInitialBundling ? '1' : undefined;\n if (packager) {\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\n RCT_METRO_PORT: port.toString(),\n __EXPO_EAGER_BUNDLE_OPTIONS: eagerBundleOptions,\n },\n };\n }\n\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\n __EXPO_EAGER_BUNDLE_OPTIONS: eagerBundleOptions,\n // Always skip launching the packager from a build script.\n // The script is used for people building their project directly from Xcode.\n // This essentially means \"› Running script 'Start Packager'\" does nothing.\n RCT_NO_LAUNCH_PACKAGER: 'true',\n // FORCE_BUNDLING: '0'\n },\n };\n}\n\nexport async function getXcodeBuildArgsAsync(\n props: Pick<\n BuildProps,\n | 'buildCache'\n | 'projectRoot'\n | 'xcodeProject'\n | 'configuration'\n | 'scheme'\n | 'device'\n | 'isSimulator'\n >\n): Promise<string[]> {\n const args = [\n props.xcodeProject.isWorkspace ? '-workspace' : '-project',\n props.xcodeProject.name,\n '-configuration',\n props.configuration,\n '-scheme',\n props.scheme,\n '-destination',\n `id=${props.device.udid}`,\n ];\n\n if (!props.isSimulator || simulatorBuildRequiresCodeSigning(props.projectRoot)) {\n const developmentTeamId = await ensureDeviceIsCodeSignedForDeploymentAsync(props.projectRoot);\n if (developmentTeamId) {\n args.push(\n `DEVELOPMENT_TEAM=${developmentTeamId}`,\n '-allowProvisioningUpdates',\n '-allowProvisioningDeviceRegistration'\n );\n }\n }\n\n // Add last\n if (props.buildCache === false) {\n args.push(\n // Will first clean the derived data folder.\n 'clean',\n // Then build step must be added otherwise the process will simply clean and exit.\n 'build'\n );\n }\n return args;\n}\n\nfunction spawnXcodeBuild(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { onData }: { onData: (data: string) => void }\n): Promise<{ code: number | null; results: string; error: string }> {\n const buildProcess = spawn('xcodebuild', args, options);\n\n let results = '';\n let error = '';\n\n buildProcess.stdout.on('data', (data: Buffer) => {\n const stringData = data.toString();\n results += stringData;\n onData(stringData);\n });\n\n buildProcess.stderr.on('data', (data: Buffer) => {\n const stringData = data instanceof Buffer ? data.toString() : data;\n error += stringData;\n });\n\n return new Promise(async (resolve, reject) => {\n buildProcess.on('close', (code: number) => {\n resolve({ code, results, error });\n });\n });\n}\n\nasync function spawnXcodeBuildWithFlush(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { onFlush }: { onFlush: (data: string) => void }\n): Promise<{ code: number | null; results: string; error: string }> {\n let currentBuffer = '';\n\n // Data can be sent in chunks that would have no relevance to our regex\n // this can cause massive slowdowns, so we need to ensure the data is complete before attempting to parse it.\n function flushBuffer() {\n if (!currentBuffer) {\n return;\n }\n\n const data = currentBuffer;\n // Reset buffer.\n currentBuffer = '';\n // Process data.\n onFlush(data);\n }\n\n const data = await spawnXcodeBuild(args, options, {\n onData(stringData) {\n currentBuffer += stringData;\n // Only flush the data if we have a full line.\n if (currentBuffer.endsWith(os.EOL)) {\n flushBuffer();\n }\n },\n });\n\n // Flush log data at the end just in case we missed something.\n flushBuffer();\n return data;\n}\n\nasync function spawnXcodeBuildWithFormat(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { projectRoot, xcodeProject }: { projectRoot: string; xcodeProject: ProjectInfo }\n): Promise<{ code: number | null; results: string; error: string; formatter: ExpoRunFormatter }> {\n Log.debug(` xcodebuild ${args.join(' ')}`);\n\n logPrettyItem(chalk.bold`Planning build`);\n\n const formatter = ExpoRunFormatter.create(projectRoot, {\n xcodeProject,\n isDebug: env.EXPO_DEBUG,\n });\n\n const results = await spawnXcodeBuildWithFlush(args, options, {\n onFlush(data) {\n // Process data.\n for (const line of formatter.pipe(data)) {\n // Log parsed results.\n Log.log(line);\n }\n },\n });\n\n Log.debug(`Exited with code: ${results.code}`);\n\n if (\n // User cancelled with ctrl-c\n results.code === null ||\n // Build interrupted\n results.code === 75\n ) {\n throw new AbortCommandError();\n }\n\n Log.log(formatter.getBuildSummary());\n\n return { ...results, formatter };\n}\n\nexport async function buildAsync(props: BuildProps): Promise<string> {\n const args = await getXcodeBuildArgsAsync(props);\n\n const { projectRoot, xcodeProject, shouldSkipInitialBundling, port, eagerBundleOptions } = props;\n\n const { code, results, formatter, error } = await spawnXcodeBuildWithFormat(\n args,\n getProcessOptions({\n packager: false,\n terminal: getUserTerminal(),\n shouldSkipInitialBundling,\n port,\n eagerBundleOptions,\n }),\n {\n projectRoot,\n xcodeProject,\n }\n );\n\n const logFilePath = writeBuildLogs(projectRoot, results, error);\n\n if (code !== 0) {\n // Determine if the logger found any errors;\n const wasErrorPresented = !!formatter.errors.length;\n\n if (wasErrorPresented) {\n // This has a flaw, if the user is missing a file, and there is a script error, only the missing file error will be shown.\n // They will only see the script error if they fix the missing file and rerun.\n // The flaw can be fixed by catching script errors in the custom logger.\n throw new CommandError(\n `Failed to build iOS project. \"xcodebuild\" exited with error code ${code}.`\n );\n }\n\n _assertXcodeBuildResults(code, results, error, xcodeProject, logFilePath);\n }\n return results;\n}\n\n// Exposed for testing.\nexport function _assertXcodeBuildResults(\n code: number | null,\n results: string,\n error: string,\n xcodeProject: { name: string },\n logFilePath: string\n): void {\n const errorTitle = `Failed to build iOS project. \"xcodebuild\" exited with error code ${code}.`;\n\n const throwWithMessage = (message: string): never => {\n throw new CommandError(\n `${errorTitle}\\nTo view more error logs, try building the app with Xcode directly, by opening ${xcodeProject.name}.\\n\\n` +\n message +\n `Build logs written to ${chalk.underline(logFilePath)}`\n );\n };\n\n const localizedError = error.match(/NSLocalizedFailure = \"(.*)\"/)?.[1];\n\n if (localizedError) {\n throwWithMessage(chalk.bold(localizedError) + '\\n\\n');\n }\n // Show all the log info because often times the error is coming from a shell script,\n // that invoked a node script, that started metro, which threw an error.\n\n throwWithMessage(results + '\\n\\n' + error);\n}\n\nfunction writeBuildLogs(projectRoot: string, buildOutput: string, errorOutput: string) {\n const [logFilePath, errorFilePath] = getErrorLogFilePath(projectRoot);\n\n fs.writeFileSync(logFilePath, buildOutput);\n fs.writeFileSync(errorFilePath, errorOutput);\n return logFilePath;\n}\n\nfunction getErrorLogFilePath(projectRoot: string): [string, string] {\n const folder = path.join(projectRoot, '.expo');\n ensureDirectory(folder);\n return [path.join(folder, 'xcodebuild.log'), path.join(folder, 'xcodebuild-error.log')];\n}\n"],"names":["_assertXcodeBuildResults","buildAsync","extractEnvVariableFromBuild","getAppBinaryPath","getEscapedPath","getProcessOptions","getXcodeBuildArgsAsync","logPrettyItem","matchEstimatedBinaryPath","message","Log","log","chalk","buildOutput","appBinaryPathMatch","match","length","CommandError","shortestPath","filter","a","sort","b","trim","debug","CONFIGURATION_BUILD_DIR","UNLOCALIZED_RESOURCES_FOLDER_PATH","binaryPath","path","join","error","code","possiblePath","filePath","fs","existsSync","unescapedPath","split","variableName","reg","RegExp","matched","matchAll","map","value","Boolean","packager","shouldSkipInitialBundling","terminal","port","eagerBundleOptions","SKIP_BUNDLING","undefined","env","process","RCT_TERMINAL","RCT_METRO_PORT","toString","__EXPO_EAGER_BUNDLE_OPTIONS","RCT_NO_LAUNCH_PACKAGER","props","args","xcodeProject","isWorkspace","name","configuration","scheme","device","udid","isSimulator","simulatorBuildRequiresCodeSigning","projectRoot","developmentTeamId","ensureDeviceIsCodeSignedForDeploymentAsync","push","buildCache","spawnXcodeBuild","options","onData","buildProcess","spawn","results","stdout","on","data","stringData","stderr","Buffer","Promise","resolve","reject","spawnXcodeBuildWithFlush","onFlush","currentBuffer","flushBuffer","endsWith","os","EOL","spawnXcodeBuildWithFormat","bold","formatter","ExpoRunFormatter","create","isDebug","EXPO_DEBUG","line","pipe","AbortCommandError","getBuildSummary","getUserTerminal","logFilePath","writeBuildLogs","wasErrorPresented","errors","errorTitle","throwWithMessage","underline","localizedError","errorOutput","errorFilePath","getErrorLogFilePath","writeFileSync","folder","ensureDirectory"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/run/ios/XcodeBuild.ts"],"sourcesContent":["import { ExpoRunFormatter } from '@expo/xcpretty';\nimport chalk from 'chalk';\nimport { spawn, SpawnOptionsWithoutStdio } from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\n\nimport { BuildProps, ProjectInfo } from './XcodeBuild.types';\nimport { ensureDeviceIsCodeSignedForDeploymentAsync } from './codeSigning/configureCodeSigning';\nimport { simulatorBuildRequiresCodeSigning } from './codeSigning/simulatorCodeSigning';\nimport * as Log from '../../log';\nimport { ensureDirectory } from '../../utils/dir';\nimport { env } from '../../utils/env';\nimport { AbortCommandError, CommandError } from '../../utils/errors';\nimport { getUserTerminal } from '../../utils/terminal';\nexport function logPrettyItem(message: string) {\n Log.log(chalk`{whiteBright \\u203A} ${message}`);\n}\n\nexport function matchEstimatedBinaryPath(buildOutput: string): string | null {\n // Match the full path that contains `/(.*)/Developer/Xcode/DerivedData/(.*)/Build/Products/(.*)/(.*).app`\n const appBinaryPathMatch = buildOutput.match(\n /(\\/(?:\\\\\\s|[^ ])+\\/Developer\\/Xcode\\/DerivedData\\/(?:\\\\\\s|[^ ])+\\/Build\\/Products\\/(?:Debug|Release)-(?:[^\\s/]+)\\/(?:\\\\\\s|[^ ])+\\.app)/\n );\n if (!appBinaryPathMatch?.length) {\n throw new CommandError(\n 'XCODE_BUILD',\n `Malformed xcodebuild results: app binary path was not generated in build output. Report this issue and run your project with Xcode instead.`\n );\n } else {\n // Sort for the shortest\n const shortestPath = (appBinaryPathMatch.filter((a) => typeof a === 'string' && a) as string[])\n .sort((a: string, b: string) => a.length - b.length)[0]\n .trim();\n\n Log.debug(`Found app binary path: ${shortestPath}`);\n return shortestPath;\n }\n}\n/**\n *\n * @returns '/Users/evanbacon/Library/Developer/Xcode/DerivedData/myapp-gpgjqjodrxtervaufttwnsgimhrx/Build/Products/Debug-iphonesimulator/myapp.app'\n */\nexport function getAppBinaryPath(buildOutput: string) {\n // Matches what's used in \"Bundle React Native code and images\" script.\n // Requires that `-hideShellScriptEnvironment` is not included in the build command (extra logs).\n\n try {\n // Like `\\=/Users/evanbacon/Library/Developer/Xcode/DerivedData/Exponent-anpuosnglkxokahjhfszejloqfvo/Build/Products/Debug-iphonesimulator`\n const CONFIGURATION_BUILD_DIR = extractEnvVariableFromBuild(\n buildOutput,\n 'CONFIGURATION_BUILD_DIR'\n ).sort(\n // Longer name means more suffixes, we want the shortest possible one to be first.\n // Massive projects (like Expo Go) can sometimes print multiple different sets of environment variables.\n // This can become an issue with some\n (a, b) => a.length - b.length\n );\n // Like `Exponent.app`\n const UNLOCALIZED_RESOURCES_FOLDER_PATH = extractEnvVariableFromBuild(\n buildOutput,\n 'UNLOCALIZED_RESOURCES_FOLDER_PATH'\n );\n\n const binaryPath = path.join(\n // Use the shortest defined env variable (usually there's just one).\n CONFIGURATION_BUILD_DIR[0],\n // Use the last defined env variable.\n UNLOCALIZED_RESOURCES_FOLDER_PATH[UNLOCALIZED_RESOURCES_FOLDER_PATH.length - 1]\n );\n\n // If the app has a space in the name it'll fail because it isn't escaped properly by Xcode.\n return getEscapedPath(binaryPath);\n } catch (error) {\n if (error instanceof CommandError && error.code === 'XCODE_BUILD') {\n const possiblePath = matchEstimatedBinaryPath(buildOutput);\n if (possiblePath) {\n return possiblePath;\n }\n }\n throw error;\n }\n}\n\nexport function getEscapedPath(filePath: string): string {\n if (fs.existsSync(filePath)) {\n return filePath;\n }\n const unescapedPath = filePath.split(/\\\\ /).join(' ');\n if (fs.existsSync(unescapedPath)) {\n return unescapedPath;\n }\n throw new CommandError(\n 'XCODE_BUILD',\n `Unexpected: Generated app at path \"${filePath}\" cannot be read, the app cannot be installed. Report this and build onto a simulator.`\n );\n}\n\nexport function extractEnvVariableFromBuild(buildOutput: string, variableName: string) {\n // Xcode can sometimes escape `=` with a backslash or put the value in quotes\n const reg = new RegExp(`export ${variableName}\\\\\\\\?=(.*)$`, 'mg');\n const matched = [...buildOutput.matchAll(reg)];\n\n if (!matched || !matched.length) {\n throw new CommandError(\n 'XCODE_BUILD',\n `Malformed xcodebuild results: \"${variableName}\" variable was not generated in build output. Report this issue and run your project with Xcode instead.`\n );\n }\n return matched.map((value) => value[1]).filter(Boolean) as string[];\n}\n\nexport function getProcessOptions({\n packager,\n shouldSkipInitialBundling,\n terminal,\n port,\n eagerBundleOptions,\n}: {\n packager: boolean;\n shouldSkipInitialBundling?: boolean;\n terminal: string | undefined;\n port: number;\n eagerBundleOptions?: string;\n}): SpawnOptionsWithoutStdio {\n const SKIP_BUNDLING = shouldSkipInitialBundling ? '1' : undefined;\n if (packager) {\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\n RCT_METRO_PORT: port.toString(),\n __EXPO_EAGER_BUNDLE_OPTIONS: eagerBundleOptions,\n },\n };\n }\n\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\n __EXPO_EAGER_BUNDLE_OPTIONS: eagerBundleOptions,\n // Always skip launching the packager from a build script.\n // The script is used for people building their project directly from Xcode.\n // This essentially means \"› Running script 'Start Packager'\" does nothing.\n RCT_NO_LAUNCH_PACKAGER: 'true',\n // FORCE_BUNDLING: '0'\n },\n };\n}\n\nexport async function getXcodeBuildArgsAsync(\n props: Pick<\n BuildProps,\n | 'buildCache'\n | 'projectRoot'\n | 'xcodeProject'\n | 'configuration'\n | 'scheme'\n | 'device'\n | 'isSimulator'\n >\n): Promise<string[]> {\n const args = [\n props.xcodeProject.isWorkspace ? '-workspace' : '-project',\n props.xcodeProject.name,\n '-configuration',\n props.configuration,\n '-scheme',\n props.scheme,\n '-destination',\n `id=${props.device.udid}`,\n ];\n\n if (!props.isSimulator || simulatorBuildRequiresCodeSigning(props.projectRoot)) {\n const developmentTeamId = await ensureDeviceIsCodeSignedForDeploymentAsync(props.projectRoot);\n if (developmentTeamId) {\n args.push(\n `DEVELOPMENT_TEAM=${developmentTeamId}`,\n '-allowProvisioningUpdates',\n '-allowProvisioningDeviceRegistration'\n );\n }\n }\n\n // Add last\n if (props.buildCache === false) {\n args.push(\n // Will first clean the derived data folder.\n 'clean',\n // Then build step must be added otherwise the process will simply clean and exit.\n 'build'\n );\n }\n return args;\n}\n\nfunction spawnXcodeBuild(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { onData }: { onData: (data: string) => void }\n): Promise<{ code: number | null; results: string; error: string }> {\n const buildProcess = spawn('xcodebuild', args, options);\n\n let results = '';\n let error = '';\n\n buildProcess.stdout.on('data', (data: Buffer) => {\n const stringData = data.toString();\n results += stringData;\n onData(stringData);\n });\n\n buildProcess.stderr.on('data', (data: Buffer) => {\n const stringData = data instanceof Buffer ? data.toString() : data;\n error += stringData;\n });\n\n return new Promise(async (resolve, reject) => {\n buildProcess.on('close', (code: number) => {\n resolve({ code, results, error });\n });\n });\n}\n\nasync function spawnXcodeBuildWithFlush(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { onFlush }: { onFlush: (data: string) => void }\n): Promise<{ code: number | null; results: string; error: string }> {\n let currentBuffer = '';\n\n // Data can be sent in chunks that would have no relevance to our regex\n // this can cause massive slowdowns, so we need to ensure the data is complete before attempting to parse it.\n function flushBuffer() {\n if (!currentBuffer) {\n return;\n }\n\n const data = currentBuffer;\n // Reset buffer.\n currentBuffer = '';\n // Process data.\n onFlush(data);\n }\n\n const data = await spawnXcodeBuild(args, options, {\n onData(stringData) {\n currentBuffer += stringData;\n // Only flush the data if we have a full line.\n if (currentBuffer.endsWith(os.EOL)) {\n flushBuffer();\n }\n },\n });\n\n // Flush log data at the end just in case we missed something.\n flushBuffer();\n return data;\n}\n\nasync function spawnXcodeBuildWithFormat(\n args: string[],\n options: SpawnOptionsWithoutStdio,\n { projectRoot, xcodeProject }: { projectRoot: string; xcodeProject: ProjectInfo }\n): Promise<{ code: number | null; results: string; error: string; formatter: ExpoRunFormatter }> {\n Log.debug(` xcodebuild ${args.join(' ')}`);\n\n logPrettyItem(chalk.bold`Planning build`);\n\n const formatter = ExpoRunFormatter.create(projectRoot, {\n xcodeProject,\n isDebug: env.EXPO_DEBUG,\n });\n\n const results = await spawnXcodeBuildWithFlush(args, options, {\n onFlush(data) {\n // Process data.\n for (const line of formatter.pipe(data)) {\n // Log parsed results.\n Log.log(line);\n }\n },\n });\n\n Log.debug(`Exited with code: ${results.code}`);\n\n if (\n // User cancelled with ctrl-c\n results.code === null ||\n // Build interrupted\n results.code === 75\n ) {\n throw new AbortCommandError();\n }\n\n Log.log(formatter.getBuildSummary());\n\n return { ...results, formatter };\n}\n\nexport async function buildAsync(props: BuildProps): Promise<string> {\n const args = await getXcodeBuildArgsAsync(props);\n\n const { projectRoot, xcodeProject, shouldSkipInitialBundling, port, eagerBundleOptions } = props;\n\n const { code, results, formatter, error } = await spawnXcodeBuildWithFormat(\n args,\n getProcessOptions({\n packager: false,\n terminal: getUserTerminal(),\n shouldSkipInitialBundling,\n port,\n eagerBundleOptions,\n }),\n {\n projectRoot,\n xcodeProject,\n }\n );\n\n const logFilePath = writeBuildLogs(projectRoot, results, error);\n\n if (code !== 0) {\n // Determine if the logger found any errors;\n const wasErrorPresented = !!formatter.errors.length;\n\n if (wasErrorPresented) {\n // This has a flaw, if the user is missing a file, and there is a script error, only the missing file error will be shown.\n // They will only see the script error if they fix the missing file and rerun.\n // The flaw can be fixed by catching script errors in the custom logger.\n throw new CommandError(\n `Failed to build iOS project. \"xcodebuild\" exited with error code ${code}.`\n );\n }\n\n _assertXcodeBuildResults(code, results, error, xcodeProject, logFilePath);\n }\n return results;\n}\n\n// Exposed for testing.\nexport function _assertXcodeBuildResults(\n code: number | null,\n results: string,\n error: string,\n xcodeProject: { name: string },\n logFilePath: string\n): void {\n const errorTitle = `Failed to build iOS project. \"xcodebuild\" exited with error code ${code}.`;\n\n const throwWithMessage = (message: string): never => {\n throw new CommandError(\n `${errorTitle}\\nTo view more error logs, try building the app with Xcode directly, by opening ${xcodeProject.name}.\\n\\n` +\n message +\n `Build logs written to ${chalk.underline(logFilePath)}`\n );\n };\n\n const localizedError = error.match(/NSLocalizedFailure = \"(.*)\"/)?.[1];\n\n if (localizedError) {\n throwWithMessage(chalk.bold(localizedError) + '\\n\\n');\n }\n // Show all the log info because often times the error is coming from a shell script,\n // that invoked a node script, that started metro, which threw an error.\n\n throwWithMessage(results + '\\n\\n' + error);\n}\n\nfunction writeBuildLogs(projectRoot: string, buildOutput: string, errorOutput: string) {\n const [logFilePath, errorFilePath] = getErrorLogFilePath(projectRoot);\n\n fs.writeFileSync(logFilePath, buildOutput);\n fs.writeFileSync(errorFilePath, errorOutput);\n return logFilePath;\n}\n\nfunction getErrorLogFilePath(projectRoot: string): [string, string] {\n const folder = path.join(projectRoot, '.expo');\n ensureDirectory(folder);\n return [path.join(folder, 'xcodebuild.log'), path.join(folder, 'xcodebuild-error.log')];\n}\n"],"names":["_assertXcodeBuildResults","buildAsync","extractEnvVariableFromBuild","getAppBinaryPath","getEscapedPath","getProcessOptions","getXcodeBuildArgsAsync","logPrettyItem","matchEstimatedBinaryPath","message","Log","log","chalk","buildOutput","appBinaryPathMatch","match","length","CommandError","shortestPath","filter","a","sort","b","trim","debug","CONFIGURATION_BUILD_DIR","UNLOCALIZED_RESOURCES_FOLDER_PATH","binaryPath","path","join","error","code","possiblePath","filePath","fs","existsSync","unescapedPath","split","variableName","reg","RegExp","matched","matchAll","map","value","Boolean","packager","shouldSkipInitialBundling","terminal","port","eagerBundleOptions","SKIP_BUNDLING","undefined","env","process","RCT_TERMINAL","RCT_METRO_PORT","toString","__EXPO_EAGER_BUNDLE_OPTIONS","RCT_NO_LAUNCH_PACKAGER","props","args","xcodeProject","isWorkspace","name","configuration","scheme","device","udid","isSimulator","simulatorBuildRequiresCodeSigning","projectRoot","developmentTeamId","ensureDeviceIsCodeSignedForDeploymentAsync","push","buildCache","spawnXcodeBuild","options","onData","buildProcess","spawn","results","stdout","on","data","stringData","stderr","Buffer","Promise","resolve","reject","spawnXcodeBuildWithFlush","onFlush","currentBuffer","flushBuffer","endsWith","os","EOL","spawnXcodeBuildWithFormat","bold","formatter","ExpoRunFormatter","create","isDebug","EXPO_DEBUG","line","pipe","AbortCommandError","getBuildSummary","getUserTerminal","logFilePath","writeBuildLogs","wasErrorPresented","errors","errorTitle","throwWithMessage","underline","localizedError","errorOutput","errorFilePath","getErrorLogFilePath","writeFileSync","folder","ensureDirectory"],"mappings":"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"}
@@ -30,7 +30,7 @@ class SecurityBinPrerequisite extends _Prerequisite.Prerequisite {
30
30
  'security'
31
31
  ]);
32
32
  } catch {
33
- throw new _Prerequisite.PrerequisiteCommandError('SECURITY_BIN', "Cannot code sign project because the CLI `security` is not available on your computer.\nPlease ensure it's installed and try again.");
33
+ throw new _Prerequisite.PrerequisiteCommandError('SECURITY_BIN', "Cannot code sign project because the CLI `security` is not available on your computer.\nEnsure it's installed and try again.");
34
34
  }
35
35
  }
36
36
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/doctor/SecurityBinPrerequisite.ts"],"sourcesContent":["import spawnAsync from '@expo/spawn-async';\n\nimport { Prerequisite, PrerequisiteCommandError } from './Prerequisite';\n\nexport class SecurityBinPrerequisite extends Prerequisite {\n static instance = new SecurityBinPrerequisite();\n\n async assertImplementation(): Promise<void> {\n try {\n // make sure we can run security\n await spawnAsync('which', ['security']);\n } catch {\n throw new PrerequisiteCommandError(\n 'SECURITY_BIN',\n \"Cannot code sign project because the CLI `security` is not available on your computer.\\nPlease ensure it's installed and try again.\"\n );\n }\n }\n}\n"],"names":["SecurityBinPrerequisite","Prerequisite","instance","assertImplementation","spawnAsync","PrerequisiteCommandError"],"mappings":";;;;+BAIaA;;;eAAAA;;;;gEAJU;;;;;;8BAEgC;;;;;;AAEhD,MAAMA,gCAAgCC,0BAAY;qBAChDC,WAAW,IAAIF;IAEtB,MAAMG,uBAAsC;QAC1C,IAAI;YACF,gCAAgC;YAChC,MAAMC,IAAAA,qBAAU,EAAC,SAAS;gBAAC;aAAW;QACxC,EAAE,OAAM;YACN,MAAM,IAAIC,sCAAwB,CAChC,gBACA;QAEJ;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../src/start/doctor/SecurityBinPrerequisite.ts"],"sourcesContent":["import spawnAsync from '@expo/spawn-async';\n\nimport { Prerequisite, PrerequisiteCommandError } from './Prerequisite';\n\nexport class SecurityBinPrerequisite extends Prerequisite {\n static instance = new SecurityBinPrerequisite();\n\n async assertImplementation(): Promise<void> {\n try {\n // make sure we can run security\n await spawnAsync('which', ['security']);\n } catch {\n throw new PrerequisiteCommandError(\n 'SECURITY_BIN',\n \"Cannot code sign project because the CLI `security` is not available on your computer.\\nEnsure it's installed and try again.\"\n );\n }\n }\n}\n"],"names":["SecurityBinPrerequisite","Prerequisite","instance","assertImplementation","spawnAsync","PrerequisiteCommandError"],"mappings":";;;;+BAIaA;;;eAAAA;;;;gEAJU;;;;;;8BAEgC;;;;;;AAEhD,MAAMA,gCAAgCC,0BAAY;qBAChDC,WAAW,IAAIF;IAEtB,MAAMG,uBAAsC;QAC1C,IAAI;YACF,gCAAgC;YAChC,MAAMC,IAAAA,qBAAU,EAAC,SAAS;gBAAC;aAAW;QACxC,EAAE,OAAM;YACN,MAAM,IAAIC,sCAAwB,CAChC,gBACA;QAEJ;IACF;AACF"}
@@ -163,7 +163,7 @@ skipPrompt = !(0, _interactive.isInteractive)(), isProjectMutable = (0, _interac
163
163
  }
164
164
  const installCommand = 'npx expo install ' + missing.map(({ pkg })=>pkg).join(' ');
165
165
  const disableMessage = warningMessage;
166
- const solution = `Please install ${_chalk().default.bold(readableMissingPackages)} by running:\n\n ${_chalk().default.reset.bold(installCommand)}\n\n`;
166
+ const solution = `Install ${_chalk().default.bold(readableMissingPackages)} by running:\n\n ${_chalk().default.reset.bold(installCommand)}\n\n`;
167
167
  // This prevents users from starting a misconfigured JS or TS project by default.
168
168
  throw new _errors.CommandError(wrapForTerminal(title + solution + disableMessage + '\n'));
169
169
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/doctor/dependencies/ensureDependenciesAsync.ts"],"sourcesContent":["import { ExpoConfig, getConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport wrapAnsi from 'wrap-ansi';\n\nimport { getMissingPackagesAsync, ResolvedPackage } from './getMissingPackages';\nimport { installAsync } from '../../../install/installAsync';\nimport * as Log from '../../../log';\nimport { CommandError } from '../../../utils/errors';\nimport { isInteractive } from '../../../utils/interactive';\nimport { logNewSection } from '../../../utils/ora';\nimport { confirmAsync } from '../../../utils/prompts';\n\nexport type EnsureDependenciesOptions = {\n /** The packages and/or version ranges that should be enforced in the project */\n requiredPackages: ResolvedPackage[];\n /** The user-facing message when the required packages are missing or incorrect */\n installMessage: string;\n /** The user-facing message when users aborted the installation */\n warningMessage: string;\n /** A previously loaded Expo configuration (loads when omitted) */\n exp?: ExpoConfig;\n /** If the prompts asking users to install should be skipped (defaults to false, in CI defaults to true) */\n skipPrompt?: boolean;\n /** Project can be mutated in the current environment (defaults to true, in CI defaults to false) */\n isProjectMutable?: boolean;\n};\n\nexport async function ensureDependenciesAsync(\n projectRoot: string,\n {\n exp = getConfig(projectRoot).exp,\n requiredPackages,\n warningMessage,\n installMessage,\n // Don't prompt in CI\n skipPrompt = !isInteractive(),\n isProjectMutable = isInteractive(),\n }: EnsureDependenciesOptions\n): Promise<boolean> {\n const { missing } = await getMissingPackagesAsync(projectRoot, {\n sdkVersion: exp.sdkVersion,\n requiredPackages,\n });\n if (!missing.length) {\n return true;\n }\n\n // Prompt to install or bail out...\n const readableMissingPackages = missing\n .map(({ pkg, version }) => (version ? [pkg, version].join('@') : pkg))\n .join(', ');\n\n let title = installMessage;\n\n if (skipPrompt && !isProjectMutable) {\n title += '\\n\\n';\n } else {\n let confirm = skipPrompt;\n if (skipPrompt) {\n // Automatically install packages without prompting.\n Log.log(wrapForTerminal(title + ` Installing ${chalk.cyan(readableMissingPackages)}`));\n } else {\n confirm = await confirmAsync({\n message: wrapForTerminal(\n title + ` Would you like to install ${chalk.cyan(readableMissingPackages)}?`\n ),\n initial: true,\n });\n }\n\n if (confirm) {\n // Format with version if available.\n const [packages, devPackages] = missing.reduce(\n ([deps, devDeps], p) => {\n const pkg = p.version ? [p.pkg, p.version].join('@') : p.pkg;\n if (p.dev) {\n return [deps, devDeps.concat(pkg)];\n }\n return [deps.concat(pkg), devDeps];\n },\n [[], []] as [string[], string[]]\n );\n\n if (packages.length) {\n await installPackagesAsync(projectRoot, {\n packages,\n });\n }\n\n if (devPackages.length) {\n await installPackagesAsync(projectRoot, {\n packages: devPackages,\n dev: true,\n });\n }\n\n // Try again but skip prompting twice, simply fail if the packages didn't install correctly.\n return await ensureDependenciesAsync(projectRoot, {\n skipPrompt: true,\n installMessage,\n warningMessage,\n requiredPackages,\n });\n }\n\n // Reset the title so it doesn't print twice in interactive mode.\n title = '';\n }\n\n const installCommand = 'npx expo install ' + missing.map(({ pkg }) => pkg).join(' ');\n\n const disableMessage = warningMessage;\n\n const solution = `Please install ${chalk.bold(\n readableMissingPackages\n )} by running:\\n\\n ${chalk.reset.bold(installCommand)}\\n\\n`;\n\n // This prevents users from starting a misconfigured JS or TS project by default.\n throw new CommandError(wrapForTerminal(title + solution + disableMessage + '\\n'));\n}\n\n/** Wrap long messages to fit smaller terminals. */\nfunction wrapForTerminal(message: string): string {\n return wrapAnsi(message, process.stdout.columns || 80);\n}\n\n/** Create the bash install command from a given set of packages and settings. */\nexport function createInstallCommand({\n packages,\n}: {\n packages: {\n file: string;\n pkg: string;\n version?: string | undefined;\n }[];\n}) {\n return 'npx expo install ' + packages.map(({ pkg }) => pkg).join(' ');\n}\n\n/** Install packages in the project. */\nasync function installPackagesAsync(\n projectRoot: string,\n { packages, dev }: { packages: string[]; dev?: boolean }\n) {\n const packagesStr = chalk.bold(packages.join(', '));\n Log.log();\n const installingPackageStep = logNewSection(`Installing ${packagesStr}`);\n try {\n await installAsync(packages, { projectRoot, dev });\n } catch (e: any) {\n installingPackageStep.fail(`Failed to install ${packagesStr} with error: ${e.message}`);\n throw e;\n }\n installingPackageStep.succeed(`Installed ${packagesStr}`);\n}\n"],"names":["createInstallCommand","ensureDependenciesAsync","projectRoot","exp","getConfig","requiredPackages","warningMessage","installMessage","skipPrompt","isInteractive","isProjectMutable","missing","getMissingPackagesAsync","sdkVersion","length","readableMissingPackages","map","pkg","version","join","title","confirm","Log","log","wrapForTerminal","chalk","cyan","confirmAsync","message","initial","packages","devPackages","reduce","deps","devDeps","p","dev","concat","installPackagesAsync","installCommand","disableMessage","solution","bold","reset","CommandError","wrapAnsi","process","stdout","columns","packagesStr","installingPackageStep","logNewSection","installAsync","e","fail","succeed"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/doctor/dependencies/ensureDependenciesAsync.ts"],"sourcesContent":["import { ExpoConfig, getConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport wrapAnsi from 'wrap-ansi';\n\nimport { getMissingPackagesAsync, ResolvedPackage } from './getMissingPackages';\nimport { installAsync } from '../../../install/installAsync';\nimport * as Log from '../../../log';\nimport { CommandError } from '../../../utils/errors';\nimport { isInteractive } from '../../../utils/interactive';\nimport { logNewSection } from '../../../utils/ora';\nimport { confirmAsync } from '../../../utils/prompts';\n\nexport type EnsureDependenciesOptions = {\n /** The packages and/or version ranges that should be enforced in the project */\n requiredPackages: ResolvedPackage[];\n /** The user-facing message when the required packages are missing or incorrect */\n installMessage: string;\n /** The user-facing message when users aborted the installation */\n warningMessage: string;\n /** A previously loaded Expo configuration (loads when omitted) */\n exp?: ExpoConfig;\n /** If the prompts asking users to install should be skipped (defaults to false, in CI defaults to true) */\n skipPrompt?: boolean;\n /** Project can be mutated in the current environment (defaults to true, in CI defaults to false) */\n isProjectMutable?: boolean;\n};\n\nexport async function ensureDependenciesAsync(\n projectRoot: string,\n {\n exp = getConfig(projectRoot).exp,\n requiredPackages,\n warningMessage,\n installMessage,\n // Don't prompt in CI\n skipPrompt = !isInteractive(),\n isProjectMutable = isInteractive(),\n }: EnsureDependenciesOptions\n): Promise<boolean> {\n const { missing } = await getMissingPackagesAsync(projectRoot, {\n sdkVersion: exp.sdkVersion,\n requiredPackages,\n });\n if (!missing.length) {\n return true;\n }\n\n // Prompt to install or bail out...\n const readableMissingPackages = missing\n .map(({ pkg, version }) => (version ? [pkg, version].join('@') : pkg))\n .join(', ');\n\n let title = installMessage;\n\n if (skipPrompt && !isProjectMutable) {\n title += '\\n\\n';\n } else {\n let confirm = skipPrompt;\n if (skipPrompt) {\n // Automatically install packages without prompting.\n Log.log(wrapForTerminal(title + ` Installing ${chalk.cyan(readableMissingPackages)}`));\n } else {\n confirm = await confirmAsync({\n message: wrapForTerminal(\n title + ` Would you like to install ${chalk.cyan(readableMissingPackages)}?`\n ),\n initial: true,\n });\n }\n\n if (confirm) {\n // Format with version if available.\n const [packages, devPackages] = missing.reduce(\n ([deps, devDeps], p) => {\n const pkg = p.version ? [p.pkg, p.version].join('@') : p.pkg;\n if (p.dev) {\n return [deps, devDeps.concat(pkg)];\n }\n return [deps.concat(pkg), devDeps];\n },\n [[], []] as [string[], string[]]\n );\n\n if (packages.length) {\n await installPackagesAsync(projectRoot, {\n packages,\n });\n }\n\n if (devPackages.length) {\n await installPackagesAsync(projectRoot, {\n packages: devPackages,\n dev: true,\n });\n }\n\n // Try again but skip prompting twice, simply fail if the packages didn't install correctly.\n return await ensureDependenciesAsync(projectRoot, {\n skipPrompt: true,\n installMessage,\n warningMessage,\n requiredPackages,\n });\n }\n\n // Reset the title so it doesn't print twice in interactive mode.\n title = '';\n }\n\n const installCommand = 'npx expo install ' + missing.map(({ pkg }) => pkg).join(' ');\n\n const disableMessage = warningMessage;\n\n const solution = `Install ${chalk.bold(\n readableMissingPackages\n )} by running:\\n\\n ${chalk.reset.bold(installCommand)}\\n\\n`;\n\n // This prevents users from starting a misconfigured JS or TS project by default.\n throw new CommandError(wrapForTerminal(title + solution + disableMessage + '\\n'));\n}\n\n/** Wrap long messages to fit smaller terminals. */\nfunction wrapForTerminal(message: string): string {\n return wrapAnsi(message, process.stdout.columns || 80);\n}\n\n/** Create the bash install command from a given set of packages and settings. */\nexport function createInstallCommand({\n packages,\n}: {\n packages: {\n file: string;\n pkg: string;\n version?: string | undefined;\n }[];\n}) {\n return 'npx expo install ' + packages.map(({ pkg }) => pkg).join(' ');\n}\n\n/** Install packages in the project. */\nasync function installPackagesAsync(\n projectRoot: string,\n { packages, dev }: { packages: string[]; dev?: boolean }\n) {\n const packagesStr = chalk.bold(packages.join(', '));\n Log.log();\n const installingPackageStep = logNewSection(`Installing ${packagesStr}`);\n try {\n await installAsync(packages, { projectRoot, dev });\n } catch (e: any) {\n installingPackageStep.fail(`Failed to install ${packagesStr} with error: ${e.message}`);\n throw e;\n }\n installingPackageStep.succeed(`Installed ${packagesStr}`);\n}\n"],"names":["createInstallCommand","ensureDependenciesAsync","projectRoot","exp","getConfig","requiredPackages","warningMessage","installMessage","skipPrompt","isInteractive","isProjectMutable","missing","getMissingPackagesAsync","sdkVersion","length","readableMissingPackages","map","pkg","version","join","title","confirm","Log","log","wrapForTerminal","chalk","cyan","confirmAsync","message","initial","packages","devPackages","reduce","deps","devDeps","p","dev","concat","installPackagesAsync","installCommand","disableMessage","solution","bold","reset","CommandError","wrapAnsi","process","stdout","columns","packagesStr","installingPackageStep","logNewSection","installAsync","e","fail","succeed"],"mappings":"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"}
@@ -59,7 +59,7 @@ async function resolvePackageVersionAsync(projectRoot, packageName) {
59
59
  }
60
60
  }
61
61
  if (!packageJsonPath) {
62
- throw new _errors.CommandError('PACKAGE_NOT_FOUND', `"${packageName}" is added as a dependency in your project's package.json but it doesn't seem to be installed. Please run "yarn" or "npm install" to fix this issue.`);
62
+ throw new _errors.CommandError('PACKAGE_NOT_FOUND', `"${packageName}" is added as a dependency in your project's package.json but it doesn't seem to be installed. Run "npm install", or the equivalent for your package manager, and try again.`);
63
63
  }
64
64
  const packageJson = await _jsonfile().default.readAsync(packageJsonPath);
65
65
  return packageJson.version;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/doctor/dependencies/resolvePackages.ts"],"sourcesContent":["import JsonFile from '@expo/json-file';\nimport resolveFrom from 'resolve-from';\nimport semver from 'semver';\n\nimport { CommandError } from '../../../utils/errors';\n\nexport async function resolvePackageVersionAsync(\n projectRoot: string,\n packageName: string\n): Promise<string> {\n let packageJsonPath: string | undefined;\n try {\n packageJsonPath = resolveFrom(projectRoot, `${packageName}/package.json`);\n } catch (error: any) {\n // This is a workaround for packages using `exports`. If this doesn't\n // include `package.json`, we have to use the error message to get the location.\n if (error.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') {\n packageJsonPath = error.message.match(/(\"exports\"|defined) in (.*)$/i)?.[2];\n }\n }\n if (!packageJsonPath) {\n throw new CommandError(\n 'PACKAGE_NOT_FOUND',\n `\"${packageName}\" is added as a dependency in your project's package.json but it doesn't seem to be installed. Please run \"yarn\" or \"npm install\" to fix this issue.`\n );\n }\n const packageJson = await JsonFile.readAsync<{ version: string }>(packageJsonPath);\n return packageJson.version;\n}\n\nexport async function resolveAllPackageVersionsAsync(projectRoot: string, packages: string[]) {\n const resolvedPackages = await Promise.all(\n packages.map(async (packageName) => [\n packageName,\n await resolvePackageVersionAsync(projectRoot, packageName),\n ])\n );\n\n return Object.fromEntries(resolvedPackages);\n}\n\n/**\n * Determine if the project has a `expo@canary` version installed.\n * This means that an unsable version is used, without the API knowing the exact packages.\n * Since this may be called during, or before, packages are installed, we also need to test on `package.json`.\n * Note, this returns `false` for beta releases.\n */\nexport async function hasExpoCanaryAsync(projectRoot: string) {\n let expoVersion = '';\n\n try {\n // Resolve installed `expo` version first\n expoVersion = await resolvePackageVersionAsync(projectRoot, 'expo');\n } catch (error: any) {\n if (error.code !== 'PACKAGE_NOT_FOUND') {\n throw error;\n }\n\n // Resolve through project `package.json`\n const packageJson = await JsonFile.readAsync<{ dependencies?: Record<string, string> }>(\n resolveFrom(projectRoot, './package.json')\n );\n expoVersion = packageJson.dependencies?.expo ?? '';\n }\n\n if (expoVersion === 'canary') {\n return true;\n }\n\n const prerelease = semver.prerelease(expoVersion) || [];\n return !!prerelease.some((segment) => typeof segment === 'string' && segment.includes('canary'));\n}\n"],"names":["hasExpoCanaryAsync","resolveAllPackageVersionsAsync","resolvePackageVersionAsync","projectRoot","packageName","packageJsonPath","resolveFrom","error","code","message","match","CommandError","packageJson","JsonFile","readAsync","version","packages","resolvedPackages","Promise","all","map","Object","fromEntries","expoVersion","dependencies","expo","prerelease","semver","some","segment","includes"],"mappings":";;;;;;;;;;;IA+CsBA,kBAAkB;eAAlBA;;IAjBAC,8BAA8B;eAA9BA;;IAxBAC,0BAA0B;eAA1BA;;;;gEAND;;;;;;;gEACG;;;;;;;gEACL;;;;;;wBAEU;;;;;;AAEtB,eAAeA,2BACpBC,WAAmB,EACnBC,WAAmB;IAEnB,IAAIC;IACJ,IAAI;QACFA,kBAAkBC,IAAAA,sBAAW,EAACH,aAAa,GAAGC,YAAY,aAAa,CAAC;IAC1E,EAAE,OAAOG,OAAY;QACnB,qEAAqE;QACrE,gFAAgF;QAChF,IAAIA,MAAMC,IAAI,KAAK,iCAAiC;gBAChCD;YAAlBF,mBAAkBE,uBAAAA,MAAME,OAAO,CAACC,KAAK,CAAC,qDAApBH,oBAAsD,CAAC,EAAE;QAC7E;IACF;IACA,IAAI,CAACF,iBAAiB;QACpB,MAAM,IAAIM,oBAAY,CACpB,qBACA,CAAC,CAAC,EAAEP,YAAY,oJAAoJ,CAAC;IAEzK;IACA,MAAMQ,cAAc,MAAMC,mBAAQ,CAACC,SAAS,CAAsBT;IAClE,OAAOO,YAAYG,OAAO;AAC5B;AAEO,eAAed,+BAA+BE,WAAmB,EAAEa,QAAkB;IAC1F,MAAMC,mBAAmB,MAAMC,QAAQC,GAAG,CACxCH,SAASI,GAAG,CAAC,OAAOhB,cAAgB;YAClCA;YACA,MAAMF,2BAA2BC,aAAaC;SAC/C;IAGH,OAAOiB,OAAOC,WAAW,CAACL;AAC5B;AAQO,eAAejB,mBAAmBG,WAAmB;IAC1D,IAAIoB,cAAc;IAElB,IAAI;QACF,yCAAyC;QACzCA,cAAc,MAAMrB,2BAA2BC,aAAa;IAC9D,EAAE,OAAOI,OAAY;YASLK;QARd,IAAIL,MAAMC,IAAI,KAAK,qBAAqB;YACtC,MAAMD;QACR;QAEA,yCAAyC;QACzC,MAAMK,cAAc,MAAMC,mBAAQ,CAACC,SAAS,CAC1CR,IAAAA,sBAAW,EAACH,aAAa;QAE3BoB,cAAcX,EAAAA,4BAAAA,YAAYY,YAAY,qBAAxBZ,0BAA0Ba,IAAI,KAAI;IAClD;IAEA,IAAIF,gBAAgB,UAAU;QAC5B,OAAO;IACT;IAEA,MAAMG,aAAaC,iBAAM,CAACD,UAAU,CAACH,gBAAgB,EAAE;IACvD,OAAO,CAAC,CAACG,WAAWE,IAAI,CAAC,CAACC,UAAY,OAAOA,YAAY,YAAYA,QAAQC,QAAQ,CAAC;AACxF"}
1
+ {"version":3,"sources":["../../../../../src/start/doctor/dependencies/resolvePackages.ts"],"sourcesContent":["import JsonFile from '@expo/json-file';\nimport resolveFrom from 'resolve-from';\nimport semver from 'semver';\n\nimport { CommandError } from '../../../utils/errors';\n\nexport async function resolvePackageVersionAsync(\n projectRoot: string,\n packageName: string\n): Promise<string> {\n let packageJsonPath: string | undefined;\n try {\n packageJsonPath = resolveFrom(projectRoot, `${packageName}/package.json`);\n } catch (error: any) {\n // This is a workaround for packages using `exports`. If this doesn't\n // include `package.json`, we have to use the error message to get the location.\n if (error.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') {\n packageJsonPath = error.message.match(/(\"exports\"|defined) in (.*)$/i)?.[2];\n }\n }\n if (!packageJsonPath) {\n throw new CommandError(\n 'PACKAGE_NOT_FOUND',\n `\"${packageName}\" is added as a dependency in your project's package.json but it doesn't seem to be installed. Run \"npm install\", or the equivalent for your package manager, and try again.`\n );\n }\n const packageJson = await JsonFile.readAsync<{ version: string }>(packageJsonPath);\n return packageJson.version;\n}\n\nexport async function resolveAllPackageVersionsAsync(projectRoot: string, packages: string[]) {\n const resolvedPackages = await Promise.all(\n packages.map(async (packageName) => [\n packageName,\n await resolvePackageVersionAsync(projectRoot, packageName),\n ])\n );\n\n return Object.fromEntries(resolvedPackages);\n}\n\n/**\n * Determine if the project has a `expo@canary` version installed.\n * This means that an unsable version is used, without the API knowing the exact packages.\n * Since this may be called during, or before, packages are installed, we also need to test on `package.json`.\n * Note, this returns `false` for beta releases.\n */\nexport async function hasExpoCanaryAsync(projectRoot: string) {\n let expoVersion = '';\n\n try {\n // Resolve installed `expo` version first\n expoVersion = await resolvePackageVersionAsync(projectRoot, 'expo');\n } catch (error: any) {\n if (error.code !== 'PACKAGE_NOT_FOUND') {\n throw error;\n }\n\n // Resolve through project `package.json`\n const packageJson = await JsonFile.readAsync<{ dependencies?: Record<string, string> }>(\n resolveFrom(projectRoot, './package.json')\n );\n expoVersion = packageJson.dependencies?.expo ?? '';\n }\n\n if (expoVersion === 'canary') {\n return true;\n }\n\n const prerelease = semver.prerelease(expoVersion) || [];\n return !!prerelease.some((segment) => typeof segment === 'string' && segment.includes('canary'));\n}\n"],"names":["hasExpoCanaryAsync","resolveAllPackageVersionsAsync","resolvePackageVersionAsync","projectRoot","packageName","packageJsonPath","resolveFrom","error","code","message","match","CommandError","packageJson","JsonFile","readAsync","version","packages","resolvedPackages","Promise","all","map","Object","fromEntries","expoVersion","dependencies","expo","prerelease","semver","some","segment","includes"],"mappings":";;;;;;;;;;;IA+CsBA,kBAAkB;eAAlBA;;IAjBAC,8BAA8B;eAA9BA;;IAxBAC,0BAA0B;eAA1BA;;;;gEAND;;;;;;;gEACG;;;;;;;gEACL;;;;;;wBAEU;;;;;;AAEtB,eAAeA,2BACpBC,WAAmB,EACnBC,WAAmB;IAEnB,IAAIC;IACJ,IAAI;QACFA,kBAAkBC,IAAAA,sBAAW,EAACH,aAAa,GAAGC,YAAY,aAAa,CAAC;IAC1E,EAAE,OAAOG,OAAY;QACnB,qEAAqE;QACrE,gFAAgF;QAChF,IAAIA,MAAMC,IAAI,KAAK,iCAAiC;gBAChCD;YAAlBF,mBAAkBE,uBAAAA,MAAME,OAAO,CAACC,KAAK,CAAC,qDAApBH,oBAAsD,CAAC,EAAE;QAC7E;IACF;IACA,IAAI,CAACF,iBAAiB;QACpB,MAAM,IAAIM,oBAAY,CACpB,qBACA,CAAC,CAAC,EAAEP,YAAY,4KAA4K,CAAC;IAEjM;IACA,MAAMQ,cAAc,MAAMC,mBAAQ,CAACC,SAAS,CAAsBT;IAClE,OAAOO,YAAYG,OAAO;AAC5B;AAEO,eAAed,+BAA+BE,WAAmB,EAAEa,QAAkB;IAC1F,MAAMC,mBAAmB,MAAMC,QAAQC,GAAG,CACxCH,SAASI,GAAG,CAAC,OAAOhB,cAAgB;YAClCA;YACA,MAAMF,2BAA2BC,aAAaC;SAC/C;IAGH,OAAOiB,OAAOC,WAAW,CAACL;AAC5B;AAQO,eAAejB,mBAAmBG,WAAmB;IAC1D,IAAIoB,cAAc;IAElB,IAAI;QACF,yCAAyC;QACzCA,cAAc,MAAMrB,2BAA2BC,aAAa;IAC9D,EAAE,OAAOI,OAAY;YASLK;QARd,IAAIL,MAAMC,IAAI,KAAK,qBAAqB;YACtC,MAAMD;QACR;QAEA,yCAAyC;QACzC,MAAMK,cAAc,MAAMC,mBAAQ,CAACC,SAAS,CAC1CR,IAAAA,sBAAW,EAACH,aAAa;QAE3BoB,cAAcX,EAAAA,4BAAAA,YAAYY,YAAY,qBAAxBZ,0BAA0Ba,IAAI,KAAI;IAClD;IAEA,IAAIF,gBAAgB,UAAU;QAC5B,OAAO;IACT;IAEA,MAAMG,aAAaC,iBAAM,CAACD,UAAU,CAACH,gBAAgB,EAAE;IACvD,OAAO,CAAC,CAACG,WAAWE,IAAI,CAAC,CAACC,UAAY,OAAOA,YAAY,YAAYA,QAAQC,QAAQ,CAAC;AACxF"}
@@ -168,7 +168,7 @@ class ExternalModule {
168
168
  shouldPrompt: false
169
169
  });
170
170
  }
171
- throw new _errors.CommandError('EXTERNAL_MODULE_AVAILABILITY', `Please install ${packageName} and try again`);
171
+ throw new _errors.CommandError('EXTERNAL_MODULE_AVAILABILITY', `Install ${packageName} and try again`);
172
172
  }
173
173
  /** Get the module. */ get() {
174
174
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/doctor/ngrok/ExternalModule.ts"],"sourcesContent":["import * as PackageManager from '@expo/package-manager';\nimport requireGlobal from 'requireg';\nimport resolveFrom from 'resolve-from';\nimport semver from 'semver';\n\nimport * as Log from '../../../log';\nimport { delayAsync } from '../../../utils/delay';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { confirmAsync } from '../../../utils/prompts';\n\nconst debug = require('debug')('expo:doctor:externalModule') as typeof console.log;\n\n/** An error that is thrown when a package is installed but doesn't meet the version criteria. */\nexport class ExternalModuleVersionError extends CommandError {\n constructor(\n message: string,\n public readonly shouldGloballyInstall: boolean\n ) {\n super('EXTERNAL_MODULE_VERSION', message);\n }\n}\n\ninterface PromptOptions {\n /** Should prompt the user to install, when false the module will just assert on missing packages, default `true`. Ignored when `autoInstall` is true. */\n shouldPrompt?: boolean;\n /** Should automatically install the package without prompting, default `false` */\n autoInstall?: boolean;\n}\n\nexport interface InstallPromptOptions extends PromptOptions {\n /** Should install the package globally, default `false` */\n shouldGloballyInstall?: boolean;\n}\n\nexport interface ResolvePromptOptions extends PromptOptions {\n /**\n * Prefer to install the package globally, this can be overridden if the function\n * detects that a locally installed package simply needs an upgrade, default `false`\n */\n prefersGlobalInstall?: boolean;\n}\n\n/** Resolves a local or globally installed package, prompts to install if missing. */\nexport class ExternalModule<TModule> {\n private instance: TModule | null = null;\n\n constructor(\n /** Project root for checking if the package is installed locally. */\n private projectRoot: string,\n /** Info on the external package. */\n private pkg: {\n /** NPM package name. */\n name: string;\n /** Required semver range, ex: `^1.0.0`. */\n versionRange: string;\n },\n /** A function used to create the installation prompt message. */\n private promptMessage: (pkgName: string) => string\n ) {}\n\n /** Resolve the globally or locally installed instance, or prompt to install. */\n async resolveAsync({\n prefersGlobalInstall,\n ...options\n }: ResolvePromptOptions = {}): Promise<TModule> {\n try {\n return (\n this.getVersioned() ??\n this.installAsync({\n ...options,\n shouldGloballyInstall: prefersGlobalInstall,\n })\n );\n } catch (error: any) {\n if (error instanceof ExternalModuleVersionError) {\n // If the module version in not compliant with the version range,\n // we should prompt the user to install the package where it already exists.\n return this.installAsync({\n ...options,\n shouldGloballyInstall: error.shouldGloballyInstall ?? prefersGlobalInstall,\n });\n }\n throw error;\n }\n }\n\n /** Prompt the user to install the package and try again. */\n async installAsync({\n shouldPrompt = true,\n autoInstall,\n shouldGloballyInstall,\n }: InstallPromptOptions = {}): Promise<TModule> {\n const packageName = [this.pkg.name, this.pkg.versionRange].join('@');\n if (!autoInstall) {\n // Delay the prompt so it doesn't conflict with other dev tool logs\n await delayAsync(100);\n }\n const answer =\n autoInstall ||\n (shouldPrompt &&\n (await confirmAsync({\n message: this.promptMessage(packageName),\n initial: true,\n })));\n if (answer) {\n Log.log(`Installing ${packageName}...`);\n\n // Always use npm for global installs\n const packageManager = shouldGloballyInstall\n ? new PackageManager.NpmPackageManager({\n cwd: this.projectRoot,\n log: Log.log,\n silent: !(env.EXPO_DEBUG || env.CI),\n })\n : PackageManager.createForProject(this.projectRoot, {\n silent: !(env.EXPO_DEBUG || env.CI),\n });\n\n try {\n if (shouldGloballyInstall) {\n await packageManager.addGlobalAsync([packageName]);\n } else {\n await packageManager.addDevAsync([packageName]);\n }\n Log.log(`Installed ${packageName}`);\n } catch (error: any) {\n error.message = `Failed to install ${packageName} ${\n shouldGloballyInstall ? 'globally' : 'locally'\n }: ${error.message}`;\n throw error;\n }\n return await this.resolveAsync({ shouldPrompt: false });\n }\n\n throw new CommandError(\n 'EXTERNAL_MODULE_AVAILABILITY',\n `Please install ${packageName} and try again`\n );\n }\n\n /** Get the module. */\n get(): TModule | null {\n try {\n return this.getVersioned();\n } catch {\n return null;\n }\n }\n\n /** Get the module, throws if the module is not versioned correctly. */\n getVersioned(): TModule | null {\n this.instance ??= this._resolveModule(true) ?? this._resolveModule(false);\n return this.instance;\n }\n\n /** Exposed for testing. */\n _require(moduleId: string): any {\n return require(moduleId);\n }\n\n /** Resolve a copy that's installed in the project. Exposed for testing. */\n _resolveLocal(moduleId: string): string {\n return resolveFrom(this.projectRoot, moduleId);\n }\n\n /** Resolve a copy that's installed globally. Exposed for testing. */\n _resolveGlobal(moduleId: string): string {\n return requireGlobal.resolve(moduleId);\n }\n\n /** Resolve the module and verify the version. Exposed for testing. */\n _resolveModule(isLocal: boolean): TModule | null {\n const resolver = isLocal ? this._resolveLocal.bind(this) : this._resolveGlobal.bind(this);\n try {\n const packageJsonPath = resolver(`${this.pkg.name}/package.json`);\n const packageJson = this._require(packageJsonPath);\n if (packageJson) {\n if (semver.satisfies(packageJson.version, this.pkg.versionRange)) {\n const modulePath = resolver(this.pkg.name);\n const requiredModule = this._require(modulePath);\n if (requiredModule == null) {\n throw new CommandError(\n 'EXTERNAL_MODULE_EXPORT',\n `${this.pkg.name} exports a nullish value, which is not allowed.`\n );\n }\n return requiredModule;\n }\n throw new ExternalModuleVersionError(\n `Required module '${this.pkg.name}@${packageJson.version}' does not satisfy ${this.pkg.versionRange}. Installed at: ${packageJsonPath}`,\n !isLocal\n );\n }\n } catch (error: any) {\n if (error instanceof CommandError) {\n throw error;\n } else if (error.code !== 'MODULE_NOT_FOUND') {\n debug('Failed to resolve module', error.message);\n }\n }\n return null;\n }\n}\n"],"names":["ExternalModule","ExternalModuleVersionError","debug","require","CommandError","constructor","message","shouldGloballyInstall","projectRoot","pkg","promptMessage","instance","resolveAsync","prefersGlobalInstall","options","getVersioned","installAsync","error","shouldPrompt","autoInstall","packageName","name","versionRange","join","delayAsync","answer","confirmAsync","initial","Log","log","packageManager","PackageManager","NpmPackageManager","cwd","silent","env","EXPO_DEBUG","CI","createForProject","addGlobalAsync","addDevAsync","get","_resolveModule","_require","moduleId","_resolveLocal","resolveFrom","_resolveGlobal","requireGlobal","resolve","isLocal","resolver","bind","packageJsonPath","packageJson","semver","satisfies","version","modulePath","requiredModule","code"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/doctor/ngrok/ExternalModule.ts"],"sourcesContent":["import * as PackageManager from '@expo/package-manager';\nimport requireGlobal from 'requireg';\nimport resolveFrom from 'resolve-from';\nimport semver from 'semver';\n\nimport * as Log from '../../../log';\nimport { delayAsync } from '../../../utils/delay';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { confirmAsync } from '../../../utils/prompts';\n\nconst debug = require('debug')('expo:doctor:externalModule') as typeof console.log;\n\n/** An error that is thrown when a package is installed but doesn't meet the version criteria. */\nexport class ExternalModuleVersionError extends CommandError {\n constructor(\n message: string,\n public readonly shouldGloballyInstall: boolean\n ) {\n super('EXTERNAL_MODULE_VERSION', message);\n }\n}\n\ninterface PromptOptions {\n /** Should prompt the user to install, when false the module will just assert on missing packages, default `true`. Ignored when `autoInstall` is true. */\n shouldPrompt?: boolean;\n /** Should automatically install the package without prompting, default `false` */\n autoInstall?: boolean;\n}\n\nexport interface InstallPromptOptions extends PromptOptions {\n /** Should install the package globally, default `false` */\n shouldGloballyInstall?: boolean;\n}\n\nexport interface ResolvePromptOptions extends PromptOptions {\n /**\n * Prefer to install the package globally, this can be overridden if the function\n * detects that a locally installed package simply needs an upgrade, default `false`\n */\n prefersGlobalInstall?: boolean;\n}\n\n/** Resolves a local or globally installed package, prompts to install if missing. */\nexport class ExternalModule<TModule> {\n private instance: TModule | null = null;\n\n constructor(\n /** Project root for checking if the package is installed locally. */\n private projectRoot: string,\n /** Info on the external package. */\n private pkg: {\n /** NPM package name. */\n name: string;\n /** Required semver range, ex: `^1.0.0`. */\n versionRange: string;\n },\n /** A function used to create the installation prompt message. */\n private promptMessage: (pkgName: string) => string\n ) {}\n\n /** Resolve the globally or locally installed instance, or prompt to install. */\n async resolveAsync({\n prefersGlobalInstall,\n ...options\n }: ResolvePromptOptions = {}): Promise<TModule> {\n try {\n return (\n this.getVersioned() ??\n this.installAsync({\n ...options,\n shouldGloballyInstall: prefersGlobalInstall,\n })\n );\n } catch (error: any) {\n if (error instanceof ExternalModuleVersionError) {\n // If the module version in not compliant with the version range,\n // we should prompt the user to install the package where it already exists.\n return this.installAsync({\n ...options,\n shouldGloballyInstall: error.shouldGloballyInstall ?? prefersGlobalInstall,\n });\n }\n throw error;\n }\n }\n\n /** Prompt the user to install the package and try again. */\n async installAsync({\n shouldPrompt = true,\n autoInstall,\n shouldGloballyInstall,\n }: InstallPromptOptions = {}): Promise<TModule> {\n const packageName = [this.pkg.name, this.pkg.versionRange].join('@');\n if (!autoInstall) {\n // Delay the prompt so it doesn't conflict with other dev tool logs\n await delayAsync(100);\n }\n const answer =\n autoInstall ||\n (shouldPrompt &&\n (await confirmAsync({\n message: this.promptMessage(packageName),\n initial: true,\n })));\n if (answer) {\n Log.log(`Installing ${packageName}...`);\n\n // Always use npm for global installs\n const packageManager = shouldGloballyInstall\n ? new PackageManager.NpmPackageManager({\n cwd: this.projectRoot,\n log: Log.log,\n silent: !(env.EXPO_DEBUG || env.CI),\n })\n : PackageManager.createForProject(this.projectRoot, {\n silent: !(env.EXPO_DEBUG || env.CI),\n });\n\n try {\n if (shouldGloballyInstall) {\n await packageManager.addGlobalAsync([packageName]);\n } else {\n await packageManager.addDevAsync([packageName]);\n }\n Log.log(`Installed ${packageName}`);\n } catch (error: any) {\n error.message = `Failed to install ${packageName} ${\n shouldGloballyInstall ? 'globally' : 'locally'\n }: ${error.message}`;\n throw error;\n }\n return await this.resolveAsync({ shouldPrompt: false });\n }\n\n throw new CommandError('EXTERNAL_MODULE_AVAILABILITY', `Install ${packageName} and try again`);\n }\n\n /** Get the module. */\n get(): TModule | null {\n try {\n return this.getVersioned();\n } catch {\n return null;\n }\n }\n\n /** Get the module, throws if the module is not versioned correctly. */\n getVersioned(): TModule | null {\n this.instance ??= this._resolveModule(true) ?? this._resolveModule(false);\n return this.instance;\n }\n\n /** Exposed for testing. */\n _require(moduleId: string): any {\n return require(moduleId);\n }\n\n /** Resolve a copy that's installed in the project. Exposed for testing. */\n _resolveLocal(moduleId: string): string {\n return resolveFrom(this.projectRoot, moduleId);\n }\n\n /** Resolve a copy that's installed globally. Exposed for testing. */\n _resolveGlobal(moduleId: string): string {\n return requireGlobal.resolve(moduleId);\n }\n\n /** Resolve the module and verify the version. Exposed for testing. */\n _resolveModule(isLocal: boolean): TModule | null {\n const resolver = isLocal ? this._resolveLocal.bind(this) : this._resolveGlobal.bind(this);\n try {\n const packageJsonPath = resolver(`${this.pkg.name}/package.json`);\n const packageJson = this._require(packageJsonPath);\n if (packageJson) {\n if (semver.satisfies(packageJson.version, this.pkg.versionRange)) {\n const modulePath = resolver(this.pkg.name);\n const requiredModule = this._require(modulePath);\n if (requiredModule == null) {\n throw new CommandError(\n 'EXTERNAL_MODULE_EXPORT',\n `${this.pkg.name} exports a nullish value, which is not allowed.`\n );\n }\n return requiredModule;\n }\n throw new ExternalModuleVersionError(\n `Required module '${this.pkg.name}@${packageJson.version}' does not satisfy ${this.pkg.versionRange}. Installed at: ${packageJsonPath}`,\n !isLocal\n );\n }\n } catch (error: any) {\n if (error instanceof CommandError) {\n throw error;\n } else if (error.code !== 'MODULE_NOT_FOUND') {\n debug('Failed to resolve module', error.message);\n }\n }\n return null;\n }\n}\n"],"names":["ExternalModule","ExternalModuleVersionError","debug","require","CommandError","constructor","message","shouldGloballyInstall","projectRoot","pkg","promptMessage","instance","resolveAsync","prefersGlobalInstall","options","getVersioned","installAsync","error","shouldPrompt","autoInstall","packageName","name","versionRange","join","delayAsync","answer","confirmAsync","initial","Log","log","packageManager","PackageManager","NpmPackageManager","cwd","silent","env","EXPO_DEBUG","CI","createForProject","addGlobalAsync","addDevAsync","get","_resolveModule","_require","moduleId","_resolveLocal","resolveFrom","_resolveGlobal","requireGlobal","resolve","isLocal","resolver","bind","packageJsonPath","packageJson","semver","satisfies","version","modulePath","requiredModule","code"],"mappings":"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"}
@@ -104,7 +104,7 @@ class PlatformManager {
104
104
  const applicationId = props.applicationId ?? await this._getAppIdResolver().getAppIdAsync();
105
105
  const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);
106
106
  if (!await deviceManager.isAppInstalledAndIfSoReturnContainerPathForIOSAsync(applicationId)) {
107
- throw new _errors.CommandError(`No development build (${applicationId}) for this project is installed. ` + `Please make and install a development build on the device first.\n${(0, _link.learnMore)('https://docs.expo.dev/development/build/')}`);
107
+ throw new _errors.CommandError(`No development build (${applicationId}) for this project is installed. ` + `Install a development build on the target device and try again.\n${(0, _link.learnMore)('https://docs.expo.dev/development/build/')}`);
108
108
  }
109
109
  if (!url) {
110
110
  url = this._resolveAlternativeLaunchUrl(applicationId, props);