@expo/cli 0.3.2 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -10
- package/build/bin/cli +2 -2
- package/build/src/api/graphql/client.js +3 -1
- package/build/src/api/graphql/client.js.map +1 -1
- package/build/src/api/rest/client.js +5 -2
- package/build/src/api/rest/client.js.map +1 -1
- package/build/src/api/rest/wrapFetchWithProxy.js +25 -0
- package/build/src/api/rest/wrapFetchWithProxy.js.map +1 -0
- package/build/src/export/createMetadataJson.js.map +1 -1
- package/build/src/export/exportApp.js +16 -1
- package/build/src/export/exportApp.js.map +1 -1
- package/build/src/export/exportAssets.js.map +1 -1
- package/build/src/export/fork-bundleAsync.js +2 -1
- package/build/src/export/fork-bundleAsync.js.map +1 -1
- package/build/src/export/printBundleSizes.js +1 -1
- package/build/src/export/printBundleSizes.js.map +1 -1
- package/build/src/export/writeContents.js +7 -2
- package/build/src/export/writeContents.js.map +1 -1
- package/build/src/install/resolveOptions.js +6 -2
- package/build/src/install/resolveOptions.js.map +1 -1
- package/build/src/prebuild/copyTemplateFiles.js +6 -33
- package/build/src/prebuild/copyTemplateFiles.js.map +1 -1
- package/build/src/prebuild/resolveTemplate.js +2 -2
- package/build/src/prebuild/resolveTemplate.js.map +1 -1
- package/build/src/prebuild/updateFromTemplate.js +1 -3
- package/build/src/prebuild/updateFromTemplate.js.map +1 -1
- package/build/src/prebuild/updatePackageJson.js +3 -46
- package/build/src/prebuild/updatePackageJson.js.map +1 -1
- package/build/src/run/ios/XcodeBuild.js +2 -1
- package/build/src/run/ios/XcodeBuild.js.map +1 -1
- package/build/src/run/ios/codeSigning/simulatorCodeSigning.js +45 -0
- package/build/src/run/ios/codeSigning/simulatorCodeSigning.js.map +1 -0
- package/build/src/start/doctor/ngrok/NgrokResolver.js +5 -0
- package/build/src/start/doctor/ngrok/NgrokResolver.js.map +1 -1
- package/build/src/start/platforms/PlatformManager.js +6 -1
- package/build/src/start/platforms/PlatformManager.js.map +1 -1
- package/build/src/start/platforms/android/adbReverse.js +10 -0
- package/build/src/start/platforms/android/adbReverse.js.map +1 -1
- package/build/src/start/resolveOptions.js +1 -1
- package/build/src/start/resolveOptions.js.map +1 -1
- package/build/src/start/server/AsyncNgrok.js +58 -14
- package/build/src/start/server/AsyncNgrok.js.map +1 -1
- package/build/src/start/server/BundlerDevServer.js +4 -1
- package/build/src/start/server/BundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +20 -5
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +1 -6
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/withMetroMultiPlatform.js +36 -5
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/middleware/ClassicManifestMiddleware.js +4 -2
- package/build/src/start/server/middleware/ClassicManifestMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js +7 -3
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/RuntimeRedirectMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/resolveEntryPoint.js +2 -1
- package/build/src/start/server/middleware/resolveEntryPoint.js.map +1 -1
- package/build/src/start/server/middleware/resolvePlatform.js +3 -2
- package/build/src/start/server/middleware/resolvePlatform.js.map +1 -1
- package/build/src/start/server/webpack/WebpackBundlerDevServer.js +2 -8
- package/build/src/start/server/webpack/WebpackBundlerDevServer.js.map +1 -1
- package/build/src/utils/analytics/rudderstackClient.js +2 -2
- package/build/src/utils/codesigning.js +3 -0
- package/build/src/utils/codesigning.js.map +1 -1
- package/build/src/utils/downloadAppAsync.js +1 -2
- package/build/src/utils/downloadAppAsync.js.map +1 -1
- package/build/src/utils/env.js +37 -1
- package/build/src/utils/env.js.map +1 -1
- package/build/src/utils/npm.js +4 -11
- package/build/src/utils/npm.js.map +1 -1
- package/build/src/utils/url.js +2 -2
- package/build/src/utils/url.js.map +1 -1
- package/build/src/utils/validateApplicationId.js +3 -3
- package/build/src/utils/validateApplicationId.js.map +1 -1
- package/build/src/utils/variadic.js +18 -0
- package/build/src/utils/variadic.js.map +1 -1
- package/package.json +5 -4
|
@@ -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 * 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';\nimport { BuildProps, ProjectInfo } from './XcodeBuild.types';\nimport { ensureDeviceIsCodeSignedForDeploymentAsync } from './codeSigning/configureCodeSigning';\n\nexport function logPrettyItem(message: string) {\n Log.log(chalk`{whiteBright \\u203A} ${message}`);\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 // 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}\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}: {\n packager: boolean;\n shouldSkipInitialBundling?: boolean;\n terminal: string | undefined;\n port: number;\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 },\n };\n }\n\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\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) {\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 } = 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 }),\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":["logPrettyItem","getAppBinaryPath","getEscapedPath","extractEnvVariableFromBuild","getProcessOptions","getXcodeBuildArgsAsync","buildAsync","_assertXcodeBuildResults","Log","message","log","chalk","buildOutput","CONFIGURATION_BUILD_DIR","sort","a","b","length","UNLOCALIZED_RESOURCES_FOLDER_PATH","binaryPath","path","join","filePath","fs","existsSync","unescapedPath","split","CommandError","variableName","reg","RegExp","matched","matchAll","map","value","filter","Boolean","packager","shouldSkipInitialBundling","terminal","port","SKIP_BUNDLING","undefined","env","process","RCT_TERMINAL","RCT_METRO_PORT","toString","RCT_NO_LAUNCH_PACKAGER","props","args","xcodeProject","isWorkspace","name","configuration","scheme","device","udid","isSimulator","developmentTeamId","ensureDeviceIsCodeSignedForDeploymentAsync","projectRoot","push","buildCache","spawnXcodeBuild","options","onData","buildProcess","spawn","results","error","stdout","on","data","stringData","stderr","Buffer","Promise","resolve","reject","code","spawnXcodeBuildWithFlush","onFlush","currentBuffer","flushBuffer","endsWith","os","EOL","spawnXcodeBuildWithFormat","debug","bold","formatter","ExpoRunFormatter","create","isDebug","EXPO_DEBUG","line","pipe","AbortCommandError","getBuildSummary","getUserTerminal","logFilePath","writeBuildLogs","wasErrorPresented","errors","errorTitle","throwWithMessage","underline","localizedError","match","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 * 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';\nimport { BuildProps, ProjectInfo } from './XcodeBuild.types';\nimport { ensureDeviceIsCodeSignedForDeploymentAsync } from './codeSigning/configureCodeSigning';\nimport { simulatorBuildRequiresCodeSigning } from './codeSigning/simulatorCodeSigning';\nexport function logPrettyItem(message: string) {\n Log.log(chalk`{whiteBright \\u203A} ${message}`);\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 // 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}\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}: {\n packager: boolean;\n shouldSkipInitialBundling?: boolean;\n terminal: string | undefined;\n port: number;\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 },\n };\n }\n\n return {\n env: {\n ...process.env,\n RCT_TERMINAL: terminal,\n SKIP_BUNDLING,\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 } = 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 }),\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":["logPrettyItem","getAppBinaryPath","getEscapedPath","extractEnvVariableFromBuild","getProcessOptions","getXcodeBuildArgsAsync","buildAsync","_assertXcodeBuildResults","Log","message","log","chalk","buildOutput","CONFIGURATION_BUILD_DIR","sort","a","b","length","UNLOCALIZED_RESOURCES_FOLDER_PATH","binaryPath","path","join","filePath","fs","existsSync","unescapedPath","split","CommandError","variableName","reg","RegExp","matched","matchAll","map","value","filter","Boolean","packager","shouldSkipInitialBundling","terminal","port","SKIP_BUNDLING","undefined","env","process","RCT_TERMINAL","RCT_METRO_PORT","toString","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","error","stdout","on","data","stringData","stderr","Buffer","Promise","resolve","reject","code","spawnXcodeBuildWithFlush","onFlush","currentBuffer","flushBuffer","endsWith","os","EOL","spawnXcodeBuildWithFormat","debug","bold","formatter","ExpoRunFormatter","create","isDebug","EXPO_DEBUG","line","pipe","AbortCommandError","getBuildSummary","getUserTerminal","logFilePath","writeBuildLogs","wasErrorPresented","errors","errorTitle","throwWithMessage","underline","localizedError","match","errorOutput","errorFilePath","getErrorLogFilePath","writeFileSync","folder","ensureDirectory"],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
exports.simulatorBuildRequiresCodeSigning = simulatorBuildRequiresCodeSigning;
|
|
6
|
+
var _configPlugins = require("@expo/config-plugins");
|
|
7
|
+
var _plist = _interopRequireDefault(require("@expo/plist"));
|
|
8
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
9
|
+
function _interopRequireDefault(obj) {
|
|
10
|
+
return obj && obj.__esModule ? obj : {
|
|
11
|
+
default: obj
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const debug = require("debug")("expo:run:ios:codeSigning:simulator");
|
|
15
|
+
// NOTE(EvanBacon): These are entitlements that work in a simulator
|
|
16
|
+
// but still require the project to have development code signing setup.
|
|
17
|
+
// There may be more, but this is fine for now.
|
|
18
|
+
const ENTITLEMENTS_THAT_REQUIRE_CODE_SIGNING = [
|
|
19
|
+
"com.apple.developer.associated-domains",
|
|
20
|
+
"com.apple.developer.applesignin",
|
|
21
|
+
];
|
|
22
|
+
function getEntitlements(projectRoot) {
|
|
23
|
+
try {
|
|
24
|
+
const entitlementsPath = _configPlugins.IOSConfig.Entitlements.getEntitlementsPath(projectRoot);
|
|
25
|
+
if (!entitlementsPath || !_fs.default.existsSync(entitlementsPath)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const entitlementsContents = _fs.default.readFileSync(entitlementsPath, "utf8");
|
|
29
|
+
const entitlements = _plist.default.parse(entitlementsContents);
|
|
30
|
+
return entitlements;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
debug("Failed to read entitlements", error);
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
function simulatorBuildRequiresCodeSigning(projectRoot) {
|
|
37
|
+
const entitlements = getEntitlements(projectRoot);
|
|
38
|
+
if (!entitlements) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return ENTITLEMENTS_THAT_REQUIRE_CODE_SIGNING.some((entitlement)=>entitlement in entitlements
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=simulatorCodeSigning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/run/ios/codeSigning/simulatorCodeSigning.ts"],"sourcesContent":["import { IOSConfig } from '@expo/config-plugins';\nimport plist from '@expo/plist';\nimport fs from 'fs';\n\nconst debug = require('debug')('expo:run:ios:codeSigning:simulator');\n\n// NOTE(EvanBacon): These are entitlements that work in a simulator\n// but still require the project to have development code signing setup.\n// There may be more, but this is fine for now.\nconst ENTITLEMENTS_THAT_REQUIRE_CODE_SIGNING = [\n 'com.apple.developer.associated-domains',\n 'com.apple.developer.applesignin',\n];\n\nfunction getEntitlements(projectRoot: string): Record<string, any> | null {\n try {\n const entitlementsPath = IOSConfig.Entitlements.getEntitlementsPath(projectRoot);\n if (!entitlementsPath || !fs.existsSync(entitlementsPath)) {\n return null;\n }\n\n const entitlementsContents = fs.readFileSync(entitlementsPath, 'utf8');\n const entitlements = plist.parse(entitlementsContents);\n return entitlements;\n } catch (error) {\n debug('Failed to read entitlements', error);\n }\n return null;\n}\n\n/** @returns true if the simulator build should be code signed for development. */\nexport function simulatorBuildRequiresCodeSigning(projectRoot: string): boolean {\n const entitlements = getEntitlements(projectRoot);\n if (!entitlements) {\n return false;\n }\n return ENTITLEMENTS_THAT_REQUIRE_CODE_SIGNING.some((entitlement) => entitlement in entitlements);\n}\n"],"names":["simulatorBuildRequiresCodeSigning","debug","require","ENTITLEMENTS_THAT_REQUIRE_CODE_SIGNING","getEntitlements","projectRoot","entitlementsPath","IOSConfig","Entitlements","getEntitlementsPath","fs","existsSync","entitlementsContents","readFileSync","entitlements","plist","parse","error","some","entitlement"],"mappings":"AAAA;;;;QA+BgBA,iCAAiC,GAAjCA,iCAAiC;AA/BvB,IAAA,cAAsB,WAAtB,sBAAsB,CAAA;AAC9B,IAAA,MAAa,kCAAb,aAAa,EAAA;AAChB,IAAA,GAAI,kCAAJ,IAAI,EAAA;;;;;;AAEnB,MAAMC,KAAK,GAAGC,OAAO,CAAC,OAAO,CAAC,CAAC,oCAAoC,CAAC,AAAC;AAErE,mEAAmE;AACnE,wEAAwE;AACxE,+CAA+C;AAC/C,MAAMC,sCAAsC,GAAG;IAC7C,wCAAwC;IACxC,iCAAiC;CAClC,AAAC;AAEF,SAASC,eAAe,CAACC,WAAmB,EAA8B;IACxE,IAAI;QACF,MAAMC,gBAAgB,GAAGC,cAAS,UAAA,CAACC,YAAY,CAACC,mBAAmB,CAACJ,WAAW,CAAC,AAAC;QACjF,IAAI,CAACC,gBAAgB,IAAI,CAACI,GAAE,QAAA,CAACC,UAAU,CAACL,gBAAgB,CAAC,EAAE;YACzD,OAAO,IAAI,CAAC;SACb;QAED,MAAMM,oBAAoB,GAAGF,GAAE,QAAA,CAACG,YAAY,CAACP,gBAAgB,EAAE,MAAM,CAAC,AAAC;QACvE,MAAMQ,YAAY,GAAGC,MAAK,QAAA,CAACC,KAAK,CAACJ,oBAAoB,CAAC,AAAC;QACvD,OAAOE,YAAY,CAAC;KACrB,CAAC,OAAOG,KAAK,EAAE;QACdhB,KAAK,CAAC,6BAA6B,EAAEgB,KAAK,CAAC,CAAC;KAC7C;IACD,OAAO,IAAI,CAAC;CACb;AAGM,SAASjB,iCAAiC,CAACK,WAAmB,EAAW;IAC9E,MAAMS,YAAY,GAAGV,eAAe,CAACC,WAAW,CAAC,AAAC;IAClD,IAAI,CAACS,YAAY,EAAE;QACjB,OAAO,KAAK,CAAC;KACd;IACD,OAAOX,sCAAsC,CAACe,IAAI,CAAC,CAACC,WAAW,GAAKA,WAAW,IAAIL,YAAY;IAAA,CAAC,CAAC;CAClG"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
+
exports.isNgrokClientError = isNgrokClientError;
|
|
5
6
|
var _externalModule = require("./ExternalModule");
|
|
6
7
|
class NgrokResolver extends _externalModule.ExternalModule {
|
|
7
8
|
constructor(projectRoot){
|
|
@@ -13,5 +14,9 @@ class NgrokResolver extends _externalModule.ExternalModule {
|
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
exports.NgrokResolver = NgrokResolver;
|
|
17
|
+
function isNgrokClientError(error) {
|
|
18
|
+
var ref;
|
|
19
|
+
return error == null ? void 0 : (ref = error.body) == null ? void 0 : ref.msg;
|
|
20
|
+
}
|
|
16
21
|
|
|
17
22
|
//# sourceMappingURL=NgrokResolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/doctor/ngrok/NgrokResolver.ts"],"sourcesContent":["import { ExternalModule } from './ExternalModule';\n\nexport interface NgrokOptions {\n authtoken?: string;\n port?: string | number | null;\n host?: string;\n httpauth?: string;\n region?: string;\n configPath?: string;\n\n proto?: 'http' | 'tcp' | 'tls';\n addr?: string;\n inspect?: boolean;\n auth?: string;\n host_header?: string;\n bind_tls?: true | false | 'both';\n subdomain?: string;\n hostname?: string;\n crt?: string;\n key?: string;\n client_cas?: string;\n remote_addr?: string;\n}\n\nexport interface NgrokInstance {\n getActiveProcess(): { pid: number };\n connect(\n props: {\n hostname
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/doctor/ngrok/NgrokResolver.ts"],"sourcesContent":["import { ExternalModule } from './ExternalModule';\n\nexport interface NgrokClientError {\n body: {\n error_code: number;\n status_code: number;\n msg: string;\n details: {\n err: string;\n };\n };\n}\n\nexport interface NgrokOptions {\n authtoken?: string;\n port?: string | number | null;\n host?: string;\n httpauth?: string;\n region?: string;\n configPath?: string;\n\n proto?: 'http' | 'tcp' | 'tls';\n addr?: string;\n inspect?: boolean;\n auth?: string;\n host_header?: string;\n bind_tls?: true | false | 'both';\n subdomain?: string;\n hostname?: string;\n crt?: string;\n key?: string;\n client_cas?: string;\n remote_addr?: string;\n}\n\nexport interface NgrokInstance {\n getActiveProcess(): { pid: number };\n connect(\n props: {\n hostname?: string;\n configPath: string;\n onStatusChange: (status: string) => void;\n } & NgrokOptions\n ): Promise<string>;\n kill(): Promise<void>;\n}\n\n/** Resolves the ngrok instance from local or globally installed package. */\nexport class NgrokResolver extends ExternalModule<NgrokInstance> {\n constructor(projectRoot: string) {\n super(\n projectRoot,\n {\n name: '@expo/ngrok',\n versionRange: '^4.1.0',\n },\n (packageName) =>\n `The package ${packageName} is required to use tunnels, would you like to install it globally?`\n );\n }\n}\n\nexport function isNgrokClientError(error: any): error is NgrokClientError {\n return error?.body?.msg;\n}\n"],"names":["isNgrokClientError","NgrokResolver","ExternalModule","constructor","projectRoot","name","versionRange","packageName","error","body","msg"],"mappings":"AAAA;;;;QA8DgBA,kBAAkB,GAAlBA,kBAAkB;AA9DH,IAAA,eAAkB,WAAlB,kBAAkB,CAAA;AAgD1C,MAAMC,aAAa,SAASC,eAAc,eAAA;IAC/CC,YAAYC,WAAmB,CAAE;QAC/B,KAAK,CACHA,WAAW,EACX;YACEC,IAAI,EAAE,aAAa;YACnBC,YAAY,EAAE,QAAQ;SACvB,EACD,CAACC,WAAW,GACV,CAAC,YAAY,EAAEA,WAAW,CAAC,mEAAmE,CAAC;QAAA,CAClG,CAAC;KACH;CACF;QAZYN,aAAa,GAAbA,aAAa;AAcnB,SAASD,kBAAkB,CAACQ,KAAU,EAA6B;QACjEA,GAAW;IAAlB,OAAOA,KAAK,QAAM,GAAXA,KAAAA,CAAW,GAAXA,CAAAA,GAAW,GAAXA,KAAK,CAAEC,IAAI,SAAA,GAAXD,KAAAA,CAAW,GAAXA,GAAW,CAAEE,GAAG,AAAL,CAAM;CACzB"}
|
|
@@ -32,7 +32,12 @@ class PlatformManager {
|
|
|
32
32
|
const redirectUrl = this.props.getRedirectUrl();
|
|
33
33
|
if (redirectUrl) {
|
|
34
34
|
// If the redirect page feature is enabled, check if the project has a resolvable native identifier.
|
|
35
|
-
|
|
35
|
+
let applicationId;
|
|
36
|
+
try {
|
|
37
|
+
applicationId = await this._getAppIdResolver().getAppIdAsync();
|
|
38
|
+
} catch {
|
|
39
|
+
_log.Log.warn(_chalk.default`\u203A Launching in Expo Go. If you want to use a ` + `development build, you need to create and install one first, or, if you already ` + _chalk.default`have a build, add {bold ios.bundleIdentifier} and {bold android.package} to ` + `this project's app config.\n${(0, _link).learnMore("https://docs.expo.dev/development/build/")}`);
|
|
40
|
+
}
|
|
36
41
|
if (applicationId) {
|
|
37
42
|
debug(`Resolving launch URL: (appId: ${applicationId}, redirect URL: ${redirectUrl})`);
|
|
38
43
|
// NOTE(EvanBacon): This adds considerable amount of time to the command, we should consider removing or memoizing it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/platforms/PlatformManager.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport assert from 'assert';\nimport chalk from 'chalk';\n\nimport { Log } from '../../log';\nimport { logEventAsync } from '../../utils/analytics/rudderstackClient';\nimport { CommandError, UnimplementedError } from '../../utils/errors';\nimport { learnMore } from '../../utils/link';\nimport { AppIdResolver } from './AppIdResolver';\nimport { DeviceManager } from './DeviceManager';\n\nconst debug = require('debug')('expo:start:platforms:platformManager') as typeof console.log;\n\nexport interface BaseOpenInCustomProps {\n scheme?: string;\n applicationId?: string | null;\n}\n\nexport interface BaseResolveDeviceProps<IDevice> {\n /** Should prompt the user to select a device. */\n shouldPrompt?: boolean;\n /** The target device to use. */\n device?: IDevice;\n}\n\n/** An abstract class for launching a URL on a device. */\nexport class PlatformManager<\n IDevice,\n IOpenInCustomProps extends BaseOpenInCustomProps = BaseOpenInCustomProps,\n IResolveDeviceProps extends BaseResolveDeviceProps<IDevice> = BaseResolveDeviceProps<IDevice>\n> {\n constructor(\n protected projectRoot: string,\n protected props: {\n platform: 'ios' | 'android';\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL. */\n getExpoGoUrl: () => string;\n /**\n * Get redirect URL for native disambiguation.\n * @returns a URL like `http://localhost:19000/_expo/loading`\n */\n getRedirectUrl: () => string | null;\n /** Dev Client */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n /** Resolve a device, this function should automatically handle opening the device and asserting any system validations. */\n resolveDeviceAsync: (\n resolver?: Partial<IResolveDeviceProps>\n ) => Promise<DeviceManager<IDevice>>;\n }\n ) {}\n\n /** Returns the project application identifier or asserts that one is not defined. Exposed for testing. */\n _getAppIdResolver(): AppIdResolver {\n throw new UnimplementedError();\n }\n\n /**\n * Get the URL for users intending to launch the project in Expo Go.\n * The CLI will check if the project has a custom dev client and if the redirect page feature is enabled.\n * If both are true, the CLI will return the redirect page URL.\n */\n protected async getExpoGoOrCustomRuntimeUrlAsync(\n deviceManager: DeviceManager<IDevice>\n ): Promise<string> {\n // Determine if the redirect page feature is enabled first since it's the cheapest to check.\n const redirectUrl = this.props.getRedirectUrl();\n if (redirectUrl) {\n // If the redirect page feature is enabled, check if the project has a resolvable native identifier.\n const applicationId = await this._getAppIdResolver().getAppIdAsync();\n if (applicationId) {\n debug(`Resolving launch URL: (appId: ${applicationId}, redirect URL: ${redirectUrl})`);\n // NOTE(EvanBacon): This adds considerable amount of time to the command, we should consider removing or memoizing it.\n // Finally determine if the target device has a custom dev client installed.\n if (await deviceManager.isAppInstalledAsync(applicationId)) {\n return redirectUrl;\n } else {\n // Log a warning if no development build is available on the device, but the\n // interstitial page would otherwise be opened.\n Log.warn(\n chalk`\\u203A The {bold expo-dev-client} package is installed, but a development build is not ` +\n chalk`installed on {bold ${deviceManager.name}}.\\nLaunching in Expo Go. If you want to use a ` +\n `development build, you need to create and install one first.\\n${learnMore(\n 'https://docs.expo.dev/development/build/'\n )}`\n );\n }\n }\n }\n\n return this.props.getExpoGoUrl();\n }\n\n protected async openProjectInExpoGoAsync(\n resolveSettings: Partial<IResolveDeviceProps> = {}\n ): Promise<{ url: string }> {\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n const url = await this.getExpoGoOrCustomRuntimeUrlAsync(deviceManager);\n\n deviceManager.logOpeningUrl(url);\n\n // TODO: Expensive, we should only do this once.\n const { exp } = getConfig(this.projectRoot);\n const installedExpo = await deviceManager.ensureExpoGoAsync(exp.sdkVersion);\n\n deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n await logEventAsync('Open Url on Device', {\n platform: this.props.platform,\n installedExpo,\n });\n\n return { url };\n }\n\n private async openProjectInCustomRuntimeAsync(\n resolveSettings: Partial<IResolveDeviceProps> = {},\n props: Partial<IOpenInCustomProps> = {}\n ): Promise<{ url: string }> {\n debug(\n `open custom (${Object.entries(props)\n .map(([k, v]) => `${k}: ${v}`)\n .join(', ')})`\n );\n\n let url = this.props.getCustomRuntimeUrl({ scheme: props.scheme });\n debug(`Opening project in custom runtime: ${url} -- %O`, props);\n // TODO: It's unclear why we do application id validation when opening with a URL\n const applicationId = props.applicationId ?? (await this._getAppIdResolver().getAppIdAsync());\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n\n if (!(await deviceManager.isAppInstalledAsync(applicationId))) {\n throw new CommandError(\n `No development build (${applicationId}) for this project is installed. ` +\n `Please make and install a development build on the device first.\\n${learnMore(\n 'https://docs.expo.dev/development/build/'\n )}`\n );\n }\n\n // TODO: Rethink analytics\n await logEventAsync('Open Url on Device', {\n platform: this.props.platform,\n installedExpo: false,\n });\n\n if (!url) {\n url = this._resolveAlternativeLaunchUrl(applicationId, props);\n }\n\n deviceManager.logOpeningUrl(url);\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n return {\n url,\n };\n }\n\n /** Launch the project on a device given the input runtime. */\n async openAsync(\n options:\n | {\n runtime: 'expo' | 'web';\n }\n | {\n runtime: 'custom';\n props?: Partial<IOpenInCustomProps>;\n },\n resolveSettings: Partial<IResolveDeviceProps> = {}\n ): Promise<{ url: string }> {\n debug(\n `open (runtime: ${options.runtime}, platform: ${this.props.platform}, device: %O, shouldPrompt: ${resolveSettings.shouldPrompt})`,\n resolveSettings.device\n );\n if (options.runtime === 'expo') {\n return this.openProjectInExpoGoAsync(resolveSettings);\n } else if (options.runtime === 'web') {\n return this.openWebProjectAsync(resolveSettings);\n } else if (options.runtime === 'custom') {\n return this.openProjectInCustomRuntimeAsync(resolveSettings, options.props);\n } else {\n throw new CommandError(`Invalid runtime target: ${options.runtime}`);\n }\n }\n\n /** Open the current web project (Webpack) in a device . */\n private async openWebProjectAsync(resolveSettings: Partial<IResolveDeviceProps> = {}): Promise<{\n url: string;\n }> {\n const url = this.props.getDevServerUrl();\n assert(url, 'Dev server is not running.');\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n deviceManager.logOpeningUrl(url);\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n return { url };\n }\n\n /** If the launch URL cannot be determined (`custom` runtimes) then an alternative string can be provided to open the device. Often a device ID or activity to launch. Exposed for testing. */\n _resolveAlternativeLaunchUrl(\n applicationId: string,\n props: Partial<IOpenInCustomProps> = {}\n ): string {\n throw new UnimplementedError();\n }\n}\n"],"names":["debug","require","PlatformManager","constructor","projectRoot","props","_getAppIdResolver","UnimplementedError","getExpoGoOrCustomRuntimeUrlAsync","deviceManager","redirectUrl","getRedirectUrl","applicationId","getAppIdAsync","isAppInstalledAsync","Log","warn","chalk","name","learnMore","getExpoGoUrl","openProjectInExpoGoAsync","resolveSettings","resolveDeviceAsync","url","logOpeningUrl","exp","getConfig","installedExpo","ensureExpoGoAsync","sdkVersion","activateWindowAsync","openUrlAsync","logEventAsync","platform","openProjectInCustomRuntimeAsync","Object","entries","map","k","v","join","getCustomRuntimeUrl","scheme","CommandError","_resolveAlternativeLaunchUrl","openAsync","options","runtime","shouldPrompt","device","openWebProjectAsync","getDevServerUrl","assert"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/platforms/PlatformManager.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport assert from 'assert';\nimport chalk from 'chalk';\n\nimport { Log } from '../../log';\nimport { logEventAsync } from '../../utils/analytics/rudderstackClient';\nimport { CommandError, UnimplementedError } from '../../utils/errors';\nimport { learnMore } from '../../utils/link';\nimport { AppIdResolver } from './AppIdResolver';\nimport { DeviceManager } from './DeviceManager';\n\nconst debug = require('debug')('expo:start:platforms:platformManager') as typeof console.log;\n\nexport interface BaseOpenInCustomProps {\n scheme?: string;\n applicationId?: string | null;\n}\n\nexport interface BaseResolveDeviceProps<IDevice> {\n /** Should prompt the user to select a device. */\n shouldPrompt?: boolean;\n /** The target device to use. */\n device?: IDevice;\n}\n\n/** An abstract class for launching a URL on a device. */\nexport class PlatformManager<\n IDevice,\n IOpenInCustomProps extends BaseOpenInCustomProps = BaseOpenInCustomProps,\n IResolveDeviceProps extends BaseResolveDeviceProps<IDevice> = BaseResolveDeviceProps<IDevice>\n> {\n constructor(\n protected projectRoot: string,\n protected props: {\n platform: 'ios' | 'android';\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL. */\n getExpoGoUrl: () => string;\n /**\n * Get redirect URL for native disambiguation.\n * @returns a URL like `http://localhost:19000/_expo/loading`\n */\n getRedirectUrl: () => string | null;\n /** Dev Client */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n /** Resolve a device, this function should automatically handle opening the device and asserting any system validations. */\n resolveDeviceAsync: (\n resolver?: Partial<IResolveDeviceProps>\n ) => Promise<DeviceManager<IDevice>>;\n }\n ) {}\n\n /** Returns the project application identifier or asserts that one is not defined. Exposed for testing. */\n _getAppIdResolver(): AppIdResolver {\n throw new UnimplementedError();\n }\n\n /**\n * Get the URL for users intending to launch the project in Expo Go.\n * The CLI will check if the project has a custom dev client and if the redirect page feature is enabled.\n * If both are true, the CLI will return the redirect page URL.\n */\n protected async getExpoGoOrCustomRuntimeUrlAsync(\n deviceManager: DeviceManager<IDevice>\n ): Promise<string> {\n // Determine if the redirect page feature is enabled first since it's the cheapest to check.\n const redirectUrl = this.props.getRedirectUrl();\n if (redirectUrl) {\n // If the redirect page feature is enabled, check if the project has a resolvable native identifier.\n let applicationId;\n try {\n applicationId = await this._getAppIdResolver().getAppIdAsync();\n } catch {\n Log.warn(\n chalk`\\u203A Launching in Expo Go. If you want to use a ` +\n `development build, you need to create and install one first, or, if you already ` +\n chalk`have a build, add {bold ios.bundleIdentifier} and {bold android.package} to ` +\n `this project's app config.\\n${learnMore('https://docs.expo.dev/development/build/')}`\n );\n }\n if (applicationId) {\n debug(`Resolving launch URL: (appId: ${applicationId}, redirect URL: ${redirectUrl})`);\n // NOTE(EvanBacon): This adds considerable amount of time to the command, we should consider removing or memoizing it.\n // Finally determine if the target device has a custom dev client installed.\n if (await deviceManager.isAppInstalledAsync(applicationId)) {\n return redirectUrl;\n } else {\n // Log a warning if no development build is available on the device, but the\n // interstitial page would otherwise be opened.\n Log.warn(\n chalk`\\u203A The {bold expo-dev-client} package is installed, but a development build is not ` +\n chalk`installed on {bold ${deviceManager.name}}.\\nLaunching in Expo Go. If you want to use a ` +\n `development build, you need to create and install one first.\\n${learnMore(\n 'https://docs.expo.dev/development/build/'\n )}`\n );\n }\n }\n }\n\n return this.props.getExpoGoUrl();\n }\n\n protected async openProjectInExpoGoAsync(\n resolveSettings: Partial<IResolveDeviceProps> = {}\n ): Promise<{ url: string }> {\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n const url = await this.getExpoGoOrCustomRuntimeUrlAsync(deviceManager);\n\n deviceManager.logOpeningUrl(url);\n\n // TODO: Expensive, we should only do this once.\n const { exp } = getConfig(this.projectRoot);\n const installedExpo = await deviceManager.ensureExpoGoAsync(exp.sdkVersion);\n\n deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n await logEventAsync('Open Url on Device', {\n platform: this.props.platform,\n installedExpo,\n });\n\n return { url };\n }\n\n private async openProjectInCustomRuntimeAsync(\n resolveSettings: Partial<IResolveDeviceProps> = {},\n props: Partial<IOpenInCustomProps> = {}\n ): Promise<{ url: string }> {\n debug(\n `open custom (${Object.entries(props)\n .map(([k, v]) => `${k}: ${v}`)\n .join(', ')})`\n );\n\n let url = this.props.getCustomRuntimeUrl({ scheme: props.scheme });\n debug(`Opening project in custom runtime: ${url} -- %O`, props);\n // TODO: It's unclear why we do application id validation when opening with a URL\n const applicationId = props.applicationId ?? (await this._getAppIdResolver().getAppIdAsync());\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n\n if (!(await deviceManager.isAppInstalledAsync(applicationId))) {\n throw new CommandError(\n `No development build (${applicationId}) for this project is installed. ` +\n `Please make and install a development build on the device first.\\n${learnMore(\n 'https://docs.expo.dev/development/build/'\n )}`\n );\n }\n\n // TODO: Rethink analytics\n await logEventAsync('Open Url on Device', {\n platform: this.props.platform,\n installedExpo: false,\n });\n\n if (!url) {\n url = this._resolveAlternativeLaunchUrl(applicationId, props);\n }\n\n deviceManager.logOpeningUrl(url);\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n return {\n url,\n };\n }\n\n /** Launch the project on a device given the input runtime. */\n async openAsync(\n options:\n | {\n runtime: 'expo' | 'web';\n }\n | {\n runtime: 'custom';\n props?: Partial<IOpenInCustomProps>;\n },\n resolveSettings: Partial<IResolveDeviceProps> = {}\n ): Promise<{ url: string }> {\n debug(\n `open (runtime: ${options.runtime}, platform: ${this.props.platform}, device: %O, shouldPrompt: ${resolveSettings.shouldPrompt})`,\n resolveSettings.device\n );\n if (options.runtime === 'expo') {\n return this.openProjectInExpoGoAsync(resolveSettings);\n } else if (options.runtime === 'web') {\n return this.openWebProjectAsync(resolveSettings);\n } else if (options.runtime === 'custom') {\n return this.openProjectInCustomRuntimeAsync(resolveSettings, options.props);\n } else {\n throw new CommandError(`Invalid runtime target: ${options.runtime}`);\n }\n }\n\n /** Open the current web project (Webpack) in a device . */\n private async openWebProjectAsync(resolveSettings: Partial<IResolveDeviceProps> = {}): Promise<{\n url: string;\n }> {\n const url = this.props.getDevServerUrl();\n assert(url, 'Dev server is not running.');\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n deviceManager.logOpeningUrl(url);\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n return { url };\n }\n\n /** If the launch URL cannot be determined (`custom` runtimes) then an alternative string can be provided to open the device. Often a device ID or activity to launch. Exposed for testing. */\n _resolveAlternativeLaunchUrl(\n applicationId: string,\n props: Partial<IOpenInCustomProps> = {}\n ): string {\n throw new UnimplementedError();\n }\n}\n"],"names":["debug","require","PlatformManager","constructor","projectRoot","props","_getAppIdResolver","UnimplementedError","getExpoGoOrCustomRuntimeUrlAsync","deviceManager","redirectUrl","getRedirectUrl","applicationId","getAppIdAsync","Log","warn","chalk","learnMore","isAppInstalledAsync","name","getExpoGoUrl","openProjectInExpoGoAsync","resolveSettings","resolveDeviceAsync","url","logOpeningUrl","exp","getConfig","installedExpo","ensureExpoGoAsync","sdkVersion","activateWindowAsync","openUrlAsync","logEventAsync","platform","openProjectInCustomRuntimeAsync","Object","entries","map","k","v","join","getCustomRuntimeUrl","scheme","CommandError","_resolveAlternativeLaunchUrl","openAsync","options","runtime","shouldPrompt","device","openWebProjectAsync","getDevServerUrl","assert"],"mappings":"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"}
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
+
exports.hasAdbReverseAsync = hasAdbReverseAsync;
|
|
5
6
|
exports.startAdbReverseAsync = startAdbReverseAsync;
|
|
6
7
|
exports.stopAdbReverseAsync = stopAdbReverseAsync;
|
|
7
8
|
var Log = _interopRequireWildcard(require("../../../log"));
|
|
8
9
|
var _exit = require("../../../utils/exit");
|
|
10
|
+
var _androidSdk = require("./AndroidSdk");
|
|
9
11
|
var _adb = require("./adb");
|
|
10
12
|
function _interopRequireWildcard(obj) {
|
|
11
13
|
if (obj && obj.__esModule) {
|
|
@@ -30,6 +32,14 @@ function _interopRequireWildcard(obj) {
|
|
|
30
32
|
}
|
|
31
33
|
const debug = require("debug")("expo:start:platforms:android:adbReverse");
|
|
32
34
|
let removeExitHook = null;
|
|
35
|
+
function hasAdbReverseAsync() {
|
|
36
|
+
try {
|
|
37
|
+
return !!(0, _androidSdk).assertSdkRoot();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
debug("Failed to resolve the Android SDK path, skipping ADB: %s", error.message);
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
33
43
|
async function startAdbReverseAsync(ports) {
|
|
34
44
|
// Install cleanup automatically...
|
|
35
45
|
removeExitHook = (0, _exit).installExitHooks(()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/platforms/android/adbReverse.ts"],"sourcesContent":["import * as Log from '../../../log';\nimport { installExitHooks } from '../../../utils/exit';\nimport { adbArgs, Device, getAttachedDevicesAsync, getServer, logUnauthorized } from './adb';\n\nconst debug = require('debug')('expo:start:platforms:android:adbReverse') as typeof console.log;\n\nlet removeExitHook: (() => void) | null = null;\n\nexport async function startAdbReverseAsync(ports: number[]): Promise<boolean> {\n // Install cleanup automatically...\n removeExitHook = installExitHooks(() => {\n stopAdbReverseAsync(ports);\n });\n\n const devices = await getAttachedDevicesAsync();\n for (const device of devices) {\n for (const port of ports) {\n if (!(await adbReverseAsync(device, port))) {\n debug(`Failed to start reverse port ${port} on device \"${device.name}\"`);\n return false;\n }\n }\n }\n return true;\n}\n\nexport async function stopAdbReverseAsync(ports: number[]): Promise<void> {\n removeExitHook?.();\n\n const devices = await getAttachedDevicesAsync();\n for (const device of devices) {\n for (const port of ports) {\n await adbReverseRemoveAsync(device, port);\n }\n }\n}\n\nasync function adbReverseAsync(device: Device, port: number): Promise<boolean> {\n if (!device.isAuthorized) {\n logUnauthorized(device);\n return false;\n }\n\n try {\n await getServer().runAsync(adbArgs(device.pid, 'reverse', `tcp:${port}`, `tcp:${port}`));\n return true;\n } catch (error: any) {\n Log.warn(`[ADB] Couldn't reverse port ${port}: ${error.message}`);\n return false;\n }\n}\n\nasync function adbReverseRemoveAsync(device: Device, port: number): Promise<boolean> {\n if (!device.isAuthorized) {\n return false;\n }\n\n try {\n await getServer().runAsync(adbArgs(device.pid, 'reverse', '--remove', `tcp:${port}`));\n return true;\n } catch (error: any) {\n // Don't send this to warn because we call this preemptively sometimes\n debug(`Could not unforward port ${port}: ${error.message}`);\n return false;\n }\n}\n"],"names":["startAdbReverseAsync","stopAdbReverseAsync","Log","debug","require","removeExitHook","ports","installExitHooks","devices","getAttachedDevicesAsync","device","port","adbReverseAsync","name","adbReverseRemoveAsync","isAuthorized","logUnauthorized","getServer","runAsync","adbArgs","pid","
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/platforms/android/adbReverse.ts"],"sourcesContent":["import * as Log from '../../../log';\nimport { installExitHooks } from '../../../utils/exit';\nimport { assertSdkRoot } from './AndroidSdk';\nimport { adbArgs, Device, getAttachedDevicesAsync, getServer, logUnauthorized } from './adb';\n\nconst debug = require('debug')('expo:start:platforms:android:adbReverse') as typeof console.log;\n\nlet removeExitHook: (() => void) | null = null;\n\nexport function hasAdbReverseAsync(): boolean {\n try {\n return !!assertSdkRoot();\n } catch (error: any) {\n debug('Failed to resolve the Android SDK path, skipping ADB: %s', error.message);\n return false;\n }\n}\n\nexport async function startAdbReverseAsync(ports: number[]): Promise<boolean> {\n // Install cleanup automatically...\n removeExitHook = installExitHooks(() => {\n stopAdbReverseAsync(ports);\n });\n\n const devices = await getAttachedDevicesAsync();\n for (const device of devices) {\n for (const port of ports) {\n if (!(await adbReverseAsync(device, port))) {\n debug(`Failed to start reverse port ${port} on device \"${device.name}\"`);\n return false;\n }\n }\n }\n return true;\n}\n\nexport async function stopAdbReverseAsync(ports: number[]): Promise<void> {\n removeExitHook?.();\n\n const devices = await getAttachedDevicesAsync();\n for (const device of devices) {\n for (const port of ports) {\n await adbReverseRemoveAsync(device, port);\n }\n }\n}\n\nasync function adbReverseAsync(device: Device, port: number): Promise<boolean> {\n if (!device.isAuthorized) {\n logUnauthorized(device);\n return false;\n }\n\n try {\n await getServer().runAsync(adbArgs(device.pid, 'reverse', `tcp:${port}`, `tcp:${port}`));\n return true;\n } catch (error: any) {\n Log.warn(`[ADB] Couldn't reverse port ${port}: ${error.message}`);\n return false;\n }\n}\n\nasync function adbReverseRemoveAsync(device: Device, port: number): Promise<boolean> {\n if (!device.isAuthorized) {\n return false;\n }\n\n try {\n await getServer().runAsync(adbArgs(device.pid, 'reverse', '--remove', `tcp:${port}`));\n return true;\n } catch (error: any) {\n // Don't send this to warn because we call this preemptively sometimes\n debug(`Could not unforward port ${port}: ${error.message}`);\n return false;\n }\n}\n"],"names":["hasAdbReverseAsync","startAdbReverseAsync","stopAdbReverseAsync","Log","debug","require","removeExitHook","assertSdkRoot","error","message","ports","installExitHooks","devices","getAttachedDevicesAsync","device","port","adbReverseAsync","name","adbReverseRemoveAsync","isAuthorized","logUnauthorized","getServer","runAsync","adbArgs","pid","warn"],"mappings":"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"}
|
|
@@ -54,7 +54,7 @@ async function resolveOptionsAsync(projectRoot, args) {
|
|
|
54
54
|
var ref;
|
|
55
55
|
return {
|
|
56
56
|
forceManifestType,
|
|
57
|
-
privateKeyPath: (ref = args["private-key-path"]) != null ? ref : null,
|
|
57
|
+
privateKeyPath: (ref = args["--private-key-path"]) != null ? ref : null,
|
|
58
58
|
android: !!args["--android"],
|
|
59
59
|
web: !!args["--web"],
|
|
60
60
|
ios: !!args["--ios"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/start/resolveOptions.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { AbortCommandError, CommandError } from '../utils/errors';\nimport { resolvePortAsync } from '../utils/port';\n\nexport type Options = {\n forceManifestType: 'classic' | 'expo-updates';\n privateKeyPath: string | null;\n android: boolean;\n web: boolean;\n ios: boolean;\n offline: boolean;\n clear: boolean;\n dev: boolean;\n https: boolean;\n maxWorkers: number;\n port: number;\n /** Should instruct the bundler to create minified bundles. */\n minify: boolean;\n devClient: boolean;\n scheme: string | null;\n host: 'localhost' | 'lan' | 'tunnel';\n};\n\nexport async function resolveOptionsAsync(projectRoot: string, args: any): Promise<Options> {\n const forceManifestType = args['--force-manifest-type'];\n if (forceManifestType) {\n assert.match(forceManifestType, /^(classic|expo-updates)$/);\n }\n const host = resolveHostType({\n host: args['--host'],\n offline: args['--offline'],\n lan: args['--lan'],\n localhost: args['--localhost'],\n tunnel: args['--tunnel'],\n });\n\n const scheme = await resolveSchemeAsync(projectRoot, {\n scheme: args['--scheme'],\n devClient: args['--dev-client'],\n });\n\n return {\n forceManifestType,\n privateKeyPath: args['private-key-path'] ?? null,\n\n android: !!args['--android'],\n web: !!args['--web'],\n ios: !!args['--ios'],\n offline: !!args['--offline'],\n\n clear: !!args['--clear'],\n dev: !args['--no-dev'],\n https: !!args['--https'],\n maxWorkers: args['--max-workers'],\n port: args['--port'],\n minify: !!args['--minify'],\n\n devClient: !!args['--dev-client'],\n\n scheme,\n host,\n };\n}\n\nexport async function resolveSchemeAsync(\n projectRoot: string,\n options: { scheme?: string; devClient?: boolean }\n): Promise<string | null> {\n const resolveFrom = await import('resolve-from').then((m) => m.default);\n\n const isDevClientPackageInstalled = (() => {\n try {\n // we check if `expo-dev-launcher` is installed instead of `expo-dev-client`\n // because someone could install only launcher.\n resolveFrom(projectRoot, 'expo-dev-launcher');\n return true;\n } catch {\n return false;\n }\n })();\n\n if (typeof options.scheme === 'string') {\n // Use the custom scheme\n return options.scheme ?? null;\n } else if (options.devClient || isDevClientPackageInstalled) {\n const { getOptionalDevClientSchemeAsync } = await import('../utils/scheme');\n // Attempt to find the scheme or warn the user how to setup a custom scheme\n return await getOptionalDevClientSchemeAsync(projectRoot);\n } else {\n // Ensure this is reset when users don't use `--scheme`, `--dev-client` and don't have the `expo-dev-client` package installed.\n return null;\n }\n}\n\n/** Resolve and assert host type options. */\nexport function resolveHostType(options: {\n host?: string;\n offline?: boolean;\n lan?: boolean;\n localhost?: boolean;\n tunnel?: boolean;\n}): 'lan' | 'tunnel' | 'localhost' {\n if (\n [options.offline, options.host, options.lan, options.localhost, options.tunnel].filter((i) => i)\n .length > 1\n ) {\n throw new CommandError(\n 'BAD_ARGS',\n 'Specify at most one of: --offline, --host, --tunnel, --lan, --localhost'\n );\n }\n\n if (options.offline) {\n // Force `lan` in offline mode.\n return 'lan';\n } else if (options.host) {\n assert.match(options.host, /^(lan|tunnel|localhost)$/);\n return options.host as 'lan' | 'tunnel' | 'localhost';\n } else if (options.tunnel) {\n return 'tunnel';\n } else if (options.lan) {\n return 'lan';\n } else if (options.localhost) {\n return 'localhost';\n }\n return 'lan';\n}\n\n/** Resolve the port options for all supported bundlers. */\nexport async function resolvePortsAsync(\n projectRoot: string,\n options: Partial<Pick<Options, 'port' | 'devClient'>>,\n settings: { webOnly?: boolean }\n) {\n const multiBundlerSettings: { webpackPort?: number; metroPort?: number } = {};\n\n if (settings.webOnly) {\n const webpackPort = await resolvePortAsync(projectRoot, {\n defaultPort: options.port,\n // Default web port\n fallbackPort: 19006,\n });\n if (!webpackPort) {\n throw new AbortCommandError();\n }\n multiBundlerSettings.webpackPort = webpackPort;\n } else {\n const devClientDefaultPort = process.env.RCT_METRO_PORT\n ? parseInt(process.env.RCT_METRO_PORT, 10)\n : 8081;\n const expoGoDefaultPort = 19000;\n const metroPort = await resolvePortAsync(projectRoot, {\n defaultPort: options.port,\n fallbackPort: options.devClient ? devClientDefaultPort : expoGoDefaultPort,\n });\n if (!metroPort) {\n throw new AbortCommandError();\n }\n multiBundlerSettings.metroPort = metroPort;\n }\n\n return multiBundlerSettings;\n}\n"],"names":["resolveOptionsAsync","resolveSchemeAsync","resolveHostType","resolvePortsAsync","projectRoot","args","forceManifestType","assert","match","host","offline","lan","localhost","tunnel","scheme","devClient","privateKeyPath","android","web","ios","clear","dev","https","maxWorkers","port","minify","options","resolveFrom","then","m","default","isDevClientPackageInstalled","getOptionalDevClientSchemeAsync","filter","i","length","CommandError","settings","multiBundlerSettings","webOnly","webpackPort","resolvePortAsync","defaultPort","fallbackPort","AbortCommandError","devClientDefaultPort","process","env","RCT_METRO_PORT","parseInt","expoGoDefaultPort","metroPort"],"mappings":"AAAA;;;;QAwBsBA,mBAAmB,GAAnBA,mBAAmB;QAyCnBC,kBAAkB,GAAlBA,kBAAkB;QA+BxBC,eAAe,GAAfA,eAAe;QAkCTC,iBAAiB,GAAjBA,iBAAiB;AAlIpB,IAAA,OAAQ,kCAAR,QAAQ,EAAA;AAEqB,IAAA,OAAiB,WAAjB,iBAAiB,CAAA;AAChC,IAAA,KAAe,WAAf,eAAe,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBzC,eAAeH,mBAAmB,CAACI,WAAmB,EAAEC,IAAS,EAAoB;IAC1F,MAAMC,iBAAiB,GAAGD,IAAI,CAAC,uBAAuB,CAAC,AAAC;IACxD,IAAIC,iBAAiB,EAAE;QACrBC,OAAM,QAAA,CAACC,KAAK,CAACF,iBAAiB,6BAA6B,CAAC;KAC7D;IACD,MAAMG,IAAI,GAAGP,eAAe,CAAC;QAC3BO,IAAI,EAAEJ,IAAI,CAAC,QAAQ,CAAC;QACpBK,OAAO,EAAEL,IAAI,CAAC,WAAW,CAAC;QAC1BM,GAAG,EAAEN,IAAI,CAAC,OAAO,CAAC;QAClBO,SAAS,EAAEP,IAAI,CAAC,aAAa,CAAC;QAC9BQ,MAAM,EAAER,IAAI,CAAC,UAAU,CAAC;KACzB,CAAC,AAAC;IAEH,MAAMS,MAAM,GAAG,MAAMb,kBAAkB,CAACG,WAAW,EAAE;QACnDU,MAAM,EAAET,IAAI,CAAC,UAAU,CAAC;QACxBU,SAAS,EAAEV,IAAI,CAAC,cAAc,CAAC;KAChC,CAAC,AAAC;QAIeA,
|
|
1
|
+
{"version":3,"sources":["../../../src/start/resolveOptions.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { AbortCommandError, CommandError } from '../utils/errors';\nimport { resolvePortAsync } from '../utils/port';\n\nexport type Options = {\n forceManifestType: 'classic' | 'expo-updates';\n privateKeyPath: string | null;\n android: boolean;\n web: boolean;\n ios: boolean;\n offline: boolean;\n clear: boolean;\n dev: boolean;\n https: boolean;\n maxWorkers: number;\n port: number;\n /** Should instruct the bundler to create minified bundles. */\n minify: boolean;\n devClient: boolean;\n scheme: string | null;\n host: 'localhost' | 'lan' | 'tunnel';\n};\n\nexport async function resolveOptionsAsync(projectRoot: string, args: any): Promise<Options> {\n const forceManifestType = args['--force-manifest-type'];\n if (forceManifestType) {\n assert.match(forceManifestType, /^(classic|expo-updates)$/);\n }\n const host = resolveHostType({\n host: args['--host'],\n offline: args['--offline'],\n lan: args['--lan'],\n localhost: args['--localhost'],\n tunnel: args['--tunnel'],\n });\n\n const scheme = await resolveSchemeAsync(projectRoot, {\n scheme: args['--scheme'],\n devClient: args['--dev-client'],\n });\n\n return {\n forceManifestType,\n privateKeyPath: args['--private-key-path'] ?? null,\n\n android: !!args['--android'],\n web: !!args['--web'],\n ios: !!args['--ios'],\n offline: !!args['--offline'],\n\n clear: !!args['--clear'],\n dev: !args['--no-dev'],\n https: !!args['--https'],\n maxWorkers: args['--max-workers'],\n port: args['--port'],\n minify: !!args['--minify'],\n\n devClient: !!args['--dev-client'],\n\n scheme,\n host,\n };\n}\n\nexport async function resolveSchemeAsync(\n projectRoot: string,\n options: { scheme?: string; devClient?: boolean }\n): Promise<string | null> {\n const resolveFrom = await import('resolve-from').then((m) => m.default);\n\n const isDevClientPackageInstalled = (() => {\n try {\n // we check if `expo-dev-launcher` is installed instead of `expo-dev-client`\n // because someone could install only launcher.\n resolveFrom(projectRoot, 'expo-dev-launcher');\n return true;\n } catch {\n return false;\n }\n })();\n\n if (typeof options.scheme === 'string') {\n // Use the custom scheme\n return options.scheme ?? null;\n } else if (options.devClient || isDevClientPackageInstalled) {\n const { getOptionalDevClientSchemeAsync } = await import('../utils/scheme');\n // Attempt to find the scheme or warn the user how to setup a custom scheme\n return await getOptionalDevClientSchemeAsync(projectRoot);\n } else {\n // Ensure this is reset when users don't use `--scheme`, `--dev-client` and don't have the `expo-dev-client` package installed.\n return null;\n }\n}\n\n/** Resolve and assert host type options. */\nexport function resolveHostType(options: {\n host?: string;\n offline?: boolean;\n lan?: boolean;\n localhost?: boolean;\n tunnel?: boolean;\n}): 'lan' | 'tunnel' | 'localhost' {\n if (\n [options.offline, options.host, options.lan, options.localhost, options.tunnel].filter((i) => i)\n .length > 1\n ) {\n throw new CommandError(\n 'BAD_ARGS',\n 'Specify at most one of: --offline, --host, --tunnel, --lan, --localhost'\n );\n }\n\n if (options.offline) {\n // Force `lan` in offline mode.\n return 'lan';\n } else if (options.host) {\n assert.match(options.host, /^(lan|tunnel|localhost)$/);\n return options.host as 'lan' | 'tunnel' | 'localhost';\n } else if (options.tunnel) {\n return 'tunnel';\n } else if (options.lan) {\n return 'lan';\n } else if (options.localhost) {\n return 'localhost';\n }\n return 'lan';\n}\n\n/** Resolve the port options for all supported bundlers. */\nexport async function resolvePortsAsync(\n projectRoot: string,\n options: Partial<Pick<Options, 'port' | 'devClient'>>,\n settings: { webOnly?: boolean }\n) {\n const multiBundlerSettings: { webpackPort?: number; metroPort?: number } = {};\n\n if (settings.webOnly) {\n const webpackPort = await resolvePortAsync(projectRoot, {\n defaultPort: options.port,\n // Default web port\n fallbackPort: 19006,\n });\n if (!webpackPort) {\n throw new AbortCommandError();\n }\n multiBundlerSettings.webpackPort = webpackPort;\n } else {\n const devClientDefaultPort = process.env.RCT_METRO_PORT\n ? parseInt(process.env.RCT_METRO_PORT, 10)\n : 8081;\n const expoGoDefaultPort = 19000;\n const metroPort = await resolvePortAsync(projectRoot, {\n defaultPort: options.port,\n fallbackPort: options.devClient ? devClientDefaultPort : expoGoDefaultPort,\n });\n if (!metroPort) {\n throw new AbortCommandError();\n }\n multiBundlerSettings.metroPort = metroPort;\n }\n\n return multiBundlerSettings;\n}\n"],"names":["resolveOptionsAsync","resolveSchemeAsync","resolveHostType","resolvePortsAsync","projectRoot","args","forceManifestType","assert","match","host","offline","lan","localhost","tunnel","scheme","devClient","privateKeyPath","android","web","ios","clear","dev","https","maxWorkers","port","minify","options","resolveFrom","then","m","default","isDevClientPackageInstalled","getOptionalDevClientSchemeAsync","filter","i","length","CommandError","settings","multiBundlerSettings","webOnly","webpackPort","resolvePortAsync","defaultPort","fallbackPort","AbortCommandError","devClientDefaultPort","process","env","RCT_METRO_PORT","parseInt","expoGoDefaultPort","metroPort"],"mappings":"AAAA;;;;QAwBsBA,mBAAmB,GAAnBA,mBAAmB;QAyCnBC,kBAAkB,GAAlBA,kBAAkB;QA+BxBC,eAAe,GAAfA,eAAe;QAkCTC,iBAAiB,GAAjBA,iBAAiB;AAlIpB,IAAA,OAAQ,kCAAR,QAAQ,EAAA;AAEqB,IAAA,OAAiB,WAAjB,iBAAiB,CAAA;AAChC,IAAA,KAAe,WAAf,eAAe,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBzC,eAAeH,mBAAmB,CAACI,WAAmB,EAAEC,IAAS,EAAoB;IAC1F,MAAMC,iBAAiB,GAAGD,IAAI,CAAC,uBAAuB,CAAC,AAAC;IACxD,IAAIC,iBAAiB,EAAE;QACrBC,OAAM,QAAA,CAACC,KAAK,CAACF,iBAAiB,6BAA6B,CAAC;KAC7D;IACD,MAAMG,IAAI,GAAGP,eAAe,CAAC;QAC3BO,IAAI,EAAEJ,IAAI,CAAC,QAAQ,CAAC;QACpBK,OAAO,EAAEL,IAAI,CAAC,WAAW,CAAC;QAC1BM,GAAG,EAAEN,IAAI,CAAC,OAAO,CAAC;QAClBO,SAAS,EAAEP,IAAI,CAAC,aAAa,CAAC;QAC9BQ,MAAM,EAAER,IAAI,CAAC,UAAU,CAAC;KACzB,CAAC,AAAC;IAEH,MAAMS,MAAM,GAAG,MAAMb,kBAAkB,CAACG,WAAW,EAAE;QACnDU,MAAM,EAAET,IAAI,CAAC,UAAU,CAAC;QACxBU,SAAS,EAAEV,IAAI,CAAC,cAAc,CAAC;KAChC,CAAC,AAAC;QAIeA,GAA0B;IAF5C,OAAO;QACLC,iBAAiB;QACjBU,cAAc,EAAEX,CAAAA,GAA0B,GAA1BA,IAAI,CAAC,oBAAoB,CAAC,YAA1BA,GAA0B,GAAI,IAAI;QAElDY,OAAO,EAAE,CAAC,CAACZ,IAAI,CAAC,WAAW,CAAC;QAC5Ba,GAAG,EAAE,CAAC,CAACb,IAAI,CAAC,OAAO,CAAC;QACpBc,GAAG,EAAE,CAAC,CAACd,IAAI,CAAC,OAAO,CAAC;QACpBK,OAAO,EAAE,CAAC,CAACL,IAAI,CAAC,WAAW,CAAC;QAE5Be,KAAK,EAAE,CAAC,CAACf,IAAI,CAAC,SAAS,CAAC;QACxBgB,GAAG,EAAE,CAAChB,IAAI,CAAC,UAAU,CAAC;QACtBiB,KAAK,EAAE,CAAC,CAACjB,IAAI,CAAC,SAAS,CAAC;QACxBkB,UAAU,EAAElB,IAAI,CAAC,eAAe,CAAC;QACjCmB,IAAI,EAAEnB,IAAI,CAAC,QAAQ,CAAC;QACpBoB,MAAM,EAAE,CAAC,CAACpB,IAAI,CAAC,UAAU,CAAC;QAE1BU,SAAS,EAAE,CAAC,CAACV,IAAI,CAAC,cAAc,CAAC;QAEjCS,MAAM;QACNL,IAAI;KACL,CAAC;CACH;AAEM,eAAeR,kBAAkB,CACtCG,WAAmB,EACnBsB,OAAiD,EACzB;IACxB,MAAMC,WAAW,GAAG,MAAM;+CAAO,cAAc;MAAC,CAACC,IAAI,CAAC,CAACC,CAAC,GAAKA,CAAC,CAACC,OAAO;IAAA,CAAC,AAAC;IAExE,MAAMC,2BAA2B,GAAG,CAAC,IAAM;QACzC,IAAI;YACF,4EAA4E;YAC5E,+CAA+C;YAC/CJ,WAAW,CAACvB,WAAW,EAAE,mBAAmB,CAAC,CAAC;YAC9C,OAAO,IAAI,CAAC;SACb,CAAC,OAAM;YACN,OAAO,KAAK,CAAC;SACd;KACF,CAAC,EAAE,AAAC;IAEL,IAAI,OAAOsB,OAAO,CAACZ,MAAM,KAAK,QAAQ,EAAE;YAE/BY,OAAc;QADrB,wBAAwB;QACxB,OAAOA,CAAAA,OAAc,GAAdA,OAAO,CAACZ,MAAM,YAAdY,OAAc,GAAI,IAAI,CAAC;KAC/B,MAAM,IAAIA,OAAO,CAACX,SAAS,IAAIgB,2BAA2B,EAAE;QAC3D,MAAM,EAAEC,+BAA+B,CAAA,EAAE,GAAG,MAAM;mDAAO,iBAAiB;UAAC,AAAC;QAC5E,2EAA2E;QAC3E,OAAO,MAAMA,+BAA+B,CAAC5B,WAAW,CAAC,CAAC;KAC3D,MAAM;QACL,+HAA+H;QAC/H,OAAO,IAAI,CAAC;KACb;CACF;AAGM,SAASF,eAAe,CAACwB,OAM/B,EAAkC;IACjC,IACE;QAACA,OAAO,CAAChB,OAAO;QAAEgB,OAAO,CAACjB,IAAI;QAAEiB,OAAO,CAACf,GAAG;QAAEe,OAAO,CAACd,SAAS;QAAEc,OAAO,CAACb,MAAM;KAAC,CAACoB,MAAM,CAAC,CAACC,CAAC,GAAKA,CAAC;IAAA,CAAC,CAC7FC,MAAM,GAAG,CAAC,EACb;QACA,MAAM,IAAIC,OAAY,aAAA,CACpB,UAAU,EACV,yEAAyE,CAC1E,CAAC;KACH;IAED,IAAIV,OAAO,CAAChB,OAAO,EAAE;QACnB,+BAA+B;QAC/B,OAAO,KAAK,CAAC;KACd,MAAM,IAAIgB,OAAO,CAACjB,IAAI,EAAE;QACvBF,OAAM,QAAA,CAACC,KAAK,CAACkB,OAAO,CAACjB,IAAI,6BAA6B,CAAC;QACvD,OAAOiB,OAAO,CAACjB,IAAI,CAAmC;KACvD,MAAM,IAAIiB,OAAO,CAACb,MAAM,EAAE;QACzB,OAAO,QAAQ,CAAC;KACjB,MAAM,IAAIa,OAAO,CAACf,GAAG,EAAE;QACtB,OAAO,KAAK,CAAC;KACd,MAAM,IAAIe,OAAO,CAACd,SAAS,EAAE;QAC5B,OAAO,WAAW,CAAC;KACpB;IACD,OAAO,KAAK,CAAC;CACd;AAGM,eAAeT,iBAAiB,CACrCC,WAAmB,EACnBsB,OAAqD,EACrDW,QAA+B,EAC/B;IACA,MAAMC,oBAAoB,GAAiD,EAAE,AAAC;IAE9E,IAAID,QAAQ,CAACE,OAAO,EAAE;QACpB,MAAMC,WAAW,GAAG,MAAMC,CAAAA,GAAAA,KAAgB,AAIxC,CAAA,iBAJwC,CAACrC,WAAW,EAAE;YACtDsC,WAAW,EAAEhB,OAAO,CAACF,IAAI;YACzB,mBAAmB;YACnBmB,YAAY,EAAE,KAAK;SACpB,CAAC,AAAC;QACH,IAAI,CAACH,WAAW,EAAE;YAChB,MAAM,IAAII,OAAiB,kBAAA,EAAE,CAAC;SAC/B;QACDN,oBAAoB,CAACE,WAAW,GAAGA,WAAW,CAAC;KAChD,MAAM;QACL,MAAMK,oBAAoB,GAAGC,OAAO,CAACC,GAAG,CAACC,cAAc,GACnDC,QAAQ,CAACH,OAAO,CAACC,GAAG,CAACC,cAAc,EAAE,EAAE,CAAC,GACxC,IAAI,AAAC;QACT,MAAME,iBAAiB,GAAG,KAAK,AAAC;QAChC,MAAMC,SAAS,GAAG,MAAMV,CAAAA,GAAAA,KAAgB,AAGtC,CAAA,iBAHsC,CAACrC,WAAW,EAAE;YACpDsC,WAAW,EAAEhB,OAAO,CAACF,IAAI;YACzBmB,YAAY,EAAEjB,OAAO,CAACX,SAAS,GAAG8B,oBAAoB,GAAGK,iBAAiB;SAC3E,CAAC,AAAC;QACH,IAAI,CAACC,SAAS,EAAE;YACd,MAAM,IAAIP,OAAiB,kBAAA,EAAE,CAAC;SAC/B;QACDN,oBAAoB,CAACa,SAAS,GAAGA,SAAS,CAAC;KAC5C;IAED,OAAOb,oBAAoB,CAAC;CAC7B"}
|
|
@@ -9,6 +9,7 @@ var _userSettings = _interopRequireDefault(require("../../api/user/UserSettings"
|
|
|
9
9
|
var _user = require("../../api/user/user");
|
|
10
10
|
var Log = _interopRequireWildcard(require("../../log"));
|
|
11
11
|
var _delay = require("../../utils/delay");
|
|
12
|
+
var _env = require("../../utils/env");
|
|
12
13
|
var _errors = require("../../utils/errors");
|
|
13
14
|
var _ngrokResolver = require("../doctor/ngrok/NgrokResolver");
|
|
14
15
|
var _adbReverse = require("../platforms/android/adbReverse");
|
|
@@ -55,7 +56,7 @@ class AsyncNgrok {
|
|
|
55
56
|
getActiveUrl() {
|
|
56
57
|
return this.serverUrl;
|
|
57
58
|
}
|
|
58
|
-
/** Exposed for testing. */ async
|
|
59
|
+
/** Exposed for testing. */ async _getIdentifyingUrlSegmentsAsync() {
|
|
59
60
|
const user = await (0, _user).getUserAsync();
|
|
60
61
|
if ((user == null ? void 0 : user.__typename) === "Robot") {
|
|
61
62
|
throw new _errors.CommandError("NGROK_ROBOT", "Cannot use ngrok with a robot user.");
|
|
@@ -66,22 +67,34 @@ class AsyncNgrok {
|
|
|
66
67
|
await this.getProjectRandomnessAsync(),
|
|
67
68
|
(0, _slugify).default(username),
|
|
68
69
|
// Use the port to distinguish between multiple tunnels (webpack, metro).
|
|
69
|
-
this.port,
|
|
70
|
-
|
|
70
|
+
String(this.port),
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
/** Exposed for testing. */ async _getProjectHostnameAsync() {
|
|
74
|
+
return [
|
|
75
|
+
...await this._getIdentifyingUrlSegmentsAsync(),
|
|
76
|
+
NGROK_CONFIG.domain
|
|
71
77
|
].join(".");
|
|
72
78
|
}
|
|
79
|
+
/** Exposed for testing. */ async _getProjectSubdomainAsync() {
|
|
80
|
+
return (await this._getIdentifyingUrlSegmentsAsync()).join("-");
|
|
81
|
+
}
|
|
73
82
|
/** Start ngrok on the given port for the project. */ async startAsync({ timeout } = {}) {
|
|
74
83
|
// Ensure the instance is loaded first, this can linger so we should run it before the timeout.
|
|
75
84
|
await this.resolver.resolveAsync({
|
|
76
85
|
// For now, prefer global install since the package has native code (harder to install) and doesn't change very often.
|
|
77
86
|
prefersGlobalInstall: true
|
|
78
87
|
});
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
// NOTE(EvanBacon): If the user doesn't have ADB installed,
|
|
89
|
+
// then skip attempting to reverse the port.
|
|
90
|
+
if ((0, _adbReverse).hasAdbReverseAsync()) {
|
|
91
|
+
// Ensure ADB reverse is running.
|
|
92
|
+
if (!await (0, _adbReverse).startAdbReverseAsync([
|
|
93
|
+
this.port
|
|
94
|
+
])) {
|
|
95
|
+
// TODO: Better error message.
|
|
96
|
+
throw new _errors.CommandError("NGROK_ADB", `Cannot start tunnel URL because \`adb reverse\` failed for the connected Android device(s).`);
|
|
97
|
+
}
|
|
85
98
|
}
|
|
86
99
|
this.serverUrl = await this._connectToNgrokAsync({
|
|
87
100
|
timeout
|
|
@@ -118,17 +131,32 @@ class AsyncNgrok {
|
|
|
118
131
|
await (0, _delay).delayAsync(100);
|
|
119
132
|
return this._connectToNgrokAsync(options, attempts + 1);
|
|
120
133
|
}
|
|
134
|
+
async _getConnectionPropsAsync() {
|
|
135
|
+
const userDefinedSubdomain = _env.env.EXPO_TUNNEL_SUBDOMAIN;
|
|
136
|
+
if (userDefinedSubdomain) {
|
|
137
|
+
const subdomain = typeof userDefinedSubdomain === "string" ? userDefinedSubdomain : await this._getProjectSubdomainAsync();
|
|
138
|
+
debug("Subdomain:", subdomain);
|
|
139
|
+
return {
|
|
140
|
+
subdomain
|
|
141
|
+
};
|
|
142
|
+
} else {
|
|
143
|
+
const hostname = await this._getProjectHostnameAsync();
|
|
144
|
+
debug("Hostname:", hostname);
|
|
145
|
+
return {
|
|
146
|
+
hostname
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
121
150
|
async connectToNgrokInternalAsync(instance, attempts = 0) {
|
|
122
151
|
try {
|
|
123
152
|
// Global config path.
|
|
124
153
|
const configPath = path.join(_userSettings.default.getDirectory(), "ngrok.yml");
|
|
125
154
|
debug("Global config path:", configPath);
|
|
126
|
-
const
|
|
127
|
-
debug("Hostname:", hostname);
|
|
155
|
+
const urlProps = await this._getConnectionPropsAsync();
|
|
128
156
|
const url = await instance.connect({
|
|
157
|
+
...urlProps,
|
|
129
158
|
authtoken: NGROK_CONFIG.authToken,
|
|
130
159
|
proto: "http",
|
|
131
|
-
hostname,
|
|
132
160
|
configPath,
|
|
133
161
|
onStatusChange (status) {
|
|
134
162
|
if (status === "closed") {
|
|
@@ -141,12 +169,28 @@ class AsyncNgrok {
|
|
|
141
169
|
});
|
|
142
170
|
return url;
|
|
143
171
|
} catch (error) {
|
|
172
|
+
const assertNgrok = ()=>{
|
|
173
|
+
if ((0, _ngrokResolver).isNgrokClientError(error)) {
|
|
174
|
+
var ref;
|
|
175
|
+
throw new _errors.CommandError("NGROK_CONNECT", [
|
|
176
|
+
error.body.msg,
|
|
177
|
+
(ref = error.body.details) == null ? void 0 : ref.err
|
|
178
|
+
].filter(Boolean).join("\n\n"));
|
|
179
|
+
}
|
|
180
|
+
throw new _errors.CommandError("NGROK_CONNECT", error.toString());
|
|
181
|
+
};
|
|
144
182
|
// Attempt to connect 3 times
|
|
145
183
|
if (attempts >= 2) {
|
|
146
|
-
|
|
184
|
+
assertNgrok();
|
|
147
185
|
}
|
|
148
186
|
// Attempt to fix the issue
|
|
149
|
-
if ((error
|
|
187
|
+
if ((0, _ngrokResolver).isNgrokClientError(error) && error.body.error_code === 103) {
|
|
188
|
+
// Assert early if a custom subdomain is used since it cannot
|
|
189
|
+
// be changed and retried. If the tunnel subdomain is a boolean
|
|
190
|
+
// then we can reset the randomness and try again.
|
|
191
|
+
if (typeof _env.env.EXPO_TUNNEL_SUBDOMAIN === "string") {
|
|
192
|
+
assertNgrok();
|
|
193
|
+
}
|
|
150
194
|
// Change randomness to avoid conflict if killing ngrok doesn't help
|
|
151
195
|
await this._resetProjectRandomnessAsync();
|
|
152
196
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/server/AsyncNgrok.ts"],"sourcesContent":["import crypto from 'crypto';\nimport * as path from 'path';\nimport slugify from 'slugify';\n\nimport UserSettings from '../../api/user/UserSettings';\nimport { getActorDisplayName, getUserAsync } from '../../api/user/user';\nimport * as Log from '../../log';\nimport { delayAsync, resolveWithTimeout } from '../../utils/delay';\nimport { CommandError } from '../../utils/errors';\nimport { NgrokInstance, NgrokResolver } from '../doctor/ngrok/NgrokResolver';\nimport { startAdbReverseAsync } from '../platforms/android/adbReverse';\nimport { ProjectSettings } from '../project/settings';\n\nconst debug = require('debug')('expo:start:server:ngrok') as typeof console.log;\n\nconst NGROK_CONFIG = {\n authToken: '5W1bR67GNbWcXqmxZzBG1_56GezNeaX6sSRvn8npeQ8',\n domain: 'exp.direct',\n};\n\nconst TUNNEL_TIMEOUT = 10 * 1000;\n\nexport class AsyncNgrok {\n /** Resolves the best instance of ngrok, exposed for testing. */\n resolver: NgrokResolver;\n\n /** Info about the currently running instance of ngrok. */\n private serverUrl: string | null = null;\n\n constructor(private projectRoot: string, private port: number) {\n this.resolver = new NgrokResolver(projectRoot);\n }\n\n public getActiveUrl(): string | null {\n return this.serverUrl;\n }\n\n /** Exposed for testing. */\n async _getProjectHostnameAsync() {\n const user = await getUserAsync();\n if (user?.__typename === 'Robot') {\n throw new CommandError('NGROK_ROBOT', 'Cannot use ngrok with a robot user.');\n }\n const username = getActorDisplayName(user);\n\n return [\n // NOTE: https://github.com/expo/expo/pull/16556#discussion_r822944286\n await this.getProjectRandomnessAsync(),\n slugify(username),\n // Use the port to distinguish between multiple tunnels (webpack, metro).\n this.port,\n NGROK_CONFIG.domain,\n ].join('.');\n }\n\n /** Start ngrok on the given port for the project. */\n async startAsync({ timeout }: { timeout?: number } = {}): Promise<void> {\n // Ensure the instance is loaded first, this can linger so we should run it before the timeout.\n await this.resolver.resolveAsync({\n // For now, prefer global install since the package has native code (harder to install) and doesn't change very often.\n prefersGlobalInstall: true,\n });\n\n // Ensure ADB reverse is running.\n if (!(await startAdbReverseAsync([this.port]))) {\n // TODO: Better error message.\n throw new CommandError(\n 'NGROK_ADB',\n `Cannot start tunnel URL because \\`adb reverse\\` failed for the connected Android device(s).`\n );\n }\n\n this.serverUrl = await this._connectToNgrokAsync({ timeout });\n\n debug('Tunnel URL:', this.serverUrl);\n Log.log('Tunnel ready.');\n }\n\n /** Stop the ngrok process if it's running. */\n public async stopAsync(): Promise<void> {\n debug('Stopping Tunnel');\n\n await this.resolver.get()?.kill?.();\n this.serverUrl = null;\n }\n\n /** Exposed for testing. */\n async _connectToNgrokAsync(\n options: { timeout?: number } = {},\n attempts: number = 0\n ): Promise<string> {\n // Attempt to stop any hanging processes, this increases the chances of a successful connection.\n await this.stopAsync();\n\n // Get the instance quietly or assert otherwise.\n const instance = await this.resolver.resolveAsync({\n shouldPrompt: false,\n autoInstall: false,\n });\n\n // TODO(Bacon): Consider dropping the timeout functionality:\n // https://github.com/expo/expo/pull/16556#discussion_r822307373\n const results = await resolveWithTimeout(\n () => this.connectToNgrokInternalAsync(instance, attempts),\n {\n timeout: options.timeout ?? TUNNEL_TIMEOUT,\n errorMessage: 'ngrok tunnel took too long to connect.',\n }\n );\n if (typeof results === 'string') {\n return results;\n }\n\n // Wait 100ms and then try again\n await delayAsync(100);\n\n return this._connectToNgrokAsync(options, attempts + 1);\n }\n\n private async connectToNgrokInternalAsync(\n instance: NgrokInstance,\n attempts: number = 0\n ): Promise<string | false> {\n try {\n // Global config path.\n const configPath = path.join(UserSettings.getDirectory(), 'ngrok.yml');\n debug('Global config path:', configPath);\n const hostname = await this._getProjectHostnameAsync();\n debug('Hostname:', hostname);\n\n const url = await instance.connect({\n authtoken: NGROK_CONFIG.authToken,\n proto: 'http',\n hostname,\n configPath,\n onStatusChange(status) {\n if (status === 'closed') {\n Log.error(\n 'We noticed your tunnel is having issues. ' +\n 'This may be due to intermittent problems with ngrok. ' +\n 'If you have trouble connecting to your app, try to restart the project, ' +\n 'or switch the host to `lan`.'\n );\n } else if (status === 'connected') {\n Log.log('Tunnel connected.');\n }\n },\n port: this.port,\n });\n return url;\n } catch (error: any) {\n // Attempt to connect 3 times\n if (attempts >= 2) {\n throw new CommandError('NGROK_CONNECT', error.toString());\n }\n\n // Attempt to fix the issue\n if (error?.error_code === 103) {\n // Change randomness to avoid conflict if killing ngrok doesn't help\n await this._resetProjectRandomnessAsync();\n }\n return false;\n }\n }\n\n private async getProjectRandomnessAsync() {\n const { urlRandomness: randomness } = await ProjectSettings.readAsync(this.projectRoot);\n if (randomness) {\n return randomness;\n }\n return await this._resetProjectRandomnessAsync();\n }\n\n async _resetProjectRandomnessAsync() {\n const randomness = crypto.randomBytes(5).toString('base64url');\n await ProjectSettings.setAsync(this.projectRoot, { urlRandomness: randomness });\n debug('Resetting project randomness:', randomness);\n return randomness;\n }\n}\n"],"names":["path","Log","debug","require","NGROK_CONFIG","authToken","domain","TUNNEL_TIMEOUT","AsyncNgrok","constructor","projectRoot","port","serverUrl","resolver","NgrokResolver","getActiveUrl","_getProjectHostnameAsync","user","getUserAsync","__typename","CommandError","username","getActorDisplayName","getProjectRandomnessAsync","slugify","join","startAsync","timeout","resolveAsync","prefersGlobalInstall","startAdbReverseAsync","_connectToNgrokAsync","log","stopAsync","get","kill","options","attempts","instance","shouldPrompt","autoInstall","results","resolveWithTimeout","connectToNgrokInternalAsync","errorMessage","delayAsync","configPath","UserSettings","getDirectory","hostname","url","connect","authtoken","proto","onStatusChange","status","error","toString","error_code","_resetProjectRandomnessAsync","urlRandomness","randomness","ProjectSettings","readAsync","crypto","randomBytes","setAsync"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/server/AsyncNgrok.ts"],"sourcesContent":["import crypto from 'crypto';\nimport * as path from 'path';\nimport slugify from 'slugify';\n\nimport UserSettings from '../../api/user/UserSettings';\nimport { getActorDisplayName, getUserAsync } from '../../api/user/user';\nimport * as Log from '../../log';\nimport { delayAsync, resolveWithTimeout } from '../../utils/delay';\nimport { env } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { isNgrokClientError, NgrokInstance, NgrokResolver } from '../doctor/ngrok/NgrokResolver';\nimport { hasAdbReverseAsync, startAdbReverseAsync } from '../platforms/android/adbReverse';\nimport { ProjectSettings } from '../project/settings';\n\nconst debug = require('debug')('expo:start:server:ngrok') as typeof console.log;\n\nconst NGROK_CONFIG = {\n authToken: '5W1bR67GNbWcXqmxZzBG1_56GezNeaX6sSRvn8npeQ8',\n domain: 'exp.direct',\n};\n\nconst TUNNEL_TIMEOUT = 10 * 1000;\n\nexport class AsyncNgrok {\n /** Resolves the best instance of ngrok, exposed for testing. */\n resolver: NgrokResolver;\n\n /** Info about the currently running instance of ngrok. */\n private serverUrl: string | null = null;\n\n constructor(private projectRoot: string, private port: number) {\n this.resolver = new NgrokResolver(projectRoot);\n }\n\n public getActiveUrl(): string | null {\n return this.serverUrl;\n }\n\n /** Exposed for testing. */\n async _getIdentifyingUrlSegmentsAsync(): Promise<string[]> {\n const user = await getUserAsync();\n if (user?.__typename === 'Robot') {\n throw new CommandError('NGROK_ROBOT', 'Cannot use ngrok with a robot user.');\n }\n const username = getActorDisplayName(user);\n\n return [\n // NOTE: https://github.com/expo/expo/pull/16556#discussion_r822944286\n await this.getProjectRandomnessAsync(),\n slugify(username),\n // Use the port to distinguish between multiple tunnels (webpack, metro).\n String(this.port),\n ];\n }\n\n /** Exposed for testing. */\n async _getProjectHostnameAsync(): Promise<string> {\n return [...(await this._getIdentifyingUrlSegmentsAsync()), NGROK_CONFIG.domain].join('.');\n }\n\n /** Exposed for testing. */\n async _getProjectSubdomainAsync(): Promise<string> {\n return (await this._getIdentifyingUrlSegmentsAsync()).join('-');\n }\n\n /** Start ngrok on the given port for the project. */\n async startAsync({ timeout }: { timeout?: number } = {}): Promise<void> {\n // Ensure the instance is loaded first, this can linger so we should run it before the timeout.\n await this.resolver.resolveAsync({\n // For now, prefer global install since the package has native code (harder to install) and doesn't change very often.\n prefersGlobalInstall: true,\n });\n\n // NOTE(EvanBacon): If the user doesn't have ADB installed,\n // then skip attempting to reverse the port.\n if (hasAdbReverseAsync()) {\n // Ensure ADB reverse is running.\n if (!(await startAdbReverseAsync([this.port]))) {\n // TODO: Better error message.\n throw new CommandError(\n 'NGROK_ADB',\n `Cannot start tunnel URL because \\`adb reverse\\` failed for the connected Android device(s).`\n );\n }\n }\n\n this.serverUrl = await this._connectToNgrokAsync({ timeout });\n\n debug('Tunnel URL:', this.serverUrl);\n Log.log('Tunnel ready.');\n }\n\n /** Stop the ngrok process if it's running. */\n public async stopAsync(): Promise<void> {\n debug('Stopping Tunnel');\n\n await this.resolver.get()?.kill?.();\n this.serverUrl = null;\n }\n\n /** Exposed for testing. */\n async _connectToNgrokAsync(\n options: { timeout?: number } = {},\n attempts: number = 0\n ): Promise<string> {\n // Attempt to stop any hanging processes, this increases the chances of a successful connection.\n await this.stopAsync();\n\n // Get the instance quietly or assert otherwise.\n const instance = await this.resolver.resolveAsync({\n shouldPrompt: false,\n autoInstall: false,\n });\n\n // TODO(Bacon): Consider dropping the timeout functionality:\n // https://github.com/expo/expo/pull/16556#discussion_r822307373\n const results = await resolveWithTimeout(\n () => this.connectToNgrokInternalAsync(instance, attempts),\n {\n timeout: options.timeout ?? TUNNEL_TIMEOUT,\n errorMessage: 'ngrok tunnel took too long to connect.',\n }\n );\n if (typeof results === 'string') {\n return results;\n }\n\n // Wait 100ms and then try again\n await delayAsync(100);\n\n return this._connectToNgrokAsync(options, attempts + 1);\n }\n\n private async _getConnectionPropsAsync(): Promise<{ hostname?: string; subdomain?: string }> {\n const userDefinedSubdomain = env.EXPO_TUNNEL_SUBDOMAIN;\n if (userDefinedSubdomain) {\n const subdomain =\n typeof userDefinedSubdomain === 'string'\n ? userDefinedSubdomain\n : await this._getProjectSubdomainAsync();\n debug('Subdomain:', subdomain);\n return { subdomain };\n } else {\n const hostname = await this._getProjectHostnameAsync();\n debug('Hostname:', hostname);\n return { hostname };\n }\n }\n\n private async connectToNgrokInternalAsync(\n instance: NgrokInstance,\n attempts: number = 0\n ): Promise<string | false> {\n try {\n // Global config path.\n const configPath = path.join(UserSettings.getDirectory(), 'ngrok.yml');\n debug('Global config path:', configPath);\n const urlProps = await this._getConnectionPropsAsync();\n\n const url = await instance.connect({\n ...urlProps,\n authtoken: NGROK_CONFIG.authToken,\n proto: 'http',\n configPath,\n onStatusChange(status) {\n if (status === 'closed') {\n Log.error(\n 'We noticed your tunnel is having issues. ' +\n 'This may be due to intermittent problems with ngrok. ' +\n 'If you have trouble connecting to your app, try to restart the project, ' +\n 'or switch the host to `lan`.'\n );\n } else if (status === 'connected') {\n Log.log('Tunnel connected.');\n }\n },\n port: this.port,\n });\n return url;\n } catch (error: any) {\n const assertNgrok = () => {\n if (isNgrokClientError(error)) {\n throw new CommandError(\n 'NGROK_CONNECT',\n [error.body.msg, error.body.details?.err].filter(Boolean).join('\\n\\n')\n );\n }\n throw new CommandError('NGROK_CONNECT', error.toString());\n };\n\n // Attempt to connect 3 times\n if (attempts >= 2) {\n assertNgrok();\n }\n\n // Attempt to fix the issue\n if (isNgrokClientError(error) && error.body.error_code === 103) {\n // Assert early if a custom subdomain is used since it cannot\n // be changed and retried. If the tunnel subdomain is a boolean\n // then we can reset the randomness and try again.\n if (typeof env.EXPO_TUNNEL_SUBDOMAIN === 'string') {\n assertNgrok();\n }\n // Change randomness to avoid conflict if killing ngrok doesn't help\n await this._resetProjectRandomnessAsync();\n }\n\n return false;\n }\n }\n\n private async getProjectRandomnessAsync() {\n const { urlRandomness: randomness } = await ProjectSettings.readAsync(this.projectRoot);\n if (randomness) {\n return randomness;\n }\n return await this._resetProjectRandomnessAsync();\n }\n\n async _resetProjectRandomnessAsync() {\n const randomness = crypto.randomBytes(5).toString('base64url');\n await ProjectSettings.setAsync(this.projectRoot, { urlRandomness: randomness });\n debug('Resetting project randomness:', randomness);\n return randomness;\n }\n}\n"],"names":["path","Log","debug","require","NGROK_CONFIG","authToken","domain","TUNNEL_TIMEOUT","AsyncNgrok","constructor","projectRoot","port","serverUrl","resolver","NgrokResolver","getActiveUrl","_getIdentifyingUrlSegmentsAsync","user","getUserAsync","__typename","CommandError","username","getActorDisplayName","getProjectRandomnessAsync","slugify","String","_getProjectHostnameAsync","join","_getProjectSubdomainAsync","startAsync","timeout","resolveAsync","prefersGlobalInstall","hasAdbReverseAsync","startAdbReverseAsync","_connectToNgrokAsync","log","stopAsync","get","kill","options","attempts","instance","shouldPrompt","autoInstall","results","resolveWithTimeout","connectToNgrokInternalAsync","errorMessage","delayAsync","_getConnectionPropsAsync","userDefinedSubdomain","env","EXPO_TUNNEL_SUBDOMAIN","subdomain","hostname","configPath","UserSettings","getDirectory","urlProps","url","connect","authtoken","proto","onStatusChange","status","error","assertNgrok","isNgrokClientError","body","msg","details","err","filter","Boolean","toString","error_code","_resetProjectRandomnessAsync","urlRandomness","randomness","ProjectSettings","readAsync","crypto","randomBytes","setAsync"],"mappings":"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"}
|