@expo/cli 57.0.12 → 57.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin/cli +1 -1
- package/build/src/events/index.js +1 -1
- package/build/src/start/platforms/ios/devicectl.js +6 -2
- package/build/src/start/platforms/ios/devicectl.js.map +1 -1
- package/build/src/start/server/middleware/ManifestMiddleware.js +4 -23
- package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
- package/build/src/utils/qr.js +1 -3
- package/build/src/utils/qr.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +12 -12
package/build/bin/cli
CHANGED
|
@@ -76,7 +76,7 @@ function getInitMetadata() {
|
|
|
76
76
|
return {
|
|
77
77
|
format: 'v0-jsonl',
|
|
78
78
|
// Version is added in the build script.
|
|
79
|
-
version: "57.0.
|
|
79
|
+
version: "57.0.14" ?? 'UNVERSIONED'
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
function getWellKnownTemporaryLogFile(projectRoot, command) {
|
|
@@ -185,12 +185,16 @@ async function getConnectedAppleDevicesAsync() {
|
|
|
185
185
|
const devicesJson = await _jsonfile().default.readAsync(tmpPath);
|
|
186
186
|
if (![
|
|
187
187
|
2,
|
|
188
|
-
3
|
|
188
|
+
3,
|
|
189
|
+
5
|
|
189
190
|
].includes(devicesJson == null ? void 0 : (_devicesJson_info = devicesJson.info) == null ? void 0 : _devicesJson_info.jsonVersion)) {
|
|
190
191
|
_log.warn('Unexpected devicectl JSON version output from devicectl. Connecting to physical Apple devices may not work as expected.');
|
|
191
192
|
}
|
|
192
193
|
assertDevicesJson(devicesJson);
|
|
193
|
-
return devicesJson.result.devices
|
|
194
|
+
return devicesJson.result.devices.filter((device)=>{
|
|
195
|
+
var _device_hardwareProperties;
|
|
196
|
+
return (device == null ? void 0 : (_device_hardwareProperties = device.hardwareProperties) == null ? void 0 : _device_hardwareProperties.reality) !== 'simulated';
|
|
197
|
+
});
|
|
194
198
|
}
|
|
195
199
|
function assertDevicesJson(results) {
|
|
196
200
|
var _results_result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/platforms/ios/devicectl.ts"],"sourcesContent":["/**\n * Copyright © 2024 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport JsonFile from '@expo/json-file';\nimport type { SpawnOptions, SpawnResult } from '@expo/spawn-async';\nimport spawnAsync from '@expo/spawn-async';\nimport chalk from 'chalk';\nimport { spawn, execSync } from 'child_process';\nimport fs from 'fs';\nimport assert from 'node:assert';\nimport type { Ora } from 'ora';\nimport { EOL } from 'os';\nimport path from 'path';\n\nimport { xcrunAsync } from './xcrun';\nimport { getExpoHomeDirectory } from '../../../api/user/UserSettings';\nimport * as Log from '../../../log';\nimport { createTempFilePath } from '../../../utils/createTempPath';\nimport { CommandError } from '../../../utils/errors';\nimport { installExitHooks } from '../../../utils/exit';\nimport { isInteractive } from '../../../utils/interactive';\nimport { ora } from '../../../utils/ora';\nimport { confirmAsync } from '../../../utils/prompts';\n\nconst DEVICE_CTL_EXISTS_PATH = path.join(getExpoHomeDirectory(), 'devicectl-exists');\n\nconst debug = require('debug')('expo:devicectl') as typeof console.log;\n\ntype AnyEnum<T extends string = string> = T | (string & object);\n\ntype DeviceCtlDevice = {\n capabilities: DeviceCtlDeviceCapability[];\n connectionProperties: DeviceCtlConnectionProperties;\n deviceProperties: DeviceCtlDeviceProperties;\n hardwareProperties: DeviceCtlHardwareProperties;\n /** \"A1A1AAA1-0011-1AA1-11A1-10A1111AA11A\" */\n identifier: string;\n visibilityClass: AnyEnum<'default'>;\n};\n\ntype DeviceCtlHardwareProperties = {\n cpuType: DeviceCtlCpuType;\n deviceType: AnyEnum<'iPhone'>;\n /** 1114404411111111 */\n ecid: number;\n /** \"D74AP\" */\n hardwareModel: string;\n /** 512000000000 */\n internalStorageCapacity: number;\n /** true */\n isProductionFused: boolean;\n /** \"iPhone 14 Pro Max\" */\n marketingName: string;\n /** \"iOS\" */\n platform: AnyEnum<'iOS' | 'xrOS'>;\n /** \"iPhone15,3\" */\n productType: AnyEnum<'iPhone13,4' | 'iPhone15,3'>;\n reality: AnyEnum<'physical'>;\n /** \"X2X1CC1XXX\" */\n serialNumber: string;\n supportedCPUTypes: DeviceCtlCpuType[];\n /** [1] */\n supportedDeviceFamilies: number[];\n thinningProductType: AnyEnum<'iPhone15,3'>;\n /** \"00001110-001111110110101A\" */\n udid: string;\n};\n\ntype DeviceCtlDeviceProperties = {\n /** true */\n bootedFromSnapshot: boolean;\n /** \"com.apple.os.update-AD0CF111ACFF11A11111A76A3D1262AE42A3F56F305AF5AE1135393A7A14A7D1\" */\n bootedSnapshotName: string;\n /** false */\n ddiServicesAvailable: boolean;\n\n developerModeStatus: AnyEnum<'enabled'>;\n /** false */\n hasInternalOSBuild: boolean;\n /** \"Evan's phone\" */\n name: string;\n /** \"21E236\" */\n osBuildUpdate: string;\n /** \"17.4.1\" */\n osVersionNumber: string;\n /** false */\n rootFileSystemIsWritable: boolean;\n};\n\ntype DeviceCtlDeviceCapability =\n | {\n name: AnyEnum;\n featureIdentifier: AnyEnum;\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.connectdevice';\n name: 'Connect to Device';\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.unpairdevice';\n name: 'Unpair Device';\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.acquireusageassertion';\n name: 'Acquire Usage Assertion';\n };\n\ntype DeviceCtlConnectionProperties = {\n authenticationType: AnyEnum<'manualPairing'>;\n isMobileDeviceOnly: boolean;\n /** \"2024-04-20T22:50:04.244Z\" */\n lastConnectionDate: string;\n pairingState: AnyEnum<'paired'>;\n /** [\"00001111-001111110110101A.coredevice.local\", \"A1A1AAA1-0011-1AA1-11A1-10A1111AA11A.coredevice.local\"] */\n potentialHostnames: string[];\n transportType: AnyEnum<'localNetwork' | 'wired'>;\n tunnelState: AnyEnum<'disconnected' | 'unavailable'>;\n tunnelTransportProtocol: AnyEnum<'tcp'>;\n};\n\ntype DeviceCtlCpuType = {\n name: AnyEnum<'arm64e' | 'arm64' | 'arm64_32'>;\n subType: number;\n /** 16777228 */\n type: number;\n};\n\n/** Run a `devicectl` command. */\nexport async function devicectlAsync(\n args: (string | undefined)[],\n options?: SpawnOptions\n): Promise<SpawnResult> {\n try {\n return await xcrunAsync(['devicectl', ...args], options);\n } catch (error: any) {\n if (error instanceof CommandError) {\n throw error;\n }\n if ('stderr' in error) {\n const errorCodes = getDeviceCtlErrorCodes(error.stderr);\n if (errorCodes.includes('Locked')) {\n throw new CommandError('APPLE_DEVICE_LOCKED', 'Device is locked, unlock and try again.');\n }\n }\n throw error;\n }\n}\n\nexport async function getConnectedAppleDevicesAsync() {\n if (!hasDevicectlEverBeenInstalled()) {\n debug('devicectl not found, skipping remote Apple devices.');\n return [];\n }\n\n const tmpPath = createTempFilePath();\n const devices = await devicectlAsync([\n 'list',\n 'devices',\n '--json-output',\n tmpPath,\n // Give two seconds before timing out: between 5 and 9223372036854775807\n '--timeout',\n '5',\n ]);\n debug(devices.stdout);\n const devicesJson = await JsonFile.readAsync(tmpPath);\n\n if (![2, 3].includes((devicesJson as any)?.info?.jsonVersion)) {\n Log.warn(\n 'Unexpected devicectl JSON version output from devicectl. Connecting to physical Apple devices may not work as expected.'\n );\n }\n\n assertDevicesJson(devicesJson);\n\n return devicesJson.result.devices as DeviceCtlDevice[];\n}\n\nfunction assertDevicesJson(\n results: any\n): asserts results is { result: { devices: DeviceCtlDevice[] } } {\n assert(\n results != null && 'result' in results && Array.isArray(results?.result?.devices),\n 'Malformed JSON output from devicectl: ' + JSON.stringify(results, null, 2)\n );\n}\n\nexport async function launchBinaryOnMacAsync(\n bundleId: string,\n appBinaryPath: string\n): Promise<void> {\n const args = ['-b', bundleId, appBinaryPath];\n try {\n await spawnAsync('open', args);\n } catch (error: any) {\n if ('code' in error) {\n if (error.code === 1) {\n throw new CommandError(\n 'MACOS_LAUNCH',\n 'Failed to launch the compatible binary on macOS: open ' +\n args.join(' ') +\n '\\n\\n' +\n error.message\n );\n }\n }\n throw error;\n }\n}\n\nasync function installAppWithDeviceCtlAsync(\n uuid: string,\n bundleIdOrAppPath: string,\n onProgress: (event: { status: string; isComplete: boolean; progress: number }) => void\n): Promise<void> {\n const maxAttempts = 3;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n await installAppWithDeviceCtlInternalAsync(uuid, bundleIdOrAppPath, onProgress, attempt);\n return;\n } catch (error: any) {\n if (error.code === 'detached') {\n throw error;\n }\n const isTransientDisconnect =\n error.message &&\n (error.message.includes('CoreDeviceError') || error.message.includes('0xFA0'));\n\n if (!isTransientDisconnect || attempt === maxAttempts) {\n throw error;\n }\n const backoffDelay = 500 + Math.pow(2, attempt - 1) * 500;\n await new Promise((resolve) => setTimeout(resolve, backoffDelay));\n }\n }\n}\n\nasync function installAppWithDeviceCtlInternalAsync(\n uuid: string,\n bundleIdOrAppPath: string,\n onProgress: (event: { status: string; isComplete: boolean; progress: number }) => void,\n attempt: number\n): Promise<void> {\n // 𝝠 xcrun devicectl device install app --device 00001110-001111110110101A /Users/evanbacon/Library/Developer/Xcode/DerivedData/Router-hgbqaxzhrhkiftfweydvhgttadvn/Build/Products/Debug-iphoneos/Router.app --verbose\n return new Promise((resolve, reject) => {\n const args: string[] = [\n 'devicectl',\n 'device',\n 'install',\n 'app',\n '--device',\n uuid,\n bundleIdOrAppPath,\n ];\n const childProcess = spawn('xcrun', args);\n debug('xcrun ' + args.join(' '));\n\n let currentProgress = 0;\n let hasStarted = false;\n\n function updateProgress(progress: number) {\n hasStarted = true;\n if (progress <= currentProgress) {\n return;\n }\n currentProgress = progress;\n const statusPrefix = attempt > 1 ? `Installing (attempt ${attempt})` : 'Installing';\n onProgress({\n progress,\n isComplete: progress === 100,\n status: statusPrefix,\n });\n }\n\n childProcess.stdout.on('data', (data: Buffer) => {\n // Sometimes more than one chunk comes at a time, here we split by system newline,\n // then trim and filter.\n const strings = data\n .toString()\n .split(EOL)\n .map((value) => value.trim());\n\n strings.forEach((str) => {\n // Match the progress percentage:\n // - '34%... 35%...' -> 34\n // - '31%...' -> 31\n // - 'Complete!' -> 100\n\n const match = str.match(/(\\d+)%\\.\\.\\./);\n if (match) {\n updateProgress(parseInt(match[1]!, 10));\n } else if (hasStarted) {\n updateProgress(100);\n }\n });\n\n debug('[stdout]:', strings);\n });\n\n let stderrBuffer = '';\n childProcess.stderr.on('data', (data: Buffer) => {\n stderrBuffer += data.toString();\n });\n\n childProcess.on('close', (code) => {\n debug('[close]: ' + code);\n if (code === 0) {\n resolve();\n } else {\n const err = new Error(stderrBuffer || `Command failed with exit code ${code}`);\n (err as any).code = code;\n detach(err);\n }\n });\n\n const detach = async (err?: Error) => {\n off?.();\n if (childProcess) {\n return new Promise<void>((resolve) => {\n childProcess?.on('close', () => resolve());\n childProcess?.kill();\n reject(err ?? new CommandError('detached'));\n });\n }\n };\n\n const off = installExitHooks(() => detach());\n });\n}\n\nexport async function launchAppWithDeviceCtl(deviceId: string, bundleId: string) {\n await devicectlAsync([\n 'device',\n 'process',\n 'launch',\n '--terminate-existing',\n '--device',\n deviceId,\n bundleId,\n ]);\n}\n\n/** Find all error codes from the output log */\nfunction getDeviceCtlErrorCodes(log: string): string[] {\n return [...log.matchAll(/BSErrorCodeDescription\\s+=\\s+(.*)$/gim)].map(([_line, code]) => code!);\n}\n\nlet hasEverBeenInstalled: boolean | undefined;\n\nexport function hasDevicectlEverBeenInstalled() {\n if (hasEverBeenInstalled) return hasEverBeenInstalled;\n // It doesn't appear possible for devicectl to ever be uninstalled. We can just check once and store this result forever\n // to prevent cold boots of devicectl from slowing down all invocations of `expo run ios`\n if (fs.existsSync(DEVICE_CTL_EXISTS_PATH)) {\n hasEverBeenInstalled = true;\n return true;\n }\n\n const isInstalled = isDevicectlInstalled();\n\n if (isInstalled) {\n fs.writeFileSync(DEVICE_CTL_EXISTS_PATH, '1');\n }\n hasEverBeenInstalled = isInstalled;\n return isInstalled;\n}\n\nfunction isDevicectlInstalled() {\n try {\n execSync('xcrun devicectl --version', { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Wraps the apple device method for installing and running an app,\n * adds indicator and retry loop for when the device is locked.\n */\nexport async function installAndLaunchAppAsync(props: {\n bundle: string;\n bundleIdentifier: string;\n udid: string;\n deviceName: string;\n}): Promise<void> {\n debug('Running on device:', props);\n const { bundle, bundleIdentifier, udid, deviceName } = props;\n let indicator: Ora | undefined;\n\n try {\n if (!indicator) {\n indicator = ora(`Connecting to: ${props.deviceName}`).start();\n }\n\n await installAppWithDeviceCtlAsync(\n udid,\n bundle,\n ({\n status,\n isComplete,\n progress,\n }: {\n status: string;\n isComplete: boolean;\n progress: number;\n }) => {\n if (!indicator) {\n indicator = ora(status).start();\n }\n indicator.text = `${chalk.bold(status)} ${progress}%`;\n if (isComplete) {\n indicator.succeed();\n }\n }\n );\n } catch (error: any) {\n if (indicator) {\n indicator.fail();\n }\n throw error;\n }\n\n async function launchAppOptionally() {\n try {\n await launchAppWithDeviceCtl(udid, bundleIdentifier);\n } catch (error: any) {\n if (indicator) {\n indicator.fail();\n }\n if (error.code === 'APPLE_DEVICE_LOCKED') {\n // Get the app name from the binary path.\n const appName = path.basename(bundle).split('.')[0] ?? 'app';\n if (\n isInteractive() &&\n (await confirmAsync({\n message: `Cannot launch ${appName} because the device is locked. Unlock ${deviceName} to continue...`,\n initial: true,\n }))\n ) {\n return launchAppOptionally();\n }\n throw new CommandError(\n `Cannot launch ${appName} on ${deviceName} because the device is locked.`\n );\n }\n throw error;\n }\n }\n\n await launchAppOptionally();\n}\n"],"names":["devicectlAsync","getConnectedAppleDevicesAsync","hasDevicectlEverBeenInstalled","installAndLaunchAppAsync","launchAppWithDeviceCtl","launchBinaryOnMacAsync","DEVICE_CTL_EXISTS_PATH","path","join","getExpoHomeDirectory","debug","require","args","options","xcrunAsync","error","CommandError","errorCodes","getDeviceCtlErrorCodes","stderr","includes","tmpPath","createTempFilePath","devices","stdout","devicesJson","JsonFile","readAsync","info","jsonVersion","Log","warn","assertDevicesJson","result","results","assert","Array","isArray","JSON","stringify","bundleId","appBinaryPath","spawnAsync","code","message","installAppWithDeviceCtlAsync","uuid","bundleIdOrAppPath","onProgress","maxAttempts","attempt","installAppWithDeviceCtlInternalAsync","isTransientDisconnect","backoffDelay","Math","pow","Promise","resolve","setTimeout","reject","childProcess","spawn","currentProgress","hasStarted","updateProgress","progress","statusPrefix","isComplete","status","on","data","strings","toString","split","EOL","map","value","trim","forEach","str","match","parseInt","stderrBuffer","err","Error","detach","off","kill","installExitHooks","deviceId","log","matchAll","_line","hasEverBeenInstalled","fs","existsSync","isInstalled","isDevicectlInstalled","writeFileSync","execSync","stdio","props","bundle","bundleIdentifier","udid","deviceName","indicator","ora","start","text","chalk","bold","succeed","fail","launchAppOptionally","appName","basename","isInteractive","confirmAsync","initial"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/platforms/ios/devicectl.ts"],"sourcesContent":["/**\n * Copyright © 2024 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport JsonFile from '@expo/json-file';\nimport type { SpawnOptions, SpawnResult } from '@expo/spawn-async';\nimport spawnAsync from '@expo/spawn-async';\nimport chalk from 'chalk';\nimport { spawn, execSync } from 'child_process';\nimport fs from 'fs';\nimport assert from 'node:assert';\nimport type { Ora } from 'ora';\nimport { EOL } from 'os';\nimport path from 'path';\n\nimport { xcrunAsync } from './xcrun';\nimport { getExpoHomeDirectory } from '../../../api/user/UserSettings';\nimport * as Log from '../../../log';\nimport { createTempFilePath } from '../../../utils/createTempPath';\nimport { CommandError } from '../../../utils/errors';\nimport { installExitHooks } from '../../../utils/exit';\nimport { isInteractive } from '../../../utils/interactive';\nimport { ora } from '../../../utils/ora';\nimport { confirmAsync } from '../../../utils/prompts';\n\nconst DEVICE_CTL_EXISTS_PATH = path.join(getExpoHomeDirectory(), 'devicectl-exists');\n\nconst debug = require('debug')('expo:devicectl') as typeof console.log;\n\ntype AnyEnum<T extends string = string> = T | (string & object);\n\ntype DeviceCtlDevice = {\n capabilities: DeviceCtlDeviceCapability[];\n connectionProperties: DeviceCtlConnectionProperties;\n deviceProperties: DeviceCtlDeviceProperties;\n hardwareProperties: DeviceCtlHardwareProperties;\n /** \"A1A1AAA1-0011-1AA1-11A1-10A1111AA11A\" */\n identifier: string;\n visibilityClass: AnyEnum<'default'>;\n};\n\ntype DeviceCtlHardwareProperties = {\n cpuType: DeviceCtlCpuType;\n deviceType: AnyEnum<'iPhone'>;\n /** 1114404411111111 */\n ecid: number;\n /** \"D74AP\" */\n hardwareModel: string;\n /** 512000000000 */\n internalStorageCapacity: number;\n /** true */\n isProductionFused: boolean;\n /** \"iPhone 14 Pro Max\" */\n marketingName: string;\n /** \"iOS\" */\n platform: AnyEnum<'iOS' | 'xrOS'>;\n /** \"iPhone15,3\" */\n productType: AnyEnum<'iPhone13,4' | 'iPhone15,3'>;\n reality: AnyEnum<'physical' | 'simulated'>;\n /** \"X2X1CC1XXX\" */\n serialNumber: string;\n supportedCPUTypes: DeviceCtlCpuType[];\n /** [1] */\n supportedDeviceFamilies: number[];\n thinningProductType: AnyEnum<'iPhone15,3'>;\n /** \"00001110-001111110110101A\" */\n udid: string;\n};\n\ntype DeviceCtlDeviceProperties = {\n /** true */\n bootedFromSnapshot: boolean;\n /** \"com.apple.os.update-AD0CF111ACFF11A11111A76A3D1262AE42A3F56F305AF5AE1135393A7A14A7D1\" */\n bootedSnapshotName: string;\n /** false */\n ddiServicesAvailable: boolean;\n\n developerModeStatus: AnyEnum<'enabled'>;\n /** false */\n hasInternalOSBuild: boolean;\n /** \"Evan's phone\" */\n name: string;\n /** \"21E236\" */\n osBuildUpdate: string;\n /** \"17.4.1\" */\n osVersionNumber: string;\n /** false */\n rootFileSystemIsWritable: boolean;\n};\n\ntype DeviceCtlDeviceCapability =\n | {\n name: AnyEnum;\n featureIdentifier: AnyEnum;\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.connectdevice';\n name: 'Connect to Device';\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.unpairdevice';\n name: 'Unpair Device';\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.acquireusageassertion';\n name: 'Acquire Usage Assertion';\n };\n\ntype DeviceCtlConnectionProperties = {\n authenticationType: AnyEnum<'manualPairing'>;\n isMobileDeviceOnly: boolean;\n /** \"2024-04-20T22:50:04.244Z\" */\n lastConnectionDate: string;\n pairingState: AnyEnum<'paired'>;\n /** [\"00001111-001111110110101A.coredevice.local\", \"A1A1AAA1-0011-1AA1-11A1-10A1111AA11A.coredevice.local\"] */\n potentialHostnames: string[];\n transportType: AnyEnum<'localNetwork' | 'wired'>;\n tunnelState: AnyEnum<'disconnected' | 'unavailable'>;\n tunnelTransportProtocol: AnyEnum<'tcp'>;\n};\n\ntype DeviceCtlCpuType = {\n name: AnyEnum<'arm64e' | 'arm64' | 'arm64_32'>;\n subType: number;\n /** 16777228 */\n type: number;\n};\n\n/** Run a `devicectl` command. */\nexport async function devicectlAsync(\n args: (string | undefined)[],\n options?: SpawnOptions\n): Promise<SpawnResult> {\n try {\n return await xcrunAsync(['devicectl', ...args], options);\n } catch (error: any) {\n if (error instanceof CommandError) {\n throw error;\n }\n if ('stderr' in error) {\n const errorCodes = getDeviceCtlErrorCodes(error.stderr);\n if (errorCodes.includes('Locked')) {\n throw new CommandError('APPLE_DEVICE_LOCKED', 'Device is locked, unlock and try again.');\n }\n }\n throw error;\n }\n}\n\nexport async function getConnectedAppleDevicesAsync() {\n if (!hasDevicectlEverBeenInstalled()) {\n debug('devicectl not found, skipping remote Apple devices.');\n return [];\n }\n\n const tmpPath = createTempFilePath();\n const devices = await devicectlAsync([\n 'list',\n 'devices',\n '--json-output',\n tmpPath,\n // Give two seconds before timing out: between 5 and 9223372036854775807\n '--timeout',\n '5',\n ]);\n debug(devices.stdout);\n const devicesJson = await JsonFile.readAsync(tmpPath);\n\n if (![2, 3, 5].includes((devicesJson as any)?.info?.jsonVersion)) {\n Log.warn(\n 'Unexpected devicectl JSON version output from devicectl. Connecting to physical Apple devices may not work as expected.'\n );\n }\n\n assertDevicesJson(devicesJson);\n\n return (devicesJson.result.devices as DeviceCtlDevice[]).filter(\n (device) => device?.hardwareProperties?.reality !== 'simulated'\n );\n}\n\nfunction assertDevicesJson(\n results: any\n): asserts results is { result: { devices: DeviceCtlDevice[] } } {\n assert(\n results != null && 'result' in results && Array.isArray(results?.result?.devices),\n 'Malformed JSON output from devicectl: ' + JSON.stringify(results, null, 2)\n );\n}\n\nexport async function launchBinaryOnMacAsync(\n bundleId: string,\n appBinaryPath: string\n): Promise<void> {\n const args = ['-b', bundleId, appBinaryPath];\n try {\n await spawnAsync('open', args);\n } catch (error: any) {\n if ('code' in error) {\n if (error.code === 1) {\n throw new CommandError(\n 'MACOS_LAUNCH',\n 'Failed to launch the compatible binary on macOS: open ' +\n args.join(' ') +\n '\\n\\n' +\n error.message\n );\n }\n }\n throw error;\n }\n}\n\nasync function installAppWithDeviceCtlAsync(\n uuid: string,\n bundleIdOrAppPath: string,\n onProgress: (event: { status: string; isComplete: boolean; progress: number }) => void\n): Promise<void> {\n const maxAttempts = 3;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n await installAppWithDeviceCtlInternalAsync(uuid, bundleIdOrAppPath, onProgress, attempt);\n return;\n } catch (error: any) {\n if (error.code === 'detached') {\n throw error;\n }\n const isTransientDisconnect =\n error.message &&\n (error.message.includes('CoreDeviceError') || error.message.includes('0xFA0'));\n\n if (!isTransientDisconnect || attempt === maxAttempts) {\n throw error;\n }\n const backoffDelay = 500 + Math.pow(2, attempt - 1) * 500;\n await new Promise((resolve) => setTimeout(resolve, backoffDelay));\n }\n }\n}\n\nasync function installAppWithDeviceCtlInternalAsync(\n uuid: string,\n bundleIdOrAppPath: string,\n onProgress: (event: { status: string; isComplete: boolean; progress: number }) => void,\n attempt: number\n): Promise<void> {\n // 𝝠 xcrun devicectl device install app --device 00001110-001111110110101A /Users/evanbacon/Library/Developer/Xcode/DerivedData/Router-hgbqaxzhrhkiftfweydvhgttadvn/Build/Products/Debug-iphoneos/Router.app --verbose\n return new Promise((resolve, reject) => {\n const args: string[] = [\n 'devicectl',\n 'device',\n 'install',\n 'app',\n '--device',\n uuid,\n bundleIdOrAppPath,\n ];\n const childProcess = spawn('xcrun', args);\n debug('xcrun ' + args.join(' '));\n\n let currentProgress = 0;\n let hasStarted = false;\n\n function updateProgress(progress: number) {\n hasStarted = true;\n if (progress <= currentProgress) {\n return;\n }\n currentProgress = progress;\n const statusPrefix = attempt > 1 ? `Installing (attempt ${attempt})` : 'Installing';\n onProgress({\n progress,\n isComplete: progress === 100,\n status: statusPrefix,\n });\n }\n\n childProcess.stdout.on('data', (data: Buffer) => {\n // Sometimes more than one chunk comes at a time, here we split by system newline,\n // then trim and filter.\n const strings = data\n .toString()\n .split(EOL)\n .map((value) => value.trim());\n\n strings.forEach((str) => {\n // Match the progress percentage:\n // - '34%... 35%...' -> 34\n // - '31%...' -> 31\n // - 'Complete!' -> 100\n\n const match = str.match(/(\\d+)%\\.\\.\\./);\n if (match) {\n updateProgress(parseInt(match[1]!, 10));\n } else if (hasStarted) {\n updateProgress(100);\n }\n });\n\n debug('[stdout]:', strings);\n });\n\n let stderrBuffer = '';\n childProcess.stderr.on('data', (data: Buffer) => {\n stderrBuffer += data.toString();\n });\n\n childProcess.on('close', (code) => {\n debug('[close]: ' + code);\n if (code === 0) {\n resolve();\n } else {\n const err = new Error(stderrBuffer || `Command failed with exit code ${code}`);\n (err as any).code = code;\n detach(err);\n }\n });\n\n const detach = async (err?: Error) => {\n off?.();\n if (childProcess) {\n return new Promise<void>((resolve) => {\n childProcess?.on('close', () => resolve());\n childProcess?.kill();\n reject(err ?? new CommandError('detached'));\n });\n }\n };\n\n const off = installExitHooks(() => detach());\n });\n}\n\nexport async function launchAppWithDeviceCtl(deviceId: string, bundleId: string) {\n await devicectlAsync([\n 'device',\n 'process',\n 'launch',\n '--terminate-existing',\n '--device',\n deviceId,\n bundleId,\n ]);\n}\n\n/** Find all error codes from the output log */\nfunction getDeviceCtlErrorCodes(log: string): string[] {\n return [...log.matchAll(/BSErrorCodeDescription\\s+=\\s+(.*)$/gim)].map(([_line, code]) => code!);\n}\n\nlet hasEverBeenInstalled: boolean | undefined;\n\nexport function hasDevicectlEverBeenInstalled() {\n if (hasEverBeenInstalled) return hasEverBeenInstalled;\n // It doesn't appear possible for devicectl to ever be uninstalled. We can just check once and store this result forever\n // to prevent cold boots of devicectl from slowing down all invocations of `expo run ios`\n if (fs.existsSync(DEVICE_CTL_EXISTS_PATH)) {\n hasEverBeenInstalled = true;\n return true;\n }\n\n const isInstalled = isDevicectlInstalled();\n\n if (isInstalled) {\n fs.writeFileSync(DEVICE_CTL_EXISTS_PATH, '1');\n }\n hasEverBeenInstalled = isInstalled;\n return isInstalled;\n}\n\nfunction isDevicectlInstalled() {\n try {\n execSync('xcrun devicectl --version', { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Wraps the apple device method for installing and running an app,\n * adds indicator and retry loop for when the device is locked.\n */\nexport async function installAndLaunchAppAsync(props: {\n bundle: string;\n bundleIdentifier: string;\n udid: string;\n deviceName: string;\n}): Promise<void> {\n debug('Running on device:', props);\n const { bundle, bundleIdentifier, udid, deviceName } = props;\n let indicator: Ora | undefined;\n\n try {\n if (!indicator) {\n indicator = ora(`Connecting to: ${props.deviceName}`).start();\n }\n\n await installAppWithDeviceCtlAsync(\n udid,\n bundle,\n ({\n status,\n isComplete,\n progress,\n }: {\n status: string;\n isComplete: boolean;\n progress: number;\n }) => {\n if (!indicator) {\n indicator = ora(status).start();\n }\n indicator.text = `${chalk.bold(status)} ${progress}%`;\n if (isComplete) {\n indicator.succeed();\n }\n }\n );\n } catch (error: any) {\n if (indicator) {\n indicator.fail();\n }\n throw error;\n }\n\n async function launchAppOptionally() {\n try {\n await launchAppWithDeviceCtl(udid, bundleIdentifier);\n } catch (error: any) {\n if (indicator) {\n indicator.fail();\n }\n if (error.code === 'APPLE_DEVICE_LOCKED') {\n // Get the app name from the binary path.\n const appName = path.basename(bundle).split('.')[0] ?? 'app';\n if (\n isInteractive() &&\n (await confirmAsync({\n message: `Cannot launch ${appName} because the device is locked. Unlock ${deviceName} to continue...`,\n initial: true,\n }))\n ) {\n return launchAppOptionally();\n }\n throw new CommandError(\n `Cannot launch ${appName} on ${deviceName} because the device is locked.`\n );\n }\n throw error;\n }\n }\n\n await launchAppOptionally();\n}\n"],"names":["devicectlAsync","getConnectedAppleDevicesAsync","hasDevicectlEverBeenInstalled","installAndLaunchAppAsync","launchAppWithDeviceCtl","launchBinaryOnMacAsync","DEVICE_CTL_EXISTS_PATH","path","join","getExpoHomeDirectory","debug","require","args","options","xcrunAsync","error","CommandError","errorCodes","getDeviceCtlErrorCodes","stderr","includes","tmpPath","createTempFilePath","devices","stdout","devicesJson","JsonFile","readAsync","info","jsonVersion","Log","warn","assertDevicesJson","result","filter","device","hardwareProperties","reality","results","assert","Array","isArray","JSON","stringify","bundleId","appBinaryPath","spawnAsync","code","message","installAppWithDeviceCtlAsync","uuid","bundleIdOrAppPath","onProgress","maxAttempts","attempt","installAppWithDeviceCtlInternalAsync","isTransientDisconnect","backoffDelay","Math","pow","Promise","resolve","setTimeout","reject","childProcess","spawn","currentProgress","hasStarted","updateProgress","progress","statusPrefix","isComplete","status","on","data","strings","toString","split","EOL","map","value","trim","forEach","str","match","parseInt","stderrBuffer","err","Error","detach","off","kill","installExitHooks","deviceId","log","matchAll","_line","hasEverBeenInstalled","fs","existsSync","isInstalled","isDevicectlInstalled","writeFileSync","execSync","stdio","props","bundle","bundleIdentifier","udid","deviceName","indicator","ora","start","text","chalk","bold","succeed","fail","launchAppOptionally","appName","basename","isInteractive","confirmAsync","initial"],"mappings":"AAAA;;;;;CAKC;;;;;;;;;;;QA+HqBA;eAAAA;;QAoBAC;eAAAA;;QA2MNC;eAAAA;;QA+BMC;eAAAA;;QAlDAC;eAAAA;;QA/IAC;eAAAA;;;;gEA1LD;;;;;;;gEAEE;;;;;;;gEACL;;;;;;;yBACc;;;;;;;gEACjB;;;;;;;gEACI;;;;;;;yBAEC;;;;;;;gEACH;;;;;;uBAEU;8BACU;6DAChB;gCACc;wBACN;sBACI;6BACH;qBACV;yBACS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE7B,MAAMC,yBAAyBC,eAAI,CAACC,IAAI,CAACC,IAAAA,kCAAoB,KAAI;AAEjE,MAAMC,QAAQC,QAAQ,SAAS;AAsGxB,eAAeX,eACpBY,IAA4B,EAC5BC,OAAsB;IAEtB,IAAI;QACF,OAAO,MAAMC,IAAAA,iBAAU,EAAC;YAAC;eAAgBF;SAAK,EAAEC;IAClD,EAAE,OAAOE,OAAY;QACnB,IAAIA,iBAAiBC,oBAAY,EAAE;YACjC,MAAMD;QACR;QACA,IAAI,YAAYA,OAAO;YACrB,MAAME,aAAaC,uBAAuBH,MAAMI,MAAM;YACtD,IAAIF,WAAWG,QAAQ,CAAC,WAAW;gBACjC,MAAM,IAAIJ,oBAAY,CAAC,uBAAuB;YAChD;QACF;QACA,MAAMD;IACR;AACF;AAEO,eAAed;QAmBI;IAlBxB,IAAI,CAACC,iCAAiC;QACpCQ,MAAM;QACN,OAAO,EAAE;IACX;IAEA,MAAMW,UAAUC,IAAAA,kCAAkB;IAClC,MAAMC,UAAU,MAAMvB,eAAe;QACnC;QACA;QACA;QACAqB;QACA,wEAAwE;QACxE;QACA;KACD;IACDX,MAAMa,QAAQC,MAAM;IACpB,MAAMC,cAAc,MAAMC,mBAAQ,CAACC,SAAS,CAACN;IAE7C,IAAI,CAAC;QAAC;QAAG;QAAG;KAAE,CAACD,QAAQ,CAAEK,gCAAD,oBAAA,AAACA,YAAqBG,IAAI,qBAA1B,kBAA4BC,WAAW,GAAG;QAChEC,KAAIC,IAAI,CACN;IAEJ;IAEAC,kBAAkBP;IAElB,OAAO,AAACA,YAAYQ,MAAM,CAACV,OAAO,CAAuBW,MAAM,CAC7D,CAACC;YAAWA;eAAAA,CAAAA,2BAAAA,6BAAAA,OAAQC,kBAAkB,qBAA1BD,2BAA4BE,OAAO,MAAK;;AAExD;AAEA,SAASL,kBACPM,OAAY;QAG8CA;IAD1DC,IAAAA,qBAAM,EACJD,WAAW,QAAQ,YAAYA,WAAWE,MAAMC,OAAO,CAACH,4BAAAA,kBAAAA,QAASL,MAAM,qBAAfK,gBAAiBf,OAAO,GAChF,2CAA2CmB,KAAKC,SAAS,CAACL,SAAS,MAAM;AAE7E;AAEO,eAAejC,uBACpBuC,QAAgB,EAChBC,aAAqB;IAErB,MAAMjC,OAAO;QAAC;QAAMgC;QAAUC;KAAc;IAC5C,IAAI;QACF,MAAMC,IAAAA,qBAAU,EAAC,QAAQlC;IAC3B,EAAE,OAAOG,OAAY;QACnB,IAAI,UAAUA,OAAO;YACnB,IAAIA,MAAMgC,IAAI,KAAK,GAAG;gBACpB,MAAM,IAAI/B,oBAAY,CACpB,gBACA,2DACEJ,KAAKJ,IAAI,CAAC,OACV,SACAO,MAAMiC,OAAO;YAEnB;QACF;QACA,MAAMjC;IACR;AACF;AAEA,eAAekC,6BACbC,IAAY,EACZC,iBAAyB,EACzBC,UAAsF;IAEtF,MAAMC,cAAc;IACpB,IAAK,IAAIC,UAAU,GAAGA,WAAWD,aAAaC,UAAW;QACvD,IAAI;YACF,MAAMC,qCAAqCL,MAAMC,mBAAmBC,YAAYE;YAChF;QACF,EAAE,OAAOvC,OAAY;YACnB,IAAIA,MAAMgC,IAAI,KAAK,YAAY;gBAC7B,MAAMhC;YACR;YACA,MAAMyC,wBACJzC,MAAMiC,OAAO,IACZjC,CAAAA,MAAMiC,OAAO,CAAC5B,QAAQ,CAAC,sBAAsBL,MAAMiC,OAAO,CAAC5B,QAAQ,CAAC,QAAO;YAE9E,IAAI,CAACoC,yBAAyBF,YAAYD,aAAa;gBACrD,MAAMtC;YACR;YACA,MAAM0C,eAAe,MAAMC,KAAKC,GAAG,CAAC,GAAGL,UAAU,KAAK;YACtD,MAAM,IAAIM,QAAQ,CAACC,UAAYC,WAAWD,SAASJ;QACrD;IACF;AACF;AAEA,eAAeF,qCACbL,IAAY,EACZC,iBAAyB,EACzBC,UAAsF,EACtFE,OAAe;IAEf,uNAAuN;IACvN,OAAO,IAAIM,QAAQ,CAACC,SAASE;QAC3B,MAAMnD,OAAiB;YACrB;YACA;YACA;YACA;YACA;YACAsC;YACAC;SACD;QACD,MAAMa,eAAeC,IAAAA,sBAAK,EAAC,SAASrD;QACpCF,MAAM,WAAWE,KAAKJ,IAAI,CAAC;QAE3B,IAAI0D,kBAAkB;QACtB,IAAIC,aAAa;QAEjB,SAASC,eAAeC,QAAgB;YACtCF,aAAa;YACb,IAAIE,YAAYH,iBAAiB;gBAC/B;YACF;YACAA,kBAAkBG;YAClB,MAAMC,eAAehB,UAAU,IAAI,CAAC,oBAAoB,EAAEA,QAAQ,CAAC,CAAC,GAAG;YACvEF,WAAW;gBACTiB;gBACAE,YAAYF,aAAa;gBACzBG,QAAQF;YACV;QACF;QAEAN,aAAaxC,MAAM,CAACiD,EAAE,CAAC,QAAQ,CAACC;YAC9B,kFAAkF;YAClF,wBAAwB;YACxB,MAAMC,UAAUD,KACbE,QAAQ,GACRC,KAAK,CAACC,SAAG,EACTC,GAAG,CAAC,CAACC,QAAUA,MAAMC,IAAI;YAE5BN,QAAQO,OAAO,CAAC,CAACC;gBACf,iCAAiC;gBACjC,0BAA0B;gBAC1B,mBAAmB;gBACnB,uBAAuB;gBAEvB,MAAMC,QAAQD,IAAIC,KAAK,CAAC;gBACxB,IAAIA,OAAO;oBACThB,eAAeiB,SAASD,KAAK,CAAC,EAAE,EAAG;gBACrC,OAAO,IAAIjB,YAAY;oBACrBC,eAAe;gBACjB;YACF;YAEA1D,MAAM,aAAaiE;QACrB;QAEA,IAAIW,eAAe;QACnBtB,aAAa7C,MAAM,CAACsD,EAAE,CAAC,QAAQ,CAACC;YAC9BY,gBAAgBZ,KAAKE,QAAQ;QAC/B;QAEAZ,aAAaS,EAAE,CAAC,SAAS,CAAC1B;YACxBrC,MAAM,cAAcqC;YACpB,IAAIA,SAAS,GAAG;gBACdc;YACF,OAAO;gBACL,MAAM0B,MAAM,IAAIC,MAAMF,gBAAgB,CAAC,8BAA8B,EAAEvC,MAAM;gBAC5EwC,IAAYxC,IAAI,GAAGA;gBACpB0C,OAAOF;YACT;QACF;QAEA,MAAME,SAAS,OAAOF;YACpBG,uBAAAA;YACA,IAAI1B,cAAc;gBAChB,OAAO,IAAIJ,QAAc,CAACC;oBACxBG,gCAAAA,aAAcS,EAAE,CAAC,SAAS,IAAMZ;oBAChCG,gCAAAA,aAAc2B,IAAI;oBAClB5B,OAAOwB,OAAO,IAAIvE,oBAAY,CAAC;gBACjC;YACF;QACF;QAEA,MAAM0E,MAAME,IAAAA,sBAAgB,EAAC,IAAMH;IACrC;AACF;AAEO,eAAerF,uBAAuByF,QAAgB,EAAEjD,QAAgB;IAC7E,MAAM5C,eAAe;QACnB;QACA;QACA;QACA;QACA;QACA6F;QACAjD;KACD;AACH;AAEA,6CAA6C,GAC7C,SAAS1B,uBAAuB4E,GAAW;IACzC,OAAO;WAAIA,IAAIC,QAAQ,CAAC;KAAyC,CAAChB,GAAG,CAAC,CAAC,CAACiB,OAAOjD,KAAK,GAAKA;AAC3F;AAEA,IAAIkD;AAEG,SAAS/F;IACd,IAAI+F,sBAAsB,OAAOA;IACjC,wHAAwH;IACxH,yFAAyF;IACzF,IAAIC,aAAE,CAACC,UAAU,CAAC7F,yBAAyB;QACzC2F,uBAAuB;QACvB,OAAO;IACT;IAEA,MAAMG,cAAcC;IAEpB,IAAID,aAAa;QACfF,aAAE,CAACI,aAAa,CAAChG,wBAAwB;IAC3C;IACA2F,uBAAuBG;IACvB,OAAOA;AACT;AAEA,SAASC;IACP,IAAI;QACFE,IAAAA,yBAAQ,EAAC,6BAA6B;YAAEC,OAAO;QAAS;QACxD,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAMO,eAAerG,yBAAyBsG,KAK9C;IACC/F,MAAM,sBAAsB+F;IAC5B,MAAM,EAAEC,MAAM,EAAEC,gBAAgB,EAAEC,IAAI,EAAEC,UAAU,EAAE,GAAGJ;IACvD,IAAIK;IAEJ,IAAI;QACF,IAAI,CAACA,WAAW;YACdA,YAAYC,IAAAA,QAAG,EAAC,CAAC,eAAe,EAAEN,MAAMI,UAAU,EAAE,EAAEG,KAAK;QAC7D;QAEA,MAAM/D,6BACJ2D,MACAF,QACA,CAAC,EACClC,MAAM,EACND,UAAU,EACVF,QAAQ,EAKT;YACC,IAAI,CAACyC,WAAW;gBACdA,YAAYC,IAAAA,QAAG,EAACvC,QAAQwC,KAAK;YAC/B;YACAF,UAAUG,IAAI,GAAG,GAAGC,gBAAK,CAACC,IAAI,CAAC3C,QAAQ,CAAC,EAAEH,SAAS,CAAC,CAAC;YACrD,IAAIE,YAAY;gBACduC,UAAUM,OAAO;YACnB;QACF;IAEJ,EAAE,OAAOrG,OAAY;QACnB,IAAI+F,WAAW;YACbA,UAAUO,IAAI;QAChB;QACA,MAAMtG;IACR;IAEA,eAAeuG;QACb,IAAI;YACF,MAAMlH,uBAAuBwG,MAAMD;QACrC,EAAE,OAAO5F,OAAY;YACnB,IAAI+F,WAAW;gBACbA,UAAUO,IAAI;YAChB;YACA,IAAItG,MAAMgC,IAAI,KAAK,uBAAuB;gBACxC,yCAAyC;gBACzC,MAAMwE,UAAUhH,eAAI,CAACiH,QAAQ,CAACd,QAAQ7B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI;gBACvD,IACE4C,IAAAA,0BAAa,OACZ,MAAMC,IAAAA,qBAAY,EAAC;oBAClB1E,SAAS,CAAC,cAAc,EAAEuE,QAAQ,sCAAsC,EAAEV,WAAW,eAAe,CAAC;oBACrGc,SAAS;gBACX,IACA;oBACA,OAAOL;gBACT;gBACA,MAAM,IAAItG,oBAAY,CACpB,CAAC,cAAc,EAAEuG,QAAQ,IAAI,EAAEV,WAAW,8BAA8B,CAAC;YAE7E;YACA,MAAM9F;QACR;IACF;IAEA,MAAMuG;AACR"}
|
|
@@ -30,16 +30,9 @@ function _paths() {
|
|
|
30
30
|
};
|
|
31
31
|
return data;
|
|
32
32
|
}
|
|
33
|
-
function
|
|
34
|
-
const data = require("
|
|
35
|
-
|
|
36
|
-
return data;
|
|
37
|
-
};
|
|
38
|
-
return data;
|
|
39
|
-
}
|
|
40
|
-
function _promises() {
|
|
41
|
-
const data = require("node:stream/promises");
|
|
42
|
-
_promises = function() {
|
|
33
|
+
function _http() {
|
|
34
|
+
const data = require("expo-server/adapter/http");
|
|
35
|
+
_http = function() {
|
|
43
36
|
return data;
|
|
44
37
|
};
|
|
45
38
|
return data;
|
|
@@ -315,19 +308,7 @@ class ManifestMiddleware extends _ExpoMiddleware.ExpoMiddleware {
|
|
|
315
308
|
// Read from headers
|
|
316
309
|
const options = this.getParsedHeaders(req);
|
|
317
310
|
const response = await this._getManifestResponseAsync(options);
|
|
318
|
-
|
|
319
|
-
if (typeof res.setHeaders === 'function') {
|
|
320
|
-
res.setHeaders(response.headers);
|
|
321
|
-
} else {
|
|
322
|
-
for (const [key, value] of response.headers.entries()){
|
|
323
|
-
res.appendHeader(key, value);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
if (response.body) {
|
|
327
|
-
await (0, _promises().pipeline)(_nodestream().Readable.fromWeb(response.body), res);
|
|
328
|
-
} else {
|
|
329
|
-
res.end();
|
|
330
|
-
}
|
|
311
|
+
await (0, _http().respond)(res, response);
|
|
331
312
|
}
|
|
332
313
|
}
|
|
333
314
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/middleware/ManifestMiddleware.ts"],"sourcesContent":["import type { ExpoConfig, ExpoGoConfig, PackageJSONConfig, ProjectConfig } from '@expo/config';\nimport { getConfig } from '@expo/config';\nimport { resolveRelativeEntryPoint } from '@expo/config/paths';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { resolve } from 'url';\n\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport {\n createBundleUrlPath,\n getBaseUrlFromExpoConfig,\n getAsyncRoutesFromExpoConfig,\n createBundleUrlPathFromExpoConfig,\n} from './metroOptions';\nimport { resolveGoogleServicesFile, resolveManifestAssets } from './resolveAssets';\nimport type { RuntimePlatform } from './resolvePlatform';\nimport { parsePlatformHeader } from './resolvePlatform';\nimport type { ServerNext, ServerRequest, ServerResponse } from './server.types';\nimport { getActorDisplayName, getUserAsync } from '../../../api/user/user';\nimport { isEnableHermesManaged } from '../../../export/exportHermes';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport * as ProjectDevices from '../../project/devices';\nimport type { UrlCreator } from '../UrlCreator';\nimport { getRouterDirectoryModuleIdWithManifest } from '../metro/router';\nimport type { PlatformBundlers } from '../platformBundlers';\nimport { getPlatformBundlers } from '../platformBundlers';\nimport { createTemplateHtmlFromExpoConfigAsync } from '../webTemplate';\n\nconst debug = require('debug')('expo:start:server:middleware:manifest') as typeof console.log;\n\n/** Info about the computer hosting the dev server. */\nexport interface HostInfo {\n host: string;\n server: 'expo';\n serverVersion: string;\n serverDriver: string | null;\n serverOS: NodeJS.Platform;\n serverOSVersion: string;\n}\n\n/** Parsed values from the supported request headers. */\nexport interface ManifestRequestInfo {\n /** Platform to serve. */\n platform: RuntimePlatform;\n /** Requested host name. */\n hostname?: string | null;\n /** The protocol used to request the manifest */\n protocol?: 'http' | 'https';\n}\n\n/** Project related info. */\nexport type ResponseProjectSettings = {\n expoGoConfig: ExpoGoConfig;\n hostUri: string;\n bundleUrl: string;\n exp: ExpoConfig;\n};\n\nexport const DEVELOPER_TOOL = 'expo-cli';\n\nexport type ManifestMiddlewareOptions = {\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n constructUrl: UrlCreator['constructUrl'];\n isNativeWebpack?: boolean;\n privateKeyPath?: string;\n};\n\n/** Base middleware creator for serving the Expo manifest (like the index.html but for native runtimes). */\nexport abstract class ManifestMiddleware<\n TManifestRequestInfo extends ManifestRequestInfo,\n> extends ExpoMiddleware {\n private initialProjectConfig: ProjectConfig;\n private platformBundlers: PlatformBundlers;\n\n constructor(\n protected projectRoot: string,\n protected options: ManifestMiddlewareOptions\n ) {\n super(\n projectRoot,\n /**\n * Only support `/`, `/manifest`, `/index.exp` for the manifest middleware.\n */\n ['/', '/manifest', '/index.exp']\n );\n this.initialProjectConfig = getConfig(projectRoot);\n this.platformBundlers = getPlatformBundlers(projectRoot, this.initialProjectConfig.exp);\n }\n\n /** Exposed for testing. */\n public async _resolveProjectSettingsAsync({\n platform,\n hostname,\n protocol,\n }: Pick<\n TManifestRequestInfo,\n 'hostname' | 'platform' | 'protocol'\n >): Promise<ResponseProjectSettings> {\n // Read the config\n const projectConfig = getConfig(this.projectRoot);\n\n // Read from headers\n const mainModuleName = this.resolveMainModuleName({\n pkg: projectConfig.pkg,\n platform,\n });\n\n const isHermesEnabled = isEnableHermesManaged(projectConfig.exp, platform);\n\n // Resolve the signed-in CLI user to pass through the manifest\n const user = await getUserAsync();\n const username = getActorDisplayName(user);\n\n // Create the manifest and set fields within it\n const expoGoConfig = this.getExpoGoConfig({\n mainModuleName,\n hostname,\n username: username !== 'anonymous' ? username : undefined,\n });\n\n const hostUri = this.options.constructUrl({ scheme: '', hostname });\n\n const bundleUrl = this._getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n engine: isHermesEnabled ? 'hermes' : undefined,\n baseUrl: getBaseUrlFromExpoConfig(projectConfig.exp),\n asyncRoutes: getAsyncRoutesFromExpoConfig(\n projectConfig.exp,\n this.options.mode ?? 'development',\n platform\n ),\n routerRoot: getRouterDirectoryModuleIdWithManifest(this.projectRoot, projectConfig.exp),\n protocol,\n reactCompiler: !!projectConfig.exp.experiments?.reactCompiler,\n });\n\n // Resolve all assets and set them on the manifest as URLs\n await this.mutateManifestWithAssetsAsync(projectConfig.exp, bundleUrl);\n\n return {\n expoGoConfig,\n hostUri,\n bundleUrl,\n exp: projectConfig.exp,\n };\n }\n\n /** Get the main entry module ID (file) relative to the project root. */\n private resolveMainModuleName(props: { pkg: PackageJSONConfig; platform: string }): string {\n // NOTE(Bacon): Webpack is currently hardcoded to index.bundle on native\n // in the future (TODO) we should move this logic into a Webpack plugin and use\n // a generated file name like we do on web.\n // const server = getDefaultDevServer();\n // // TODO: Move this into BundlerDevServer and read this info from self.\n // const isNativeWebpack = server instanceof WebpackBundlerDevServer && server.isTargetingNative();\n if (this.options.isNativeWebpack) {\n return 'index';\n }\n\n const entry = resolveRelativeEntryPoint(this.projectRoot, props);\n debug(`Resolved entry point: ${entry} (project root: ${this.projectRoot})`);\n return entry;\n }\n\n /** Parse request headers into options. */\n public abstract getParsedHeaders(req: ServerRequest): TManifestRequestInfo;\n\n /** Store device IDs that were sent in the request headers. */\n private async saveDevicesAsync(req: ServerRequest) {\n const deviceIds = req.headers?.['expo-dev-client-id'];\n if (deviceIds) {\n await ProjectDevices.saveDevicesAsync(this.projectRoot, deviceIds).catch((e) =>\n Log.exception(e)\n );\n }\n }\n\n /** Create the bundle URL (points to the single JS entry file). Exposed for testing. */\n public _getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n engine,\n baseUrl,\n isExporting,\n asyncRoutes,\n routerRoot,\n protocol,\n reactCompiler,\n }: {\n platform: string;\n hostname?: string | null;\n mainModuleName: string;\n engine?: 'hermes';\n baseUrl?: string;\n asyncRoutes: boolean;\n isExporting?: boolean;\n routerRoot: string;\n protocol?: 'http' | 'https';\n reactCompiler: boolean;\n }): string {\n const path = createBundleUrlPath({\n mode: this.options.mode ?? 'development',\n minify: this.options.minify,\n platform,\n mainModuleName,\n lazy: !env.EXPO_NO_METRO_LAZY,\n engine,\n bytecode: engine === 'hermes',\n baseUrl,\n isExporting: !!isExporting,\n asyncRoutes,\n routerRoot,\n reactCompiler,\n });\n\n return (\n this.options.constructUrl({\n scheme: protocol ?? 'http',\n // hostType: this.options.location.hostType,\n hostname,\n }) + path\n );\n }\n\n /** Get the manifest response to return to the runtime. This file contains info regarding where the assets can be loaded from. Exposed for testing. */\n public abstract _getManifestResponseAsync(options: TManifestRequestInfo): Promise<Response>;\n\n private getExpoGoConfig({\n mainModuleName,\n hostname,\n username,\n }: {\n mainModuleName: string;\n hostname?: string | null;\n username?: string;\n }): ExpoGoConfig {\n return {\n // localhost:8081\n debuggerHost: this.options.constructUrl({ scheme: '', hostname }),\n // Required for Expo Go to function.\n developer: {\n tool: DEVELOPER_TOOL,\n projectRoot: this.projectRoot,\n },\n packagerOpts: {\n // Required for dev client.\n dev: this.options.mode !== 'production',\n },\n // Indicates the name of the main bundle.\n mainModuleName,\n // The signed-in CLI username, used by Expo Go to verify account match.\n ...(username ? { username } : undefined),\n };\n }\n\n /** Resolve all assets and set them on the manifest as URLs */\n private async mutateManifestWithAssetsAsync(manifest: ExpoConfig, bundleUrl: string) {\n await resolveManifestAssets(this.projectRoot, {\n manifest,\n resolver: async (path) => {\n if (this.options.isNativeWebpack) {\n // When using our custom dev server, just do assets normally\n // without the `assets/` subpath redirect.\n return resolve(bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0], path);\n }\n return bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0] + 'assets/' + path;\n },\n });\n // The server normally inserts this but if we're offline we'll do it here\n await resolveGoogleServicesFile(this.projectRoot, manifest);\n }\n\n public getWebBundleUrl() {\n const platform = 'web';\n // Read from headers\n const mainModuleName = this.resolveMainModuleName({\n pkg: this.initialProjectConfig.pkg,\n platform,\n });\n\n return createBundleUrlPathFromExpoConfig(this.projectRoot, this.initialProjectConfig.exp, {\n platform,\n mainModuleName,\n minify: this.options.minify,\n lazy: !env.EXPO_NO_METRO_LAZY,\n mode: this.options.mode ?? 'development',\n // Hermes doesn't support more modern JS features than most, if not all, modern browser.\n engine: 'hermes',\n isExporting: false,\n bytecode: false,\n });\n }\n\n /**\n * Web platforms should create an index.html response using the same script resolution as native.\n *\n * Instead of adding a `bundleUrl` to a `manifest.json` (native) we'll add a `<script src=\"\">`\n * to an `index.html`, this enables the web platform to load JavaScript from the server.\n */\n private async handleWebRequestAsync(req: ServerRequest, res: ServerResponse) {\n res.setHeader('Content-Type', 'text/html');\n\n res.end(await this.getSingleHtmlTemplateAsync());\n }\n\n getSingleHtmlTemplateAsync() {\n // Read from headers\n const bundleUrl = this.getWebBundleUrl();\n\n return createTemplateHtmlFromExpoConfigAsync(this.projectRoot, {\n exp: this.initialProjectConfig.exp,\n scripts: [bundleUrl],\n });\n }\n\n /** Exposed for testing. */\n async checkBrowserRequestAsync(req: ServerRequest, res: ServerResponse, next: ServerNext) {\n if (\n this.platformBundlers.web === 'metro' &&\n this.initialProjectConfig.exp.platforms?.includes('web')\n ) {\n // NOTE(EvanBacon): This effectively disables the safety check we do on custom runtimes to ensure\n // the `expo-platform` header is included. When `web.bundler=web`, if the user has non-standard Expo\n // code loading then they'll get a web bundle without a clear assertion of platform support.\n const platform = parsePlatformHeader(req);\n // On web, serve the public folder\n if (!platform || platform === 'web') {\n if (['static', 'server'].includes(this.initialProjectConfig.exp.web?.output ?? '')) {\n // Skip the spa-styled index.html when static generation is enabled.\n next();\n return true;\n } else {\n await this.handleWebRequestAsync(req, res);\n return true;\n }\n }\n }\n return false;\n }\n\n async handleRequestAsync(\n req: ServerRequest,\n res: ServerResponse,\n next: ServerNext\n ): Promise<void> {\n // First check for standard JavaScript runtimes (aka legacy browsers like Chrome).\n if (await this.checkBrowserRequestAsync(req, res, next)) {\n return;\n }\n\n // Save device IDs for dev client.\n await this.saveDevicesAsync(req);\n\n // Read from headers\n const options = this.getParsedHeaders(req);\n\n const response = await this._getManifestResponseAsync(options);\n // Convert `Response` to node:http response\n if (typeof res.setHeaders === 'function') {\n res.setHeaders(response.headers);\n } else {\n for (const [key, value] of response.headers.entries()) {\n res.appendHeader(key, value);\n }\n }\n if (response.body) {\n await pipeline(Readable.fromWeb(response.body as any), res);\n } else {\n res.end();\n }\n }\n}\n"],"names":["DEVELOPER_TOOL","ManifestMiddleware","debug","require","ExpoMiddleware","projectRoot","options","initialProjectConfig","getConfig","platformBundlers","getPlatformBundlers","exp","_resolveProjectSettingsAsync","platform","hostname","protocol","projectConfig","mainModuleName","resolveMainModuleName","pkg","isHermesEnabled","isEnableHermesManaged","user","getUserAsync","username","getActorDisplayName","expoGoConfig","getExpoGoConfig","undefined","hostUri","constructUrl","scheme","bundleUrl","_getBundleUrl","engine","baseUrl","getBaseUrlFromExpoConfig","asyncRoutes","getAsyncRoutesFromExpoConfig","mode","routerRoot","getRouterDirectoryModuleIdWithManifest","reactCompiler","experiments","mutateManifestWithAssetsAsync","props","isNativeWebpack","entry","resolveRelativeEntryPoint","saveDevicesAsync","req","deviceIds","headers","ProjectDevices","catch","e","Log","exception","isExporting","path","createBundleUrlPath","minify","lazy","env","EXPO_NO_METRO_LAZY","bytecode","debuggerHost","developer","tool","packagerOpts","dev","manifest","resolveManifestAssets","resolver","resolve","match","resolveGoogleServicesFile","getWebBundleUrl","createBundleUrlPathFromExpoConfig","handleWebRequestAsync","res","setHeader","end","getSingleHtmlTemplateAsync","createTemplateHtmlFromExpoConfigAsync","scripts","checkBrowserRequestAsync","next","web","platforms","includes","parsePlatformHeader","output","handleRequestAsync","getParsedHeaders","response","_getManifestResponseAsync","setHeaders","key","value","entries","appendHeader","body","pipeline","Readable","fromWeb"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/middleware/ManifestMiddleware.ts"],"sourcesContent":["import type { ExpoConfig, ExpoGoConfig, PackageJSONConfig, ProjectConfig } from '@expo/config';\nimport { getConfig } from '@expo/config';\nimport { resolveRelativeEntryPoint } from '@expo/config/paths';\nimport { respond } from 'expo-server/adapter/http';\nimport { resolve } from 'url';\n\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport {\n createBundleUrlPath,\n getBaseUrlFromExpoConfig,\n getAsyncRoutesFromExpoConfig,\n createBundleUrlPathFromExpoConfig,\n} from './metroOptions';\nimport { resolveGoogleServicesFile, resolveManifestAssets } from './resolveAssets';\nimport type { RuntimePlatform } from './resolvePlatform';\nimport { parsePlatformHeader } from './resolvePlatform';\nimport type { ServerNext, ServerRequest, ServerResponse } from './server.types';\nimport { getActorDisplayName, getUserAsync } from '../../../api/user/user';\nimport { isEnableHermesManaged } from '../../../export/exportHermes';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport * as ProjectDevices from '../../project/devices';\nimport type { UrlCreator } from '../UrlCreator';\nimport { getRouterDirectoryModuleIdWithManifest } from '../metro/router';\nimport type { PlatformBundlers } from '../platformBundlers';\nimport { getPlatformBundlers } from '../platformBundlers';\nimport { createTemplateHtmlFromExpoConfigAsync } from '../webTemplate';\n\nconst debug = require('debug')('expo:start:server:middleware:manifest') as typeof console.log;\n\n/** Info about the computer hosting the dev server. */\nexport interface HostInfo {\n host: string;\n server: 'expo';\n serverVersion: string;\n serverDriver: string | null;\n serverOS: NodeJS.Platform;\n serverOSVersion: string;\n}\n\n/** Parsed values from the supported request headers. */\nexport interface ManifestRequestInfo {\n /** Platform to serve. */\n platform: RuntimePlatform;\n /** Requested host name. */\n hostname?: string | null;\n /** The protocol used to request the manifest */\n protocol?: 'http' | 'https';\n}\n\n/** Project related info. */\nexport type ResponseProjectSettings = {\n expoGoConfig: ExpoGoConfig;\n hostUri: string;\n bundleUrl: string;\n exp: ExpoConfig;\n};\n\nexport const DEVELOPER_TOOL = 'expo-cli';\n\nexport type ManifestMiddlewareOptions = {\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n constructUrl: UrlCreator['constructUrl'];\n isNativeWebpack?: boolean;\n privateKeyPath?: string;\n};\n\n/** Base middleware creator for serving the Expo manifest (like the index.html but for native runtimes). */\nexport abstract class ManifestMiddleware<\n TManifestRequestInfo extends ManifestRequestInfo,\n> extends ExpoMiddleware {\n private initialProjectConfig: ProjectConfig;\n private platformBundlers: PlatformBundlers;\n\n constructor(\n protected projectRoot: string,\n protected options: ManifestMiddlewareOptions\n ) {\n super(\n projectRoot,\n /**\n * Only support `/`, `/manifest`, `/index.exp` for the manifest middleware.\n */\n ['/', '/manifest', '/index.exp']\n );\n this.initialProjectConfig = getConfig(projectRoot);\n this.platformBundlers = getPlatformBundlers(projectRoot, this.initialProjectConfig.exp);\n }\n\n /** Exposed for testing. */\n public async _resolveProjectSettingsAsync({\n platform,\n hostname,\n protocol,\n }: Pick<\n TManifestRequestInfo,\n 'hostname' | 'platform' | 'protocol'\n >): Promise<ResponseProjectSettings> {\n // Read the config\n const projectConfig = getConfig(this.projectRoot);\n\n // Read from headers\n const mainModuleName = this.resolveMainModuleName({\n pkg: projectConfig.pkg,\n platform,\n });\n\n const isHermesEnabled = isEnableHermesManaged(projectConfig.exp, platform);\n\n // Resolve the signed-in CLI user to pass through the manifest\n const user = await getUserAsync();\n const username = getActorDisplayName(user);\n\n // Create the manifest and set fields within it\n const expoGoConfig = this.getExpoGoConfig({\n mainModuleName,\n hostname,\n username: username !== 'anonymous' ? username : undefined,\n });\n\n const hostUri = this.options.constructUrl({ scheme: '', hostname });\n\n const bundleUrl = this._getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n engine: isHermesEnabled ? 'hermes' : undefined,\n baseUrl: getBaseUrlFromExpoConfig(projectConfig.exp),\n asyncRoutes: getAsyncRoutesFromExpoConfig(\n projectConfig.exp,\n this.options.mode ?? 'development',\n platform\n ),\n routerRoot: getRouterDirectoryModuleIdWithManifest(this.projectRoot, projectConfig.exp),\n protocol,\n reactCompiler: !!projectConfig.exp.experiments?.reactCompiler,\n });\n\n // Resolve all assets and set them on the manifest as URLs\n await this.mutateManifestWithAssetsAsync(projectConfig.exp, bundleUrl);\n\n return {\n expoGoConfig,\n hostUri,\n bundleUrl,\n exp: projectConfig.exp,\n };\n }\n\n /** Get the main entry module ID (file) relative to the project root. */\n private resolveMainModuleName(props: { pkg: PackageJSONConfig; platform: string }): string {\n // NOTE(Bacon): Webpack is currently hardcoded to index.bundle on native\n // in the future (TODO) we should move this logic into a Webpack plugin and use\n // a generated file name like we do on web.\n // const server = getDefaultDevServer();\n // // TODO: Move this into BundlerDevServer and read this info from self.\n // const isNativeWebpack = server instanceof WebpackBundlerDevServer && server.isTargetingNative();\n if (this.options.isNativeWebpack) {\n return 'index';\n }\n\n const entry = resolveRelativeEntryPoint(this.projectRoot, props);\n debug(`Resolved entry point: ${entry} (project root: ${this.projectRoot})`);\n return entry;\n }\n\n /** Parse request headers into options. */\n public abstract getParsedHeaders(req: ServerRequest): TManifestRequestInfo;\n\n /** Store device IDs that were sent in the request headers. */\n private async saveDevicesAsync(req: ServerRequest) {\n const deviceIds = req.headers?.['expo-dev-client-id'];\n if (deviceIds) {\n await ProjectDevices.saveDevicesAsync(this.projectRoot, deviceIds).catch((e) =>\n Log.exception(e)\n );\n }\n }\n\n /** Create the bundle URL (points to the single JS entry file). Exposed for testing. */\n public _getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n engine,\n baseUrl,\n isExporting,\n asyncRoutes,\n routerRoot,\n protocol,\n reactCompiler,\n }: {\n platform: string;\n hostname?: string | null;\n mainModuleName: string;\n engine?: 'hermes';\n baseUrl?: string;\n asyncRoutes: boolean;\n isExporting?: boolean;\n routerRoot: string;\n protocol?: 'http' | 'https';\n reactCompiler: boolean;\n }): string {\n const path = createBundleUrlPath({\n mode: this.options.mode ?? 'development',\n minify: this.options.minify,\n platform,\n mainModuleName,\n lazy: !env.EXPO_NO_METRO_LAZY,\n engine,\n bytecode: engine === 'hermes',\n baseUrl,\n isExporting: !!isExporting,\n asyncRoutes,\n routerRoot,\n reactCompiler,\n });\n\n return (\n this.options.constructUrl({\n scheme: protocol ?? 'http',\n // hostType: this.options.location.hostType,\n hostname,\n }) + path\n );\n }\n\n /** Get the manifest response to return to the runtime. This file contains info regarding where the assets can be loaded from. Exposed for testing. */\n public abstract _getManifestResponseAsync(options: TManifestRequestInfo): Promise<Response>;\n\n private getExpoGoConfig({\n mainModuleName,\n hostname,\n username,\n }: {\n mainModuleName: string;\n hostname?: string | null;\n username?: string;\n }): ExpoGoConfig {\n return {\n // localhost:8081\n debuggerHost: this.options.constructUrl({ scheme: '', hostname }),\n // Required for Expo Go to function.\n developer: {\n tool: DEVELOPER_TOOL,\n projectRoot: this.projectRoot,\n },\n packagerOpts: {\n // Required for dev client.\n dev: this.options.mode !== 'production',\n },\n // Indicates the name of the main bundle.\n mainModuleName,\n // The signed-in CLI username, used by Expo Go to verify account match.\n ...(username ? { username } : undefined),\n };\n }\n\n /** Resolve all assets and set them on the manifest as URLs */\n private async mutateManifestWithAssetsAsync(manifest: ExpoConfig, bundleUrl: string) {\n await resolveManifestAssets(this.projectRoot, {\n manifest,\n resolver: async (path) => {\n if (this.options.isNativeWebpack) {\n // When using our custom dev server, just do assets normally\n // without the `assets/` subpath redirect.\n return resolve(bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0], path);\n }\n return bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0] + 'assets/' + path;\n },\n });\n // The server normally inserts this but if we're offline we'll do it here\n await resolveGoogleServicesFile(this.projectRoot, manifest);\n }\n\n public getWebBundleUrl() {\n const platform = 'web';\n // Read from headers\n const mainModuleName = this.resolveMainModuleName({\n pkg: this.initialProjectConfig.pkg,\n platform,\n });\n\n return createBundleUrlPathFromExpoConfig(this.projectRoot, this.initialProjectConfig.exp, {\n platform,\n mainModuleName,\n minify: this.options.minify,\n lazy: !env.EXPO_NO_METRO_LAZY,\n mode: this.options.mode ?? 'development',\n // Hermes doesn't support more modern JS features than most, if not all, modern browser.\n engine: 'hermes',\n isExporting: false,\n bytecode: false,\n });\n }\n\n /**\n * Web platforms should create an index.html response using the same script resolution as native.\n *\n * Instead of adding a `bundleUrl` to a `manifest.json` (native) we'll add a `<script src=\"\">`\n * to an `index.html`, this enables the web platform to load JavaScript from the server.\n */\n private async handleWebRequestAsync(req: ServerRequest, res: ServerResponse) {\n res.setHeader('Content-Type', 'text/html');\n\n res.end(await this.getSingleHtmlTemplateAsync());\n }\n\n getSingleHtmlTemplateAsync() {\n // Read from headers\n const bundleUrl = this.getWebBundleUrl();\n\n return createTemplateHtmlFromExpoConfigAsync(this.projectRoot, {\n exp: this.initialProjectConfig.exp,\n scripts: [bundleUrl],\n });\n }\n\n /** Exposed for testing. */\n async checkBrowserRequestAsync(req: ServerRequest, res: ServerResponse, next: ServerNext) {\n if (\n this.platformBundlers.web === 'metro' &&\n this.initialProjectConfig.exp.platforms?.includes('web')\n ) {\n // NOTE(EvanBacon): This effectively disables the safety check we do on custom runtimes to ensure\n // the `expo-platform` header is included. When `web.bundler=web`, if the user has non-standard Expo\n // code loading then they'll get a web bundle without a clear assertion of platform support.\n const platform = parsePlatformHeader(req);\n // On web, serve the public folder\n if (!platform || platform === 'web') {\n if (['static', 'server'].includes(this.initialProjectConfig.exp.web?.output ?? '')) {\n // Skip the spa-styled index.html when static generation is enabled.\n next();\n return true;\n } else {\n await this.handleWebRequestAsync(req, res);\n return true;\n }\n }\n }\n return false;\n }\n\n async handleRequestAsync(\n req: ServerRequest,\n res: ServerResponse,\n next: ServerNext\n ): Promise<void> {\n // First check for standard JavaScript runtimes (aka legacy browsers like Chrome).\n if (await this.checkBrowserRequestAsync(req, res, next)) {\n return;\n }\n\n // Save device IDs for dev client.\n await this.saveDevicesAsync(req);\n\n // Read from headers\n const options = this.getParsedHeaders(req);\n\n const response = await this._getManifestResponseAsync(options);\n await respond(res, response);\n }\n}\n"],"names":["DEVELOPER_TOOL","ManifestMiddleware","debug","require","ExpoMiddleware","projectRoot","options","initialProjectConfig","getConfig","platformBundlers","getPlatformBundlers","exp","_resolveProjectSettingsAsync","platform","hostname","protocol","projectConfig","mainModuleName","resolveMainModuleName","pkg","isHermesEnabled","isEnableHermesManaged","user","getUserAsync","username","getActorDisplayName","expoGoConfig","getExpoGoConfig","undefined","hostUri","constructUrl","scheme","bundleUrl","_getBundleUrl","engine","baseUrl","getBaseUrlFromExpoConfig","asyncRoutes","getAsyncRoutesFromExpoConfig","mode","routerRoot","getRouterDirectoryModuleIdWithManifest","reactCompiler","experiments","mutateManifestWithAssetsAsync","props","isNativeWebpack","entry","resolveRelativeEntryPoint","saveDevicesAsync","req","deviceIds","headers","ProjectDevices","catch","e","Log","exception","isExporting","path","createBundleUrlPath","minify","lazy","env","EXPO_NO_METRO_LAZY","bytecode","debuggerHost","developer","tool","packagerOpts","dev","manifest","resolveManifestAssets","resolver","resolve","match","resolveGoogleServicesFile","getWebBundleUrl","createBundleUrlPathFromExpoConfig","handleWebRequestAsync","res","setHeader","end","getSingleHtmlTemplateAsync","createTemplateHtmlFromExpoConfigAsync","scripts","checkBrowserRequestAsync","next","web","platforms","includes","parsePlatformHeader","output","handleRequestAsync","getParsedHeaders","response","_getManifestResponseAsync","respond"],"mappings":"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"}
|
package/build/src/utils/qr.js
CHANGED
|
@@ -89,10 +89,8 @@ function printQRCode(url) {
|
|
|
89
89
|
}
|
|
90
90
|
const isGhostty = process.env.TERM_PROGRAM === 'ghostty';
|
|
91
91
|
const isWezterm = process.env.TERM_PROGRAM === 'WezTerm';
|
|
92
|
-
// NOTE(@kitten): Zed regressed on rendering sextants
|
|
93
|
-
const isZed = process.env.TERM_PROGRAM === 'zed';
|
|
94
92
|
const isKitty = !!((_process_env_KITTY_WINDOW_ID = process.env.KITTY_WINDOW_ID) == null ? void 0 : _process_env_KITTY_WINDOW_ID.length);
|
|
95
|
-
const isAlacritty = !!((_process_env_ALACRITTY_WINDOW_ID = process.env.ALACRITTY_WINDOW_ID) == null ? void 0 : _process_env_ALACRITTY_WINDOW_ID.length)
|
|
93
|
+
const isAlacritty = !!((_process_env_ALACRITTY_WINDOW_ID = process.env.ALACRITTY_WINDOW_ID) == null ? void 0 : _process_env_ALACRITTY_WINDOW_ID.length);
|
|
96
94
|
return isGhostty || isWezterm || isKitty || isAlacritty;
|
|
97
95
|
}
|
|
98
96
|
/** ANSI QR code output by using half-blocks (1x2-sized unicode blocks) */ function createHalfblockOutput(data) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/qr.ts"],"sourcesContent":["import tty from 'node:tty';\nimport { toQR } from 'toqr';\n\nimport { env } from './env';\nimport * as Log from '../log';\n\nexport interface QROutput {\n lines: number;\n print(): void;\n}\n\n/** Print the world famous 'Expo QR Code'. */\nexport function printQRCode(url: string): QROutput {\n const qr = toQR(url);\n const output = supportsSextants() ? createSextantOutput(qr) : createHalfblockOutput(qr);\n return {\n lines: output.split('\\n').length,\n print() {\n Log.log(output);\n },\n };\n}\n\n/** On specific terminals we can print a smaller QR code */\nfunction supportsSextants() {\n if (env.CI || !tty.isatty(1) || !tty.isatty(2)) {\n return false;\n } else if (process.env.COLOR === '0' || process.env.COLOR === 'false') {\n return false;\n }\n const isGhostty = process.env.TERM_PROGRAM === 'ghostty';\n const isWezterm = process.env.TERM_PROGRAM === 'WezTerm';\n
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/qr.ts"],"sourcesContent":["import tty from 'node:tty';\nimport { toQR } from 'toqr';\n\nimport { env } from './env';\nimport * as Log from '../log';\n\nexport interface QROutput {\n lines: number;\n print(): void;\n}\n\n/** Print the world famous 'Expo QR Code'. */\nexport function printQRCode(url: string): QROutput {\n const qr = toQR(url);\n const output = supportsSextants() ? createSextantOutput(qr) : createHalfblockOutput(qr);\n return {\n lines: output.split('\\n').length,\n print() {\n Log.log(output);\n },\n };\n}\n\n/** On specific terminals we can print a smaller QR code */\nfunction supportsSextants() {\n if (env.CI || !tty.isatty(1) || !tty.isatty(2)) {\n return false;\n } else if (process.env.COLOR === '0' || process.env.COLOR === 'false') {\n return false;\n }\n const isGhostty = process.env.TERM_PROGRAM === 'ghostty';\n const isWezterm = process.env.TERM_PROGRAM === 'WezTerm';\n const isKitty = !!process.env.KITTY_WINDOW_ID?.length;\n const isAlacritty = !!process.env.ALACRITTY_WINDOW_ID?.length;\n return isGhostty || isWezterm || isKitty || isAlacritty;\n}\n\n/** ANSI QR code output by using half-blocks (1x2-sized unicode blocks) */\nfunction createHalfblockOutput(data: Uint8Array): string {\n const extent = Math.sqrt(data.byteLength) | 0;\n const CHAR_00 = '\\u2588';\n const CHAR_10 = '\\u2584';\n const CHAR_01 = '\\u2580';\n const CHAR_11 = ' ';\n let output = '';\n output += CHAR_10.repeat(extent + 2);\n for (let row = 0; row < extent; row += 2) {\n output += '\\n' + CHAR_00;\n for (let col = 0; col < extent; col++) {\n const value = (data[row * extent + col]! << 1) | data[(row + 1) * extent + col]!;\n switch (value) {\n case 0b00:\n output += CHAR_00;\n break;\n case 0b01:\n output += CHAR_01;\n break;\n case 0b10:\n output += CHAR_10;\n break;\n case 0b11:\n output += CHAR_11;\n break;\n }\n }\n output += CHAR_00;\n }\n if (extent % 2 === 0) {\n output += '\\n' + CHAR_01.repeat(extent + 2);\n }\n output += '\\n';\n return output;\n}\n\n/** ANSI QR code output by using sextant-blocks (2x3-sized unicode blocks) */\nfunction createSextantOutput(data: Uint8Array): string {\n const getChar = (p: number): string => {\n // Invert then reverse\n let char = p ^ 0b111111;\n char = ((char & 0xaa) >> 1) | ((char & 0x55) << 1);\n char = ((char & 0xcc) >> 2) | ((char & 0x33) << 2);\n char = (char >> 4) | (char << 4);\n char = (char >> 2) & 63;\n switch (char) {\n case 0:\n return ' ';\n case 63:\n return '\\u2588';\n case 21:\n return '\\u258C';\n case 42:\n return '\\u2590';\n default:\n return String.fromCodePoint(0x1fb00 + char - 1 - (char > 21 ? 1 : 0) - (char > 42 ? 1 : 0));\n }\n };\n const extent = Math.sqrt(data.byteLength) | 0;\n const padded = extent + 2;\n let output = '';\n for (let baseRow = 0; baseRow < padded; baseRow += 3) {\n if (baseRow) output += '\\n';\n for (let baseCol = 0; baseCol < padded; baseCol += 2) {\n let p = 0;\n for (let dr = 0; dr < 3; dr++) {\n for (let dc = 0; dc < 2; dc++) {\n const r = baseRow + dr;\n const c = baseCol + dc;\n const bit = 5 - (dr * 2 + dc);\n let cell = 1; // default empty (out of bounds)\n if (r < padded && c < padded) {\n if (r === 0 || c === 0 || r === padded - 1 || c === padded - 1) {\n cell = 0; // border is filled\n } else if (r <= extent && c <= extent) {\n cell = data[(r - 1) * extent + (c - 1)]!;\n }\n }\n p |= (cell & 1) << bit;\n }\n }\n output += getChar(p);\n }\n }\n if (padded % 3 === 0) {\n // Only add newline if the padded output lines up with a newline exactly\n output += '\\n';\n }\n return output;\n}\n"],"names":["printQRCode","url","qr","toQR","output","supportsSextants","createSextantOutput","createHalfblockOutput","lines","split","length","print","Log","log","process","env","CI","tty","isatty","COLOR","isGhostty","TERM_PROGRAM","isWezterm","isKitty","KITTY_WINDOW_ID","isAlacritty","ALACRITTY_WINDOW_ID","data","extent","Math","sqrt","byteLength","CHAR_00","CHAR_10","CHAR_01","CHAR_11","repeat","row","col","value","getChar","p","char","String","fromCodePoint","padded","baseRow","baseCol","dr","dc","r","c","bit","cell"],"mappings":";;;;+BAYgBA;;;eAAAA;;;;gEAZA;;;;;;;yBACK;;;;;;qBAED;6DACC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQd,SAASA,YAAYC,GAAW;IACrC,MAAMC,KAAKC,IAAAA,YAAI,EAACF;IAChB,MAAMG,SAASC,qBAAqBC,oBAAoBJ,MAAMK,sBAAsBL;IACpF,OAAO;QACLM,OAAOJ,OAAOK,KAAK,CAAC,MAAMC,MAAM;QAChCC;YACEC,KAAIC,GAAG,CAACT;QACV;IACF;AACF;AAEA,yDAAyD,GACzD,SAASC;QAQWS,8BACIA;IARtB,IAAIC,QAAG,CAACC,EAAE,IAAI,CAACC,kBAAG,CAACC,MAAM,CAAC,MAAM,CAACD,kBAAG,CAACC,MAAM,CAAC,IAAI;QAC9C,OAAO;IACT,OAAO,IAAIJ,QAAQC,GAAG,CAACI,KAAK,KAAK,OAAOL,QAAQC,GAAG,CAACI,KAAK,KAAK,SAAS;QACrE,OAAO;IACT;IACA,MAAMC,YAAYN,QAAQC,GAAG,CAACM,YAAY,KAAK;IAC/C,MAAMC,YAAYR,QAAQC,GAAG,CAACM,YAAY,KAAK;IAC/C,MAAME,UAAU,CAAC,GAACT,+BAAAA,QAAQC,GAAG,CAACS,eAAe,qBAA3BV,6BAA6BJ,MAAM;IACrD,MAAMe,cAAc,CAAC,GAACX,mCAAAA,QAAQC,GAAG,CAACW,mBAAmB,qBAA/BZ,iCAAiCJ,MAAM;IAC7D,OAAOU,aAAaE,aAAaC,WAAWE;AAC9C;AAEA,wEAAwE,GACxE,SAASlB,sBAAsBoB,IAAgB;IAC7C,MAAMC,SAASC,KAAKC,IAAI,CAACH,KAAKI,UAAU,IAAI;IAC5C,MAAMC,UAAU;IAChB,MAAMC,UAAU;IAChB,MAAMC,UAAU;IAChB,MAAMC,UAAU;IAChB,IAAI/B,SAAS;IACbA,UAAU6B,QAAQG,MAAM,CAACR,SAAS;IAClC,IAAK,IAAIS,MAAM,GAAGA,MAAMT,QAAQS,OAAO,EAAG;QACxCjC,UAAU,OAAO4B;QACjB,IAAK,IAAIM,MAAM,GAAGA,MAAMV,QAAQU,MAAO;YACrC,MAAMC,QAAQ,AAACZ,IAAI,CAACU,MAAMT,SAASU,IAAI,IAAK,IAAKX,IAAI,CAAC,AAACU,CAAAA,MAAM,CAAA,IAAKT,SAASU,IAAI;YAC/E,OAAQC;gBACN,KAAK;oBACHnC,UAAU4B;oBACV;gBACF,KAAK;oBACH5B,UAAU8B;oBACV;gBACF,KAAK;oBACH9B,UAAU6B;oBACV;gBACF,KAAK;oBACH7B,UAAU+B;oBACV;YACJ;QACF;QACA/B,UAAU4B;IACZ;IACA,IAAIJ,SAAS,MAAM,GAAG;QACpBxB,UAAU,OAAO8B,QAAQE,MAAM,CAACR,SAAS;IAC3C;IACAxB,UAAU;IACV,OAAOA;AACT;AAEA,2EAA2E,GAC3E,SAASE,oBAAoBqB,IAAgB;IAC3C,MAAMa,UAAU,CAACC;QACf,sBAAsB;QACtB,IAAIC,OAAOD,IAAI;QACfC,OAAO,AAAEA,CAAAA,OAAO,IAAG,KAAM,IAAM,AAACA,CAAAA,OAAO,IAAG,KAAM;QAChDA,OAAO,AAAEA,CAAAA,OAAO,IAAG,KAAM,IAAM,AAACA,CAAAA,OAAO,IAAG,KAAM;QAChDA,OAAO,AAACA,QAAQ,IAAMA,QAAQ;QAC9BA,OAAO,AAACA,QAAQ,IAAK;QACrB,OAAQA;YACN,KAAK;gBACH,OAAO;YACT,KAAK;gBACH,OAAO;YACT,KAAK;gBACH,OAAO;YACT,KAAK;gBACH,OAAO;YACT;gBACE,OAAOC,OAAOC,aAAa,CAAC,UAAUF,OAAO,IAAKA,CAAAA,OAAO,KAAK,IAAI,CAAA,IAAMA,CAAAA,OAAO,KAAK,IAAI,CAAA;QAC5F;IACF;IACA,MAAMd,SAASC,KAAKC,IAAI,CAACH,KAAKI,UAAU,IAAI;IAC5C,MAAMc,SAASjB,SAAS;IACxB,IAAIxB,SAAS;IACb,IAAK,IAAI0C,UAAU,GAAGA,UAAUD,QAAQC,WAAW,EAAG;QACpD,IAAIA,SAAS1C,UAAU;QACvB,IAAK,IAAI2C,UAAU,GAAGA,UAAUF,QAAQE,WAAW,EAAG;YACpD,IAAIN,IAAI;YACR,IAAK,IAAIO,KAAK,GAAGA,KAAK,GAAGA,KAAM;gBAC7B,IAAK,IAAIC,KAAK,GAAGA,KAAK,GAAGA,KAAM;oBAC7B,MAAMC,IAAIJ,UAAUE;oBACpB,MAAMG,IAAIJ,UAAUE;oBACpB,MAAMG,MAAM,IAAKJ,CAAAA,KAAK,IAAIC,EAAC;oBAC3B,IAAII,OAAO,GAAG,gCAAgC;oBAC9C,IAAIH,IAAIL,UAAUM,IAAIN,QAAQ;wBAC5B,IAAIK,MAAM,KAAKC,MAAM,KAAKD,MAAML,SAAS,KAAKM,MAAMN,SAAS,GAAG;4BAC9DQ,OAAO,GAAG,mBAAmB;wBAC/B,OAAO,IAAIH,KAAKtB,UAAUuB,KAAKvB,QAAQ;4BACrCyB,OAAO1B,IAAI,CAAC,AAACuB,CAAAA,IAAI,CAAA,IAAKtB,SAAUuB,CAAAA,IAAI,CAAA,EAAG;wBACzC;oBACF;oBACAV,KAAK,AAACY,CAAAA,OAAO,CAAA,KAAMD;gBACrB;YACF;YACAhD,UAAUoC,QAAQC;QACpB;IACF;IACA,IAAII,SAAS,MAAM,GAAG;QACpB,wEAAwE;QACxEzC,UAAU;IACZ;IACA,OAAOA;AACT"}
|
|
@@ -26,7 +26,7 @@ class FetchClient {
|
|
|
26
26
|
this.headers = {
|
|
27
27
|
accept: 'application/json',
|
|
28
28
|
'content-type': 'application/json',
|
|
29
|
-
'user-agent': `expo-cli/${"57.0.
|
|
29
|
+
'user-agent': `expo-cli/${"57.0.14"}`,
|
|
30
30
|
authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
|
|
31
31
|
};
|
|
32
32
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/cli",
|
|
3
|
-
"version": "57.0.
|
|
3
|
+
"version": "57.0.14",
|
|
4
4
|
"description": "The Expo CLI",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"bin": {
|
|
@@ -38,21 +38,21 @@
|
|
|
38
38
|
"homepage": "https://github.com/expo/expo/tree/main/packages/@expo/cli",
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@expo/code-signing-certificates": "^0.0.6",
|
|
41
|
-
"@expo/config": "~57.0.
|
|
42
|
-
"@expo/config-plugins": "~57.0.
|
|
41
|
+
"@expo/config": "~57.0.7",
|
|
42
|
+
"@expo/config-plugins": "~57.0.7",
|
|
43
43
|
"@expo/devcert": "^1.2.1",
|
|
44
44
|
"@expo/env": "~2.4.2",
|
|
45
45
|
"@expo/image-utils": "^0.11.4",
|
|
46
|
-
"@expo/inline-modules": "^0.1.
|
|
46
|
+
"@expo/inline-modules": "^0.1.5",
|
|
47
47
|
"@expo/json-file": "^11.0.1",
|
|
48
48
|
"@expo/log-box": "^57.0.2",
|
|
49
49
|
"@expo/metro": "~56.0.0",
|
|
50
|
-
"@expo/metro-config": "~57.0.
|
|
50
|
+
"@expo/metro-config": "~57.0.8",
|
|
51
51
|
"@expo/metro-file-map": "^57.0.1",
|
|
52
52
|
"@expo/osascript": "^2.7.1",
|
|
53
53
|
"@expo/package-manager": "^1.13.1",
|
|
54
54
|
"@expo/plist": "^0.8.1",
|
|
55
|
-
"@expo/prebuild-config": "^57.0.
|
|
55
|
+
"@expo/prebuild-config": "^57.0.11",
|
|
56
56
|
"@expo/require-utils": "^57.0.4",
|
|
57
57
|
"@expo/router-server": "^57.0.5",
|
|
58
58
|
"@expo/schema-utils": "^57.0.2",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"connect": "^3.7.0",
|
|
72
72
|
"debug": "^4.3.4",
|
|
73
73
|
"dnssd-advertise": "^1.1.4",
|
|
74
|
-
"expo-server": "^57.0.
|
|
74
|
+
"expo-server": "^57.0.2",
|
|
75
75
|
"fetch-nodeshim": "^0.4.10",
|
|
76
76
|
"getenv": "^2.0.0",
|
|
77
77
|
"glob": "^13.0.0",
|
|
@@ -156,13 +156,13 @@
|
|
|
156
156
|
"playwright": "^1.59.0",
|
|
157
157
|
"taskr": "^1.1.0",
|
|
158
158
|
"tree-kill": "^1.2.2",
|
|
159
|
-
"
|
|
160
|
-
"expo
|
|
161
|
-
"expo": "57.0.10",
|
|
159
|
+
"expo": "57.0.12",
|
|
160
|
+
"@expo/fingerprint": "0.20.7",
|
|
162
161
|
"expo-module-scripts": "56.0.3",
|
|
163
|
-
"expo-modules-autolinking": "57.0.9"
|
|
162
|
+
"expo-modules-autolinking": "57.0.9",
|
|
163
|
+
"expo-router": "57.0.12"
|
|
164
164
|
},
|
|
165
|
-
"gitHead": "
|
|
165
|
+
"gitHead": "9a08ef16f8abc1788dec0014612be5eeb5dc03af",
|
|
166
166
|
"scripts": {
|
|
167
167
|
"build": "taskr",
|
|
168
168
|
"clean": "expo-module clean",
|