@expo/cli 55.0.7 → 55.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/build/bin/cli +13 -1
  2. package/build/bin/cli.map +1 -1
  3. package/build/src/config/configAsync.js +1 -1
  4. package/build/src/config/configAsync.js.map +1 -1
  5. package/build/src/customize/customizeAsync.js +1 -1
  6. package/build/src/customize/customizeAsync.js.map +1 -1
  7. package/build/src/export/embed/exportEmbedAsync.js +1 -1
  8. package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
  9. package/build/src/export/exportApp.js +1 -1
  10. package/build/src/export/exportApp.js.map +1 -1
  11. package/build/src/export/exportStaticAsync.js +7 -11
  12. package/build/src/export/exportStaticAsync.js.map +1 -1
  13. package/build/src/export/web/exportWebAsync.js +1 -1
  14. package/build/src/export/web/exportWebAsync.js.map +1 -1
  15. package/build/src/install/installAsync.js +1 -1
  16. package/build/src/install/installAsync.js.map +1 -1
  17. package/build/src/lint/lintAsync.js +1 -1
  18. package/build/src/lint/lintAsync.js.map +1 -1
  19. package/build/src/prebuild/prebuildAsync.js +1 -1
  20. package/build/src/prebuild/prebuildAsync.js.map +1 -1
  21. package/build/src/run/android/runAndroidAsync.js +1 -1
  22. package/build/src/run/android/runAndroidAsync.js.map +1 -1
  23. package/build/src/run/ios/runIosAsync.js +1 -1
  24. package/build/src/run/ios/runIosAsync.js.map +1 -1
  25. package/build/src/serve/serveAsync.js +1 -1
  26. package/build/src/serve/serveAsync.js.map +1 -1
  27. package/build/src/start/interface/commandsTable.js +89 -69
  28. package/build/src/start/interface/commandsTable.js.map +1 -1
  29. package/build/src/start/interface/interactiveActions.js +29 -14
  30. package/build/src/start/interface/interactiveActions.js.map +1 -1
  31. package/build/src/start/server/BundlerDevServer.js +16 -9
  32. package/build/src/start/server/BundlerDevServer.js.map +1 -1
  33. package/build/src/start/server/DevServerManager.js +5 -1
  34. package/build/src/start/server/DevServerManager.js.map +1 -1
  35. package/build/src/start/server/UrlCreator.js +17 -7
  36. package/build/src/start/server/UrlCreator.js.map +1 -1
  37. package/build/src/start/server/getStaticRenderFunctions.js +8 -8
  38. package/build/src/start/server/getStaticRenderFunctions.js.map +1 -1
  39. package/build/src/start/server/metro/MetroBundlerDevServer.js +20 -20
  40. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  41. package/build/src/start/server/metro/MetroTerminalReporter.js +1 -1
  42. package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
  43. package/build/src/start/server/metro/createServerComponentsMiddleware.js +1 -1
  44. package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
  45. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +18 -18
  46. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
  47. package/build/src/start/server/metro/log-box/LogBoxSymbolication.js +5 -1
  48. package/build/src/start/server/metro/log-box/LogBoxSymbolication.js.map +1 -1
  49. package/build/src/start/server/metro/resolveLoader.js +2 -0
  50. package/build/src/start/server/metro/resolveLoader.js.map +1 -1
  51. package/build/src/start/server/metro/runServer-fork.js +6 -5
  52. package/build/src/start/server/metro/runServer-fork.js.map +1 -1
  53. package/build/src/start/server/webpack/WebpackBundlerDevServer.js +4 -4
  54. package/build/src/start/server/webpack/WebpackBundlerDevServer.js.map +1 -1
  55. package/build/src/utils/editor.js +404 -31
  56. package/build/src/utils/editor.js.map +1 -1
  57. package/build/src/utils/getRunningProcess.js +80 -41
  58. package/build/src/utils/getRunningProcess.js.map +1 -1
  59. package/build/src/utils/ip.js +44 -8
  60. package/build/src/utils/ip.js.map +1 -1
  61. package/build/src/utils/nodeEnv.js +66 -1
  62. package/build/src/utils/nodeEnv.js.map +1 -1
  63. package/build/src/utils/port.js +2 -2
  64. package/build/src/utils/port.js.map +1 -1
  65. package/build/src/utils/qr.js +186 -0
  66. package/build/src/utils/qr.js.map +1 -0
  67. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  68. package/build/src/utils/telemetry/utils/context.js +1 -1
  69. package/package.json +16 -17
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/serve/serveAsync.ts"],"sourcesContent":["import chalk from 'chalk';\nimport connect from 'connect';\nimport { createRequestHandler } from 'expo-server/adapter/http';\nimport http from 'http';\nimport path from 'path';\nimport send from 'send';\n\nimport * as Log from '../log';\nimport { directoryExistsAsync, fileExistsAsync } from '../utils/dir';\nimport { CommandError } from '../utils/errors';\nimport { findUpProjectRootOrAssert } from '../utils/findUp';\nimport { setNodeEnv } from '../utils/nodeEnv';\nimport { resolvePortAsync } from '../utils/port';\n\ntype Options = {\n port?: number;\n isDefaultDirectory: boolean;\n};\n\nconst debug = require('debug')('expo:serve') as typeof console.log;\n\n// Start a basic http server\nexport async function serveAsync(inputDir: string, options: Options) {\n const projectRoot = findUpProjectRootOrAssert(inputDir);\n\n setNodeEnv('production');\n require('@expo/env').load(projectRoot);\n\n const port = await resolvePortAsync(projectRoot, {\n defaultPort: options.port,\n fallbackPort: 8081,\n });\n\n if (port == null) {\n throw new CommandError('Could not start server. Port is not available.');\n }\n options.port = port;\n\n const serverDist = options.isDefaultDirectory ? path.join(inputDir, 'dist') : inputDir;\n // TODO: `.expo/server/ios`, `.expo/server/android`, etc.\n\n if (!(await directoryExistsAsync(serverDist))) {\n throw new CommandError(\n `The server directory ${serverDist} does not exist. Run \\`npx expo export\\` first.`\n );\n }\n\n const isStatic = await isStaticExportAsync(serverDist);\n\n Log.log(chalk.dim(`Starting ${isStatic ? 'static ' : ''}server in ${serverDist}`));\n\n if (isStatic) {\n await startStaticServerAsync(serverDist, options);\n } else {\n await startDynamicServerAsync(serverDist, options);\n }\n Log.log(`Server running at http://localhost:${options.port}`);\n // Detect the type of server we need to setup:\n}\n\nasync function startStaticServerAsync(dist: string, options: Options) {\n const server = http.createServer((req, res) => {\n // Remove query strings and decode URI\n const filePath = decodeURI(req.url?.split('?')[0] ?? '');\n\n send(req, filePath, {\n root: dist,\n index: 'index.html',\n extensions: ['html'],\n })\n .on('error', (err: any) => {\n if (err.status === 404) {\n res.statusCode = 404;\n res.end('Not Found');\n return;\n }\n res.statusCode = err.status || 500;\n res.end('Internal Server Error');\n })\n .pipe(res);\n });\n\n server.listen(options.port!);\n}\n\nasync function startDynamicServerAsync(dist: string, options: Options) {\n const middleware = connect();\n\n const staticDirectory = path.join(dist, 'client');\n const serverDirectory = path.join(dist, 'server');\n\n const serverHandler = createRequestHandler({ build: serverDirectory });\n\n // DOM component CORS support\n middleware.use((req, res, next) => {\n // TODO: Only when origin is `file://` (iOS), and Android equivalent.\n\n // Required for DOM components security in release builds.\n\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader(\n 'Access-Control-Allow-Headers',\n 'Origin, X-Requested-With, Content-Type, Accept, expo-platform'\n );\n\n // Handle OPTIONS preflight requests\n if (req.method === 'OPTIONS') {\n res.statusCode = 200;\n res.end();\n return;\n }\n next();\n });\n\n middleware.use((req, res, next) => {\n if (!req?.url || (req.method !== 'GET' && req.method !== 'HEAD')) {\n return next();\n }\n\n const pathname = canParseURL(req.url) ? new URL(req.url).pathname : req.url;\n if (!pathname) {\n return next();\n }\n\n debug(`Maybe serve static:`, pathname);\n\n const stream = send(req, pathname, {\n root: staticDirectory,\n extensions: ['html'],\n });\n\n // add file listener for fallthrough\n let forwardError = false;\n stream.on('file', function onFile() {\n // once file is determined, always forward error\n forwardError = true;\n });\n\n // forward errors\n stream.on('error', function error(err: any) {\n if (forwardError || !(err.statusCode < 500)) {\n next(err);\n return;\n }\n\n next();\n });\n\n // pipe\n stream.pipe(res);\n });\n\n middleware.use(serverHandler);\n\n middleware.listen(options.port!);\n}\n\nfunction canParseURL(url: string): boolean {\n try {\n // eslint-disable-next-line no-new\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isStaticExportAsync(dist: string): Promise<boolean> {\n const routesFile = path.join(dist, `server/_expo/routes.json`);\n return !(await fileExistsAsync(routesFile));\n}\n"],"names":["serveAsync","debug","require","inputDir","options","projectRoot","findUpProjectRootOrAssert","setNodeEnv","load","port","resolvePortAsync","defaultPort","fallbackPort","CommandError","serverDist","isDefaultDirectory","path","join","directoryExistsAsync","isStatic","isStaticExportAsync","Log","log","chalk","dim","startStaticServerAsync","startDynamicServerAsync","dist","server","http","createServer","req","res","filePath","decodeURI","url","split","send","root","index","extensions","on","err","status","statusCode","end","pipe","listen","middleware","connect","staticDirectory","serverDirectory","serverHandler","createRequestHandler","build","use","next","setHeader","method","pathname","canParseURL","URL","stream","forwardError","onFile","error","routesFile","fileExistsAsync"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/serve/serveAsync.ts"],"sourcesContent":["import chalk from 'chalk';\nimport connect from 'connect';\nimport { createRequestHandler } from 'expo-server/adapter/http';\nimport http from 'http';\nimport path from 'path';\nimport send from 'send';\n\nimport * as Log from '../log';\nimport { directoryExistsAsync, fileExistsAsync } from '../utils/dir';\nimport { CommandError } from '../utils/errors';\nimport { findUpProjectRootOrAssert } from '../utils/findUp';\nimport { setNodeEnv, loadEnvFiles } from '../utils/nodeEnv';\nimport { resolvePortAsync } from '../utils/port';\n\ntype Options = {\n port?: number;\n isDefaultDirectory: boolean;\n};\n\nconst debug = require('debug')('expo:serve') as typeof console.log;\n\n// Start a basic http server\nexport async function serveAsync(inputDir: string, options: Options) {\n const projectRoot = findUpProjectRootOrAssert(inputDir);\n\n setNodeEnv('production');\n loadEnvFiles(projectRoot);\n\n const port = await resolvePortAsync(projectRoot, {\n defaultPort: options.port,\n fallbackPort: 8081,\n });\n\n if (port == null) {\n throw new CommandError('Could not start server. Port is not available.');\n }\n options.port = port;\n\n const serverDist = options.isDefaultDirectory ? path.join(inputDir, 'dist') : inputDir;\n // TODO: `.expo/server/ios`, `.expo/server/android`, etc.\n\n if (!(await directoryExistsAsync(serverDist))) {\n throw new CommandError(\n `The server directory ${serverDist} does not exist. Run \\`npx expo export\\` first.`\n );\n }\n\n const isStatic = await isStaticExportAsync(serverDist);\n\n Log.log(chalk.dim(`Starting ${isStatic ? 'static ' : ''}server in ${serverDist}`));\n\n if (isStatic) {\n await startStaticServerAsync(serverDist, options);\n } else {\n await startDynamicServerAsync(serverDist, options);\n }\n Log.log(`Server running at http://localhost:${options.port}`);\n // Detect the type of server we need to setup:\n}\n\nasync function startStaticServerAsync(dist: string, options: Options) {\n const server = http.createServer((req, res) => {\n // Remove query strings and decode URI\n const filePath = decodeURI(req.url?.split('?')[0] ?? '');\n\n send(req, filePath, {\n root: dist,\n index: 'index.html',\n extensions: ['html'],\n })\n .on('error', (err: any) => {\n if (err.status === 404) {\n res.statusCode = 404;\n res.end('Not Found');\n return;\n }\n res.statusCode = err.status || 500;\n res.end('Internal Server Error');\n })\n .pipe(res);\n });\n\n server.listen(options.port!);\n}\n\nasync function startDynamicServerAsync(dist: string, options: Options) {\n const middleware = connect();\n\n const staticDirectory = path.join(dist, 'client');\n const serverDirectory = path.join(dist, 'server');\n\n const serverHandler = createRequestHandler({ build: serverDirectory });\n\n // DOM component CORS support\n middleware.use((req, res, next) => {\n // TODO: Only when origin is `file://` (iOS), and Android equivalent.\n\n // Required for DOM components security in release builds.\n\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader(\n 'Access-Control-Allow-Headers',\n 'Origin, X-Requested-With, Content-Type, Accept, expo-platform'\n );\n\n // Handle OPTIONS preflight requests\n if (req.method === 'OPTIONS') {\n res.statusCode = 200;\n res.end();\n return;\n }\n next();\n });\n\n middleware.use((req, res, next) => {\n if (!req?.url || (req.method !== 'GET' && req.method !== 'HEAD')) {\n return next();\n }\n\n const pathname = canParseURL(req.url) ? new URL(req.url).pathname : req.url;\n if (!pathname) {\n return next();\n }\n\n debug(`Maybe serve static:`, pathname);\n\n const stream = send(req, pathname, {\n root: staticDirectory,\n extensions: ['html'],\n });\n\n // add file listener for fallthrough\n let forwardError = false;\n stream.on('file', function onFile() {\n // once file is determined, always forward error\n forwardError = true;\n });\n\n // forward errors\n stream.on('error', function error(err: any) {\n if (forwardError || !(err.statusCode < 500)) {\n next(err);\n return;\n }\n\n next();\n });\n\n // pipe\n stream.pipe(res);\n });\n\n middleware.use(serverHandler);\n\n middleware.listen(options.port!);\n}\n\nfunction canParseURL(url: string): boolean {\n try {\n // eslint-disable-next-line no-new\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isStaticExportAsync(dist: string): Promise<boolean> {\n const routesFile = path.join(dist, `server/_expo/routes.json`);\n return !(await fileExistsAsync(routesFile));\n}\n"],"names":["serveAsync","debug","require","inputDir","options","projectRoot","findUpProjectRootOrAssert","setNodeEnv","loadEnvFiles","port","resolvePortAsync","defaultPort","fallbackPort","CommandError","serverDist","isDefaultDirectory","path","join","directoryExistsAsync","isStatic","isStaticExportAsync","Log","log","chalk","dim","startStaticServerAsync","startDynamicServerAsync","dist","server","http","createServer","req","res","filePath","decodeURI","url","split","send","root","index","extensions","on","err","status","statusCode","end","pipe","listen","middleware","connect","staticDirectory","serverDirectory","serverHandler","createRequestHandler","build","use","next","setHeader","method","pathname","canParseURL","URL","stream","forwardError","onFile","error","routesFile","fileExistsAsync"],"mappings":";;;;+BAsBsBA;;;eAAAA;;;;gEAtBJ;;;;;;;gEACE;;;;;;;yBACiB;;;;;;;gEACpB;;;;;;;gEACA;;;;;;;gEACA;;;;;;6DAEI;qBACiC;wBACzB;wBACa;yBACD;sBACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOjC,MAAMC,QAAQC,QAAQ,SAAS;AAGxB,eAAeF,WAAWG,QAAgB,EAAEC,OAAgB;IACjE,MAAMC,cAAcC,IAAAA,iCAAyB,EAACH;IAE9CI,IAAAA,mBAAU,EAAC;IACXC,IAAAA,qBAAY,EAACH;IAEb,MAAMI,OAAO,MAAMC,IAAAA,sBAAgB,EAACL,aAAa;QAC/CM,aAAaP,QAAQK,IAAI;QACzBG,cAAc;IAChB;IAEA,IAAIH,QAAQ,MAAM;QAChB,MAAM,IAAII,oBAAY,CAAC;IACzB;IACAT,QAAQK,IAAI,GAAGA;IAEf,MAAMK,aAAaV,QAAQW,kBAAkB,GAAGC,eAAI,CAACC,IAAI,CAACd,UAAU,UAAUA;IAC9E,0DAA0D;IAE1D,IAAI,CAAE,MAAMe,IAAAA,yBAAoB,EAACJ,aAAc;QAC7C,MAAM,IAAID,oBAAY,CACpB,CAAC,qBAAqB,EAAEC,WAAW,+CAA+C,CAAC;IAEvF;IAEA,MAAMK,WAAW,MAAMC,oBAAoBN;IAE3CO,KAAIC,GAAG,CAACC,gBAAK,CAACC,GAAG,CAAC,CAAC,SAAS,EAAEL,WAAW,YAAY,GAAG,UAAU,EAAEL,YAAY;IAEhF,IAAIK,UAAU;QACZ,MAAMM,uBAAuBX,YAAYV;IAC3C,OAAO;QACL,MAAMsB,wBAAwBZ,YAAYV;IAC5C;IACAiB,KAAIC,GAAG,CAAC,CAAC,mCAAmC,EAAElB,QAAQK,IAAI,EAAE;AAC5D,8CAA8C;AAChD;AAEA,eAAegB,uBAAuBE,IAAY,EAAEvB,OAAgB;IAClE,MAAMwB,SAASC,gBAAI,CAACC,YAAY,CAAC,CAACC,KAAKC;YAEVD;QAD3B,sCAAsC;QACtC,MAAME,WAAWC,UAAUH,EAAAA,WAAAA,IAAII,GAAG,qBAAPJ,SAASK,KAAK,CAAC,IAAI,CAAC,EAAE,KAAI;QAErDC,IAAAA,eAAI,EAACN,KAAKE,UAAU;YAClBK,MAAMX;YACNY,OAAO;YACPC,YAAY;gBAAC;aAAO;QACtB,GACGC,EAAE,CAAC,SAAS,CAACC;YACZ,IAAIA,IAAIC,MAAM,KAAK,KAAK;gBACtBX,IAAIY,UAAU,GAAG;gBACjBZ,IAAIa,GAAG,CAAC;gBACR;YACF;YACAb,IAAIY,UAAU,GAAGF,IAAIC,MAAM,IAAI;YAC/BX,IAAIa,GAAG,CAAC;QACV,GACCC,IAAI,CAACd;IACV;IAEAJ,OAAOmB,MAAM,CAAC3C,QAAQK,IAAI;AAC5B;AAEA,eAAeiB,wBAAwBC,IAAY,EAAEvB,OAAgB;IACnE,MAAM4C,aAAaC,IAAAA,kBAAO;IAE1B,MAAMC,kBAAkBlC,eAAI,CAACC,IAAI,CAACU,MAAM;IACxC,MAAMwB,kBAAkBnC,eAAI,CAACC,IAAI,CAACU,MAAM;IAExC,MAAMyB,gBAAgBC,IAAAA,4BAAoB,EAAC;QAAEC,OAAOH;IAAgB;IAEpE,6BAA6B;IAC7BH,WAAWO,GAAG,CAAC,CAACxB,KAAKC,KAAKwB;QACxB,qEAAqE;QAErE,0DAA0D;QAE1DxB,IAAIyB,SAAS,CAAC,+BAA+B;QAC7CzB,IAAIyB,SAAS,CAAC,gCAAgC;QAC9CzB,IAAIyB,SAAS,CACX,gCACA;QAGF,oCAAoC;QACpC,IAAI1B,IAAI2B,MAAM,KAAK,WAAW;YAC5B1B,IAAIY,UAAU,GAAG;YACjBZ,IAAIa,GAAG;YACP;QACF;QACAW;IACF;IAEAR,WAAWO,GAAG,CAAC,CAACxB,KAAKC,KAAKwB;QACxB,IAAI,EAACzB,uBAAAA,IAAKI,GAAG,KAAKJ,IAAI2B,MAAM,KAAK,SAAS3B,IAAI2B,MAAM,KAAK,QAAS;YAChE,OAAOF;QACT;QAEA,MAAMG,WAAWC,YAAY7B,IAAII,GAAG,IAAI,IAAI0B,IAAI9B,IAAII,GAAG,EAAEwB,QAAQ,GAAG5B,IAAII,GAAG;QAC3E,IAAI,CAACwB,UAAU;YACb,OAAOH;QACT;QAEAvD,MAAM,CAAC,mBAAmB,CAAC,EAAE0D;QAE7B,MAAMG,SAASzB,IAAAA,eAAI,EAACN,KAAK4B,UAAU;YACjCrB,MAAMY;YACNV,YAAY;gBAAC;aAAO;QACtB;QAEA,oCAAoC;QACpC,IAAIuB,eAAe;QACnBD,OAAOrB,EAAE,CAAC,QAAQ,SAASuB;YACzB,gDAAgD;YAChDD,eAAe;QACjB;QAEA,iBAAiB;QACjBD,OAAOrB,EAAE,CAAC,SAAS,SAASwB,MAAMvB,GAAQ;YACxC,IAAIqB,gBAAgB,CAAErB,CAAAA,IAAIE,UAAU,GAAG,GAAE,GAAI;gBAC3CY,KAAKd;gBACL;YACF;YAEAc;QACF;QAEA,OAAO;QACPM,OAAOhB,IAAI,CAACd;IACd;IAEAgB,WAAWO,GAAG,CAACH;IAEfJ,WAAWD,MAAM,CAAC3C,QAAQK,IAAI;AAChC;AAEA,SAASmD,YAAYzB,GAAW;IAC9B,IAAI;QACF,kCAAkC;QAClC,IAAI0B,IAAI1B;QACR,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,eAAef,oBAAoBO,IAAY;IAC7C,MAAMuC,aAAalD,eAAI,CAACC,IAAI,CAACU,MAAM,CAAC,wBAAwB,CAAC;IAC7D,OAAO,CAAE,MAAMwC,IAAAA,oBAAe,EAACD;AACjC"}
@@ -21,9 +21,6 @@ _export(exports, {
21
21
  printItem: function() {
22
22
  return printItem;
23
23
  },
24
- printQRCode: function() {
25
- return printQRCode;
26
- },
27
24
  printUsage: function() {
28
25
  return printUsage;
29
26
  }
@@ -35,13 +32,6 @@ function _chalk() {
35
32
  };
36
33
  return data;
37
34
  }
38
- function _qrcodeterminal() {
39
- const data = /*#__PURE__*/ _interop_require_default(require("qrcode-terminal"));
40
- _qrcodeterminal = function() {
41
- return data;
42
- };
43
- return data;
44
- }
45
35
  function _wrapansi() {
46
36
  const data = /*#__PURE__*/ _interop_require_default(require("wrap-ansi"));
47
37
  _wrapansi = function() {
@@ -96,6 +86,10 @@ function _interop_require_wildcard(obj, nodeInterop) {
96
86
  }
97
87
  return newObj;
98
88
  }
89
+ // Approximately how many rows apart from the commands table (usage guide on `expo start`)
90
+ // will be printed after the QR code? The `rows` input doesn't account for all of them,
91
+ // so we add our best guess instead.
92
+ const RESERVED_ROWS = 6;
99
93
  const BLT = '\u203A';
100
94
  const printHelp = ()=>{
101
95
  logCommandsTable([
@@ -103,16 +97,17 @@ const printHelp = ()=>{
103
97
  key: '?',
104
98
  msg: 'show all commands'
105
99
  }
106
- ]);
100
+ ]).print();
107
101
  };
108
- function printQRCode(url) {
109
- _qrcodeterminal().default.generate(url, {
110
- small: true
111
- }, (code)=>_log.log(code));
112
- }
113
102
  const getTerminalColumns = ()=>process.stdout.columns || 80;
114
- const printItem = (text)=>`${BLT} ` + (0, _wrapansi().default)(text, getTerminalColumns()).trimStart();
115
- function printUsage(options, { verbose }) {
103
+ const printItem = (text, opts)=>{
104
+ let output = `${BLT} ` + (0, _wrapansi().default)(text, getTerminalColumns()).trimStart();
105
+ if (opts == null ? void 0 : opts.dim) {
106
+ output = (0, _chalk().default)`{dim ${output}}`;
107
+ }
108
+ return output;
109
+ };
110
+ function printUsage(options, { verbose, rows }) {
116
111
  const isMac = process.platform === 'darwin';
117
112
  const { platforms = [
118
113
  'ios',
@@ -124,10 +119,19 @@ function printUsage(options, { verbose }) {
124
119
  const isWebDisable = !platforms.includes('web');
125
120
  const switchMsg = `switch to ${options.devClient === false ? 'development build' : 'Expo Go'}`;
126
121
  const target = options.devClient === false ? `Expo Go` : 'development build';
127
- _log.log();
128
- _log.log(printItem((0, _chalk().default)`Using {cyan ${target}}`));
122
+ const printPrefix = ({ short })=>{
123
+ _log.log();
124
+ let message = (0, _chalk().default)`Using {cyan ${target}}`;
125
+ if (!short) {
126
+ message += (0, _chalk().default)` {dim (Press {bold s} to ${switchMsg})}`;
127
+ }
128
+ _log.log(printItem(message));
129
+ };
129
130
  if (verbose) {
130
- logCommandsTable([
131
+ printPrefix({
132
+ short: true
133
+ });
134
+ return logCommandsTable([
131
135
  {
132
136
  key: 's',
133
137
  msg: switchMsg
@@ -184,57 +188,67 @@ function printUsage(options, { verbose }) {
184
188
  msg: 'show project QR'
185
189
  },
186
190
  {}
187
- ]);
191
+ ]).print();
192
+ }
193
+ const table = logCommandsTable([
194
+ {
195
+ key: 's',
196
+ msg: switchMsg
197
+ },
198
+ {},
199
+ {
200
+ key: 'a',
201
+ msg: 'open Android',
202
+ disabled: isAndroidDisabled
203
+ },
204
+ isMac && {
205
+ key: 'i',
206
+ msg: 'open iOS simulator',
207
+ disabled: isIosDisabled
208
+ },
209
+ {
210
+ key: 'w',
211
+ msg: 'open web',
212
+ disabled: isWebDisable
213
+ },
214
+ {},
215
+ {
216
+ key: 'j',
217
+ msg: 'open debugger'
218
+ },
219
+ {
220
+ key: 'r',
221
+ msg: 'reload app'
222
+ },
223
+ !!options.isWebSocketsEnabled && {
224
+ key: 'm',
225
+ msg: 'toggle menu'
226
+ },
227
+ !!options.isWebSocketsEnabled && {
228
+ key: 'shift+m',
229
+ msg: 'more tools'
230
+ },
231
+ {
232
+ key: 'o',
233
+ msg: 'open project code in your editor'
234
+ },
235
+ {}
236
+ ]);
237
+ // If we're not in verbose mode, we check if we have enough space. If we don't, we don't print
238
+ // the full usage guide and rely on the `printHelp()` message being shown instead
239
+ if ((rows || Infinity) - RESERVED_ROWS > table.lines) {
240
+ printPrefix({
241
+ short: true
242
+ });
243
+ table.print();
188
244
  } else {
189
- logCommandsTable([
190
- {
191
- key: 's',
192
- msg: switchMsg
193
- },
194
- {},
195
- {
196
- key: 'a',
197
- msg: 'open Android',
198
- disabled: isAndroidDisabled
199
- },
200
- isMac && {
201
- key: 'i',
202
- msg: 'open iOS simulator',
203
- disabled: isIosDisabled
204
- },
205
- {
206
- key: 'w',
207
- msg: 'open web',
208
- disabled: isWebDisable
209
- },
210
- {},
211
- {
212
- key: 'j',
213
- msg: 'open debugger'
214
- },
215
- {
216
- key: 'r',
217
- msg: 'reload app'
218
- },
219
- !!options.isWebSocketsEnabled && {
220
- key: 'm',
221
- msg: 'toggle menu'
222
- },
223
- !!options.isWebSocketsEnabled && {
224
- key: 'shift+m',
225
- msg: 'more tools'
226
- },
227
- {
228
- key: 'o',
229
- msg: 'open project code in your editor'
230
- },
231
- {}
232
- ]);
245
+ printPrefix({
246
+ short: false
247
+ });
233
248
  }
234
249
  }
235
250
  function logCommandsTable(ui) {
236
- _log.log(ui.filter(Boolean)// @ts-ignore: filter doesn't work
237
- .map(({ key, msg, status, disabled })=>{
251
+ const lines = ui.filter((x)=>!!x).map(({ key, msg, status, disabled })=>{
238
252
  if (!key) return '';
239
253
  let view = `${BLT} `;
240
254
  if (key.length === 1) view += 'Press ';
@@ -247,7 +261,13 @@ function logCommandsTable(ui) {
247
261
  view = _chalk().default.dim(view);
248
262
  }
249
263
  return view;
250
- }).join('\n'));
264
+ });
265
+ return {
266
+ lines: lines.length,
267
+ print () {
268
+ _log.log(lines.join('\n'));
269
+ }
270
+ };
251
271
  }
252
272
 
253
273
  //# sourceMappingURL=commandsTable.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/interface/commandsTable.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport qrcode from 'qrcode-terminal';\nimport wrapAnsi from 'wrap-ansi';\n\nimport * as Log from '../../log';\nimport type { McpServer } from '../server/MCP';\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};\n\nexport const printHelp = (): void => {\n logCommandsTable([{ key: '?', msg: 'show all commands' }]);\n};\n\n/** Print the world famous 'Expo QR Code'. */\nexport function printQRCode(url: string) {\n qrcode.generate(url, { small: true }, (code) => Log.log(code));\n}\n\nexport const getTerminalColumns = () => process.stdout.columns || 80;\nexport const printItem = (text: string): string =>\n `${BLT} ` + wrapAnsi(text, getTerminalColumns()).trimStart();\n\nexport function printUsage(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>,\n { verbose }: { verbose: boolean }\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 Log.log();\n Log.log(printItem(chalk`Using {cyan ${target}}`));\n\n if (verbose) {\n 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 ]);\n } else {\n 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}\n\nfunction logCommandsTable(\n ui: (false | { key?: string; msg?: string; status?: string; disabled?: boolean })[]\n) {\n Log.log(\n ui\n .filter(Boolean)\n // @ts-ignore: filter doesn't work\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 .join('\\n')\n );\n}\n"],"names":["BLT","getTerminalColumns","printHelp","printItem","printQRCode","printUsage","logCommandsTable","key","msg","url","qrcode","generate","small","code","Log","log","process","stdout","columns","text","wrapAnsi","trimStart","options","verbose","isMac","platform","platforms","isAndroidDisabled","includes","isIosDisabled","isWebDisable","switchMsg","devClient","target","chalk","disabled","isWebSocketsEnabled","ui","filter","Boolean","map","status","view","length","dim","italic","join"],"mappings":";;;;;;;;;;;IAQaA,GAAG;eAAHA;;IAqBAC,kBAAkB;eAAlBA;;IATAC,SAAS;eAATA;;IAUAC,SAAS;eAATA;;IALGC,WAAW;eAAXA;;IAQAC,UAAU;eAAVA;;;;gEAhCE;;;;;;;gEACC;;;;;;;gEACE;;;;;;6DAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGd,MAAML,MAAM;AAYZ,MAAME,YAAY;IACvBI,iBAAiB;QAAC;YAAEC,KAAK;YAAKC,KAAK;QAAoB;KAAE;AAC3D;AAGO,SAASJ,YAAYK,GAAW;IACrCC,yBAAM,CAACC,QAAQ,CAACF,KAAK;QAAEG,OAAO;IAAK,GAAG,CAACC,OAASC,KAAIC,GAAG,CAACF;AAC1D;AAEO,MAAMZ,qBAAqB,IAAMe,QAAQC,MAAM,CAACC,OAAO,IAAI;AAC3D,MAAMf,YAAY,CAACgB,OACxB,GAAGnB,IAAI,CAAC,CAAC,GAAGoB,IAAAA,mBAAQ,EAACD,MAAMlB,sBAAsBoB,SAAS;AAErD,SAAShB,WACdiB,OAA8E,EAC9E,EAAEC,OAAO,EAAwB;IAEjC,MAAMC,QAAQR,QAAQS,QAAQ,KAAK;IAEnC,MAAM,EAAEC,YAAY;QAAC;QAAO;QAAW;KAAM,EAAE,GAAGJ;IAElD,MAAMK,oBAAoB,CAACD,UAAUE,QAAQ,CAAC;IAC9C,MAAMC,gBAAgB,CAACH,UAAUE,QAAQ,CAAC;IAC1C,MAAME,eAAe,CAACJ,UAAUE,QAAQ,CAAC;IAEzC,MAAMG,YAAY,CAAC,UAAU,EAAET,QAAQU,SAAS,KAAK,QAAQ,sBAAsB,WAAW;IAC9F,MAAMC,SAASX,QAAQU,SAAS,KAAK,QAAQ,CAAC,OAAO,CAAC,GAAG;IAEzDlB,KAAIC,GAAG;IACPD,KAAIC,GAAG,CAACZ,UAAU+B,IAAAA,gBAAK,CAAA,CAAC,YAAY,EAAED,OAAO,CAAC,CAAC;IAE/C,IAAIV,SAAS;QACXjB,iBAAiB;YACf;gBAAEC,KAAK;gBAAKC,KAAKuB;YAAU;YAC3B,CAAC;YACD;gBAAExB,KAAK;gBAAKC,KAAK;gBAAgB2B,UAAUR;YAAkB;YAC7D;gBAAEpB,KAAK;gBAAWC,KAAK;gBAAwC2B,UAAUR;YAAkB;YAC3FH,SAAS;gBAAEjB,KAAK;gBAAKC,KAAK;gBAAsB2B,UAAUN;YAAc;YACxEL,SAAS;gBAAEjB,KAAK;gBAAWC,KAAK;gBAA2B2B,UAAUN;YAAc;YACnF;gBAAEtB,KAAK;gBAAKC,KAAK;gBAAY2B,UAAUL;YAAa;YACpD,CAAC;YACD;gBAAEvB,KAAK;gBAAKC,KAAK;YAAa;YAC9B,CAAC,CAACc,QAAQc,mBAAmB,IAAI;gBAAE7B,KAAK;gBAAKC,KAAK;YAAgB;YAClE,CAAC,CAACc,QAAQc,mBAAmB,IAAI;gBAAE7B,KAAK;gBAAKC,KAAK;YAAc;YAChE,CAAC,CAACc,QAAQc,mBAAmB,IAAI;gBAAE7B,KAAK;gBAAWC,KAAK;YAAa;YACrE;gBAAED,KAAK;gBAAKC,KAAK;YAAmC;YACpD;gBAAED,KAAK;gBAAKC,KAAK;YAAkB;YACnC,CAAC;SACF;IACH,OAAO;QACLF,iBAAiB;YACf;gBAAEC,KAAK;gBAAKC,KAAKuB;YAAU;YAC3B,CAAC;YACD;gBAAExB,KAAK;gBAAKC,KAAK;gBAAgB2B,UAAUR;YAAkB;YAC7DH,SAAS;gBAAEjB,KAAK;gBAAKC,KAAK;gBAAsB2B,UAAUN;YAAc;YACxE;gBAAEtB,KAAK;gBAAKC,KAAK;gBAAY2B,UAAUL;YAAa;YACpD,CAAC;YACD;gBAAEvB,KAAK;gBAAKC,KAAK;YAAgB;YACjC;gBAAED,KAAK;gBAAKC,KAAK;YAAa;YAC9B,CAAC,CAACc,QAAQc,mBAAmB,IAAI;gBAAE7B,KAAK;gBAAKC,KAAK;YAAc;YAChE,CAAC,CAACc,QAAQc,mBAAmB,IAAI;gBAAE7B,KAAK;gBAAWC,KAAK;YAAa;YACrE;gBAAED,KAAK;gBAAKC,KAAK;YAAmC;YACpD,CAAC;SACF;IACH;AACF;AAEA,SAASF,iBACP+B,EAAmF;IAEnFvB,KAAIC,GAAG,CACLsB,GACGC,MAAM,CAACC,QACR,kCAAkC;KACjCC,GAAG,CAAC,CAAC,EAAEjC,GAAG,EAAEC,GAAG,EAAEiC,MAAM,EAAEN,QAAQ,EAAE;QAClC,IAAI,CAAC5B,KAAK,OAAO;QACjB,IAAImC,OAAO,GAAG1C,IAAI,CAAC,CAAC;QACpB,IAAIO,IAAIoC,MAAM,KAAK,GAAGD,QAAQ;QAC9BA,QAAQR,IAAAA,gBAAK,CAAA,CAAC,MAAM,EAAE3B,IAAI,UAAU,CAAC;QACrCmC,QAAQlC;QACR,IAAIiC,QAAQ;YACVC,QAAQ,CAAC,CAAC,EAAER,gBAAK,CAACU,GAAG,CAAC,CAAC,CAAC,EAAEV,gBAAK,CAACW,MAAM,CAACJ,QAAQ,CAAC,CAAC,GAAG;QACtD;QACA,IAAIN,UAAU;YACZO,OAAOR,gBAAK,CAACU,GAAG,CAACF;QACnB;QACA,OAAOA;IACT,GACCI,IAAI,CAAC;AAEZ"}
1
+ {"version":3,"sources":["../../../../src/start/interface/commandsTable.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport wrapAnsi from 'wrap-ansi';\n\nimport * as Log from '../../log';\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};\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\ninterface LogCommandsOutput {\n lines: number;\n print(): void;\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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"}
@@ -21,6 +21,7 @@ const _log = /*#__PURE__*/ _interop_require_wildcard(require("../../log"));
21
21
  const _env = require("../../utils/env");
22
22
  const _link = require("../../utils/link");
23
23
  const _prompts = require("../../utils/prompts");
24
+ const _qr = require("../../utils/qr");
24
25
  const _JsInspector = require("../server/middleware/inspector/JsInspector");
25
26
  function _interop_require_default(obj) {
26
27
  return obj && obj.__esModule ? obj : {
@@ -76,29 +77,41 @@ class DevServerManagerActions {
76
77
  }
77
78
  printDevServerInfo(options) {
78
79
  var _this_options_platforms;
80
+ // Keep track of approximately how much space we have to print our usage guide
81
+ let rows = process.stdout.rows || Infinity;
79
82
  // If native dev server is running, print its URL.
80
83
  if (this.devServerManager.getNativeDevServerPort()) {
81
84
  const devServer = this.devServerManager.getDefaultDevServer();
82
85
  try {
83
86
  const nativeRuntimeUrl = devServer.getNativeRuntimeUrl();
84
87
  const interstitialPageUrl = devServer.getRedirectUrl();
85
- (0, _commandsTable.printQRCode)(interstitialPageUrl ?? nativeRuntimeUrl);
86
- if (interstitialPageUrl) {
87
- _log.log((0, _commandsTable.printItem)((0, _chalk().default)`Choose an app to open your project at {underline ${interstitialPageUrl}}`));
88
- }
88
+ // Print the URL to stdout for tests
89
89
  if (_env.env.__EXPO_E2E_TEST) {
90
- // Print the URL to stdout for tests
91
90
  console.info(`[__EXPO_E2E_TEST:server] ${JSON.stringify({
92
91
  url: devServer.getDevServerUrl()
93
92
  })}`);
93
+ rows--;
94
94
  }
95
- _log.log((0, _commandsTable.printItem)((0, _chalk().default)`Metro waiting on {underline ${nativeRuntimeUrl}}`));
96
- if (options.devClient === false) {
97
- // TODO: if development build, change this message!
98
- _log.log((0, _commandsTable.printItem)('Scan the QR code above to open the project in Expo Go.'));
95
+ const qr = (0, _qr.printQRCode)(interstitialPageUrl ?? nativeRuntimeUrl);
96
+ rows -= qr.lines;
97
+ qr.print();
98
+ let qrMessage = '';
99
+ if (!options.devClient) {
100
+ qrMessage = `Scan the QR code above to open in ${(0, _chalk().default)`{bold Expo Go}`}.`;
99
101
  } else {
100
- _log.log((0, _commandsTable.printItem)('Scan the QR code above to open the project in a development build. ' + (0, _link.learnMore)('https://expo.fyi/start')));
102
+ qrMessage = (0, _chalk().default)`Scan the QR code above to open in a {bold development build}.`;
103
+ qrMessage += ` (${(0, _link.learnMore)('https://expo.fyi/start')})`;
104
+ }
105
+ rows--;
106
+ _log.log((0, _commandsTable.printItem)(qrMessage, {
107
+ dim: true
108
+ }));
109
+ if (interstitialPageUrl) {
110
+ rows--;
111
+ _log.log((0, _commandsTable.printItem)((0, _chalk().default)`Choose an app to open your project at {underline ${interstitialPageUrl}}`));
101
112
  }
113
+ rows--;
114
+ _log.log((0, _commandsTable.printItem)((0, _chalk().default)`Metro: {underline ${nativeRuntimeUrl}}`));
102
115
  } catch (error) {
103
116
  console.log('err', error);
104
117
  // @ts-ignore: If there is no development build scheme, then skip the QR code.
@@ -106,8 +119,9 @@ class DevServerManagerActions {
106
119
  throw error;
107
120
  } else {
108
121
  const serverUrl = devServer.getDevServerUrl();
109
- _log.log((0, _commandsTable.printItem)((0, _chalk().default)`Metro waiting on {underline ${serverUrl}}`));
122
+ _log.log((0, _commandsTable.printItem)((0, _chalk().default)`Metro: {underline ${serverUrl}}`));
110
123
  _log.log((0, _commandsTable.printItem)(`Linking is disabled because the client scheme cannot be resolved.`));
124
+ rows -= 2;
111
125
  }
112
126
  }
113
127
  }
@@ -117,12 +131,13 @@ class DevServerManagerActions {
117
131
  hostType: 'localhost'
118
132
  });
119
133
  if (webUrl) {
120
- _log.log();
121
- _log.log((0, _commandsTable.printItem)((0, _chalk().default)`Web is waiting on {underline ${webUrl}}`));
134
+ _log.log((0, _commandsTable.printItem)((0, _chalk().default)`Web: {underline ${webUrl}}`));
135
+ rows--;
122
136
  }
123
137
  }
124
138
  (0, _commandsTable.printUsage)(options, {
125
- verbose: false
139
+ verbose: false,
140
+ rows
126
141
  });
127
142
  (0, _commandsTable.printHelp)();
128
143
  _log.log();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/interface/interactiveActions.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { BLT, printHelp, printItem, printQRCode, printUsage, StartOptions } from './commandsTable';\nimport { createDevToolsMenuItems } from './createDevToolsMenuItems';\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { learnMore } from '../../utils/link';\nimport { openBrowserAsync } from '../../utils/open';\nimport { ExpoChoice, selectAsync } from '../../utils/prompts';\nimport { 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 // 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 printQRCode(interstitialPageUrl ?? nativeRuntimeUrl);\n\n if (interstitialPageUrl) {\n Log.log(\n printItem(\n chalk`Choose an app to open your project at {underline ${interstitialPageUrl}}`\n )\n );\n }\n\n if (env.__EXPO_E2E_TEST) {\n // Print the URL to stdout for tests\n console.info(\n `[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: devServer.getDevServerUrl() })}`\n );\n }\n\n Log.log(printItem(chalk`Metro waiting on {underline ${nativeRuntimeUrl}}`));\n if (options.devClient === false) {\n // TODO: if development build, change this message!\n Log.log(printItem('Scan the QR code above to open the project in Expo Go.'));\n } else {\n Log.log(\n printItem(\n 'Scan the QR code above to open the project in a development build. ' +\n learnMore('https://expo.fyi/start')\n )\n );\n }\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 waiting on {underline ${serverUrl}}`));\n Log.log(printItem(`Linking is disabled because the client scheme cannot be resolved.`));\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();\n Log.log(printItem(chalk`Web is waiting on {underline ${webUrl}}`));\n }\n }\n\n printUsage(options, { verbose: false });\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","constructor","devServerManager","options","printDevServerInfo","getNativeDevServerPort","devServer","getDefaultDevServer","nativeRuntimeUrl","getNativeRuntimeUrl","interstitialPageUrl","getRedirectUrl","printQRCode","Log","log","printItem","chalk","env","__EXPO_E2E_TEST","console","info","JSON","stringify","url","getDevServerUrl","devClient","learnMore","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 { BLT, printHelp, printItem, printUsage, StartOptions } from './commandsTable';\nimport { createDevToolsMenuItems } from './createDevToolsMenuItems';\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { learnMore } from '../../utils/link';\nimport { ExpoChoice, selectAsync } from '../../utils/prompts';\nimport { printQRCode } from '../../utils/qr';\nimport { 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 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 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","constructor","devServerManager","options","printDevServerInfo","rows","process","stdout","Infinity","getNativeDevServerPort","devServer","getDefaultDevServer","nativeRuntimeUrl","getNativeRuntimeUrl","interstitialPageUrl","getRedirectUrl","env","__EXPO_E2E_TEST","console","info","JSON","stringify","url","getDevServerUrl","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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"}
@@ -137,7 +137,7 @@ class BundlerDevServer {
137
137
  * This is used for the run commands where you can reuse the server from a previous run.
138
138
  */ async startHeadlessAsync(options) {
139
139
  if (!options.port) throw new _errors.CommandError('HEADLESS_SERVER', 'headless dev server requires a port option');
140
- this.urlCreator = this.getUrlCreator(options);
140
+ await this.initUrlCreator(options);
141
141
  return {
142
142
  // Create a mock server
143
143
  server: {
@@ -242,6 +242,8 @@ class BundlerDevServer {
242
242
  _this_notifier, // Stop the bonjour advertiser
243
243
  _this_bonjour, // Stop the dev session timer and tell Expo API to remove dev session.
244
244
  _this_devSession, _this_tunnel;
245
+ // Reset url creator
246
+ this.urlCreator = undefined;
245
247
  (_this_notifier = this.notifier) == null ? void 0 : _this_notifier.stopObserving();
246
248
  await Promise.all([
247
249
  (_this_bonjour = this.bonjour) == null ? void 0 : _this_bonjour.closeAsync(),
@@ -282,14 +284,19 @@ class BundlerDevServer {
282
284
  errorMessage: `Timeout waiting for '${this.name}' dev server to close`
283
285
  });
284
286
  }
285
- getUrlCreator(options = {}) {
286
- if (!this.urlCreator) {
287
- (0, _assert().default)(options == null ? void 0 : options.port, 'Dev server instance not found');
288
- this.urlCreator = new _UrlCreator.UrlCreator(options.location, {
289
- port: options.port,
290
- getTunnelUrl: this.getTunnelUrl.bind(this)
291
- });
292
- }
287
+ // TODO(@kitten): This should be created top-down rather than bottom up from implementors
288
+ async initUrlCreator(options = {}) {
289
+ (0, _assert().default)(options == null ? void 0 : options.port, 'Dev server instance not found');
290
+ (0, _assert().default)(!this.urlCreator, 'Dev server is already initialized');
291
+ const urlCreator = await _UrlCreator.UrlCreator.init(options.location, {
292
+ port: options.port,
293
+ getTunnelUrl: this.getTunnelUrl.bind(this)
294
+ });
295
+ this.urlCreator = urlCreator;
296
+ return urlCreator;
297
+ }
298
+ getUrlCreator() {
299
+ (0, _assert().default)(this.urlCreator, 'Dev server is uninitialized');
293
300
  return this.urlCreator;
294
301
  }
295
302
  getNativeRuntimeUrl(opts = {}) {