@expo/cli 56.0.5 → 56.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/bin/cli CHANGED
@@ -139,7 +139,7 @@ const args = (0, _arg().default)({
139
139
  });
140
140
  if (args['--version']) {
141
141
  // Version is added in the build script.
142
- console.log("56.0.5");
142
+ console.log("56.0.6");
143
143
  process.exit(0);
144
144
  }
145
145
  if (args['--non-interactive']) {
@@ -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: "56.0.5" ?? 'UNVERSIONED'
79
+ version: "56.0.6" ?? 'UNVERSIONED'
80
80
  };
81
81
  }
82
82
  function getWellKnownTemporaryLogFile(projectRoot, command) {
@@ -9,8 +9,11 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
- get checkDependenciesAsync () {
13
- return checkDependenciesAsync;
12
+ get checkDependencies () {
13
+ return checkDependencies;
14
+ },
15
+ get getDependencyCheckMessage () {
16
+ return getDependencyCheckMessage;
14
17
  },
15
18
  get printDependencyCheckResult () {
16
19
  return printDependencyCheckResult;
@@ -71,7 +74,10 @@ function _interop_require_wildcard(obj, nodeInterop) {
71
74
  }
72
75
  return newObj;
73
76
  }
74
- async function checkDependenciesAsync(projectRoot, exp, pkg) {
77
+ /**
78
+ * Fetch dependency version check results.
79
+ * Returns null if everything is up-to-date.
80
+ */ async function checkDependenciesAsync(projectRoot, exp, pkg) {
75
81
  const incorrectDeps = await (0, _validateDependenciesVersions.getVersionedDependenciesAsync)(projectRoot, exp, pkg);
76
82
  if (incorrectDeps.length === 0) {
77
83
  return null;
@@ -86,12 +92,39 @@ async function checkDependenciesAsync(projectRoot, exp, pkg) {
86
92
  otherCount
87
93
  };
88
94
  }
89
- function printDependencyCheckResult(result) {
90
- if (result.expo) {
91
- _log.warn((0, _chalk().default)`An update for {bold expo} is available: {red ${result.expo.actualVersion}} {dim →} {green ${result.expo.expectedVersionOrRange}}`);
95
+ let _checkDependenciesRef;
96
+ function checkDependencies(projectRoot, exp, pkg) {
97
+ if (_checkDependenciesRef) {
98
+ return _checkDependenciesRef;
92
99
  }
93
- if (result.otherCount > 0) {
94
- _log.warn((0, _chalk().default)`${result.otherCount} other package${result.otherCount === 1 ? '' : 's'} may need updating. Run {bold npx expo install --check} for details.`);
100
+ const ref = {
101
+ result: null,
102
+ promise: Promise.resolve(null)
103
+ };
104
+ ref.promise = checkDependenciesAsync(projectRoot, exp, pkg).then((result)=>{
105
+ ref.result = result;
106
+ return result;
107
+ }, (_error)=>null);
108
+ _checkDependenciesRef = ref;
109
+ return ref;
110
+ }
111
+ function getDependencyCheckMessage(result) {
112
+ if (result == null ? void 0 : result.expo) {
113
+ return [
114
+ _chalk().default.yellow`An update for {bold expo} is available: {red ${result.expo.actualVersion}} {dim →} {green ${result.expo.expectedVersionOrRange}}`,
115
+ _chalk().default.yellow`${result.otherCount} other package${result.otherCount === 1 ? '' : 's'} may need updating. Run {bold npx expo install --check} for details.`
116
+ ];
117
+ } else if (result == null ? void 0 : result.otherCount) {
118
+ return [
119
+ _chalk().default.yellow`${result.otherCount} package${result.otherCount === 1 ? '' : 's'} may need updating. Run {bold npx expo install --check} for details.`
120
+ ];
121
+ } else {
122
+ return [];
123
+ }
124
+ }
125
+ function printDependencyCheckResult(result) {
126
+ for (const line of getDependencyCheckMessage(result)){
127
+ _log.log(line);
95
128
  }
96
129
  }
97
130
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/start/checkDependenciesOnStart.ts"],"sourcesContent":["import type { ExpoConfig, PackageJSONConfig } from '@expo/config';\nimport chalk from 'chalk';\n\nimport * as Log from '../log';\nimport { getVersionedDependenciesAsync } from './doctor/dependencies/validateDependenciesVersions';\n\nexport type DependencyCheckResult = {\n expo?: { actualVersion: string; expectedVersionOrRange: string };\n otherCount: number;\n};\n\n/**\n * Fetch dependency version check results.\n * Returns null if everything is up-to-date.\n */\nexport async function checkDependenciesAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'sdkVersion'>,\n pkg: PackageJSONConfig\n): Promise<DependencyCheckResult | null> {\n const incorrectDeps = await getVersionedDependenciesAsync(projectRoot, exp, pkg);\n if (incorrectDeps.length === 0) {\n return null;\n }\n\n const expoDep = incorrectDeps.find((dep) => dep.packageName === 'expo');\n const otherCount = incorrectDeps.filter((dep) => dep.packageName !== 'expo').length;\n\n return {\n expo: expoDep\n ? {\n actualVersion: expoDep.actualVersion,\n expectedVersionOrRange: expoDep.expectedVersionOrRange,\n }\n : undefined,\n otherCount,\n };\n}\n\n/** Print the condensed dependency check messages to the terminal. */\nexport function printDependencyCheckResult(result: DependencyCheckResult): void {\n if (result.expo) {\n Log.warn(\n chalk`An update for {bold expo} is available: {red ${result.expo.actualVersion}} {dim →} {green ${result.expo.expectedVersionOrRange}}`\n );\n }\n if (result.otherCount > 0) {\n Log.warn(\n chalk`${result.otherCount} other package${result.otherCount === 1 ? '' : 's'} may need updating. Run {bold npx expo install --check} for details.`\n );\n }\n}\n"],"names":["checkDependenciesAsync","printDependencyCheckResult","projectRoot","exp","pkg","incorrectDeps","getVersionedDependenciesAsync","length","expoDep","find","dep","packageName","otherCount","filter","expo","actualVersion","expectedVersionOrRange","undefined","result","Log","warn","chalk"],"mappings":";;;;;;;;;;;QAesBA;eAAAA;;QAyBNC;eAAAA;;;;gEAvCE;;;;;;6DAEG;8CACyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWvC,eAAeD,uBACpBE,WAAmB,EACnBC,GAAmC,EACnCC,GAAsB;IAEtB,MAAMC,gBAAgB,MAAMC,IAAAA,2DAA6B,EAACJ,aAAaC,KAAKC;IAC5E,IAAIC,cAAcE,MAAM,KAAK,GAAG;QAC9B,OAAO;IACT;IAEA,MAAMC,UAAUH,cAAcI,IAAI,CAAC,CAACC,MAAQA,IAAIC,WAAW,KAAK;IAChE,MAAMC,aAAaP,cAAcQ,MAAM,CAAC,CAACH,MAAQA,IAAIC,WAAW,KAAK,QAAQJ,MAAM;IAEnF,OAAO;QACLO,MAAMN,UACF;YACEO,eAAeP,QAAQO,aAAa;YACpCC,wBAAwBR,QAAQQ,sBAAsB;QACxD,IACAC;QACJL;IACF;AACF;AAGO,SAASX,2BAA2BiB,MAA6B;IACtE,IAAIA,OAAOJ,IAAI,EAAE;QACfK,KAAIC,IAAI,CACNC,IAAAA,gBAAK,CAAA,CAAC,6CAA6C,EAAEH,OAAOJ,IAAI,CAACC,aAAa,CAAC,iBAAiB,EAAEG,OAAOJ,IAAI,CAACE,sBAAsB,CAAC,CAAC,CAAC;IAE3I;IACA,IAAIE,OAAON,UAAU,GAAG,GAAG;QACzBO,KAAIC,IAAI,CACNC,IAAAA,gBAAK,CAAA,CAAC,EAAEH,OAAON,UAAU,CAAC,cAAc,EAAEM,OAAON,UAAU,KAAK,IAAI,KAAK,IAAI,oEAAoE,CAAC;IAEtJ;AACF"}
1
+ {"version":3,"sources":["../../../src/start/checkDependenciesOnStart.ts"],"sourcesContent":["import type { ExpoConfig, PackageJSONConfig } from '@expo/config';\nimport chalk from 'chalk';\n\nimport * as Log from '../log';\nimport { getVersionedDependenciesAsync } from './doctor/dependencies/validateDependenciesVersions';\n\nexport interface DependencyCheckResult {\n expo?: { actualVersion: string; expectedVersionOrRange: string };\n otherCount: number;\n}\n\nexport interface DependencyCheckRef {\n result: DependencyCheckResult | null;\n promise: Promise<DependencyCheckResult | null>;\n}\n\n/**\n * Fetch dependency version check results.\n * Returns null if everything is up-to-date.\n */\nasync function checkDependenciesAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'sdkVersion'>,\n pkg: PackageJSONConfig\n): Promise<DependencyCheckResult | null> {\n const incorrectDeps = await getVersionedDependenciesAsync(projectRoot, exp, pkg);\n if (incorrectDeps.length === 0) {\n return null;\n }\n\n const expoDep = incorrectDeps.find((dep) => dep.packageName === 'expo');\n const otherCount = incorrectDeps.filter((dep) => dep.packageName !== 'expo').length;\n\n return {\n expo: expoDep\n ? {\n actualVersion: expoDep.actualVersion,\n expectedVersionOrRange: expoDep.expectedVersionOrRange,\n }\n : undefined,\n otherCount,\n };\n}\n\nlet _checkDependenciesRef: DependencyCheckRef | undefined;\n\nexport function checkDependencies(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'sdkVersion'>,\n pkg: PackageJSONConfig\n) {\n if (_checkDependenciesRef) {\n return _checkDependenciesRef;\n }\n\n const ref: DependencyCheckRef = {\n result: null,\n promise: Promise.resolve(null),\n };\n\n ref.promise = checkDependenciesAsync(projectRoot, exp, pkg).then(\n (result) => {\n ref.result = result;\n return result;\n },\n (_error) => null\n );\n\n _checkDependenciesRef = ref;\n return ref;\n}\n\n/** Print the condensed dependency check messages to the terminal. */\nexport function getDependencyCheckMessage(\n result: DependencyCheckResult | null | undefined\n): string[] {\n if (result?.expo) {\n return [\n chalk.yellow`An update for {bold expo} is available: {red ${result.expo.actualVersion}} {dim →} {green ${result.expo.expectedVersionOrRange}}`,\n chalk.yellow`${result.otherCount} other package${result.otherCount === 1 ? '' : 's'} may need updating. Run {bold npx expo install --check} for details.`,\n ];\n } else if (result?.otherCount) {\n return [\n chalk.yellow`${result.otherCount} package${result.otherCount === 1 ? '' : 's'} may need updating. Run {bold npx expo install --check} for details.`,\n ];\n } else {\n return [];\n }\n}\n\n/** Print the condensed dependency check messages to the terminal. */\nexport function printDependencyCheckResult(result: DependencyCheckResult): void {\n for (const line of getDependencyCheckMessage(result)) {\n Log.log(line);\n }\n}\n"],"names":["checkDependencies","getDependencyCheckMessage","printDependencyCheckResult","checkDependenciesAsync","projectRoot","exp","pkg","incorrectDeps","getVersionedDependenciesAsync","length","expoDep","find","dep","packageName","otherCount","filter","expo","actualVersion","expectedVersionOrRange","undefined","_checkDependenciesRef","ref","result","promise","Promise","resolve","then","_error","chalk","yellow","line","Log","log"],"mappings":";;;;;;;;;;;QA8CgBA;eAAAA;;QA2BAC;eAAAA;;QAkBAC;eAAAA;;;;gEA1FE;;;;;;6DAEG;8CACyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAY9C;;;CAGC,GACD,eAAeC,uBACbC,WAAmB,EACnBC,GAAmC,EACnCC,GAAsB;IAEtB,MAAMC,gBAAgB,MAAMC,IAAAA,2DAA6B,EAACJ,aAAaC,KAAKC;IAC5E,IAAIC,cAAcE,MAAM,KAAK,GAAG;QAC9B,OAAO;IACT;IAEA,MAAMC,UAAUH,cAAcI,IAAI,CAAC,CAACC,MAAQA,IAAIC,WAAW,KAAK;IAChE,MAAMC,aAAaP,cAAcQ,MAAM,CAAC,CAACH,MAAQA,IAAIC,WAAW,KAAK,QAAQJ,MAAM;IAEnF,OAAO;QACLO,MAAMN,UACF;YACEO,eAAeP,QAAQO,aAAa;YACpCC,wBAAwBR,QAAQQ,sBAAsB;QACxD,IACAC;QACJL;IACF;AACF;AAEA,IAAIM;AAEG,SAASpB,kBACdI,WAAmB,EACnBC,GAAmC,EACnCC,GAAsB;IAEtB,IAAIc,uBAAuB;QACzB,OAAOA;IACT;IAEA,MAAMC,MAA0B;QAC9BC,QAAQ;QACRC,SAASC,QAAQC,OAAO,CAAC;IAC3B;IAEAJ,IAAIE,OAAO,GAAGpB,uBAAuBC,aAAaC,KAAKC,KAAKoB,IAAI,CAC9D,CAACJ;QACCD,IAAIC,MAAM,GAAGA;QACb,OAAOA;IACT,GACA,CAACK,SAAW;IAGdP,wBAAwBC;IACxB,OAAOA;AACT;AAGO,SAASpB,0BACdqB,MAAgD;IAEhD,IAAIA,0BAAAA,OAAQN,IAAI,EAAE;QAChB,OAAO;YACLY,gBAAK,CAACC,MAAM,CAAC,6CAA6C,EAAEP,OAAON,IAAI,CAACC,aAAa,CAAC,iBAAiB,EAAEK,OAAON,IAAI,CAACE,sBAAsB,CAAC,CAAC,CAAC;YAC9IU,gBAAK,CAACC,MAAM,CAAC,EAAEP,OAAOR,UAAU,CAAC,cAAc,EAAEQ,OAAOR,UAAU,KAAK,IAAI,KAAK,IAAI,oEAAoE,CAAC;SAC1J;IACH,OAAO,IAAIQ,0BAAAA,OAAQR,UAAU,EAAE;QAC7B,OAAO;YACLc,gBAAK,CAACC,MAAM,CAAC,EAAEP,OAAOR,UAAU,CAAC,QAAQ,EAAEQ,OAAOR,UAAU,KAAK,IAAI,KAAK,IAAI,oEAAoE,CAAC;SACpJ;IACH,OAAO;QACL,OAAO,EAAE;IACX;AACF;AAGO,SAASZ,2BAA2BoB,MAA6B;IACtE,KAAK,MAAMQ,QAAQ7B,0BAA0BqB,QAAS;QACpDS,KAAIC,GAAG,CAACF;IACV;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/interface/commandsTable.ts"],"sourcesContent":["import type { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport wrapAnsi from 'wrap-ansi';\n\nimport * as Log from '../../log';\nimport type { DependencyCheckResult } from '../checkDependenciesOnStart';\nimport type { McpServer } from '../server/MCP';\n\n// Approximately how many rows apart from the commands table (usage guide on `expo start`)\n// will be printed after the QR code? The `rows` input doesn't account for all of them,\n// so we add our best guess instead.\nconst RESERVED_ROWS = 6;\n\nexport const BLT = '\\u203A';\n\nexport type StartOptions = {\n isWebSocketsEnabled?: boolean;\n devClient?: boolean;\n reset?: boolean;\n nonPersistent?: boolean;\n maxWorkers?: number;\n platforms?: ExpoConfig['platforms'];\n mcpServer?: McpServer;\n dependencyCheckPromise?: Promise<DependencyCheckResult | null>;\n};\n\nexport const printHelp = (): void => {\n logCommandsTable([{ key: '?', msg: 'show all commands' }]).print();\n};\n\nexport const getTerminalColumns = () => process.stdout.columns || 80;\n\nexport const printItem = (text: string, opts?: { dim: boolean }): string => {\n let output = `${BLT} ` + wrapAnsi(text, getTerminalColumns()).trimStart();\n if (opts?.dim) {\n output = chalk`{dim ${output}}`;\n }\n return output;\n};\n\nexport function printUsage(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>,\n { verbose, rows }: { verbose: boolean; rows?: number }\n) {\n const isMac = process.platform === 'darwin';\n\n const { platforms = ['ios', 'android', 'web'] } = options;\n\n const isAndroidDisabled = !platforms.includes('android');\n const isIosDisabled = !platforms.includes('ios');\n const isWebDisable = !platforms.includes('web');\n\n const switchMsg = `switch to ${options.devClient === false ? 'development build' : 'Expo Go'}`;\n const target = options.devClient === false ? `Expo Go` : 'development build';\n\n const printPrefix = ({ short }: { short: boolean }) => {\n Log.log();\n let message = chalk`Using {cyan ${target}}`;\n if (!short) {\n message += chalk` {dim (Press {bold s} to ${switchMsg})}`;\n }\n Log.log(printItem(message));\n };\n\n if (verbose) {\n printPrefix({ short: true });\n return logCommandsTable([\n { key: 's', msg: switchMsg },\n {},\n { key: 'a', msg: 'open Android', disabled: isAndroidDisabled },\n { key: 'shift+a', msg: 'select an Android device or emulator', disabled: isAndroidDisabled },\n isMac && { key: 'i', msg: 'open iOS simulator', disabled: isIosDisabled },\n isMac && { key: 'shift+i', msg: 'select an iOS simulator', disabled: isIosDisabled },\n { key: 'w', msg: 'open web', disabled: isWebDisable },\n {},\n { key: 'r', msg: 'reload app' },\n !!options.isWebSocketsEnabled && { key: 'j', msg: 'open debugger' },\n !!options.isWebSocketsEnabled && { key: 'm', msg: 'toggle menu' },\n !!options.isWebSocketsEnabled && { key: 'shift+m', msg: 'more tools' },\n { key: 'o', msg: 'open project code in your editor' },\n { key: 'c', msg: 'show project QR' },\n {},\n ]).print();\n }\n\n const table = logCommandsTable([\n { key: 's', msg: switchMsg },\n {},\n { key: 'a', msg: 'open Android', disabled: isAndroidDisabled },\n isMac && { key: 'i', msg: 'open iOS simulator', disabled: isIosDisabled },\n { key: 'w', msg: 'open web', disabled: isWebDisable },\n {},\n { key: 'j', msg: 'open debugger' },\n { key: 'r', msg: 'reload app' },\n !!options.isWebSocketsEnabled && { key: 'm', msg: 'toggle menu' },\n !!options.isWebSocketsEnabled && { key: 'shift+m', msg: 'more tools' },\n { key: 'o', msg: 'open project code in your editor' },\n {},\n ]);\n\n // If we're not in verbose mode, we check if we have enough space. If we don't, we don't print\n // the full usage guide and rely on the `printHelp()` message being shown instead\n if ((rows || Infinity) - RESERVED_ROWS > table.lines) {\n printPrefix({ short: true });\n table.print();\n } else {\n printPrefix({ short: false });\n }\n}\n\nfunction logCommandsTable(\n ui: (false | { key?: string; msg?: string; status?: string; disabled?: boolean })[]\n) {\n const lines = ui\n .filter((x) => !!x)\n .map(({ key, msg, status, disabled }) => {\n if (!key) return '';\n let view = `${BLT} `;\n if (key.length === 1) view += 'Press ';\n view += chalk`{bold ${key}} {dim │} `;\n view += msg;\n if (status) {\n view += ` ${chalk.dim(`(${chalk.italic(status)})`)}`;\n }\n if (disabled) {\n view = chalk.dim(view);\n }\n return view;\n });\n return {\n lines: lines.length,\n print() {\n Log.log(lines.join('\\n'));\n },\n };\n}\n"],"names":["BLT","getTerminalColumns","printHelp","printItem","printUsage","RESERVED_ROWS","logCommandsTable","key","msg","print","process","stdout","columns","text","opts","output","wrapAnsi","trimStart","dim","chalk","options","verbose","rows","isMac","platform","platforms","isAndroidDisabled","includes","isIosDisabled","isWebDisable","switchMsg","devClient","target","printPrefix","short","Log","log","message","disabled","isWebSocketsEnabled","table","Infinity","lines","ui","filter","x","map","status","view","length","italic","join"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/start/interface/commandsTable.ts"],"sourcesContent":["import type { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport wrapAnsi from 'wrap-ansi';\n\nimport * as Log from '../../log';\nimport type { DependencyCheckRef } from '../checkDependenciesOnStart';\nimport type { McpServer } from '../server/MCP';\n\n// Approximately how many rows apart from the commands table (usage guide on `expo start`)\n// will be printed after the QR code? The `rows` input doesn't account for all of them,\n// so we add our best guess instead.\nconst RESERVED_ROWS = 6;\n\nexport const BLT = '\\u203A';\n\nexport type StartOptions = {\n isWebSocketsEnabled?: boolean;\n devClient?: boolean;\n reset?: boolean;\n nonPersistent?: boolean;\n maxWorkers?: number;\n platforms?: ExpoConfig['platforms'];\n mcpServer?: McpServer;\n dependencyCheckRef?: DependencyCheckRef;\n};\n\nexport const printHelp = (): void => {\n logCommandsTable([{ key: '?', msg: 'show all commands' }]).print();\n};\n\nexport const getTerminalColumns = () => process.stdout.columns || 80;\n\nexport const printItem = (text: string, opts?: { dim: boolean }): string => {\n let output = `${BLT} ` + wrapAnsi(text, getTerminalColumns()).trimStart();\n if (opts?.dim) {\n output = chalk`{dim ${output}}`;\n }\n return output;\n};\n\nexport function printUsage(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>,\n { verbose, rows }: { verbose: boolean; rows?: number }\n) {\n const isMac = process.platform === 'darwin';\n\n const { platforms = ['ios', 'android', 'web'] } = options;\n\n const isAndroidDisabled = !platforms.includes('android');\n const isIosDisabled = !platforms.includes('ios');\n const isWebDisable = !platforms.includes('web');\n\n const switchMsg = `switch to ${options.devClient === false ? 'development build' : 'Expo Go'}`;\n const target = options.devClient === false ? `Expo Go` : 'development build';\n\n const printPrefix = ({ short }: { short: boolean }) => {\n Log.log();\n let message = chalk`Using {cyan ${target}}`;\n if (!short) {\n message += chalk` {dim (Press {bold s} to ${switchMsg})}`;\n }\n Log.log(printItem(message));\n };\n\n if (verbose) {\n printPrefix({ short: true });\n return logCommandsTable([\n { key: 's', msg: switchMsg },\n {},\n { key: 'a', msg: 'open Android', disabled: isAndroidDisabled },\n { key: 'shift+a', msg: 'select an Android device or emulator', disabled: isAndroidDisabled },\n isMac && { key: 'i', msg: 'open iOS simulator', disabled: isIosDisabled },\n isMac && { key: 'shift+i', msg: 'select an iOS simulator', disabled: isIosDisabled },\n { key: 'w', msg: 'open web', disabled: isWebDisable },\n {},\n { key: 'r', msg: 'reload app' },\n !!options.isWebSocketsEnabled && { key: 'j', msg: 'open debugger' },\n !!options.isWebSocketsEnabled && { key: 'm', msg: 'toggle menu' },\n !!options.isWebSocketsEnabled && { key: 'shift+m', msg: 'more tools' },\n { key: 'o', msg: 'open project code in your editor' },\n { key: 'c', msg: 'show project QR' },\n {},\n ]).print();\n }\n\n const table = logCommandsTable([\n { key: 's', msg: switchMsg },\n {},\n { key: 'a', msg: 'open Android', disabled: isAndroidDisabled },\n isMac && { key: 'i', msg: 'open iOS simulator', disabled: isIosDisabled },\n { key: 'w', msg: 'open web', disabled: isWebDisable },\n {},\n { key: 'j', msg: 'open debugger' },\n { key: 'r', msg: 'reload app' },\n !!options.isWebSocketsEnabled && { key: 'm', msg: 'toggle menu' },\n !!options.isWebSocketsEnabled && { key: 'shift+m', msg: 'more tools' },\n { key: 'o', msg: 'open project code in your editor' },\n {},\n ]);\n\n // If we're not in verbose mode, we check if we have enough space. If we don't, we don't print\n // the full usage guide and rely on the `printHelp()` message being shown instead\n if ((rows || Infinity) - RESERVED_ROWS > table.lines) {\n printPrefix({ short: true });\n table.print();\n } else {\n printPrefix({ short: false });\n }\n}\n\nfunction logCommandsTable(\n ui: (false | { key?: string; msg?: string; status?: string; disabled?: boolean })[]\n) {\n const lines = ui\n .filter((x) => !!x)\n .map(({ key, msg, status, disabled }) => {\n if (!key) return '';\n let view = `${BLT} `;\n if (key.length === 1) view += 'Press ';\n view += chalk`{bold ${key}} {dim │} `;\n view += msg;\n if (status) {\n view += ` ${chalk.dim(`(${chalk.italic(status)})`)}`;\n }\n if (disabled) {\n view = chalk.dim(view);\n }\n return view;\n });\n return {\n lines: lines.length,\n print() {\n Log.log(lines.join('\\n'));\n },\n };\n}\n"],"names":["BLT","getTerminalColumns","printHelp","printItem","printUsage","RESERVED_ROWS","logCommandsTable","key","msg","print","process","stdout","columns","text","opts","output","wrapAnsi","trimStart","dim","chalk","options","verbose","rows","isMac","platform","platforms","isAndroidDisabled","includes","isIosDisabled","isWebDisable","switchMsg","devClient","target","printPrefix","short","Log","log","message","disabled","isWebSocketsEnabled","table","Infinity","lines","ui","filter","x","map","status","view","length","italic","join"],"mappings":"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"}
@@ -22,6 +22,7 @@ const _env = require("../../utils/env");
22
22
  const _link = require("../../utils/link");
23
23
  const _prompts = require("../../utils/prompts");
24
24
  const _qr = require("../../utils/qr");
25
+ const _checkDependenciesOnStart = require("../checkDependenciesOnStart");
25
26
  const _JsInspector = require("../server/middleware/inspector/JsInspector");
26
27
  function _interop_require_default(obj) {
27
28
  return obj && obj.__esModule ? obj : {
@@ -76,7 +77,7 @@ class DevServerManagerActions {
76
77
  this.options = options;
77
78
  }
78
79
  printDevServerInfo(options) {
79
- var _this_options_platforms;
80
+ var _this_options_platforms, _options_dependencyCheckRef;
80
81
  // Keep track of approximately how much space we have to print our usage guide
81
82
  let rows = process.stdout.rows || Infinity;
82
83
  // If native dev server is running, print its URL.
@@ -137,12 +138,17 @@ class DevServerManagerActions {
137
138
  rows--;
138
139
  }
139
140
  }
141
+ const dependencyCheckLines = (0, _checkDependenciesOnStart.getDependencyCheckMessage)((_options_dependencyCheckRef = options.dependencyCheckRef) == null ? void 0 : _options_dependencyCheckRef.result);
142
+ rows -= dependencyCheckLines.length;
140
143
  (0, _commandsTable.printUsage)(options, {
141
144
  verbose: false,
142
145
  rows
143
146
  });
144
147
  (0, _commandsTable.printHelp)();
145
148
  _log.log();
149
+ for (const line of dependencyCheckLines){
150
+ _log.log(line);
151
+ }
146
152
  }
147
153
  async openJsInspectorAsync() {
148
154
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/interface/interactiveActions.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport type { StartOptions } from './commandsTable';\nimport { BLT, printHelp, printItem, printUsage } from './commandsTable';\nimport { createDevToolsMenuItems } from './createDevToolsMenuItems';\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { learnMore } from '../../utils/link';\nimport type { ExpoChoice } from '../../utils/prompts';\nimport { selectAsync } from '../../utils/prompts';\nimport { printQRCode } from '../../utils/qr';\nimport type { DevServerManager } from '../server/DevServerManager';\nimport {\n openJsInspector,\n queryAllInspectorAppsAsync,\n promptInspectorAppAsync,\n} from '../server/middleware/inspector/JsInspector';\n\nconst debug = require('debug')('expo:start:interface:interactiveActions') as typeof console.log;\n\ninterface MoreToolMenuItem extends ExpoChoice<string> {\n action?: () => unknown;\n}\n\n/** Wraps the DevServerManager and adds an interface for user actions. */\nexport class DevServerManagerActions {\n constructor(\n private devServerManager: DevServerManager,\n private options: Pick<StartOptions, 'devClient' | 'platforms'>\n ) {}\n\n printDevServerInfo(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>\n ) {\n // Keep track of approximately how much space we have to print our usage guide\n let rows = process.stdout.rows || Infinity;\n\n // If native dev server is running, print its URL.\n if (this.devServerManager.getNativeDevServerPort()) {\n const devServer = this.devServerManager.getDefaultDevServer();\n try {\n const nativeRuntimeUrl = devServer.getNativeRuntimeUrl()!;\n const interstitialPageUrl = devServer.getRedirectUrl();\n\n // Print the URL to stdout for tests\n if (env.__EXPO_E2E_TEST) {\n console.info(\n `[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: devServer.getDevServerUrl() })}`\n );\n rows--;\n }\n\n if (!env.EXPO_NO_QR_CODE) {\n const qr = printQRCode(interstitialPageUrl ?? nativeRuntimeUrl);\n rows -= qr.lines;\n qr.print();\n\n let qrMessage = '';\n if (!options.devClient) {\n qrMessage = `Scan the QR code above to open in ${chalk`{bold Expo Go}`}.`;\n } else {\n qrMessage = chalk`Scan the QR code above to open in a {bold development build}.`;\n qrMessage += ` (${learnMore('https://expo.fyi/start')})`;\n }\n rows--;\n Log.log(printItem(qrMessage, { dim: true }));\n }\n\n if (interstitialPageUrl) {\n rows--;\n Log.log(\n printItem(\n chalk`Choose an app to open your project at {underline ${interstitialPageUrl}}`\n )\n );\n }\n\n rows--;\n Log.log(printItem(chalk`Metro: {underline ${nativeRuntimeUrl}}`));\n } catch (error) {\n console.log('err', error);\n // @ts-ignore: If there is no development build scheme, then skip the QR code.\n if (error.code !== 'NO_DEV_CLIENT_SCHEME') {\n throw error;\n } else {\n const serverUrl = devServer.getDevServerUrl();\n Log.log(printItem(chalk`Metro: {underline ${serverUrl}}`));\n Log.log(printItem(`Linking is disabled because the client scheme cannot be resolved.`));\n rows -= 2;\n }\n }\n }\n\n if (this.options.platforms?.includes('web')) {\n const webDevServer = this.devServerManager.getWebDevServer();\n const webUrl = webDevServer?.getDevServerUrl({ hostType: 'localhost' });\n if (webUrl) {\n Log.log(printItem(chalk`Web: {underline ${webUrl}}`));\n rows--;\n }\n }\n\n printUsage(options, { verbose: false, rows });\n printHelp();\n Log.log();\n }\n\n async openJsInspectorAsync() {\n try {\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const apps = await queryAllInspectorAppsAsync(metroServerOrigin);\n if (!apps.length) {\n return Log.warn(\n chalk`{bold Debug:} No compatible apps connected, React Native DevTools can only be used with Hermes. ${learnMore(\n 'https://docs.expo.dev/guides/using-hermes/'\n )}`\n );\n }\n\n const app = await promptInspectorAppAsync(apps);\n if (!app) {\n return Log.error(chalk`{bold Debug:} No inspectable device selected`);\n }\n\n if (!(await openJsInspector(metroServerOrigin, app))) {\n Log.warn(\n chalk`{bold Debug:} Failed to open the React Native DevTools, see debug logs for more info.`\n );\n }\n } catch (error: any) {\n // Handle aborting prompt\n if (error.code === 'ABORTED') return;\n\n Log.error('Failed to open the React Native DevTools.');\n Log.exception(error);\n }\n }\n\n reloadApp() {\n Log.log(`${BLT} Reloading apps`);\n // Send reload requests over the dev servers\n this.devServerManager.broadcastMessage('reload');\n }\n\n async openMoreToolsAsync() {\n // Options match: Chrome > View > Developer\n try {\n const defaultMenuItems: MoreToolMenuItem[] = [\n { title: 'Inspect elements', value: 'toggleElementInspector' },\n { title: 'Toggle performance monitor', value: 'togglePerformanceMonitor' },\n { title: 'Toggle developer menu', value: 'toggleDevMenu' },\n { title: 'Reload app', value: 'reload' },\n // TODO: Maybe a \"View Source\" option to open code.\n ];\n\n const defaultServerUrl = this.devServerManager\n .getDefaultDevServer()\n .getUrlCreator()\n .constructUrl({ scheme: 'http' });\n\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const plugins = await this.devServerManager.devtoolsPluginManager.queryPluginsAsync();\n\n const menuItems = [\n ...defaultMenuItems,\n ...createDevToolsMenuItems(plugins, defaultServerUrl, metroServerOrigin),\n ];\n\n const value = await selectAsync(chalk`Dev tools {dim (native only)}`, menuItems);\n const menuItem = menuItems.find((item) => item.value === value);\n if (menuItem?.action) {\n menuItem.action();\n } else if (menuItem?.value) {\n this.devServerManager.broadcastMessage('sendDevCommand', { name: menuItem.value });\n }\n } catch (error: any) {\n debug(error);\n // do nothing\n } finally {\n printHelp();\n }\n }\n\n toggleDevMenu() {\n Log.log(`${BLT} Toggling dev menu`);\n this.devServerManager.broadcastMessage('devMenu');\n }\n}\n"],"names":["DevServerManagerActions","debug","require","devServerManager","options","printDevServerInfo","rows","process","stdout","Infinity","getNativeDevServerPort","devServer","getDefaultDevServer","nativeRuntimeUrl","getNativeRuntimeUrl","interstitialPageUrl","getRedirectUrl","env","__EXPO_E2E_TEST","console","info","JSON","stringify","url","getDevServerUrl","EXPO_NO_QR_CODE","qr","printQRCode","lines","print","qrMessage","devClient","chalk","learnMore","Log","log","printItem","dim","error","code","serverUrl","platforms","includes","webDevServer","getWebDevServer","webUrl","hostType","printUsage","verbose","printHelp","openJsInspectorAsync","metroServerOrigin","getJsInspectorBaseUrl","apps","queryAllInspectorAppsAsync","length","warn","app","promptInspectorAppAsync","openJsInspector","exception","reloadApp","BLT","broadcastMessage","openMoreToolsAsync","defaultMenuItems","title","value","defaultServerUrl","getUrlCreator","constructUrl","scheme","plugins","devtoolsPluginManager","queryPluginsAsync","menuItems","createDevToolsMenuItems","selectAsync","menuItem","find","item","action","name","toggleDevMenu"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/start/interface/interactiveActions.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport type { StartOptions } from './commandsTable';\nimport { BLT, printHelp, printItem, printUsage } from './commandsTable';\nimport { createDevToolsMenuItems } from './createDevToolsMenuItems';\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { learnMore } from '../../utils/link';\nimport type { ExpoChoice } from '../../utils/prompts';\nimport { selectAsync } from '../../utils/prompts';\nimport { printQRCode } from '../../utils/qr';\nimport { getDependencyCheckMessage } from '../checkDependenciesOnStart';\nimport type { DevServerManager } from '../server/DevServerManager';\nimport {\n openJsInspector,\n queryAllInspectorAppsAsync,\n promptInspectorAppAsync,\n} from '../server/middleware/inspector/JsInspector';\n\nconst debug = require('debug')('expo:start:interface:interactiveActions') as typeof console.log;\n\ninterface MoreToolMenuItem extends ExpoChoice<string> {\n action?: () => unknown;\n}\n\n/** Wraps the DevServerManager and adds an interface for user actions. */\nexport class DevServerManagerActions {\n constructor(\n private devServerManager: DevServerManager,\n private options: Pick<StartOptions, 'devClient' | 'platforms'>\n ) {}\n\n printDevServerInfo(\n options: Pick<\n StartOptions,\n 'devClient' | 'isWebSocketsEnabled' | 'platforms' | 'dependencyCheckRef'\n >\n ) {\n // Keep track of approximately how much space we have to print our usage guide\n let rows = process.stdout.rows || Infinity;\n\n // If native dev server is running, print its URL.\n if (this.devServerManager.getNativeDevServerPort()) {\n const devServer = this.devServerManager.getDefaultDevServer();\n try {\n const nativeRuntimeUrl = devServer.getNativeRuntimeUrl()!;\n const interstitialPageUrl = devServer.getRedirectUrl();\n\n // Print the URL to stdout for tests\n if (env.__EXPO_E2E_TEST) {\n console.info(\n `[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: devServer.getDevServerUrl() })}`\n );\n rows--;\n }\n\n if (!env.EXPO_NO_QR_CODE) {\n const qr = printQRCode(interstitialPageUrl ?? nativeRuntimeUrl);\n rows -= qr.lines;\n qr.print();\n\n let qrMessage = '';\n if (!options.devClient) {\n qrMessage = `Scan the QR code above to open in ${chalk`{bold Expo Go}`}.`;\n } else {\n qrMessage = chalk`Scan the QR code above to open in a {bold development build}.`;\n qrMessage += ` (${learnMore('https://expo.fyi/start')})`;\n }\n rows--;\n Log.log(printItem(qrMessage, { dim: true }));\n }\n\n if (interstitialPageUrl) {\n rows--;\n Log.log(\n printItem(\n chalk`Choose an app to open your project at {underline ${interstitialPageUrl}}`\n )\n );\n }\n\n rows--;\n Log.log(printItem(chalk`Metro: {underline ${nativeRuntimeUrl}}`));\n } catch (error) {\n console.log('err', error);\n // @ts-ignore: If there is no development build scheme, then skip the QR code.\n if (error.code !== 'NO_DEV_CLIENT_SCHEME') {\n throw error;\n } else {\n const serverUrl = devServer.getDevServerUrl();\n Log.log(printItem(chalk`Metro: {underline ${serverUrl}}`));\n Log.log(printItem(`Linking is disabled because the client scheme cannot be resolved.`));\n rows -= 2;\n }\n }\n }\n\n if (this.options.platforms?.includes('web')) {\n const webDevServer = this.devServerManager.getWebDevServer();\n const webUrl = webDevServer?.getDevServerUrl({ hostType: 'localhost' });\n if (webUrl) {\n Log.log(printItem(chalk`Web: {underline ${webUrl}}`));\n rows--;\n }\n }\n\n const dependencyCheckLines = getDependencyCheckMessage(options.dependencyCheckRef?.result);\n rows -= dependencyCheckLines.length;\n\n printUsage(options, { verbose: false, rows });\n printHelp();\n Log.log();\n\n for (const line of dependencyCheckLines) {\n Log.log(line);\n }\n }\n\n async openJsInspectorAsync() {\n try {\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const apps = await queryAllInspectorAppsAsync(metroServerOrigin);\n if (!apps.length) {\n return Log.warn(\n chalk`{bold Debug:} No compatible apps connected, React Native DevTools can only be used with Hermes. ${learnMore(\n 'https://docs.expo.dev/guides/using-hermes/'\n )}`\n );\n }\n\n const app = await promptInspectorAppAsync(apps);\n if (!app) {\n return Log.error(chalk`{bold Debug:} No inspectable device selected`);\n }\n\n if (!(await openJsInspector(metroServerOrigin, app))) {\n Log.warn(\n chalk`{bold Debug:} Failed to open the React Native DevTools, see debug logs for more info.`\n );\n }\n } catch (error: any) {\n // Handle aborting prompt\n if (error.code === 'ABORTED') return;\n\n Log.error('Failed to open the React Native DevTools.');\n Log.exception(error);\n }\n }\n\n reloadApp() {\n Log.log(`${BLT} Reloading apps`);\n // Send reload requests over the dev servers\n this.devServerManager.broadcastMessage('reload');\n }\n\n async openMoreToolsAsync() {\n // Options match: Chrome > View > Developer\n try {\n const defaultMenuItems: MoreToolMenuItem[] = [\n { title: 'Inspect elements', value: 'toggleElementInspector' },\n { title: 'Toggle performance monitor', value: 'togglePerformanceMonitor' },\n { title: 'Toggle developer menu', value: 'toggleDevMenu' },\n { title: 'Reload app', value: 'reload' },\n // TODO: Maybe a \"View Source\" option to open code.\n ];\n\n const defaultServerUrl = this.devServerManager\n .getDefaultDevServer()\n .getUrlCreator()\n .constructUrl({ scheme: 'http' });\n\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const plugins = await this.devServerManager.devtoolsPluginManager.queryPluginsAsync();\n\n const menuItems = [\n ...defaultMenuItems,\n ...createDevToolsMenuItems(plugins, defaultServerUrl, metroServerOrigin),\n ];\n\n const value = await selectAsync(chalk`Dev tools {dim (native only)}`, menuItems);\n const menuItem = menuItems.find((item) => item.value === value);\n if (menuItem?.action) {\n menuItem.action();\n } else if (menuItem?.value) {\n this.devServerManager.broadcastMessage('sendDevCommand', { name: menuItem.value });\n }\n } catch (error: any) {\n debug(error);\n // do nothing\n } finally {\n printHelp();\n }\n }\n\n toggleDevMenu() {\n Log.log(`${BLT} Toggling dev menu`);\n this.devServerManager.broadcastMessage('devMenu');\n }\n}\n"],"names":["DevServerManagerActions","debug","require","devServerManager","options","printDevServerInfo","rows","process","stdout","Infinity","getNativeDevServerPort","devServer","getDefaultDevServer","nativeRuntimeUrl","getNativeRuntimeUrl","interstitialPageUrl","getRedirectUrl","env","__EXPO_E2E_TEST","console","info","JSON","stringify","url","getDevServerUrl","EXPO_NO_QR_CODE","qr","printQRCode","lines","print","qrMessage","devClient","chalk","learnMore","Log","log","printItem","dim","error","code","serverUrl","platforms","includes","webDevServer","getWebDevServer","webUrl","hostType","dependencyCheckLines","getDependencyCheckMessage","dependencyCheckRef","result","length","printUsage","verbose","printHelp","line","openJsInspectorAsync","metroServerOrigin","getJsInspectorBaseUrl","apps","queryAllInspectorAppsAsync","warn","app","promptInspectorAppAsync","openJsInspector","exception","reloadApp","BLT","broadcastMessage","openMoreToolsAsync","defaultMenuItems","title","value","defaultServerUrl","getUrlCreator","constructUrl","scheme","plugins","devtoolsPluginManager","queryPluginsAsync","menuItems","createDevToolsMenuItems","selectAsync","menuItem","find","item","action","name","toggleDevMenu"],"mappings":"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"}
@@ -24,7 +24,6 @@ const _errors = require("../../utils/errors");
24
24
  const _ora = require("../../utils/ora");
25
25
  const _progress = require("../../utils/progress");
26
26
  const _prompts = require("../../utils/prompts");
27
- const _checkDependenciesOnStart = require("../checkDependenciesOnStart");
28
27
  const _WebSupportProjectPrerequisite = require("../doctor/web/WebSupportProjectPrerequisite");
29
28
  function _interop_require_default(obj) {
30
29
  return obj && obj.__esModule ? obj : {
@@ -90,6 +89,13 @@ const PLATFORM_SETTINGS = {
90
89
  };
91
90
  async function startInterfaceAsync(devServerManager, options) {
92
91
  var _devServerManager_getDefaultDevServer;
92
+ // Spend one-tick waiting for the dependency check result
93
+ if (options.dependencyCheckRef) {
94
+ await Promise.race([
95
+ options.dependencyCheckRef.promise,
96
+ Promise.resolve(null)
97
+ ]);
98
+ }
93
99
  const actions = new _interactiveActions.DevServerManagerActions(devServerManager, options);
94
100
  const isWebSocketsEnabled = (_devServerManager_getDefaultDevServer = devServerManager.getDefaultDevServer()) == null ? void 0 : _devServerManager_getDefaultDevServer.isTargetingNative();
95
101
  const usageOptions = {
@@ -97,31 +103,7 @@ async function startInterfaceAsync(devServerManager, options) {
97
103
  devClient: devServerManager.options.devClient,
98
104
  ...options
99
105
  };
100
- // Print the dependency check if it completed (it runs in the background since early startup).
101
- // With a warm fetch cache this resolves near-instantly, so we defer by a tick
102
- // On cold starts it may not be ready, in which case it will appear on the next reprint or restart
103
- let dependencyCheckResult;
104
- if (options.dependencyCheckPromise) {
105
- dependencyCheckResult = await Promise.race([
106
- options.dependencyCheckPromise,
107
- Promise.resolve(null)
108
- ]);
109
- if (!dependencyCheckResult) {
110
- // Not ready yet — capture once resolved for display on next reprint
111
- options.dependencyCheckPromise.then((result)=>{
112
- if (result) {
113
- dependencyCheckResult = result;
114
- }
115
- });
116
- }
117
- }
118
- const printDependencyCheckIfAvailable = ()=>{
119
- if (dependencyCheckResult) {
120
- (0, _checkDependenciesOnStart.printDependencyCheckResult)(dependencyCheckResult);
121
- }
122
- };
123
106
  actions.printDevServerInfo(usageOptions);
124
- printDependencyCheckIfAvailable();
125
107
  const onPressAsync = async (key)=>{
126
108
  // Auxillary commands all escape.
127
109
  switch(key){
@@ -224,7 +206,6 @@ async function startInterfaceAsync(devServerManager, options) {
224
206
  if (await devServerManager.toggleRuntimeMode()) {
225
207
  usageOptions.devClient = devServerManager.options.devClient;
226
208
  actions.printDevServerInfo(usageOptions);
227
- printDependencyCheckIfAvailable();
228
209
  return;
229
210
  }
230
211
  break;
@@ -269,7 +250,6 @@ async function startInterfaceAsync(devServerManager, options) {
269
250
  case 'c':
270
251
  _log.clear();
271
252
  actions.printDevServerInfo(usageOptions);
272
- printDependencyCheckIfAvailable();
273
253
  return;
274
254
  case 'j':
275
255
  return actions.openJsInspectorAsync();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/interface/startInterface.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { KeyPressHandler } from './KeyPressHandler';\nimport type { StartOptions } from './commandsTable';\nimport { BLT, printHelp, printUsage } from './commandsTable';\nimport { DevServerManagerActions } from './interactiveActions';\nimport * as Log from '../../log';\nimport { openInEditorAsync } from '../../utils/editor';\nimport { AbortCommandError } from '../../utils/errors';\nimport { getAllSpinners, ora } from '../../utils/ora';\nimport { getProgressBar, setProgressBar } from '../../utils/progress';\nimport { addInteractionListener, pauseInteractions } from '../../utils/prompts';\nimport type { DependencyCheckResult } from '../checkDependenciesOnStart';\nimport { printDependencyCheckResult } from '../checkDependenciesOnStart';\nimport { WebSupportProjectPrerequisite } from '../doctor/web/WebSupportProjectPrerequisite';\nimport type { DevServerManager } from '../server/DevServerManager';\n\nconst debug = require('debug')('expo:start:interface:startInterface') as typeof console.log;\n\nconst CTRL_C = '\\u0003';\nconst CTRL_D = '\\u0004';\nconst CTRL_L = '\\u000C';\n\nconst PLATFORM_SETTINGS: Record<\n string,\n { name: string; key: 'android' | 'ios'; launchTarget: 'emulator' | 'simulator' }\n> = {\n android: {\n name: 'Android',\n key: 'android',\n launchTarget: 'emulator',\n },\n ios: {\n name: 'iOS',\n key: 'ios',\n launchTarget: 'simulator',\n },\n};\n\nexport async function startInterfaceAsync(\n devServerManager: DevServerManager,\n options: Pick<StartOptions, 'devClient' | 'platforms' | 'mcpServer' | 'dependencyCheckPromise'>\n) {\n const actions = new DevServerManagerActions(devServerManager, options);\n\n const isWebSocketsEnabled = devServerManager.getDefaultDevServer()?.isTargetingNative();\n\n const usageOptions = {\n isWebSocketsEnabled,\n devClient: devServerManager.options.devClient,\n ...options,\n };\n\n // Print the dependency check if it completed (it runs in the background since early startup).\n // With a warm fetch cache this resolves near-instantly, so we defer by a tick\n // On cold starts it may not be ready, in which case it will appear on the next reprint or restart\n let dependencyCheckResult: DependencyCheckResult | null | undefined;\n if (options.dependencyCheckPromise) {\n dependencyCheckResult = await Promise.race([\n options.dependencyCheckPromise,\n Promise.resolve(null),\n ]);\n if (!dependencyCheckResult) {\n // Not ready yet — capture once resolved for display on next reprint\n options.dependencyCheckPromise.then((result) => {\n if (result) {\n dependencyCheckResult = result;\n }\n });\n }\n }\n\n const printDependencyCheckIfAvailable = () => {\n if (dependencyCheckResult) {\n printDependencyCheckResult(dependencyCheckResult);\n }\n };\n\n actions.printDevServerInfo(usageOptions);\n printDependencyCheckIfAvailable();\n\n const onPressAsync = async (key: string) => {\n // Auxillary commands all escape.\n switch (key) {\n case CTRL_C:\n case CTRL_D: {\n // Prevent terminal UI from accepting commands while the process is closing.\n // Without this, fast typers will close the server then start typing their\n // next command and have a bunch of unrelated things pop up.\n pauseInteractions();\n\n const spinners = getAllSpinners();\n spinners.forEach((spinner) => {\n spinner.fail();\n });\n\n const currentProgress = getProgressBar();\n if (currentProgress) {\n currentProgress.terminate();\n setProgressBar(null);\n }\n const spinner = ora({ text: 'Stopping server', color: 'white' }).start();\n try {\n await devServerManager.stopAsync();\n if (options.mcpServer) {\n await options.mcpServer.closeAsync();\n }\n spinner.stopAndPersist({ text: 'Stopped server', symbol: `\\u203A` });\n // @ts-ignore: Argument of type '\"SIGINT\"' is not assignable to parameter of type '\"disconnect\"'.\n process.emit('SIGINT');\n\n // TODO: Is this the right place to do this?\n process.exit();\n } catch (error) {\n spinner.fail('Failed to stop server');\n throw error;\n }\n break;\n }\n case CTRL_L:\n return Log.clear();\n case '?':\n return printUsage(usageOptions, { verbose: true });\n }\n\n // Optionally enabled\n\n if (isWebSocketsEnabled) {\n switch (key) {\n case 'm':\n return actions.toggleDevMenu();\n case 'M':\n return actions.openMoreToolsAsync();\n }\n }\n\n const { platforms = ['ios', 'android', 'web'] } = options;\n\n if (['i', 'a'].includes(key.toLowerCase())) {\n const platform = key.toLowerCase() === 'i' ? 'ios' : 'android';\n\n const shouldPrompt = ['I', 'A'].includes(key);\n if (shouldPrompt) {\n Log.clear();\n }\n\n const server = devServerManager.getDefaultDevServer();\n const settings = PLATFORM_SETTINGS[platform]!;\n\n Log.log(`${BLT} Opening on ${settings.name}...`);\n\n if (server.isTargetingNative() && !platforms.includes(settings.key)) {\n Log.warn(\n chalk`${settings.name} is disabled, enable it by adding {bold ${settings.key}} to the platforms array in your app.json or app.config.js`\n );\n } else {\n try {\n await server.openPlatformAsync(settings.launchTarget, { shouldPrompt });\n printHelp();\n } catch (error: any) {\n if (!(error instanceof AbortCommandError)) {\n Log.exception(error);\n }\n }\n }\n // Break out early.\n return;\n }\n\n switch (key) {\n case 's': {\n Log.clear();\n if (await devServerManager.toggleRuntimeMode()) {\n usageOptions.devClient = devServerManager.options.devClient;\n actions.printDevServerInfo(usageOptions);\n printDependencyCheckIfAvailable();\n return;\n }\n break;\n }\n case 'w': {\n try {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n if (!platforms.includes('web')) {\n platforms.push('web');\n options.platforms?.push('web');\n }\n } catch (e: any) {\n Log.warn(e.message);\n break;\n }\n\n const isDisabled = !platforms.includes('web');\n if (isDisabled) {\n debug('Web is disabled');\n // Use warnings from the web support setup.\n break;\n }\n\n // Ensure the Webpack dev server is running first\n if (!devServerManager.getWebDevServer()) {\n debug('Starting up webpack dev server');\n await devServerManager.ensureWebDevServerRunningAsync();\n // When this is the first time webpack is started, reprint the connection info.\n actions.printDevServerInfo(usageOptions);\n }\n\n Log.log(`${BLT} Open in the web browser...`);\n try {\n await devServerManager.getWebDevServer()?.openPlatformAsync('desktop');\n printHelp();\n } catch (error: any) {\n if (!(error instanceof AbortCommandError)) {\n Log.exception(error);\n }\n }\n break;\n }\n case 'c':\n Log.clear();\n actions.printDevServerInfo(usageOptions);\n printDependencyCheckIfAvailable();\n return;\n case 'j':\n return actions.openJsInspectorAsync();\n case 'r':\n return actions.reloadApp();\n case 'o':\n Log.log(`${BLT} Opening the editor...`);\n return openInEditorAsync(devServerManager.projectRoot);\n }\n };\n\n const keyPressHandler = new KeyPressHandler(onPressAsync);\n\n const listener = keyPressHandler.createInteractionListener();\n\n addInteractionListener(listener);\n\n // Start observing...\n keyPressHandler.startInterceptingKeyStrokes();\n}\n"],"names":["startInterfaceAsync","debug","require","CTRL_C","CTRL_D","CTRL_L","PLATFORM_SETTINGS","android","name","key","launchTarget","ios","devServerManager","options","actions","DevServerManagerActions","isWebSocketsEnabled","getDefaultDevServer","isTargetingNative","usageOptions","devClient","dependencyCheckResult","dependencyCheckPromise","Promise","race","resolve","then","result","printDependencyCheckIfAvailable","printDependencyCheckResult","printDevServerInfo","onPressAsync","pauseInteractions","spinners","getAllSpinners","forEach","spinner","fail","currentProgress","getProgressBar","terminate","setProgressBar","ora","text","color","start","stopAsync","mcpServer","closeAsync","stopAndPersist","symbol","process","emit","exit","error","Log","clear","printUsage","verbose","toggleDevMenu","openMoreToolsAsync","platforms","includes","toLowerCase","platform","shouldPrompt","server","settings","log","BLT","warn","chalk","openPlatformAsync","printHelp","AbortCommandError","exception","toggleRuntimeMode","ensureProjectPrerequisiteAsync","WebSupportProjectPrerequisite","push","e","message","isDisabled","getWebDevServer","ensureWebDevServerRunningAsync","openJsInspectorAsync","reloadApp","openInEditorAsync","projectRoot","keyPressHandler","KeyPressHandler","listener","createInteractionListener","addInteractionListener","startInterceptingKeyStrokes"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/start/interface/startInterface.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { KeyPressHandler } from './KeyPressHandler';\nimport type { StartOptions } from './commandsTable';\nimport { BLT, printHelp, printUsage } from './commandsTable';\nimport { DevServerManagerActions } from './interactiveActions';\nimport * as Log from '../../log';\nimport { openInEditorAsync } from '../../utils/editor';\nimport { AbortCommandError } from '../../utils/errors';\nimport { getAllSpinners, ora } from '../../utils/ora';\nimport { getProgressBar, setProgressBar } from '../../utils/progress';\nimport { addInteractionListener, pauseInteractions } from '../../utils/prompts';\nimport { WebSupportProjectPrerequisite } from '../doctor/web/WebSupportProjectPrerequisite';\nimport type { DevServerManager } from '../server/DevServerManager';\n\nconst debug = require('debug')('expo:start:interface:startInterface') as typeof console.log;\n\nconst CTRL_C = '\\u0003';\nconst CTRL_D = '\\u0004';\nconst CTRL_L = '\\u000C';\n\nconst PLATFORM_SETTINGS: Record<\n string,\n { name: string; key: 'android' | 'ios'; launchTarget: 'emulator' | 'simulator' }\n> = {\n android: {\n name: 'Android',\n key: 'android',\n launchTarget: 'emulator',\n },\n ios: {\n name: 'iOS',\n key: 'ios',\n launchTarget: 'simulator',\n },\n};\n\nexport async function startInterfaceAsync(\n devServerManager: DevServerManager,\n options: Pick<StartOptions, 'devClient' | 'platforms' | 'mcpServer' | 'dependencyCheckRef'>\n) {\n // Spend one-tick waiting for the dependency check result\n if (options.dependencyCheckRef) {\n await Promise.race([options.dependencyCheckRef.promise, Promise.resolve(null)]);\n }\n\n const actions = new DevServerManagerActions(devServerManager, options);\n const isWebSocketsEnabled = devServerManager.getDefaultDevServer()?.isTargetingNative();\n const usageOptions = {\n isWebSocketsEnabled,\n devClient: devServerManager.options.devClient,\n ...options,\n };\n\n actions.printDevServerInfo(usageOptions);\n\n const onPressAsync = async (key: string) => {\n // Auxillary commands all escape.\n switch (key) {\n case CTRL_C:\n case CTRL_D: {\n // Prevent terminal UI from accepting commands while the process is closing.\n // Without this, fast typers will close the server then start typing their\n // next command and have a bunch of unrelated things pop up.\n pauseInteractions();\n\n const spinners = getAllSpinners();\n spinners.forEach((spinner) => {\n spinner.fail();\n });\n\n const currentProgress = getProgressBar();\n if (currentProgress) {\n currentProgress.terminate();\n setProgressBar(null);\n }\n const spinner = ora({ text: 'Stopping server', color: 'white' }).start();\n try {\n await devServerManager.stopAsync();\n if (options.mcpServer) {\n await options.mcpServer.closeAsync();\n }\n spinner.stopAndPersist({ text: 'Stopped server', symbol: `\\u203A` });\n // @ts-ignore: Argument of type '\"SIGINT\"' is not assignable to parameter of type '\"disconnect\"'.\n process.emit('SIGINT');\n\n // TODO: Is this the right place to do this?\n process.exit();\n } catch (error) {\n spinner.fail('Failed to stop server');\n throw error;\n }\n break;\n }\n case CTRL_L:\n return Log.clear();\n case '?':\n return printUsage(usageOptions, { verbose: true });\n }\n\n // Optionally enabled\n\n if (isWebSocketsEnabled) {\n switch (key) {\n case 'm':\n return actions.toggleDevMenu();\n case 'M':\n return actions.openMoreToolsAsync();\n }\n }\n\n const { platforms = ['ios', 'android', 'web'] } = options;\n\n if (['i', 'a'].includes(key.toLowerCase())) {\n const platform = key.toLowerCase() === 'i' ? 'ios' : 'android';\n\n const shouldPrompt = ['I', 'A'].includes(key);\n if (shouldPrompt) {\n Log.clear();\n }\n\n const server = devServerManager.getDefaultDevServer();\n const settings = PLATFORM_SETTINGS[platform]!;\n\n Log.log(`${BLT} Opening on ${settings.name}...`);\n\n if (server.isTargetingNative() && !platforms.includes(settings.key)) {\n Log.warn(\n chalk`${settings.name} is disabled, enable it by adding {bold ${settings.key}} to the platforms array in your app.json or app.config.js`\n );\n } else {\n try {\n await server.openPlatformAsync(settings.launchTarget, { shouldPrompt });\n printHelp();\n } catch (error: any) {\n if (!(error instanceof AbortCommandError)) {\n Log.exception(error);\n }\n }\n }\n // Break out early.\n return;\n }\n\n switch (key) {\n case 's': {\n Log.clear();\n if (await devServerManager.toggleRuntimeMode()) {\n usageOptions.devClient = devServerManager.options.devClient;\n actions.printDevServerInfo(usageOptions);\n return;\n }\n break;\n }\n case 'w': {\n try {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n if (!platforms.includes('web')) {\n platforms.push('web');\n options.platforms?.push('web');\n }\n } catch (e: any) {\n Log.warn(e.message);\n break;\n }\n\n const isDisabled = !platforms.includes('web');\n if (isDisabled) {\n debug('Web is disabled');\n // Use warnings from the web support setup.\n break;\n }\n\n // Ensure the Webpack dev server is running first\n if (!devServerManager.getWebDevServer()) {\n debug('Starting up webpack dev server');\n await devServerManager.ensureWebDevServerRunningAsync();\n // When this is the first time webpack is started, reprint the connection info.\n actions.printDevServerInfo(usageOptions);\n }\n\n Log.log(`${BLT} Open in the web browser...`);\n try {\n await devServerManager.getWebDevServer()?.openPlatformAsync('desktop');\n printHelp();\n } catch (error: any) {\n if (!(error instanceof AbortCommandError)) {\n Log.exception(error);\n }\n }\n break;\n }\n case 'c':\n Log.clear();\n actions.printDevServerInfo(usageOptions);\n return;\n case 'j':\n return actions.openJsInspectorAsync();\n case 'r':\n return actions.reloadApp();\n case 'o':\n Log.log(`${BLT} Opening the editor...`);\n return openInEditorAsync(devServerManager.projectRoot);\n }\n };\n\n const keyPressHandler = new KeyPressHandler(onPressAsync);\n\n const listener = keyPressHandler.createInteractionListener();\n\n addInteractionListener(listener);\n\n // Start observing...\n keyPressHandler.startInterceptingKeyStrokes();\n}\n"],"names":["startInterfaceAsync","debug","require","CTRL_C","CTRL_D","CTRL_L","PLATFORM_SETTINGS","android","name","key","launchTarget","ios","devServerManager","options","dependencyCheckRef","Promise","race","promise","resolve","actions","DevServerManagerActions","isWebSocketsEnabled","getDefaultDevServer","isTargetingNative","usageOptions","devClient","printDevServerInfo","onPressAsync","pauseInteractions","spinners","getAllSpinners","forEach","spinner","fail","currentProgress","getProgressBar","terminate","setProgressBar","ora","text","color","start","stopAsync","mcpServer","closeAsync","stopAndPersist","symbol","process","emit","exit","error","Log","clear","printUsage","verbose","toggleDevMenu","openMoreToolsAsync","platforms","includes","toLowerCase","platform","shouldPrompt","server","settings","log","BLT","warn","chalk","openPlatformAsync","printHelp","AbortCommandError","exception","toggleRuntimeMode","ensureProjectPrerequisiteAsync","WebSupportProjectPrerequisite","push","e","message","isDisabled","getWebDevServer","ensureWebDevServerRunningAsync","openJsInspectorAsync","reloadApp","openInEditorAsync","projectRoot","keyPressHandler","KeyPressHandler","listener","createInteractionListener","addInteractionListener","startInterceptingKeyStrokes"],"mappings":"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"}
@@ -16,6 +16,13 @@ _export(exports, {
16
16
  return withMetroErrorReportingResolver;
17
17
  }
18
18
  });
19
+ function _canonicalize() {
20
+ const data = /*#__PURE__*/ _interop_require_default(require("@expo/metro/metro-core/canonicalize"));
21
+ _canonicalize = function() {
22
+ return data;
23
+ };
24
+ return data;
25
+ }
19
26
  function _chalk() {
20
27
  const data = /*#__PURE__*/ _interop_require_default(require("chalk"));
21
28
  _chalk = function() {
@@ -56,26 +63,17 @@ function withMetroErrorReportingResolver(config) {
56
63
  const originalResolveRequest = (_config_resolver = config.resolver) == null ? void 0 : _config_resolver.resolveRequest;
57
64
  const depGraph = new Map();
58
65
  const mutateResolutionError = createMutateResolutionError(config, depGraph);
66
+ // Single-entry cache for the most recent (options, platform, origin) → deps map.
67
+ // Metro resolves depth-first, so the same origin repeats for consecutive calls.
68
+ let _prevOptions;
69
+ let _prevPlatform;
70
+ let _prevOrigin;
71
+ let _prevDeps;
59
72
  return {
60
73
  ...config,
61
74
  resolver: {
62
75
  ...config.resolver,
63
76
  resolveRequest (context, moduleName, platform) {
64
- const storeResult = (res)=>{
65
- const inputPlatform = platform ?? 'null';
66
- const key = optionsKeyForContext(context);
67
- if (!depGraph.has(key)) depGraph.set(key, new Map());
68
- const mapByTarget = depGraph.get(key);
69
- if (!mapByTarget.has(inputPlatform)) mapByTarget.set(inputPlatform, new Map());
70
- const mapByPlatform = mapByTarget.get(inputPlatform);
71
- if (!mapByPlatform.has(context.originModulePath)) mapByPlatform.set(context.originModulePath, new Set());
72
- const setForModule = mapByPlatform.get(context.originModulePath);
73
- const qualifiedModuleName = (res == null ? void 0 : res.type) === 'sourceFile' ? res.filePath : moduleName;
74
- setForModule.add({
75
- path: qualifiedModuleName,
76
- request: moduleName
77
- });
78
- };
79
77
  // If the user defined a resolver, run it first and depend on the documented
80
78
  // chaining logic: https://facebook.github.io/metro/docs/resolution/#resolution-algorithm
81
79
  //
@@ -88,7 +86,25 @@ function withMetroErrorReportingResolver(config) {
88
86
  try {
89
87
  const firstResolver = originalResolveRequest ?? context.resolveRequest;
90
88
  const res = firstResolver(context, moduleName, platform);
91
- storeResult(res);
89
+ const inputPlatform = platform ?? 'null';
90
+ let depsForModule;
91
+ if (context.customResolverOptions === _prevOptions && inputPlatform === _prevPlatform && context.originModulePath === _prevOrigin) {
92
+ depsForModule = _prevDeps;
93
+ } else {
94
+ const key = optionsKeyForContext(context);
95
+ let mapByTarget = depGraph.get(key);
96
+ if (!mapByTarget) depGraph.set(key, mapByTarget = new Map());
97
+ let mapByPlatform = mapByTarget.get(inputPlatform);
98
+ if (!mapByPlatform) mapByTarget.set(inputPlatform, mapByPlatform = new Map());
99
+ depsForModule = mapByPlatform.get(context.originModulePath);
100
+ if (!depsForModule) mapByPlatform.set(context.originModulePath, depsForModule = new Map());
101
+ _prevOptions = context.customResolverOptions;
102
+ _prevPlatform = inputPlatform;
103
+ _prevOrigin = context.originModulePath;
104
+ _prevDeps = depsForModule;
105
+ }
106
+ const qualifiedModuleName = (res == null ? void 0 : res.type) === 'sourceFile' ? res.filePath : moduleName;
107
+ depsForModule.set(qualifiedModuleName, moduleName);
92
108
  return res;
93
109
  } catch (error) {
94
110
  throw mutateResolutionError(error, context, moduleName, platform);
@@ -97,10 +113,19 @@ function withMetroErrorReportingResolver(config) {
97
113
  }
98
114
  };
99
115
  }
116
+ const optionsKeyCache = new WeakMap();
117
+ const EMPTY_OPTIONS_KEY = '{}';
100
118
  function optionsKeyForContext(context) {
101
- const canonicalize = require('@expo/metro/metro-core/canonicalize');
102
- // Compound key for the resolver cache
103
- return JSON.stringify(context.customResolverOptions ?? {}, canonicalize) ?? '';
119
+ const options = context.customResolverOptions;
120
+ if (options == null) {
121
+ return EMPTY_OPTIONS_KEY;
122
+ }
123
+ let key = optionsKeyCache.get(options);
124
+ if (key == null) {
125
+ key = JSON.stringify(options, _canonicalize().default) ?? EMPTY_OPTIONS_KEY;
126
+ optionsKeyCache.set(options, key);
127
+ }
128
+ return key;
104
129
  }
105
130
  const createMutateResolutionError = (config, depGraph, stackDepthLimit = STACK_DEPTH_LIMIT, stackCountLimit = STACK_COUNT_LIMIT)=>(error, context, moduleName, platform)=>{
106
131
  var _config_server;
@@ -116,16 +141,13 @@ const createMutateResolutionError = (config, depGraph, stackDepthLimit = STACK_D
116
141
  if (!mapByPlatform) {
117
142
  return inverseOrigin;
118
143
  }
119
- for (const [originKey, mapByTarget] of mapByPlatform){
120
- // search comparing origin to path
121
- const found = [
122
- ...mapByTarget.values()
123
- ].find((resolution)=>resolution.path === origin);
124
- if (found) {
144
+ for (const [originKey, depsMap] of mapByPlatform){
145
+ const request = depsMap.get(origin);
146
+ if (request !== undefined) {
125
147
  inverseOrigin.push({
126
148
  origin,
127
149
  previous: originKey,
128
- request: found.request
150
+ request
129
151
  });
130
152
  }
131
153
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/withMetroErrorReportingResolver.ts"],"sourcesContent":["import type { ConfigT as MetroConfig } from '@expo/metro/metro-config';\nimport type { ResolutionContext } from '@expo/metro/metro-resolver';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { stripVTControlCharacters } from 'util';\n\nimport type { ExpoCustomMetroResolver } from './withMetroResolvers';\nimport { isPathInside } from '../../../utils/dir';\nimport { env } from '../../../utils/env';\n\nconst debug = require('debug')('expo:metro:withMetroResolvers') as typeof console.log;\n\n// TODO: Do we need to expose this?\nconst STACK_DEPTH_LIMIT = 35;\nconst STACK_COUNT_LIMIT = 2_000;\n\nexport function withMetroErrorReportingResolver(config: MetroConfig): MetroConfig {\n if (!env.EXPO_METRO_UNSTABLE_ERRORS) {\n return config;\n }\n\n const originalResolveRequest = config.resolver?.resolveRequest;\n\n const depGraph: DepGraph = new Map();\n\n const mutateResolutionError = createMutateResolutionError(config, depGraph);\n\n return {\n ...config,\n resolver: {\n ...config.resolver,\n resolveRequest(context, moduleName, platform) {\n const storeResult = (res: NonNullable<ReturnType<ExpoCustomMetroResolver>>) => {\n const inputPlatform = platform ?? 'null';\n\n const key = optionsKeyForContext(context);\n if (!depGraph.has(key)) depGraph.set(key, new Map());\n const mapByTarget = depGraph.get(key);\n if (!mapByTarget!.has(inputPlatform)) mapByTarget!.set(inputPlatform, new Map());\n const mapByPlatform = mapByTarget!.get(inputPlatform);\n if (!mapByPlatform!.has(context.originModulePath))\n mapByPlatform!.set(context.originModulePath, new Set());\n const setForModule = mapByPlatform!.get(context.originModulePath)!;\n\n const qualifiedModuleName = res?.type === 'sourceFile' ? res.filePath : moduleName;\n setForModule.add({ path: qualifiedModuleName, request: moduleName });\n };\n\n // If the user defined a resolver, run it first and depend on the documented\n // chaining logic: https://facebook.github.io/metro/docs/resolution/#resolution-algorithm\n //\n // config.resolver.resolveRequest = (context, moduleName, platform) => {\n //\n // // Do work...\n //\n // return context.resolveRequest(context, moduleName, platform);\n // };\n try {\n const firstResolver = originalResolveRequest ?? context.resolveRequest;\n const res = firstResolver(context, moduleName, platform);\n storeResult(res);\n return res;\n } catch (error: any) {\n throw mutateResolutionError(error, context, moduleName, platform);\n }\n },\n },\n };\n}\n\nexport type DepGraph = Map<\n // custom options\n string,\n Map<\n // platform\n string,\n Map<\n // origin module name\n string,\n Set<{\n // required module name\n path: string;\n // This isn't entirely accurate since a module can be imported multiple times in a file,\n // and use different names. But it's good enough for now.\n request: string;\n }>\n >\n >\n>;\n\nfunction optionsKeyForContext(context: ResolutionContext) {\n const canonicalize: typeof import('@expo/metro/metro-core/canonicalize').default = require('@expo/metro/metro-core/canonicalize');\n // Compound key for the resolver cache\n return JSON.stringify(context.customResolverOptions ?? {}, canonicalize) ?? '';\n}\n\ninterface ErrorWithExpoImportStack extends Error {\n _expoImportStack?: string;\n}\n\nexport const createMutateResolutionError =\n (\n config: MetroConfig,\n depGraph: DepGraph,\n stackDepthLimit = STACK_DEPTH_LIMIT,\n stackCountLimit = STACK_COUNT_LIMIT\n ) =>\n (\n error: ErrorWithExpoImportStack,\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) => {\n const inputPlatform = platform ?? 'null';\n\n const mapByOrigin = depGraph.get(optionsKeyForContext(context));\n const mapByPlatform = mapByOrigin?.get(inputPlatform);\n\n if (!mapByPlatform) {\n return error;\n }\n\n // collect all references inversely using some expensive lookup\n\n const getReferences = (origin: string) => {\n const inverseOrigin: { origin: string; previous: string; request: string }[] = [];\n\n if (!mapByPlatform) {\n return inverseOrigin;\n }\n\n for (const [originKey, mapByTarget] of mapByPlatform) {\n // search comparing origin to path\n\n const found = [...mapByTarget.values()].find((resolution) => resolution.path === origin);\n if (found) {\n inverseOrigin.push({\n origin,\n previous: originKey,\n request: found.request,\n });\n }\n }\n\n return inverseOrigin;\n };\n\n const root = config.server?.unstable_serverRoot ?? config.projectRoot;\n const projectRoot = config.projectRoot;\n\n type Frame = {\n origin: string;\n request: string;\n };\n type Stack = {\n circular?: boolean;\n limited?: boolean;\n serverRoot?: boolean;\n projectRoot?: boolean;\n frames: Frame[];\n };\n\n let stackCounter = 0;\n let inverseStack: Stack | undefined;\n /** @returns boolean - done */\n const saveStack = (stack: Stack): boolean => {\n stackCounter++;\n\n if (!inverseStack) {\n // First stack, save it\n inverseStack = stack;\n return false;\n }\n\n if (stackCounter >= stackCountLimit) {\n // Too many stacks explored, stop searching\n return true;\n }\n\n if (stack.circular || stack.limited) {\n // Not better than the current one, skip\n return false;\n }\n\n if (inverseStack.circular || inverseStack.limited) {\n // Current one is better than the previous one, save it\n inverseStack = stack;\n // No return as we want to continue validation the new stack\n }\n\n if (inverseStack.projectRoot) {\n // The best possible stack already acquired, skip\n return true;\n }\n\n const stackOrigin = stack.frames[stack.frames.length - 1]?.origin;\n\n if (\n stackOrigin &&\n isPathInside(stackOrigin, projectRoot) &&\n !stackOrigin.includes('node_modules')\n ) {\n // The best stack to show to users is the one leading from the project code.\n stack.serverRoot = true;\n inverseStack = stack;\n return true;\n }\n\n if (\n // Has to be after the project root check\n stackOrigin &&\n isPathInside(stackOrigin, root) &&\n !stackOrigin.includes('node_modules')\n ) {\n // The best stack to show to users is the one leading from the monorepo code.\n stack.serverRoot = true;\n inverseStack = stack;\n return false;\n }\n\n // If new stack is not better do nothing\n return false;\n };\n\n /** @returns boolean - done */\n const recurseBackWithLimit = (\n frame: { origin: string; request: string },\n limit: number,\n stack: Stack = { frames: [] },\n visited: Set<string> = new Set()\n ): boolean => {\n stack.frames.push(frame);\n\n if (visited.has(frame.origin)) {\n stack.circular = true;\n return saveStack(stack);\n }\n\n if (stack.frames.length >= limit) {\n stack.limited = true;\n return saveStack(stack);\n }\n\n visited.add(frame.origin);\n\n const inverse = getReferences(frame.origin);\n if (inverse.length === 0) {\n // No more references, push the stack and return\n return saveStack(stack);\n }\n\n for (const match of inverse) {\n // Use more qualified name if possible\n // results.origin = match.origin;\n // Found entry point\n if (frame.origin === match.previous) {\n continue;\n }\n\n const isDone = recurseBackWithLimit(\n { origin: match.previous, request: match.request },\n limit,\n {\n frames: [...stack.frames],\n },\n new Set(visited)\n );\n\n if (isDone) {\n return true; // Stop search\n }\n }\n\n return false; // Continue search\n };\n\n recurseBackWithLimit(\n { origin: context.originModulePath, request: moduleName },\n stackDepthLimit\n );\n\n debug('Number of explored stacks:', stackCounter);\n\n if (inverseStack && inverseStack.frames.length > 0) {\n const formattedImport = chalk`{gray |} {cyan import} `;\n const importMessagePadding = ' '.repeat(stripVTControlCharacters(formattedImport).length + 1);\n\n debug('Found inverse graph:', JSON.stringify(inverseStack, null, 2));\n\n let extraMessage = chalk.bold(\n `Import stack${stackCounter >= stackCountLimit ? ` (${stackCounter})` : ''}:`\n );\n\n for (const frame of inverseStack.frames) {\n let currentMessage = '';\n let filename = path.relative(root, frame.origin);\n\n if (filename.match(/\\?ctx=[\\w\\d]+$/)) {\n filename = filename.replace(/\\?ctx=[\\w\\d]+$/, chalk.dim(' (require.context)'));\n } else {\n let formattedRequest = chalk.green(`\"${frame.request}\"`);\n\n if (\n // If bundling for web and the import is pulling internals from outside of react-native\n // then mark it as an invalid import.\n inputPlatform === 'web' &&\n !/^(node_modules\\/)?react-native\\//.test(filename) &&\n frame.request.match(/^react-native\\/.*/)\n ) {\n formattedRequest =\n formattedRequest +\n chalk`\\n${importMessagePadding}{yellow ^ Importing react-native internals is not supported on web.}`;\n }\n\n filename = filename + chalk`\\n${formattedImport}${formattedRequest}`;\n }\n\n let line = '\\n' + chalk.gray(' ') + filename;\n if (filename.match(/node_modules/)) {\n line = chalk.gray(\n // Bold the node module name\n line.replace(/node_modules\\/([^/]+)/, (_match, p1) => {\n return 'node_modules/' + chalk.bold(p1);\n })\n );\n }\n currentMessage += `\\n${line}`;\n extraMessage += currentMessage;\n }\n\n if (inverseStack.circular) {\n extraMessage += chalk`\\n${importMessagePadding}{yellow ^ The import above creates circular dependency.}`;\n }\n\n if (inverseStack.limited) {\n extraMessage += chalk`\\n\\n {bold {yellow Depth limit reached. The actual stack is longer than what you can see above.}}`;\n }\n\n extraMessage += '\\n';\n\n error._expoImportStack = extraMessage;\n } else {\n debug('Found no inverse tree for:', context.originModulePath);\n }\n\n return error;\n };\n"],"names":["createMutateResolutionError","withMetroErrorReportingResolver","debug","require","STACK_DEPTH_LIMIT","STACK_COUNT_LIMIT","config","env","EXPO_METRO_UNSTABLE_ERRORS","originalResolveRequest","resolver","resolveRequest","depGraph","Map","mutateResolutionError","context","moduleName","platform","storeResult","res","inputPlatform","key","optionsKeyForContext","has","set","mapByTarget","get","mapByPlatform","originModulePath","Set","setForModule","qualifiedModuleName","type","filePath","add","path","request","firstResolver","error","canonicalize","JSON","stringify","customResolverOptions","stackDepthLimit","stackCountLimit","mapByOrigin","getReferences","origin","inverseOrigin","originKey","found","values","find","resolution","push","previous","root","server","unstable_serverRoot","projectRoot","stackCounter","inverseStack","saveStack","stack","circular","limited","stackOrigin","frames","length","isPathInside","includes","serverRoot","recurseBackWithLimit","frame","limit","visited","inverse","match","isDone","formattedImport","chalk","importMessagePadding","repeat","stripVTControlCharacters","extraMessage","bold","currentMessage","filename","relative","replace","dim","formattedRequest","green","test","line","gray","_match","p1","_expoImportStack"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/server/metro/withMetroErrorReportingResolver.ts"],"sourcesContent":["import type { ConfigT as MetroConfig } from '@expo/metro/metro-config';\nimport canonicalize from '@expo/metro/metro-core/canonicalize';\nimport type { ResolutionContext } from '@expo/metro/metro-resolver';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { stripVTControlCharacters } from 'util';\n\nimport { isPathInside } from '../../../utils/dir';\nimport { env } from '../../../utils/env';\n\nconst debug = require('debug')('expo:metro:withMetroResolvers') as typeof console.log;\n\n// TODO: Do we need to expose this?\nconst STACK_DEPTH_LIMIT = 35;\nconst STACK_COUNT_LIMIT = 2_000;\n\nexport function withMetroErrorReportingResolver(config: MetroConfig): MetroConfig {\n if (!env.EXPO_METRO_UNSTABLE_ERRORS) {\n return config;\n }\n\n const originalResolveRequest = config.resolver?.resolveRequest;\n\n const depGraph: DepGraph = new Map();\n\n const mutateResolutionError = createMutateResolutionError(config, depGraph);\n\n // Single-entry cache for the most recent (options, platform, origin) → deps map.\n // Metro resolves depth-first, so the same origin repeats for consecutive calls.\n let _prevOptions: Record<string, unknown> | null | undefined;\n let _prevPlatform: string | undefined;\n let _prevOrigin: string | undefined;\n let _prevDeps: Map<string, string> | undefined;\n\n return {\n ...config,\n resolver: {\n ...config.resolver,\n resolveRequest(context, moduleName, platform) {\n // If the user defined a resolver, run it first and depend on the documented\n // chaining logic: https://facebook.github.io/metro/docs/resolution/#resolution-algorithm\n //\n // config.resolver.resolveRequest = (context, moduleName, platform) => {\n //\n // // Do work...\n //\n // return context.resolveRequest(context, moduleName, platform);\n // };\n try {\n const firstResolver = originalResolveRequest ?? context.resolveRequest;\n const res = firstResolver(context, moduleName, platform);\n\n const inputPlatform = platform ?? 'null';\n let depsForModule: Map<string, string> | undefined;\n\n if (\n context.customResolverOptions === _prevOptions &&\n inputPlatform === _prevPlatform &&\n context.originModulePath === _prevOrigin\n ) {\n depsForModule = _prevDeps!;\n } else {\n const key = optionsKeyForContext(context);\n let mapByTarget = depGraph.get(key);\n if (!mapByTarget) depGraph.set(key, (mapByTarget = new Map()));\n let mapByPlatform = mapByTarget.get(inputPlatform);\n if (!mapByPlatform) mapByTarget.set(inputPlatform, (mapByPlatform = new Map()));\n depsForModule = mapByPlatform.get(context.originModulePath);\n if (!depsForModule)\n mapByPlatform.set(context.originModulePath, (depsForModule = new Map()));\n _prevOptions = context.customResolverOptions;\n _prevPlatform = inputPlatform;\n _prevOrigin = context.originModulePath;\n _prevDeps = depsForModule;\n }\n\n const qualifiedModuleName = res?.type === 'sourceFile' ? res.filePath : moduleName;\n depsForModule.set(qualifiedModuleName, moduleName);\n\n return res;\n } catch (error: any) {\n throw mutateResolutionError(error, context, moduleName, platform);\n }\n },\n },\n };\n}\n\nexport type DepGraph = Map<\n // custom options\n string,\n Map<\n // platform\n string,\n Map<\n // origin module name\n string,\n // resolved path → import request\n // This isn't entirely accurate since a module can be imported multiple times in a file,\n // and use different names. But it's good enough for now.\n Map<string, string>\n >\n >\n>;\n\nconst optionsKeyCache = new WeakMap<Record<string, unknown>, string>();\nconst EMPTY_OPTIONS_KEY = '{}';\n\nfunction optionsKeyForContext(context: ResolutionContext): string {\n const options = context.customResolverOptions;\n if (options == null) {\n return EMPTY_OPTIONS_KEY;\n }\n let key = optionsKeyCache.get(options);\n if (key == null) {\n key = JSON.stringify(options, canonicalize) ?? EMPTY_OPTIONS_KEY;\n optionsKeyCache.set(options, key);\n }\n return key;\n}\n\ninterface ErrorWithExpoImportStack extends Error {\n _expoImportStack?: string;\n}\n\nexport const createMutateResolutionError =\n (\n config: MetroConfig,\n depGraph: DepGraph,\n stackDepthLimit = STACK_DEPTH_LIMIT,\n stackCountLimit = STACK_COUNT_LIMIT\n ) =>\n (\n error: ErrorWithExpoImportStack,\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) => {\n const inputPlatform = platform ?? 'null';\n\n const mapByOrigin = depGraph.get(optionsKeyForContext(context));\n const mapByPlatform = mapByOrigin?.get(inputPlatform);\n\n if (!mapByPlatform) {\n return error;\n }\n\n // collect all references inversely using some expensive lookup\n\n const getReferences = (origin: string) => {\n const inverseOrigin: { origin: string; previous: string; request: string }[] = [];\n\n if (!mapByPlatform) {\n return inverseOrigin;\n }\n\n for (const [originKey, depsMap] of mapByPlatform) {\n const request = depsMap.get(origin);\n if (request !== undefined) {\n inverseOrigin.push({\n origin,\n previous: originKey,\n request,\n });\n }\n }\n\n return inverseOrigin;\n };\n\n const root = config.server?.unstable_serverRoot ?? config.projectRoot;\n const projectRoot = config.projectRoot;\n\n type Frame = {\n origin: string;\n request: string;\n };\n type Stack = {\n circular?: boolean;\n limited?: boolean;\n serverRoot?: boolean;\n projectRoot?: boolean;\n frames: Frame[];\n };\n\n let stackCounter = 0;\n let inverseStack: Stack | undefined;\n /** @returns boolean - done */\n const saveStack = (stack: Stack): boolean => {\n stackCounter++;\n\n if (!inverseStack) {\n // First stack, save it\n inverseStack = stack;\n return false;\n }\n\n if (stackCounter >= stackCountLimit) {\n // Too many stacks explored, stop searching\n return true;\n }\n\n if (stack.circular || stack.limited) {\n // Not better than the current one, skip\n return false;\n }\n\n if (inverseStack.circular || inverseStack.limited) {\n // Current one is better than the previous one, save it\n inverseStack = stack;\n // No return as we want to continue validation the new stack\n }\n\n if (inverseStack.projectRoot) {\n // The best possible stack already acquired, skip\n return true;\n }\n\n const stackOrigin = stack.frames[stack.frames.length - 1]?.origin;\n\n if (\n stackOrigin &&\n isPathInside(stackOrigin, projectRoot) &&\n !stackOrigin.includes('node_modules')\n ) {\n // The best stack to show to users is the one leading from the project code.\n stack.serverRoot = true;\n inverseStack = stack;\n return true;\n }\n\n if (\n // Has to be after the project root check\n stackOrigin &&\n isPathInside(stackOrigin, root) &&\n !stackOrigin.includes('node_modules')\n ) {\n // The best stack to show to users is the one leading from the monorepo code.\n stack.serverRoot = true;\n inverseStack = stack;\n return false;\n }\n\n // If new stack is not better do nothing\n return false;\n };\n\n /** @returns boolean - done */\n const recurseBackWithLimit = (\n frame: { origin: string; request: string },\n limit: number,\n stack: Stack = { frames: [] },\n visited: Set<string> = new Set()\n ): boolean => {\n stack.frames.push(frame);\n\n if (visited.has(frame.origin)) {\n stack.circular = true;\n return saveStack(stack);\n }\n\n if (stack.frames.length >= limit) {\n stack.limited = true;\n return saveStack(stack);\n }\n\n visited.add(frame.origin);\n\n const inverse = getReferences(frame.origin);\n if (inverse.length === 0) {\n // No more references, push the stack and return\n return saveStack(stack);\n }\n\n for (const match of inverse) {\n // Use more qualified name if possible\n // results.origin = match.origin;\n // Found entry point\n if (frame.origin === match.previous) {\n continue;\n }\n\n const isDone = recurseBackWithLimit(\n { origin: match.previous, request: match.request },\n limit,\n {\n frames: [...stack.frames],\n },\n new Set(visited)\n );\n\n if (isDone) {\n return true; // Stop search\n }\n }\n\n return false; // Continue search\n };\n\n recurseBackWithLimit(\n { origin: context.originModulePath, request: moduleName },\n stackDepthLimit\n );\n\n debug('Number of explored stacks:', stackCounter);\n\n if (inverseStack && inverseStack.frames.length > 0) {\n const formattedImport = chalk`{gray |} {cyan import} `;\n const importMessagePadding = ' '.repeat(stripVTControlCharacters(formattedImport).length + 1);\n\n debug('Found inverse graph:', JSON.stringify(inverseStack, null, 2));\n\n let extraMessage = chalk.bold(\n `Import stack${stackCounter >= stackCountLimit ? ` (${stackCounter})` : ''}:`\n );\n\n for (const frame of inverseStack.frames) {\n let currentMessage = '';\n let filename = path.relative(root, frame.origin);\n\n if (filename.match(/\\?ctx=[\\w\\d]+$/)) {\n filename = filename.replace(/\\?ctx=[\\w\\d]+$/, chalk.dim(' (require.context)'));\n } else {\n let formattedRequest = chalk.green(`\"${frame.request}\"`);\n\n if (\n // If bundling for web and the import is pulling internals from outside of react-native\n // then mark it as an invalid import.\n inputPlatform === 'web' &&\n !/^(node_modules\\/)?react-native\\//.test(filename) &&\n frame.request.match(/^react-native\\/.*/)\n ) {\n formattedRequest =\n formattedRequest +\n chalk`\\n${importMessagePadding}{yellow ^ Importing react-native internals is not supported on web.}`;\n }\n\n filename = filename + chalk`\\n${formattedImport}${formattedRequest}`;\n }\n\n let line = '\\n' + chalk.gray(' ') + filename;\n if (filename.match(/node_modules/)) {\n line = chalk.gray(\n // Bold the node module name\n line.replace(/node_modules\\/([^/]+)/, (_match, p1) => {\n return 'node_modules/' + chalk.bold(p1);\n })\n );\n }\n currentMessage += `\\n${line}`;\n extraMessage += currentMessage;\n }\n\n if (inverseStack.circular) {\n extraMessage += chalk`\\n${importMessagePadding}{yellow ^ The import above creates circular dependency.}`;\n }\n\n if (inverseStack.limited) {\n extraMessage += chalk`\\n\\n {bold {yellow Depth limit reached. The actual stack is longer than what you can see above.}}`;\n }\n\n extraMessage += '\\n';\n\n error._expoImportStack = extraMessage;\n } else {\n debug('Found no inverse tree for:', context.originModulePath);\n }\n\n return error;\n };\n"],"names":["createMutateResolutionError","withMetroErrorReportingResolver","debug","require","STACK_DEPTH_LIMIT","STACK_COUNT_LIMIT","config","env","EXPO_METRO_UNSTABLE_ERRORS","originalResolveRequest","resolver","resolveRequest","depGraph","Map","mutateResolutionError","_prevOptions","_prevPlatform","_prevOrigin","_prevDeps","context","moduleName","platform","firstResolver","res","inputPlatform","depsForModule","customResolverOptions","originModulePath","key","optionsKeyForContext","mapByTarget","get","set","mapByPlatform","qualifiedModuleName","type","filePath","error","optionsKeyCache","WeakMap","EMPTY_OPTIONS_KEY","options","JSON","stringify","canonicalize","stackDepthLimit","stackCountLimit","mapByOrigin","getReferences","origin","inverseOrigin","originKey","depsMap","request","undefined","push","previous","root","server","unstable_serverRoot","projectRoot","stackCounter","inverseStack","saveStack","stack","circular","limited","stackOrigin","frames","length","isPathInside","includes","serverRoot","recurseBackWithLimit","frame","limit","visited","Set","has","add","inverse","match","isDone","formattedImport","chalk","importMessagePadding","repeat","stripVTControlCharacters","extraMessage","bold","currentMessage","filename","path","relative","replace","dim","formattedRequest","green","test","line","gray","_match","p1","_expoImportStack"],"mappings":"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"}
@@ -43,7 +43,6 @@ function _resolvefrom() {
43
43
  const _domPolyfills = require("./domPolyfills");
44
44
  const _metroOptions = require("./metroOptions");
45
45
  const _filePath = require("../../../utils/filePath");
46
- const _fn = require("../../../utils/fn");
47
46
  const _createServerComponentsMiddleware = require("../metro/createServerComponentsMiddleware");
48
47
  function _interop_require_default(obj) {
49
48
  return obj && obj.__esModule ? obj : {
@@ -51,12 +50,6 @@ function _interop_require_default(obj) {
51
50
  };
52
51
  }
53
52
  const DOM_COMPONENTS_BUNDLE_DIR = 'www.bundle';
54
- const checkWebViewInstalled = (0, _fn.memoize)((projectRoot)=>{
55
- const webViewInstalled = _resolvefrom().default.silent(projectRoot, 'react-native-webview') || _resolvefrom().default.silent(projectRoot, '@expo/dom-webview');
56
- if (!webViewInstalled) {
57
- throw new Error(`To use DOM Components, you must install the 'react-native-webview' package. Run 'npx expo install react-native-webview' to install it.`);
58
- }
59
- });
60
53
  function createDomComponentsMiddleware({ projectRoot }, instanceMetroOptions) {
61
54
  return (req, res, next)=>{
62
55
  if (!req.url) return next();
@@ -72,7 +65,6 @@ function createDomComponentsMiddleware({ projectRoot }, instanceMetroOptions) {
72
65
  res.statusMessage = 'Invalid file path: ' + file;
73
66
  return res.end();
74
67
  }
75
- checkWebViewInstalled(projectRoot);
76
68
  // NOTE(@kitten): Keep in sync with `src/export/exportDomComponents.ts`
77
69
  // Generate a unique entry file for the webview.
78
70
  const virtualEntry = (0, _resolvefrom().default)(projectRoot, 'expo/dom/entry.js');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/middleware/DomComponentsMiddleware.ts"],"sourcesContent":["import { convertEntryPointToRelative } from '@expo/config/paths';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { DOM_POLYFILLS_SCRIPT } from './domPolyfills';\nimport type { ExpoMetroOptions } from './metroOptions';\nimport { createBundleUrlPath } from './metroOptions';\nimport type { ServerRequest, ServerResponse } from './server.types';\nimport { toPosixPath } from '../../../utils/filePath';\nimport { memoize } from '../../../utils/fn';\nimport { fileURLToFilePath } from '../metro/createServerComponentsMiddleware';\n\nexport type PickPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\nexport const DOM_COMPONENTS_BUNDLE_DIR = 'www.bundle';\n\nconst checkWebViewInstalled = memoize((projectRoot: string) => {\n const webViewInstalled =\n resolveFrom.silent(projectRoot, 'react-native-webview') ||\n resolveFrom.silent(projectRoot, '@expo/dom-webview');\n if (!webViewInstalled) {\n throw new Error(\n `To use DOM Components, you must install the 'react-native-webview' package. Run 'npx expo install react-native-webview' to install it.`\n );\n }\n});\n\ntype CreateDomComponentsMiddlewareOptions = {\n /** The absolute project root, used to resolve the `expo/dom/entry.js` path */\n projectRoot: string;\n};\n\nexport function createDomComponentsMiddleware(\n { projectRoot }: CreateDomComponentsMiddlewareOptions,\n instanceMetroOptions: PickPartial<ExpoMetroOptions, 'mainModuleName' | 'platform' | 'bytecode'>\n) {\n return (req: ServerRequest, res: ServerResponse, next: (err?: Error) => void) => {\n if (!req.url) return next();\n\n const url = coerceUrl(req.url);\n\n // Match `/_expo/@dom`.\n // This URL can contain additional paths like `/_expo/@dom/foo.js?file=...` to help the Safari dev tools.\n if (!url.pathname.startsWith('/_expo/@dom')) {\n return next();\n }\n\n const file = url.searchParams.get('file');\n\n if (!file || !file.startsWith('file://')) {\n res.statusCode = 400;\n res.statusMessage = 'Invalid file path: ' + file;\n return res.end();\n }\n\n checkWebViewInstalled(projectRoot);\n\n // NOTE(@kitten): Keep in sync with `src/export/exportDomComponents.ts`\n // Generate a unique entry file for the webview.\n const virtualEntry = resolveFrom(projectRoot, 'expo/dom/entry.js');\n const generatedEntryPath = path.resolve(\n file.startsWith('file://') ? fileURLToFilePath(file) : file\n );\n // The relative import path will be used like URI so it must be POSIX.\n const relativeImport =\n './' + toPosixPath(path.relative(path.dirname(virtualEntry), generatedEntryPath));\n // Create the script URL\n const requestUrlBase = `http://${req.headers.host}`;\n // NOTE(@kitten): Keep in sync with `src/export/exportDomComponents.ts`\n const metroUrl = new URL(\n createBundleUrlPath({\n ...instanceMetroOptions,\n domRoot: encodeURI(relativeImport),\n baseUrl: '/',\n mainModuleName: convertEntryPointToRelative(projectRoot, virtualEntry),\n bytecode: false,\n platform: 'web',\n isExporting: false,\n engine: 'hermes',\n // Required for ensuring bundler errors are caught in the root entry / async boundary and can be recovered from automatically.\n lazy: true,\n }),\n requestUrlBase\n ).toString();\n\n res.statusCode = 200;\n // Return HTML file\n res.setHeader('Content-Type', 'text/html');\n\n res.end(\n // Create the entry HTML file.\n getDomComponentHtml(metroUrl, { title: path.basename(file) })\n );\n };\n}\n\nfunction coerceUrl(url: string) {\n try {\n return new URL(url);\n } catch {\n return new URL(url, 'https://localhost:0');\n }\n}\n\nexport function getDomComponentHtml(src?: string, { title }: { title?: string } = {}) {\n // This HTML is not optimized for `react-native-web` since DOM Components are meant for general React DOM web development.\n return `\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <meta httpEquiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n ${title ? `<title>${title}</title>` : ''}\n <style id=\"expo-dom-component-style\">\n /* These styles make the body full-height */\n html,\n body {\n -webkit-overflow-scrolling: touch; /* Enables smooth momentum scrolling */\n }\n /* These styles make the root element full-height */\n #root {\n display: flex;\n flex: 1;\n }\n </style>\n </head>\n <body>\n <noscript>DOM Components require <code>javaScriptEnabled</code></noscript>\n <!-- Root element for the DOM component. -->\n <div id=\"root\"></div>\n <script>${DOM_POLYFILLS_SCRIPT}</script>\n <script>\n var injectedObject = {};\n try {\n injectedObject = JSON.parse(window.ReactNativeWebView.injectedObjectJson());\n } catch (e) {\n throw new Error('Failed to parse injectedObjectJson: ' + e.message);\n }\n window.$$EXPO_DOM_HOST_OS = injectedObject.EXPO_DOM_HOST_OS;\n window.$$EXPO_INITIAL_PROPS = injectedObject.initialProps;\n </script>\n ${src ? `<script crossorigin src=\"${src.replace(/^https?:/, '')}\"></script>` : ''}\n </body>\n</html>`;\n}\n"],"names":["DOM_COMPONENTS_BUNDLE_DIR","createDomComponentsMiddleware","getDomComponentHtml","checkWebViewInstalled","memoize","projectRoot","webViewInstalled","resolveFrom","silent","Error","instanceMetroOptions","req","res","next","url","coerceUrl","pathname","startsWith","file","searchParams","get","statusCode","statusMessage","end","virtualEntry","generatedEntryPath","path","resolve","fileURLToFilePath","relativeImport","toPosixPath","relative","dirname","requestUrlBase","headers","host","metroUrl","URL","createBundleUrlPath","domRoot","encodeURI","baseUrl","mainModuleName","convertEntryPointToRelative","bytecode","platform","isExporting","engine","lazy","toString","setHeader","title","basename","src","DOM_POLYFILLS_SCRIPT","replace"],"mappings":";;;;;;;;;;;QAcaA;eAAAA;;QAkBGC;eAAAA;;QAwEAC;eAAAA;;;;yBAxG4B;;;;;;;gEAC3B;;;;;;;gEACO;;;;;;8BAEa;8BAED;0BAER;oBACJ;kDACU;;;;;;AAI3B,MAAMF,4BAA4B;AAEzC,MAAMG,wBAAwBC,IAAAA,WAAO,EAAC,CAACC;IACrC,MAAMC,mBACJC,sBAAW,CAACC,MAAM,CAACH,aAAa,2BAChCE,sBAAW,CAACC,MAAM,CAACH,aAAa;IAClC,IAAI,CAACC,kBAAkB;QACrB,MAAM,IAAIG,MACR,CAAC,sIAAsI,CAAC;IAE5I;AACF;AAOO,SAASR,8BACd,EAAEI,WAAW,EAAwC,EACrDK,oBAA+F;IAE/F,OAAO,CAACC,KAAoBC,KAAqBC;QAC/C,IAAI,CAACF,IAAIG,GAAG,EAAE,OAAOD;QAErB,MAAMC,MAAMC,UAAUJ,IAAIG,GAAG;QAE7B,uBAAuB;QACvB,yGAAyG;QACzG,IAAI,CAACA,IAAIE,QAAQ,CAACC,UAAU,CAAC,gBAAgB;YAC3C,OAAOJ;QACT;QAEA,MAAMK,OAAOJ,IAAIK,YAAY,CAACC,GAAG,CAAC;QAElC,IAAI,CAACF,QAAQ,CAACA,KAAKD,UAAU,CAAC,YAAY;YACxCL,IAAIS,UAAU,GAAG;YACjBT,IAAIU,aAAa,GAAG,wBAAwBJ;YAC5C,OAAON,IAAIW,GAAG;QAChB;QAEApB,sBAAsBE;QAEtB,uEAAuE;QACvE,gDAAgD;QAChD,MAAMmB,eAAejB,IAAAA,sBAAW,EAACF,aAAa;QAC9C,MAAMoB,qBAAqBC,eAAI,CAACC,OAAO,CACrCT,KAAKD,UAAU,CAAC,aAAaW,IAAAA,mDAAiB,EAACV,QAAQA;QAEzD,sEAAsE;QACtE,MAAMW,iBACJ,OAAOC,IAAAA,qBAAW,EAACJ,eAAI,CAACK,QAAQ,CAACL,eAAI,CAACM,OAAO,CAACR,eAAeC;QAC/D,wBAAwB;QACxB,MAAMQ,iBAAiB,CAAC,OAAO,EAAEtB,IAAIuB,OAAO,CAACC,IAAI,EAAE;QACnD,uEAAuE;QACvE,MAAMC,WAAW,IAAIC,IACnBC,IAAAA,iCAAmB,EAAC;YAClB,GAAG5B,oBAAoB;YACvB6B,SAASC,UAAUX;YACnBY,SAAS;YACTC,gBAAgBC,IAAAA,oCAA2B,EAACtC,aAAamB;YACzDoB,UAAU;YACVC,UAAU;YACVC,aAAa;YACbC,QAAQ;YACR,8HAA8H;YAC9HC,MAAM;QACR,IACAf,gBACAgB,QAAQ;QAEVrC,IAAIS,UAAU,GAAG;QACjB,mBAAmB;QACnBT,IAAIsC,SAAS,CAAC,gBAAgB;QAE9BtC,IAAIW,GAAG,CACL,8BAA8B;QAC9BrB,oBAAoBkC,UAAU;YAAEe,OAAOzB,eAAI,CAAC0B,QAAQ,CAAClC;QAAM;IAE/D;AACF;AAEA,SAASH,UAAUD,GAAW;IAC5B,IAAI;QACF,OAAO,IAAIuB,IAAIvB;IACjB,EAAE,OAAM;QACN,OAAO,IAAIuB,IAAIvB,KAAK;IACtB;AACF;AAEO,SAASZ,oBAAoBmD,GAAY,EAAE,EAAEF,KAAK,EAAsB,GAAG,CAAC,CAAC;IAClF,0HAA0H;IAC1H,OAAO,CAAC;;;;;;;QAOF,EAAEA,QAAQ,CAAC,OAAO,EAAEA,MAAM,QAAQ,CAAC,GAAG,GAAG;;;;;;;;;;;;;;;;;;gBAkBjC,EAAEG,kCAAoB,CAAC;;;;;;;;;;;QAW/B,EAAED,MAAM,CAAC,yBAAyB,EAAEA,IAAIE,OAAO,CAAC,YAAY,IAAI,WAAW,CAAC,GAAG,GAAG;;OAEnF,CAAC;AACR"}
1
+ {"version":3,"sources":["../../../../../src/start/server/middleware/DomComponentsMiddleware.ts"],"sourcesContent":["import { convertEntryPointToRelative } from '@expo/config/paths';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { DOM_POLYFILLS_SCRIPT } from './domPolyfills';\nimport type { ExpoMetroOptions } from './metroOptions';\nimport { createBundleUrlPath } from './metroOptions';\nimport type { ServerRequest, ServerResponse } from './server.types';\nimport { toPosixPath } from '../../../utils/filePath';\nimport { fileURLToFilePath } from '../metro/createServerComponentsMiddleware';\n\nexport type PickPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\nexport const DOM_COMPONENTS_BUNDLE_DIR = 'www.bundle';\n\ntype CreateDomComponentsMiddlewareOptions = {\n /** The absolute project root, used to resolve the `expo/dom/entry.js` path */\n projectRoot: string;\n};\n\nexport function createDomComponentsMiddleware(\n { projectRoot }: CreateDomComponentsMiddlewareOptions,\n instanceMetroOptions: PickPartial<ExpoMetroOptions, 'mainModuleName' | 'platform' | 'bytecode'>\n) {\n return (req: ServerRequest, res: ServerResponse, next: (err?: Error) => void) => {\n if (!req.url) return next();\n\n const url = coerceUrl(req.url);\n\n // Match `/_expo/@dom`.\n // This URL can contain additional paths like `/_expo/@dom/foo.js?file=...` to help the Safari dev tools.\n if (!url.pathname.startsWith('/_expo/@dom')) {\n return next();\n }\n\n const file = url.searchParams.get('file');\n\n if (!file || !file.startsWith('file://')) {\n res.statusCode = 400;\n res.statusMessage = 'Invalid file path: ' + file;\n return res.end();\n }\n\n // NOTE(@kitten): Keep in sync with `src/export/exportDomComponents.ts`\n // Generate a unique entry file for the webview.\n const virtualEntry = resolveFrom(projectRoot, 'expo/dom/entry.js');\n const generatedEntryPath = path.resolve(\n file.startsWith('file://') ? fileURLToFilePath(file) : file\n );\n // The relative import path will be used like URI so it must be POSIX.\n const relativeImport =\n './' + toPosixPath(path.relative(path.dirname(virtualEntry), generatedEntryPath));\n // Create the script URL\n const requestUrlBase = `http://${req.headers.host}`;\n // NOTE(@kitten): Keep in sync with `src/export/exportDomComponents.ts`\n const metroUrl = new URL(\n createBundleUrlPath({\n ...instanceMetroOptions,\n domRoot: encodeURI(relativeImport),\n baseUrl: '/',\n mainModuleName: convertEntryPointToRelative(projectRoot, virtualEntry),\n bytecode: false,\n platform: 'web',\n isExporting: false,\n engine: 'hermes',\n // Required for ensuring bundler errors are caught in the root entry / async boundary and can be recovered from automatically.\n lazy: true,\n }),\n requestUrlBase\n ).toString();\n\n res.statusCode = 200;\n // Return HTML file\n res.setHeader('Content-Type', 'text/html');\n\n res.end(\n // Create the entry HTML file.\n getDomComponentHtml(metroUrl, { title: path.basename(file) })\n );\n };\n}\n\nfunction coerceUrl(url: string) {\n try {\n return new URL(url);\n } catch {\n return new URL(url, 'https://localhost:0');\n }\n}\n\nexport function getDomComponentHtml(src?: string, { title }: { title?: string } = {}) {\n // This HTML is not optimized for `react-native-web` since DOM Components are meant for general React DOM web development.\n return `\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <meta httpEquiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n ${title ? `<title>${title}</title>` : ''}\n <style id=\"expo-dom-component-style\">\n /* These styles make the body full-height */\n html,\n body {\n -webkit-overflow-scrolling: touch; /* Enables smooth momentum scrolling */\n }\n /* These styles make the root element full-height */\n #root {\n display: flex;\n flex: 1;\n }\n </style>\n </head>\n <body>\n <noscript>DOM Components require <code>javaScriptEnabled</code></noscript>\n <!-- Root element for the DOM component. -->\n <div id=\"root\"></div>\n <script>${DOM_POLYFILLS_SCRIPT}</script>\n <script>\n var injectedObject = {};\n try {\n injectedObject = JSON.parse(window.ReactNativeWebView.injectedObjectJson());\n } catch (e) {\n throw new Error('Failed to parse injectedObjectJson: ' + e.message);\n }\n window.$$EXPO_DOM_HOST_OS = injectedObject.EXPO_DOM_HOST_OS;\n window.$$EXPO_INITIAL_PROPS = injectedObject.initialProps;\n </script>\n ${src ? `<script crossorigin src=\"${src.replace(/^https?:/, '')}\"></script>` : ''}\n </body>\n</html>`;\n}\n"],"names":["DOM_COMPONENTS_BUNDLE_DIR","createDomComponentsMiddleware","getDomComponentHtml","projectRoot","instanceMetroOptions","req","res","next","url","coerceUrl","pathname","startsWith","file","searchParams","get","statusCode","statusMessage","end","virtualEntry","resolveFrom","generatedEntryPath","path","resolve","fileURLToFilePath","relativeImport","toPosixPath","relative","dirname","requestUrlBase","headers","host","metroUrl","URL","createBundleUrlPath","domRoot","encodeURI","baseUrl","mainModuleName","convertEntryPointToRelative","bytecode","platform","isExporting","engine","lazy","toString","setHeader","title","basename","src","DOM_POLYFILLS_SCRIPT","replace"],"mappings":";;;;;;;;;;;QAaaA;eAAAA;;QAOGC;eAAAA;;QAsEAC;eAAAA;;;;yBA1F4B;;;;;;;gEAC3B;;;;;;;gEACO;;;;;;8BAEa;8BAED;0BAER;kDACM;;;;;;AAI3B,MAAMF,4BAA4B;AAOlC,SAASC,8BACd,EAAEE,WAAW,EAAwC,EACrDC,oBAA+F;IAE/F,OAAO,CAACC,KAAoBC,KAAqBC;QAC/C,IAAI,CAACF,IAAIG,GAAG,EAAE,OAAOD;QAErB,MAAMC,MAAMC,UAAUJ,IAAIG,GAAG;QAE7B,uBAAuB;QACvB,yGAAyG;QACzG,IAAI,CAACA,IAAIE,QAAQ,CAACC,UAAU,CAAC,gBAAgB;YAC3C,OAAOJ;QACT;QAEA,MAAMK,OAAOJ,IAAIK,YAAY,CAACC,GAAG,CAAC;QAElC,IAAI,CAACF,QAAQ,CAACA,KAAKD,UAAU,CAAC,YAAY;YACxCL,IAAIS,UAAU,GAAG;YACjBT,IAAIU,aAAa,GAAG,wBAAwBJ;YAC5C,OAAON,IAAIW,GAAG;QAChB;QAEA,uEAAuE;QACvE,gDAAgD;QAChD,MAAMC,eAAeC,IAAAA,sBAAW,EAAChB,aAAa;QAC9C,MAAMiB,qBAAqBC,eAAI,CAACC,OAAO,CACrCV,KAAKD,UAAU,CAAC,aAAaY,IAAAA,mDAAiB,EAACX,QAAQA;QAEzD,sEAAsE;QACtE,MAAMY,iBACJ,OAAOC,IAAAA,qBAAW,EAACJ,eAAI,CAACK,QAAQ,CAACL,eAAI,CAACM,OAAO,CAACT,eAAeE;QAC/D,wBAAwB;QACxB,MAAMQ,iBAAiB,CAAC,OAAO,EAAEvB,IAAIwB,OAAO,CAACC,IAAI,EAAE;QACnD,uEAAuE;QACvE,MAAMC,WAAW,IAAIC,IACnBC,IAAAA,iCAAmB,EAAC;YAClB,GAAG7B,oBAAoB;YACvB8B,SAASC,UAAUX;YACnBY,SAAS;YACTC,gBAAgBC,IAAAA,oCAA2B,EAACnC,aAAae;YACzDqB,UAAU;YACVC,UAAU;YACVC,aAAa;YACbC,QAAQ;YACR,8HAA8H;YAC9HC,MAAM;QACR,IACAf,gBACAgB,QAAQ;QAEVtC,IAAIS,UAAU,GAAG;QACjB,mBAAmB;QACnBT,IAAIuC,SAAS,CAAC,gBAAgB;QAE9BvC,IAAIW,GAAG,CACL,8BAA8B;QAC9Bf,oBAAoB6B,UAAU;YAAEe,OAAOzB,eAAI,CAAC0B,QAAQ,CAACnC;QAAM;IAE/D;AACF;AAEA,SAASH,UAAUD,GAAW;IAC5B,IAAI;QACF,OAAO,IAAIwB,IAAIxB;IACjB,EAAE,OAAM;QACN,OAAO,IAAIwB,IAAIxB,KAAK;IACtB;AACF;AAEO,SAASN,oBAAoB8C,GAAY,EAAE,EAAEF,KAAK,EAAsB,GAAG,CAAC,CAAC;IAClF,0HAA0H;IAC1H,OAAO,CAAC;;;;;;;QAOF,EAAEA,QAAQ,CAAC,OAAO,EAAEA,MAAM,QAAQ,CAAC,GAAG,GAAG;;;;;;;;;;;;;;;;;;gBAkBjC,EAAEG,kCAAoB,CAAC;;;;;;;;;;;QAW/B,EAAED,MAAM,CAAC,yBAAyB,EAAEA,IAAIE,OAAO,CAAC,YAAY,IAAI,WAAW,CAAC,GAAG,GAAG;;OAEnF,CAAC;AACR"}
@@ -137,9 +137,9 @@ async function startAsync(projectRoot, options, settings) {
137
137
  const { exp, pkg } = (0, _profile.profile)(_config().getConfig)(projectRoot);
138
138
  // Start dependency version check in the background as early as possible (non-blocking).
139
139
  // The result will be displayed in the TUI once it resolves.
140
- let dependencyCheckPromise;
140
+ let dependencyCheckRef;
141
141
  if (!_env.env.EXPO_OFFLINE && !_env.env.EXPO_NO_DEPENDENCY_VALIDATION && !settings.webOnly) {
142
- dependencyCheckPromise = (0, _checkDependenciesOnStart.checkDependenciesAsync)(projectRoot, exp, pkg).catch(()=>null);
142
+ dependencyCheckRef = (0, _checkDependenciesOnStart.checkDependencies)(projectRoot, exp, pkg);
143
143
  }
144
144
  if (((_exp_platforms = exp.platforms) == null ? void 0 : _exp_platforms.includes('ios')) && process.platform !== 'win32') {
145
145
  // If Xcode could potentially be used, then we should eagerly perform the
@@ -181,7 +181,7 @@ async function startAsync(projectRoot, options, settings) {
181
181
  'web'
182
182
  ],
183
183
  mcpServer,
184
- dependencyCheckPromise
184
+ dependencyCheckRef
185
185
  });
186
186
  } else {
187
187
  // Display the server location in CI...
@@ -194,10 +194,9 @@ async function startAsync(projectRoot, options, settings) {
194
194
  }
195
195
  _log.log((0, _chalk().default)`Waiting on {underline ${defaultServerUrl}}`);
196
196
  }
197
- // In non-interactive mode, await the check and print if available.
198
- const result = await dependencyCheckPromise;
199
- if (result) {
200
- (0, _checkDependenciesOnStart.printDependencyCheckResult)(result);
197
+ // In non-interactive mode, print the check outside of an interface, if it's available
198
+ if (dependencyCheckRef == null ? void 0 : dependencyCheckRef.result) {
199
+ (0, _checkDependenciesOnStart.printDependencyCheckResult)(dependencyCheckRef.result);
201
200
  }
202
201
  }
203
202
  if (mcpServer) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/start/startAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport chalk from 'chalk';\n\nimport { getLogFile, shouldReduceLogs } from '../events';\nimport type { DependencyCheckResult } from './checkDependenciesOnStart';\nimport { checkDependenciesAsync, printDependencyCheckResult } from './checkDependenciesOnStart';\nimport { SimulatorAppPrerequisite } from './doctor/apple/SimulatorAppPrerequisite';\nimport { getXcodeVersionAsync } from './doctor/apple/XcodePrerequisite';\nimport { WebSupportProjectPrerequisite } from './doctor/web/WebSupportProjectPrerequisite';\nimport { startInterfaceAsync } from './interface/startInterface';\nimport type { Options } from './resolveOptions';\nimport { resolvePortsAsync } from './resolveOptions';\nimport * as Log from '../log';\nimport type { BundlerStartOptions } from './server/BundlerDevServer';\nimport type { MultiBundlerStartOptions } from './server/DevServerManager';\nimport { DevServerManager } from './server/DevServerManager';\nimport { maybeCreateMCPServerAsync } from './server/MCP';\nimport { openPlatformsAsync } from './server/openPlatforms';\nimport type { PlatformBundlers } from './server/platformBundlers';\nimport { getPlatformBundlers } from './server/platformBundlers';\nimport { env } from '../utils/env';\nimport { isInteractive } from '../utils/interactive';\nimport { profile } from '../utils/profile';\nimport { addMcpCapabilities } from './server/MCPDevToolsPluginCLIExtensions';\n\nasync function getMultiBundlerStartOptions(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean },\n platformBundlers: PlatformBundlers\n): Promise<[BundlerStartOptions, MultiBundlerStartOptions]> {\n const commonOptions: BundlerStartOptions = {\n mode: options.dev ? 'development' : 'production',\n devClient: options.devClient,\n privateKeyPath: options.privateKeyPath ?? undefined,\n https: options.https,\n maxWorkers: options.maxWorkers,\n resetDevServer: options.clear,\n minify: options.minify,\n location: {\n hostType: options.host,\n scheme: options.scheme,\n },\n };\n const multiBundlerSettings = await resolvePortsAsync(projectRoot, options, settings);\n\n const optionalBundlers: Partial<PlatformBundlers> = { ...platformBundlers };\n // In the default case, we don't want to start multiple bundlers since this is\n // a bit slower. Our priority (for legacy) is native platforms.\n if (!options.web) {\n delete optionalBundlers['web'];\n }\n\n const bundlers = [...new Set(Object.values(optionalBundlers))];\n const multiBundlerStartOptions = bundlers.map((bundler) => {\n const port =\n bundler === 'webpack' ? multiBundlerSettings.webpackPort : multiBundlerSettings.metroPort;\n return {\n type: bundler,\n options: {\n ...commonOptions,\n port,\n },\n };\n });\n\n return [commonOptions, multiBundlerStartOptions];\n}\n\nexport async function startAsync(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean }\n) {\n if (!shouldReduceLogs()) {\n Log.log(chalk.gray(`Starting project at ${projectRoot}`));\n const logFile = getLogFile();\n if (!isInteractive() && logFile) {\n Log.log(chalk.gray(`Logs: ${logFile}`));\n }\n }\n\n const { exp, pkg } = profile(getConfig)(projectRoot);\n\n // Start dependency version check in the background as early as possible (non-blocking).\n // The result will be displayed in the TUI once it resolves.\n let dependencyCheckPromise: Promise<DependencyCheckResult | null> | undefined;\n if (!env.EXPO_OFFLINE && !env.EXPO_NO_DEPENDENCY_VALIDATION && !settings.webOnly) {\n dependencyCheckPromise = checkDependenciesAsync(projectRoot, exp, pkg).catch(() => null);\n }\n\n if (exp.platforms?.includes('ios') && process.platform !== 'win32') {\n // If Xcode could potentially be used, then we should eagerly perform the\n // assertions since they can take a while on cold boots.\n getXcodeVersionAsync({ silent: true });\n SimulatorAppPrerequisite.instance.assertAsync().catch(() => {\n // noop -- this will be thrown again when the user attempts to open the project.\n });\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n const [defaultOptions, startOptions] = await getMultiBundlerStartOptions(\n projectRoot,\n options,\n settings,\n platformBundlers\n );\n\n const devServerManager = new DevServerManager(projectRoot, defaultOptions);\n\n // Validations\n\n if (options.web || settings.webOnly) {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n }\n\n // Start the server as soon as possible.\n await profile(devServerManager.startAsync.bind(devServerManager))(startOptions);\n\n if (!settings.webOnly) {\n await devServerManager.watchEnvironmentVariables();\n\n // After the server starts, we can start attempting to bootstrap TypeScript.\n await devServerManager.bootstrapTypeScriptAsync();\n }\n\n // Open project on devices.\n await profile(openPlatformsAsync)(devServerManager, options);\n\n const defaultServerUrl = devServerManager.getDefaultDevServer()?.getDevServerUrl() ?? '';\n const mcpServer =\n (await profile(maybeCreateMCPServerAsync)({\n projectRoot,\n devServerUrl: defaultServerUrl,\n })) ?? undefined;\n\n // Present the Terminal UI.\n if (isInteractive()) {\n await profile(startInterfaceAsync)(devServerManager, {\n platforms: exp.platforms ?? ['ios', 'android', 'web'],\n mcpServer,\n dependencyCheckPromise,\n });\n } else {\n // Display the server location in CI...\n if (defaultServerUrl) {\n if (env.__EXPO_E2E_TEST) {\n // Print the URL to stdout for tests\n console.info(`[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: defaultServerUrl })}`);\n }\n Log.log(chalk`Waiting on {underline ${defaultServerUrl}}`);\n }\n // In non-interactive mode, await the check and print if available.\n const result = await dependencyCheckPromise;\n if (result) {\n printDependencyCheckResult(result);\n }\n }\n\n if (mcpServer) {\n addMcpCapabilities(mcpServer, devServerManager);\n mcpServer.start();\n }\n\n // Final note about closing the server.\n const logLocation = settings.webOnly ? 'in the browser console' : 'below';\n Log.log(\n chalk`Logs for your project will appear ${logLocation}.${\n isInteractive() ? chalk.dim(` Press Ctrl+C to exit.`) : ''\n }`\n );\n}\n"],"names":["startAsync","getMultiBundlerStartOptions","projectRoot","options","settings","platformBundlers","commonOptions","mode","dev","devClient","privateKeyPath","undefined","https","maxWorkers","resetDevServer","clear","minify","location","hostType","host","scheme","multiBundlerSettings","resolvePortsAsync","optionalBundlers","web","bundlers","Set","Object","values","multiBundlerStartOptions","map","bundler","port","webpackPort","metroPort","type","exp","devServerManager","shouldReduceLogs","Log","log","chalk","gray","logFile","getLogFile","isInteractive","pkg","profile","getConfig","dependencyCheckPromise","env","EXPO_OFFLINE","EXPO_NO_DEPENDENCY_VALIDATION","webOnly","checkDependenciesAsync","catch","platforms","includes","process","platform","getXcodeVersionAsync","silent","SimulatorAppPrerequisite","instance","assertAsync","getPlatformBundlers","defaultOptions","startOptions","DevServerManager","ensureProjectPrerequisiteAsync","WebSupportProjectPrerequisite","bind","watchEnvironmentVariables","bootstrapTypeScriptAsync","openPlatformsAsync","defaultServerUrl","getDefaultDevServer","getDevServerUrl","mcpServer","maybeCreateMCPServerAsync","devServerUrl","startInterfaceAsync","__EXPO_E2E_TEST","console","info","JSON","stringify","url","result","printDependencyCheckResult","addMcpCapabilities","start","logLocation","dim"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/start/startAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport chalk from 'chalk';\n\nimport { getLogFile, shouldReduceLogs } from '../events';\nimport {\n checkDependencies,\n printDependencyCheckResult,\n type DependencyCheckRef,\n} from './checkDependenciesOnStart';\nimport { SimulatorAppPrerequisite } from './doctor/apple/SimulatorAppPrerequisite';\nimport { getXcodeVersionAsync } from './doctor/apple/XcodePrerequisite';\nimport { WebSupportProjectPrerequisite } from './doctor/web/WebSupportProjectPrerequisite';\nimport { startInterfaceAsync } from './interface/startInterface';\nimport type { Options } from './resolveOptions';\nimport { resolvePortsAsync } from './resolveOptions';\nimport * as Log from '../log';\nimport type { BundlerStartOptions } from './server/BundlerDevServer';\nimport type { MultiBundlerStartOptions } from './server/DevServerManager';\nimport { DevServerManager } from './server/DevServerManager';\nimport { maybeCreateMCPServerAsync } from './server/MCP';\nimport { openPlatformsAsync } from './server/openPlatforms';\nimport type { PlatformBundlers } from './server/platformBundlers';\nimport { getPlatformBundlers } from './server/platformBundlers';\nimport { env } from '../utils/env';\nimport { isInteractive } from '../utils/interactive';\nimport { profile } from '../utils/profile';\nimport { addMcpCapabilities } from './server/MCPDevToolsPluginCLIExtensions';\n\nasync function getMultiBundlerStartOptions(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean },\n platformBundlers: PlatformBundlers\n): Promise<[BundlerStartOptions, MultiBundlerStartOptions]> {\n const commonOptions: BundlerStartOptions = {\n mode: options.dev ? 'development' : 'production',\n devClient: options.devClient,\n privateKeyPath: options.privateKeyPath ?? undefined,\n https: options.https,\n maxWorkers: options.maxWorkers,\n resetDevServer: options.clear,\n minify: options.minify,\n location: {\n hostType: options.host,\n scheme: options.scheme,\n },\n };\n const multiBundlerSettings = await resolvePortsAsync(projectRoot, options, settings);\n\n const optionalBundlers: Partial<PlatformBundlers> = { ...platformBundlers };\n // In the default case, we don't want to start multiple bundlers since this is\n // a bit slower. Our priority (for legacy) is native platforms.\n if (!options.web) {\n delete optionalBundlers['web'];\n }\n\n const bundlers = [...new Set(Object.values(optionalBundlers))];\n const multiBundlerStartOptions = bundlers.map((bundler) => {\n const port =\n bundler === 'webpack' ? multiBundlerSettings.webpackPort : multiBundlerSettings.metroPort;\n return {\n type: bundler,\n options: {\n ...commonOptions,\n port,\n },\n };\n });\n\n return [commonOptions, multiBundlerStartOptions];\n}\n\nexport async function startAsync(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean }\n) {\n if (!shouldReduceLogs()) {\n Log.log(chalk.gray(`Starting project at ${projectRoot}`));\n const logFile = getLogFile();\n if (!isInteractive() && logFile) {\n Log.log(chalk.gray(`Logs: ${logFile}`));\n }\n }\n\n const { exp, pkg } = profile(getConfig)(projectRoot);\n\n // Start dependency version check in the background as early as possible (non-blocking).\n // The result will be displayed in the TUI once it resolves.\n let dependencyCheckRef: DependencyCheckRef | undefined;\n if (!env.EXPO_OFFLINE && !env.EXPO_NO_DEPENDENCY_VALIDATION && !settings.webOnly) {\n dependencyCheckRef = checkDependencies(projectRoot, exp, pkg);\n }\n\n if (exp.platforms?.includes('ios') && process.platform !== 'win32') {\n // If Xcode could potentially be used, then we should eagerly perform the\n // assertions since they can take a while on cold boots.\n getXcodeVersionAsync({ silent: true });\n SimulatorAppPrerequisite.instance.assertAsync().catch(() => {\n // noop -- this will be thrown again when the user attempts to open the project.\n });\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n const [defaultOptions, startOptions] = await getMultiBundlerStartOptions(\n projectRoot,\n options,\n settings,\n platformBundlers\n );\n\n const devServerManager = new DevServerManager(projectRoot, defaultOptions);\n\n // Validations\n\n if (options.web || settings.webOnly) {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n }\n\n // Start the server as soon as possible.\n await profile(devServerManager.startAsync.bind(devServerManager))(startOptions);\n\n if (!settings.webOnly) {\n await devServerManager.watchEnvironmentVariables();\n\n // After the server starts, we can start attempting to bootstrap TypeScript.\n await devServerManager.bootstrapTypeScriptAsync();\n }\n\n // Open project on devices.\n await profile(openPlatformsAsync)(devServerManager, options);\n\n const defaultServerUrl = devServerManager.getDefaultDevServer()?.getDevServerUrl() ?? '';\n const mcpServer =\n (await profile(maybeCreateMCPServerAsync)({\n projectRoot,\n devServerUrl: defaultServerUrl,\n })) ?? undefined;\n\n // Present the Terminal UI.\n if (isInteractive()) {\n await profile(startInterfaceAsync)(devServerManager, {\n platforms: exp.platforms ?? ['ios', 'android', 'web'],\n mcpServer,\n dependencyCheckRef,\n });\n } else {\n // Display the server location in CI...\n if (defaultServerUrl) {\n if (env.__EXPO_E2E_TEST) {\n // Print the URL to stdout for tests\n console.info(`[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: defaultServerUrl })}`);\n }\n Log.log(chalk`Waiting on {underline ${defaultServerUrl}}`);\n }\n // In non-interactive mode, print the check outside of an interface, if it's available\n if (dependencyCheckRef?.result) {\n printDependencyCheckResult(dependencyCheckRef.result);\n }\n }\n\n if (mcpServer) {\n addMcpCapabilities(mcpServer, devServerManager);\n mcpServer.start();\n }\n\n // Final note about closing the server.\n const logLocation = settings.webOnly ? 'in the browser console' : 'below';\n Log.log(\n chalk`Logs for your project will appear ${logLocation}.${\n isInteractive() ? chalk.dim(` Press Ctrl+C to exit.`) : ''\n }`\n );\n}\n"],"names":["startAsync","getMultiBundlerStartOptions","projectRoot","options","settings","platformBundlers","commonOptions","mode","dev","devClient","privateKeyPath","undefined","https","maxWorkers","resetDevServer","clear","minify","location","hostType","host","scheme","multiBundlerSettings","resolvePortsAsync","optionalBundlers","web","bundlers","Set","Object","values","multiBundlerStartOptions","map","bundler","port","webpackPort","metroPort","type","exp","devServerManager","shouldReduceLogs","Log","log","chalk","gray","logFile","getLogFile","isInteractive","pkg","profile","getConfig","dependencyCheckRef","env","EXPO_OFFLINE","EXPO_NO_DEPENDENCY_VALIDATION","webOnly","checkDependencies","platforms","includes","process","platform","getXcodeVersionAsync","silent","SimulatorAppPrerequisite","instance","assertAsync","catch","getPlatformBundlers","defaultOptions","startOptions","DevServerManager","ensureProjectPrerequisiteAsync","WebSupportProjectPrerequisite","bind","watchEnvironmentVariables","bootstrapTypeScriptAsync","openPlatformsAsync","defaultServerUrl","getDefaultDevServer","getDevServerUrl","mcpServer","maybeCreateMCPServerAsync","devServerUrl","startInterfaceAsync","__EXPO_E2E_TEST","console","info","JSON","stringify","url","result","printDependencyCheckResult","addMcpCapabilities","start","logLocation","dim"],"mappings":"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"}
@@ -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/${"56.0.5"}`,
29
+ 'user-agent': `expo-cli/${"56.0.6"}`,
30
30
  authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
31
31
  };
32
32
  }
@@ -83,7 +83,7 @@ function createContext() {
83
83
  cpu: summarizeCpuInfo(),
84
84
  app: {
85
85
  name: 'expo/cli',
86
- version: "56.0.5"
86
+ version: "56.0.6"
87
87
  },
88
88
  ci: _ciinfo().isCI ? {
89
89
  name: _ciinfo().name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/cli",
3
- "version": "56.0.5",
3
+ "version": "56.0.6",
4
4
  "description": "The Expo CLI",
5
5
  "main": "main.js",
6
6
  "bin": {
@@ -46,9 +46,9 @@
46
46
  "@expo/image-utils": "^0.9.0",
47
47
  "@expo/inline-modules": "0.0.4",
48
48
  "@expo/json-file": "^10.1.0",
49
- "@expo/log-box": "56.0.4",
49
+ "@expo/log-box": "56.0.5",
50
50
  "@expo/metro": "~56.0.0",
51
- "@expo/metro-config": "~56.0.3",
51
+ "@expo/metro-config": "~56.0.4",
52
52
  "@expo/metro-file-map": "56.0.0-2",
53
53
  "@expo/osascript": "^2.5.0",
54
54
  "@expo/package-manager": "^1.11.0",
@@ -59,7 +59,7 @@
59
59
  "@expo/schema-utils": "^56.0.0",
60
60
  "@expo/spawn-async": "^1.7.2",
61
61
  "@expo/ws-tunnel": "^1.0.1",
62
- "@expo/xcpretty": "^4.4.0",
62
+ "@expo/xcpretty": "^4.4.4",
63
63
  "@react-native/dev-middleware": "0.85.3",
64
64
  "accepts": "^1.3.8",
65
65
  "arg": "^5.0.2",
@@ -159,13 +159,13 @@
159
159
  "playwright": "^1.59.0",
160
160
  "taskr": "^1.1.0",
161
161
  "tree-kill": "^1.2.2",
162
- "@expo/fingerprint": "0.17.3",
163
- "expo": "56.0.0-preview.5",
162
+ "expo": "56.0.0-preview.6",
164
163
  "expo-module-scripts": "56.0.2",
164
+ "@expo/fingerprint": "0.17.3",
165
165
  "expo-modules-autolinking": "56.0.2",
166
- "expo-router": "56.0.4"
166
+ "expo-router": "56.1.0"
167
167
  },
168
- "gitHead": "a8ab3da510a34b7bdb2262aa9887d4f78b102280",
168
+ "gitHead": "d7b4e5edff4bf2e619d2c2f16d158798c6d592ef",
169
169
  "scripts": {
170
170
  "build": "taskr",
171
171
  "clean": "expo-module clean",