@expo/cli 55.0.26 → 55.0.28

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("55.0.26");
142
+ console.log("55.0.28");
143
143
  process.exit(0);
144
144
  }
145
145
  if (args['--non-interactive']) {
@@ -70,7 +70,7 @@ function getInitMetadata() {
70
70
  return {
71
71
  format: 'v0-jsonl',
72
72
  // Version is added in the build script.
73
- version: "55.0.26" ?? 'UNVERSIONED'
73
+ version: "55.0.28" ?? 'UNVERSIONED'
74
74
  };
75
75
  }
76
76
  function installEventLogger(env = process.env.LOG_EVENTS) {
@@ -55,9 +55,9 @@ const _ExpoMiddleware = require("./ExpoMiddleware");
55
55
  const _metroOptions = require("./metroOptions");
56
56
  const _resolveAssets = require("./resolveAssets");
57
57
  const _resolvePlatform = require("./resolvePlatform");
58
+ const _user = require("../../../api/user/user");
58
59
  const _exportHermes = require("../../../export/exportHermes");
59
60
  const _log = /*#__PURE__*/ _interop_require_wildcard(require("../../../log"));
60
- const _user = require("../../../api/user/user");
61
61
  const _env = require("../../../utils/env");
62
62
  const _devices = /*#__PURE__*/ _interop_require_wildcard(require("../../project/devices"));
63
63
  const _router = require("../metro/router");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/middleware/ManifestMiddleware.ts"],"sourcesContent":["import {\n ExpoConfig,\n ExpoGoConfig,\n getConfig,\n PackageJSONConfig,\n ProjectConfig,\n} from '@expo/config';\nimport { resolveRelativeEntryPoint } from '@expo/config/paths';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { resolve } from 'url';\n\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport {\n createBundleUrlPath,\n getBaseUrlFromExpoConfig,\n getAsyncRoutesFromExpoConfig,\n createBundleUrlPathFromExpoConfig,\n} from './metroOptions';\nimport { resolveGoogleServicesFile, resolveManifestAssets } from './resolveAssets';\nimport { parsePlatformHeader, RuntimePlatform } from './resolvePlatform';\nimport { ServerNext, ServerRequest, ServerResponse } from './server.types';\nimport { isEnableHermesManaged } from '../../../export/exportHermes';\nimport * as Log from '../../../log';\nimport { getActorDisplayName, getUserAsync } from '../../../api/user/user';\nimport { env } from '../../../utils/env';\nimport * as ProjectDevices from '../../project/devices';\nimport { UrlCreator } from '../UrlCreator';\nimport { getRouterDirectoryModuleIdWithManifest } from '../metro/router';\nimport { getPlatformBundlers, PlatformBundlers } from '../platformBundlers';\nimport { createTemplateHtmlFromExpoConfigAsync } from '../webTemplate';\n\nconst debug = require('debug')('expo:start:server:middleware:manifest') as typeof console.log;\n\n/** Info about the computer hosting the dev server. */\nexport interface HostInfo {\n host: string;\n server: 'expo';\n serverVersion: string;\n serverDriver: string | null;\n serverOS: NodeJS.Platform;\n serverOSVersion: string;\n}\n\n/** Parsed values from the supported request headers. */\nexport interface ManifestRequestInfo {\n /** Platform to serve. */\n platform: RuntimePlatform;\n /** Requested host name. */\n hostname?: string | null;\n /** The protocol used to request the manifest */\n protocol?: 'http' | 'https';\n}\n\n/** Project related info. */\nexport type ResponseProjectSettings = {\n expoGoConfig: ExpoGoConfig;\n hostUri: string;\n bundleUrl: string;\n exp: ExpoConfig;\n};\n\nexport const DEVELOPER_TOOL = 'expo-cli';\n\nexport type ManifestMiddlewareOptions = {\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n constructUrl: UrlCreator['constructUrl'];\n isNativeWebpack?: boolean;\n privateKeyPath?: string;\n};\n\n/** Base middleware creator for serving the Expo manifest (like the index.html but for native runtimes). */\nexport abstract class ManifestMiddleware<\n TManifestRequestInfo extends ManifestRequestInfo,\n> extends ExpoMiddleware {\n private initialProjectConfig: ProjectConfig;\n private platformBundlers: PlatformBundlers;\n\n constructor(\n protected projectRoot: string,\n protected options: ManifestMiddlewareOptions\n ) {\n super(\n projectRoot,\n /**\n * Only support `/`, `/manifest`, `/index.exp` for the manifest middleware.\n */\n ['/', '/manifest', '/index.exp']\n );\n this.initialProjectConfig = getConfig(projectRoot);\n this.platformBundlers = getPlatformBundlers(projectRoot, this.initialProjectConfig.exp);\n }\n\n /** Exposed for testing. */\n public async _resolveProjectSettingsAsync({\n platform,\n hostname,\n protocol,\n }: Pick<\n TManifestRequestInfo,\n 'hostname' | 'platform' | 'protocol'\n >): Promise<ResponseProjectSettings> {\n // Read the config\n const projectConfig = getConfig(this.projectRoot);\n\n // Read from headers\n const mainModuleName = this.resolveMainModuleName({\n pkg: projectConfig.pkg,\n platform,\n });\n\n const isHermesEnabled = isEnableHermesManaged(projectConfig.exp, platform);\n\n // Resolve the signed-in CLI user to pass through the manifest\n const user = await getUserAsync();\n const username = getActorDisplayName(user);\n\n // Create the manifest and set fields within it\n const expoGoConfig = this.getExpoGoConfig({\n mainModuleName,\n hostname,\n username: username !== 'anonymous' ? username : undefined,\n });\n\n const hostUri = this.options.constructUrl({ scheme: '', hostname });\n\n const bundleUrl = this._getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n engine: isHermesEnabled ? 'hermes' : undefined,\n baseUrl: getBaseUrlFromExpoConfig(projectConfig.exp),\n asyncRoutes: getAsyncRoutesFromExpoConfig(\n projectConfig.exp,\n this.options.mode ?? 'development',\n platform\n ),\n routerRoot: getRouterDirectoryModuleIdWithManifest(this.projectRoot, projectConfig.exp),\n protocol,\n reactCompiler: !!projectConfig.exp.experiments?.reactCompiler,\n });\n\n // Resolve all assets and set them on the manifest as URLs\n await this.mutateManifestWithAssetsAsync(projectConfig.exp, bundleUrl);\n\n return {\n expoGoConfig,\n hostUri,\n bundleUrl,\n exp: projectConfig.exp,\n };\n }\n\n /** Get the main entry module ID (file) relative to the project root. */\n private resolveMainModuleName(props: { pkg: PackageJSONConfig; platform: string }): string {\n // NOTE(Bacon): Webpack is currently hardcoded to index.bundle on native\n // in the future (TODO) we should move this logic into a Webpack plugin and use\n // a generated file name like we do on web.\n // const server = getDefaultDevServer();\n // // TODO: Move this into BundlerDevServer and read this info from self.\n // const isNativeWebpack = server instanceof WebpackBundlerDevServer && server.isTargetingNative();\n if (this.options.isNativeWebpack) {\n return 'index';\n }\n\n const entry = resolveRelativeEntryPoint(this.projectRoot, props);\n debug(`Resolved entry point: ${entry} (project root: ${this.projectRoot})`);\n return entry;\n }\n\n /** Parse request headers into options. */\n public abstract getParsedHeaders(req: ServerRequest): TManifestRequestInfo;\n\n /** Store device IDs that were sent in the request headers. */\n private async saveDevicesAsync(req: ServerRequest) {\n const deviceIds = req.headers?.['expo-dev-client-id'];\n if (deviceIds) {\n await ProjectDevices.saveDevicesAsync(this.projectRoot, deviceIds).catch((e) =>\n Log.exception(e)\n );\n }\n }\n\n /** Create the bundle URL (points to the single JS entry file). Exposed for testing. */\n public _getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n engine,\n baseUrl,\n isExporting,\n asyncRoutes,\n routerRoot,\n protocol,\n reactCompiler,\n }: {\n platform: string;\n hostname?: string | null;\n mainModuleName: string;\n engine?: 'hermes';\n baseUrl?: string;\n asyncRoutes: boolean;\n isExporting?: boolean;\n routerRoot: string;\n protocol?: 'http' | 'https';\n reactCompiler: boolean;\n }): string {\n const path = createBundleUrlPath({\n mode: this.options.mode ?? 'development',\n minify: this.options.minify,\n platform,\n mainModuleName,\n lazy: !env.EXPO_NO_METRO_LAZY,\n engine,\n bytecode: engine === 'hermes',\n baseUrl,\n isExporting: !!isExporting,\n asyncRoutes,\n routerRoot,\n reactCompiler,\n });\n\n return (\n this.options.constructUrl({\n scheme: protocol ?? 'http',\n // hostType: this.options.location.hostType,\n hostname,\n }) + path\n );\n }\n\n /** Get the manifest response to return to the runtime. This file contains info regarding where the assets can be loaded from. Exposed for testing. */\n public abstract _getManifestResponseAsync(options: TManifestRequestInfo): Promise<Response>;\n\n private getExpoGoConfig({\n mainModuleName,\n hostname,\n username,\n }: {\n mainModuleName: string;\n hostname?: string | null;\n username?: string;\n }): ExpoGoConfig {\n return {\n // localhost:8081\n debuggerHost: this.options.constructUrl({ scheme: '', hostname }),\n // Required for Expo Go to function.\n developer: {\n tool: DEVELOPER_TOOL,\n projectRoot: this.projectRoot,\n },\n packagerOpts: {\n // Required for dev client.\n dev: this.options.mode !== 'production',\n },\n // Indicates the name of the main bundle.\n mainModuleName,\n // The signed-in CLI username, used by Expo Go to verify account match.\n ...(username ? { username } : undefined),\n };\n }\n\n /** Resolve all assets and set them on the manifest as URLs */\n private async mutateManifestWithAssetsAsync(manifest: ExpoConfig, bundleUrl: string) {\n await resolveManifestAssets(this.projectRoot, {\n manifest,\n resolver: async (path) => {\n if (this.options.isNativeWebpack) {\n // When using our custom dev server, just do assets normally\n // without the `assets/` subpath redirect.\n return resolve(bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0], path);\n }\n return bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0] + 'assets/' + path;\n },\n });\n // The server normally inserts this but if we're offline we'll do it here\n await resolveGoogleServicesFile(this.projectRoot, manifest);\n }\n\n public getWebBundleUrl() {\n const platform = 'web';\n // Read from headers\n const mainModuleName = this.resolveMainModuleName({\n pkg: this.initialProjectConfig.pkg,\n platform,\n });\n\n return createBundleUrlPathFromExpoConfig(this.projectRoot, this.initialProjectConfig.exp, {\n platform,\n mainModuleName,\n minify: this.options.minify,\n lazy: !env.EXPO_NO_METRO_LAZY,\n mode: this.options.mode ?? 'development',\n // Hermes doesn't support more modern JS features than most, if not all, modern browser.\n engine: 'hermes',\n isExporting: false,\n bytecode: false,\n });\n }\n\n /**\n * Web platforms should create an index.html response using the same script resolution as native.\n *\n * Instead of adding a `bundleUrl` to a `manifest.json` (native) we'll add a `<script src=\"\">`\n * to an `index.html`, this enables the web platform to load JavaScript from the server.\n */\n private async handleWebRequestAsync(req: ServerRequest, res: ServerResponse) {\n res.setHeader('Content-Type', 'text/html');\n\n res.end(await this.getSingleHtmlTemplateAsync());\n }\n\n getSingleHtmlTemplateAsync() {\n // Read from headers\n const bundleUrl = this.getWebBundleUrl();\n\n return createTemplateHtmlFromExpoConfigAsync(this.projectRoot, {\n exp: this.initialProjectConfig.exp,\n scripts: [bundleUrl],\n });\n }\n\n /** Exposed for testing. */\n async checkBrowserRequestAsync(req: ServerRequest, res: ServerResponse, next: ServerNext) {\n if (\n this.platformBundlers.web === 'metro' &&\n this.initialProjectConfig.exp.platforms?.includes('web')\n ) {\n // NOTE(EvanBacon): This effectively disables the safety check we do on custom runtimes to ensure\n // the `expo-platform` header is included. When `web.bundler=web`, if the user has non-standard Expo\n // code loading then they'll get a web bundle without a clear assertion of platform support.\n const platform = parsePlatformHeader(req);\n // On web, serve the public folder\n if (!platform || platform === 'web') {\n if (['static', 'server'].includes(this.initialProjectConfig.exp.web?.output ?? '')) {\n // Skip the spa-styled index.html when static generation is enabled.\n next();\n return true;\n } else {\n await this.handleWebRequestAsync(req, res);\n return true;\n }\n }\n }\n return false;\n }\n\n async handleRequestAsync(\n req: ServerRequest,\n res: ServerResponse,\n next: ServerNext\n ): Promise<void> {\n // First check for standard JavaScript runtimes (aka legacy browsers like Chrome).\n if (await this.checkBrowserRequestAsync(req, res, next)) {\n return;\n }\n\n // Save device IDs for dev client.\n await this.saveDevicesAsync(req);\n\n // Read from headers\n const options = this.getParsedHeaders(req);\n\n const response = await this._getManifestResponseAsync(options);\n // Convert `Response` to node:http response\n if (typeof res.setHeaders === 'function') {\n res.setHeaders(response.headers);\n } else {\n for (const [key, value] of response.headers.entries()) {\n res.appendHeader(key, value);\n }\n }\n if (response.body) {\n await pipeline(Readable.fromWeb(response.body as any), res);\n } else {\n res.end();\n }\n }\n}\n"],"names":["DEVELOPER_TOOL","ManifestMiddleware","debug","require","ExpoMiddleware","constructor","projectRoot","options","initialProjectConfig","getConfig","platformBundlers","getPlatformBundlers","exp","_resolveProjectSettingsAsync","platform","hostname","protocol","projectConfig","mainModuleName","resolveMainModuleName","pkg","isHermesEnabled","isEnableHermesManaged","user","getUserAsync","username","getActorDisplayName","expoGoConfig","getExpoGoConfig","undefined","hostUri","constructUrl","scheme","bundleUrl","_getBundleUrl","engine","baseUrl","getBaseUrlFromExpoConfig","asyncRoutes","getAsyncRoutesFromExpoConfig","mode","routerRoot","getRouterDirectoryModuleIdWithManifest","reactCompiler","experiments","mutateManifestWithAssetsAsync","props","isNativeWebpack","entry","resolveRelativeEntryPoint","saveDevicesAsync","req","deviceIds","headers","ProjectDevices","catch","e","Log","exception","isExporting","path","createBundleUrlPath","minify","lazy","env","EXPO_NO_METRO_LAZY","bytecode","debuggerHost","developer","tool","packagerOpts","dev","manifest","resolveManifestAssets","resolver","resolve","match","resolveGoogleServicesFile","getWebBundleUrl","createBundleUrlPathFromExpoConfig","handleWebRequestAsync","res","setHeader","end","getSingleHtmlTemplateAsync","createTemplateHtmlFromExpoConfigAsync","scripts","checkBrowserRequestAsync","next","web","platforms","includes","parsePlatformHeader","output","handleRequestAsync","getParsedHeaders","response","_getManifestResponseAsync","setHeaders","key","value","entries","appendHeader","body","pipeline","Readable","fromWeb"],"mappings":";;;;;;;;;;;IA8DaA,cAAc;eAAdA;;IAaSC,kBAAkB;eAAlBA;;;;yBArEf;;;;;;;yBACmC;;;;;;;yBACjB;;;;;;;yBACA;;;;;;;yBACD;;;;;;gCAEO;8BAMxB;+BAC0D;iCACZ;8BAEf;6DACjB;sBAC6B;qBAC9B;iEACY;wBAEuB;kCACD;6BACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEtD,MAAMC,QAAQC,QAAQ,SAAS;AA8BxB,MAAMH,iBAAiB;AAavB,MAAeC,2BAEZG,8BAAc;IAItBC,YACE,AAAUC,WAAmB,EAC7B,AAAUC,OAAkC,CAC5C;QACA,KAAK,CACHD,aACA;;OAEC,GACD;YAAC;YAAK;YAAa;SAAa,QARxBA,cAAAA,kBACAC,UAAAA;QASV,IAAI,CAACC,oBAAoB,GAAGC,IAAAA,mBAAS,EAACH;QACtC,IAAI,CAACI,gBAAgB,GAAGC,IAAAA,qCAAmB,EAACL,aAAa,IAAI,CAACE,oBAAoB,CAACI,GAAG;IACxF;IAEA,yBAAyB,GACzB,MAAaC,6BAA6B,EACxCC,QAAQ,EACRC,QAAQ,EACRC,QAAQ,EAIT,EAAoC;YAsChBC;QArCnB,kBAAkB;QAClB,MAAMA,gBAAgBR,IAAAA,mBAAS,EAAC,IAAI,CAACH,WAAW;QAEhD,oBAAoB;QACpB,MAAMY,iBAAiB,IAAI,CAACC,qBAAqB,CAAC;YAChDC,KAAKH,cAAcG,GAAG;YACtBN;QACF;QAEA,MAAMO,kBAAkBC,IAAAA,mCAAqB,EAACL,cAAcL,GAAG,EAAEE;QAEjE,8DAA8D;QAC9D,MAAMS,OAAO,MAAMC,IAAAA,kBAAY;QAC/B,MAAMC,WAAWC,IAAAA,yBAAmB,EAACH;QAErC,+CAA+C;QAC/C,MAAMI,eAAe,IAAI,CAACC,eAAe,CAAC;YACxCV;YACAH;YACAU,UAAUA,aAAa,cAAcA,WAAWI;QAClD;QAEA,MAAMC,UAAU,IAAI,CAACvB,OAAO,CAACwB,YAAY,CAAC;YAAEC,QAAQ;YAAIjB;QAAS;QAEjE,MAAMkB,YAAY,IAAI,CAACC,aAAa,CAAC;YACnCpB;YACAI;YACAH;YACAoB,QAAQd,kBAAkB,WAAWQ;YACrCO,SAASC,IAAAA,sCAAwB,EAACpB,cAAcL,GAAG;YACnD0B,aAAaC,IAAAA,0CAA4B,EACvCtB,cAAcL,GAAG,EACjB,IAAI,CAACL,OAAO,CAACiC,IAAI,IAAI,eACrB1B;YAEF2B,YAAYC,IAAAA,8CAAsC,EAAC,IAAI,CAACpC,WAAW,EAAEW,cAAcL,GAAG;YACtFI;YACA2B,eAAe,CAAC,GAAC1B,iCAAAA,cAAcL,GAAG,CAACgC,WAAW,qBAA7B3B,+BAA+B0B,aAAa;QAC/D;QAEA,0DAA0D;QAC1D,MAAM,IAAI,CAACE,6BAA6B,CAAC5B,cAAcL,GAAG,EAAEqB;QAE5D,OAAO;YACLN;YACAG;YACAG;YACArB,KAAKK,cAAcL,GAAG;QACxB;IACF;IAEA,sEAAsE,GACtE,AAAQO,sBAAsB2B,KAAmD,EAAU;QACzF,wEAAwE;QACxE,+EAA+E;QAC/E,2CAA2C;QAC3C,wCAAwC;QACxC,yEAAyE;QACzE,mGAAmG;QACnG,IAAI,IAAI,CAACvC,OAAO,CAACwC,eAAe,EAAE;YAChC,OAAO;QACT;QAEA,MAAMC,QAAQC,IAAAA,kCAAyB,EAAC,IAAI,CAAC3C,WAAW,EAAEwC;QAC1D5C,MAAM,CAAC,sBAAsB,EAAE8C,MAAM,gBAAgB,EAAE,IAAI,CAAC1C,WAAW,CAAC,CAAC,CAAC;QAC1E,OAAO0C;IACT;IAKA,4DAA4D,GAC5D,MAAcE,iBAAiBC,GAAkB,EAAE;YAC/BA;QAAlB,MAAMC,aAAYD,eAAAA,IAAIE,OAAO,qBAAXF,YAAa,CAAC,qBAAqB;QACrD,IAAIC,WAAW;YACb,MAAME,SAAeJ,gBAAgB,CAAC,IAAI,CAAC5C,WAAW,EAAE8C,WAAWG,KAAK,CAAC,CAACC,IACxEC,KAAIC,SAAS,CAACF;QAElB;IACF;IAEA,qFAAqF,GACrF,AAAOtB,cAAc,EACnBpB,QAAQ,EACRI,cAAc,EACdH,QAAQ,EACRoB,MAAM,EACNC,OAAO,EACPuB,WAAW,EACXrB,WAAW,EACXG,UAAU,EACVzB,QAAQ,EACR2B,aAAa,EAYd,EAAU;QACT,MAAMiB,OAAOC,IAAAA,iCAAmB,EAAC;YAC/BrB,MAAM,IAAI,CAACjC,OAAO,CAACiC,IAAI,IAAI;YAC3BsB,QAAQ,IAAI,CAACvD,OAAO,CAACuD,MAAM;YAC3BhD;YACAI;YACA6C,MAAM,CAACC,QAAG,CAACC,kBAAkB;YAC7B9B;YACA+B,UAAU/B,WAAW;YACrBC;YACAuB,aAAa,CAAC,CAACA;YACfrB;YACAG;YACAE;QACF;QAEA,OACE,IAAI,CAACpC,OAAO,CAACwB,YAAY,CAAC;YACxBC,QAAQhB,YAAY;YACpB,4CAA4C;YAC5CD;QACF,KAAK6C;IAET;IAKQhC,gBAAgB,EACtBV,cAAc,EACdH,QAAQ,EACRU,QAAQ,EAKT,EAAgB;QACf,OAAO;YACL,iBAAiB;YACjB0C,cAAc,IAAI,CAAC5D,OAAO,CAACwB,YAAY,CAAC;gBAAEC,QAAQ;gBAAIjB;YAAS;YAC/D,oCAAoC;YACpCqD,WAAW;gBACTC,MAAMrE;gBACNM,aAAa,IAAI,CAACA,WAAW;YAC/B;YACAgE,cAAc;gBACZ,2BAA2B;gBAC3BC,KAAK,IAAI,CAAChE,OAAO,CAACiC,IAAI,KAAK;YAC7B;YACA,yCAAyC;YACzCtB;YACA,uEAAuE;YACvE,GAAIO,WAAW;gBAAEA;YAAS,IAAII,SAAS;QACzC;IACF;IAEA,4DAA4D,GAC5D,MAAcgB,8BAA8B2B,QAAoB,EAAEvC,SAAiB,EAAE;QACnF,MAAMwC,IAAAA,oCAAqB,EAAC,IAAI,CAACnE,WAAW,EAAE;YAC5CkE;YACAE,UAAU,OAAOd;gBACf,IAAI,IAAI,CAACrD,OAAO,CAACwC,eAAe,EAAE;oBAChC,4DAA4D;oBAC5D,0CAA0C;oBAC1C,OAAO4B,IAAAA,cAAO,EAAC1C,UAAW2C,KAAK,CAAC,oBAAqB,CAAC,EAAE,EAAEhB;gBAC5D;gBACA,OAAO3B,UAAW2C,KAAK,CAAC,oBAAqB,CAAC,EAAE,GAAG,YAAYhB;YACjE;QACF;QACA,yEAAyE;QACzE,MAAMiB,IAAAA,wCAAyB,EAAC,IAAI,CAACvE,WAAW,EAAEkE;IACpD;IAEOM,kBAAkB;QACvB,MAAMhE,WAAW;QACjB,oBAAoB;QACpB,MAAMI,iBAAiB,IAAI,CAACC,qBAAqB,CAAC;YAChDC,KAAK,IAAI,CAACZ,oBAAoB,CAACY,GAAG;YAClCN;QACF;QAEA,OAAOiE,IAAAA,+CAAiC,EAAC,IAAI,CAACzE,WAAW,EAAE,IAAI,CAACE,oBAAoB,CAACI,GAAG,EAAE;YACxFE;YACAI;YACA4C,QAAQ,IAAI,CAACvD,OAAO,CAACuD,MAAM;YAC3BC,MAAM,CAACC,QAAG,CAACC,kBAAkB;YAC7BzB,MAAM,IAAI,CAACjC,OAAO,CAACiC,IAAI,IAAI;YAC3B,wFAAwF;YACxFL,QAAQ;YACRwB,aAAa;YACbO,UAAU;QACZ;IACF;IAEA;;;;;GAKC,GACD,MAAcc,sBAAsB7B,GAAkB,EAAE8B,GAAmB,EAAE;QAC3EA,IAAIC,SAAS,CAAC,gBAAgB;QAE9BD,IAAIE,GAAG,CAAC,MAAM,IAAI,CAACC,0BAA0B;IAC/C;IAEAA,6BAA6B;QAC3B,oBAAoB;QACpB,MAAMnD,YAAY,IAAI,CAAC6C,eAAe;QAEtC,OAAOO,IAAAA,kDAAqC,EAAC,IAAI,CAAC/E,WAAW,EAAE;YAC7DM,KAAK,IAAI,CAACJ,oBAAoB,CAACI,GAAG;YAClC0E,SAAS;gBAACrD;aAAU;QACtB;IACF;IAEA,yBAAyB,GACzB,MAAMsD,yBAAyBpC,GAAkB,EAAE8B,GAAmB,EAAEO,IAAgB,EAAE;YAGtF;QAFF,IACE,IAAI,CAAC9E,gBAAgB,CAAC+E,GAAG,KAAK,aAC9B,2CAAA,IAAI,CAACjF,oBAAoB,CAACI,GAAG,CAAC8E,SAAS,qBAAvC,yCAAyCC,QAAQ,CAAC,SAClD;YACA,iGAAiG;YACjG,oGAAoG;YACpG,4FAA4F;YAC5F,MAAM7E,WAAW8E,IAAAA,oCAAmB,EAACzC;YACrC,kCAAkC;YAClC,IAAI,CAACrC,YAAYA,aAAa,OAAO;oBACD;gBAAlC,IAAI;oBAAC;oBAAU;iBAAS,CAAC6E,QAAQ,CAAC,EAAA,qCAAA,IAAI,CAACnF,oBAAoB,CAACI,GAAG,CAAC6E,GAAG,qBAAjC,mCAAmCI,MAAM,KAAI,KAAK;oBAClF,oEAAoE;oBACpEL;oBACA,OAAO;gBACT,OAAO;oBACL,MAAM,IAAI,CAACR,qBAAqB,CAAC7B,KAAK8B;oBACtC,OAAO;gBACT;YACF;QACF;QACA,OAAO;IACT;IAEA,MAAMa,mBACJ3C,GAAkB,EAClB8B,GAAmB,EACnBO,IAAgB,EACD;QACf,kFAAkF;QAClF,IAAI,MAAM,IAAI,CAACD,wBAAwB,CAACpC,KAAK8B,KAAKO,OAAO;YACvD;QACF;QAEA,kCAAkC;QAClC,MAAM,IAAI,CAACtC,gBAAgB,CAACC;QAE5B,oBAAoB;QACpB,MAAM5C,UAAU,IAAI,CAACwF,gBAAgB,CAAC5C;QAEtC,MAAM6C,WAAW,MAAM,IAAI,CAACC,yBAAyB,CAAC1F;QACtD,2CAA2C;QAC3C,IAAI,OAAO0E,IAAIiB,UAAU,KAAK,YAAY;YACxCjB,IAAIiB,UAAU,CAACF,SAAS3C,OAAO;QACjC,OAAO;YACL,KAAK,MAAM,CAAC8C,KAAKC,MAAM,IAAIJ,SAAS3C,OAAO,CAACgD,OAAO,GAAI;gBACrDpB,IAAIqB,YAAY,CAACH,KAAKC;YACxB;QACF;QACA,IAAIJ,SAASO,IAAI,EAAE;YACjB,MAAMC,IAAAA,oBAAQ,EAACC,sBAAQ,CAACC,OAAO,CAACV,SAASO,IAAI,GAAUtB;QACzD,OAAO;YACLA,IAAIE,GAAG;QACT;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../../src/start/server/middleware/ManifestMiddleware.ts"],"sourcesContent":["import {\n ExpoConfig,\n ExpoGoConfig,\n getConfig,\n PackageJSONConfig,\n ProjectConfig,\n} from '@expo/config';\nimport { resolveRelativeEntryPoint } from '@expo/config/paths';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { resolve } from 'url';\n\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport {\n createBundleUrlPath,\n getBaseUrlFromExpoConfig,\n getAsyncRoutesFromExpoConfig,\n createBundleUrlPathFromExpoConfig,\n} from './metroOptions';\nimport { resolveGoogleServicesFile, resolveManifestAssets } from './resolveAssets';\nimport { parsePlatformHeader, RuntimePlatform } from './resolvePlatform';\nimport { ServerNext, ServerRequest, ServerResponse } from './server.types';\nimport { getActorDisplayName, getUserAsync } from '../../../api/user/user';\nimport { isEnableHermesManaged } from '../../../export/exportHermes';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport * as ProjectDevices from '../../project/devices';\nimport { UrlCreator } from '../UrlCreator';\nimport { getRouterDirectoryModuleIdWithManifest } from '../metro/router';\nimport { getPlatformBundlers, PlatformBundlers } from '../platformBundlers';\nimport { createTemplateHtmlFromExpoConfigAsync } from '../webTemplate';\n\nconst debug = require('debug')('expo:start:server:middleware:manifest') as typeof console.log;\n\n/** Info about the computer hosting the dev server. */\nexport interface HostInfo {\n host: string;\n server: 'expo';\n serverVersion: string;\n serverDriver: string | null;\n serverOS: NodeJS.Platform;\n serverOSVersion: string;\n}\n\n/** Parsed values from the supported request headers. */\nexport interface ManifestRequestInfo {\n /** Platform to serve. */\n platform: RuntimePlatform;\n /** Requested host name. */\n hostname?: string | null;\n /** The protocol used to request the manifest */\n protocol?: 'http' | 'https';\n}\n\n/** Project related info. */\nexport type ResponseProjectSettings = {\n expoGoConfig: ExpoGoConfig;\n hostUri: string;\n bundleUrl: string;\n exp: ExpoConfig;\n};\n\nexport const DEVELOPER_TOOL = 'expo-cli';\n\nexport type ManifestMiddlewareOptions = {\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n constructUrl: UrlCreator['constructUrl'];\n isNativeWebpack?: boolean;\n privateKeyPath?: string;\n};\n\n/** Base middleware creator for serving the Expo manifest (like the index.html but for native runtimes). */\nexport abstract class ManifestMiddleware<\n TManifestRequestInfo extends ManifestRequestInfo,\n> extends ExpoMiddleware {\n private initialProjectConfig: ProjectConfig;\n private platformBundlers: PlatformBundlers;\n\n constructor(\n protected projectRoot: string,\n protected options: ManifestMiddlewareOptions\n ) {\n super(\n projectRoot,\n /**\n * Only support `/`, `/manifest`, `/index.exp` for the manifest middleware.\n */\n ['/', '/manifest', '/index.exp']\n );\n this.initialProjectConfig = getConfig(projectRoot);\n this.platformBundlers = getPlatformBundlers(projectRoot, this.initialProjectConfig.exp);\n }\n\n /** Exposed for testing. */\n public async _resolveProjectSettingsAsync({\n platform,\n hostname,\n protocol,\n }: Pick<\n TManifestRequestInfo,\n 'hostname' | 'platform' | 'protocol'\n >): Promise<ResponseProjectSettings> {\n // Read the config\n const projectConfig = getConfig(this.projectRoot);\n\n // Read from headers\n const mainModuleName = this.resolveMainModuleName({\n pkg: projectConfig.pkg,\n platform,\n });\n\n const isHermesEnabled = isEnableHermesManaged(projectConfig.exp, platform);\n\n // Resolve the signed-in CLI user to pass through the manifest\n const user = await getUserAsync();\n const username = getActorDisplayName(user);\n\n // Create the manifest and set fields within it\n const expoGoConfig = this.getExpoGoConfig({\n mainModuleName,\n hostname,\n username: username !== 'anonymous' ? username : undefined,\n });\n\n const hostUri = this.options.constructUrl({ scheme: '', hostname });\n\n const bundleUrl = this._getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n engine: isHermesEnabled ? 'hermes' : undefined,\n baseUrl: getBaseUrlFromExpoConfig(projectConfig.exp),\n asyncRoutes: getAsyncRoutesFromExpoConfig(\n projectConfig.exp,\n this.options.mode ?? 'development',\n platform\n ),\n routerRoot: getRouterDirectoryModuleIdWithManifest(this.projectRoot, projectConfig.exp),\n protocol,\n reactCompiler: !!projectConfig.exp.experiments?.reactCompiler,\n });\n\n // Resolve all assets and set them on the manifest as URLs\n await this.mutateManifestWithAssetsAsync(projectConfig.exp, bundleUrl);\n\n return {\n expoGoConfig,\n hostUri,\n bundleUrl,\n exp: projectConfig.exp,\n };\n }\n\n /** Get the main entry module ID (file) relative to the project root. */\n private resolveMainModuleName(props: { pkg: PackageJSONConfig; platform: string }): string {\n // NOTE(Bacon): Webpack is currently hardcoded to index.bundle on native\n // in the future (TODO) we should move this logic into a Webpack plugin and use\n // a generated file name like we do on web.\n // const server = getDefaultDevServer();\n // // TODO: Move this into BundlerDevServer and read this info from self.\n // const isNativeWebpack = server instanceof WebpackBundlerDevServer && server.isTargetingNative();\n if (this.options.isNativeWebpack) {\n return 'index';\n }\n\n const entry = resolveRelativeEntryPoint(this.projectRoot, props);\n debug(`Resolved entry point: ${entry} (project root: ${this.projectRoot})`);\n return entry;\n }\n\n /** Parse request headers into options. */\n public abstract getParsedHeaders(req: ServerRequest): TManifestRequestInfo;\n\n /** Store device IDs that were sent in the request headers. */\n private async saveDevicesAsync(req: ServerRequest) {\n const deviceIds = req.headers?.['expo-dev-client-id'];\n if (deviceIds) {\n await ProjectDevices.saveDevicesAsync(this.projectRoot, deviceIds).catch((e) =>\n Log.exception(e)\n );\n }\n }\n\n /** Create the bundle URL (points to the single JS entry file). Exposed for testing. */\n public _getBundleUrl({\n platform,\n mainModuleName,\n hostname,\n engine,\n baseUrl,\n isExporting,\n asyncRoutes,\n routerRoot,\n protocol,\n reactCompiler,\n }: {\n platform: string;\n hostname?: string | null;\n mainModuleName: string;\n engine?: 'hermes';\n baseUrl?: string;\n asyncRoutes: boolean;\n isExporting?: boolean;\n routerRoot: string;\n protocol?: 'http' | 'https';\n reactCompiler: boolean;\n }): string {\n const path = createBundleUrlPath({\n mode: this.options.mode ?? 'development',\n minify: this.options.minify,\n platform,\n mainModuleName,\n lazy: !env.EXPO_NO_METRO_LAZY,\n engine,\n bytecode: engine === 'hermes',\n baseUrl,\n isExporting: !!isExporting,\n asyncRoutes,\n routerRoot,\n reactCompiler,\n });\n\n return (\n this.options.constructUrl({\n scheme: protocol ?? 'http',\n // hostType: this.options.location.hostType,\n hostname,\n }) + path\n );\n }\n\n /** Get the manifest response to return to the runtime. This file contains info regarding where the assets can be loaded from. Exposed for testing. */\n public abstract _getManifestResponseAsync(options: TManifestRequestInfo): Promise<Response>;\n\n private getExpoGoConfig({\n mainModuleName,\n hostname,\n username,\n }: {\n mainModuleName: string;\n hostname?: string | null;\n username?: string;\n }): ExpoGoConfig {\n return {\n // localhost:8081\n debuggerHost: this.options.constructUrl({ scheme: '', hostname }),\n // Required for Expo Go to function.\n developer: {\n tool: DEVELOPER_TOOL,\n projectRoot: this.projectRoot,\n },\n packagerOpts: {\n // Required for dev client.\n dev: this.options.mode !== 'production',\n },\n // Indicates the name of the main bundle.\n mainModuleName,\n // The signed-in CLI username, used by Expo Go to verify account match.\n ...(username ? { username } : undefined),\n };\n }\n\n /** Resolve all assets and set them on the manifest as URLs */\n private async mutateManifestWithAssetsAsync(manifest: ExpoConfig, bundleUrl: string) {\n await resolveManifestAssets(this.projectRoot, {\n manifest,\n resolver: async (path) => {\n if (this.options.isNativeWebpack) {\n // When using our custom dev server, just do assets normally\n // without the `assets/` subpath redirect.\n return resolve(bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0], path);\n }\n return bundleUrl!.match(/^https?:\\/\\/.*?\\//)![0] + 'assets/' + path;\n },\n });\n // The server normally inserts this but if we're offline we'll do it here\n await resolveGoogleServicesFile(this.projectRoot, manifest);\n }\n\n public getWebBundleUrl() {\n const platform = 'web';\n // Read from headers\n const mainModuleName = this.resolveMainModuleName({\n pkg: this.initialProjectConfig.pkg,\n platform,\n });\n\n return createBundleUrlPathFromExpoConfig(this.projectRoot, this.initialProjectConfig.exp, {\n platform,\n mainModuleName,\n minify: this.options.minify,\n lazy: !env.EXPO_NO_METRO_LAZY,\n mode: this.options.mode ?? 'development',\n // Hermes doesn't support more modern JS features than most, if not all, modern browser.\n engine: 'hermes',\n isExporting: false,\n bytecode: false,\n });\n }\n\n /**\n * Web platforms should create an index.html response using the same script resolution as native.\n *\n * Instead of adding a `bundleUrl` to a `manifest.json` (native) we'll add a `<script src=\"\">`\n * to an `index.html`, this enables the web platform to load JavaScript from the server.\n */\n private async handleWebRequestAsync(req: ServerRequest, res: ServerResponse) {\n res.setHeader('Content-Type', 'text/html');\n\n res.end(await this.getSingleHtmlTemplateAsync());\n }\n\n getSingleHtmlTemplateAsync() {\n // Read from headers\n const bundleUrl = this.getWebBundleUrl();\n\n return createTemplateHtmlFromExpoConfigAsync(this.projectRoot, {\n exp: this.initialProjectConfig.exp,\n scripts: [bundleUrl],\n });\n }\n\n /** Exposed for testing. */\n async checkBrowserRequestAsync(req: ServerRequest, res: ServerResponse, next: ServerNext) {\n if (\n this.platformBundlers.web === 'metro' &&\n this.initialProjectConfig.exp.platforms?.includes('web')\n ) {\n // NOTE(EvanBacon): This effectively disables the safety check we do on custom runtimes to ensure\n // the `expo-platform` header is included. When `web.bundler=web`, if the user has non-standard Expo\n // code loading then they'll get a web bundle without a clear assertion of platform support.\n const platform = parsePlatformHeader(req);\n // On web, serve the public folder\n if (!platform || platform === 'web') {\n if (['static', 'server'].includes(this.initialProjectConfig.exp.web?.output ?? '')) {\n // Skip the spa-styled index.html when static generation is enabled.\n next();\n return true;\n } else {\n await this.handleWebRequestAsync(req, res);\n return true;\n }\n }\n }\n return false;\n }\n\n async handleRequestAsync(\n req: ServerRequest,\n res: ServerResponse,\n next: ServerNext\n ): Promise<void> {\n // First check for standard JavaScript runtimes (aka legacy browsers like Chrome).\n if (await this.checkBrowserRequestAsync(req, res, next)) {\n return;\n }\n\n // Save device IDs for dev client.\n await this.saveDevicesAsync(req);\n\n // Read from headers\n const options = this.getParsedHeaders(req);\n\n const response = await this._getManifestResponseAsync(options);\n // Convert `Response` to node:http response\n if (typeof res.setHeaders === 'function') {\n res.setHeaders(response.headers);\n } else {\n for (const [key, value] of response.headers.entries()) {\n res.appendHeader(key, value);\n }\n }\n if (response.body) {\n await pipeline(Readable.fromWeb(response.body as any), res);\n } else {\n res.end();\n }\n }\n}\n"],"names":["DEVELOPER_TOOL","ManifestMiddleware","debug","require","ExpoMiddleware","constructor","projectRoot","options","initialProjectConfig","getConfig","platformBundlers","getPlatformBundlers","exp","_resolveProjectSettingsAsync","platform","hostname","protocol","projectConfig","mainModuleName","resolveMainModuleName","pkg","isHermesEnabled","isEnableHermesManaged","user","getUserAsync","username","getActorDisplayName","expoGoConfig","getExpoGoConfig","undefined","hostUri","constructUrl","scheme","bundleUrl","_getBundleUrl","engine","baseUrl","getBaseUrlFromExpoConfig","asyncRoutes","getAsyncRoutesFromExpoConfig","mode","routerRoot","getRouterDirectoryModuleIdWithManifest","reactCompiler","experiments","mutateManifestWithAssetsAsync","props","isNativeWebpack","entry","resolveRelativeEntryPoint","saveDevicesAsync","req","deviceIds","headers","ProjectDevices","catch","e","Log","exception","isExporting","path","createBundleUrlPath","minify","lazy","env","EXPO_NO_METRO_LAZY","bytecode","debuggerHost","developer","tool","packagerOpts","dev","manifest","resolveManifestAssets","resolver","resolve","match","resolveGoogleServicesFile","getWebBundleUrl","createBundleUrlPathFromExpoConfig","handleWebRequestAsync","res","setHeader","end","getSingleHtmlTemplateAsync","createTemplateHtmlFromExpoConfigAsync","scripts","checkBrowserRequestAsync","next","web","platforms","includes","parsePlatformHeader","output","handleRequestAsync","getParsedHeaders","response","_getManifestResponseAsync","setHeaders","key","value","entries","appendHeader","body","pipeline","Readable","fromWeb"],"mappings":"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"}
@@ -29,7 +29,6 @@ function _chalk() {
29
29
  };
30
30
  return data;
31
31
  }
32
- const _CdpClient = require("./CdpClient");
33
32
  const _prompts = require("../../../../utils/prompts");
34
33
  const _pageIsSupported = require("../../metro/debugging/pageIsSupported");
35
34
  function _interop_require_default(obj) {
@@ -74,25 +73,7 @@ async function queryAllInspectorAppsAsync(metroServerOrigin) {
74
73
  // The newest runtime will be at the end of the list,
75
74
  // reversing the result would save time from try-error.
76
75
  const apps = (await resp.json()).reverse();
77
- const results = [];
78
- for (const app of apps){
79
- // Only use targets with better reloading support
80
- if (!(0, _pageIsSupported.pageIsSupported)(app)) {
81
- continue;
82
- }
83
- try {
84
- // Hide targets that are marked as hidden from the inspector, e.g. instances from expo-dev-menu and expo-dev-launcher.
85
- if (await appShouldBeIgnoredAsync(app)) {
86
- continue;
87
- }
88
- } catch (e) {
89
- // If we can't evaluate the JS, we just ignore the error and skips the target.
90
- debug(`Can't evaluate the JS on the app:`, JSON.stringify(e, null, 2));
91
- continue;
92
- }
93
- results.push(app);
94
- }
95
- return results;
76
+ return apps.filter((app)=>(0, _pageIsSupported.pageIsSupported)(app));
96
77
  }
97
78
  async function promptInspectorAppAsync(apps) {
98
79
  var _choices_find;
@@ -113,11 +94,5 @@ async function promptInspectorAppAsync(apps) {
113
94
  const value = await (0, _prompts.selectAsync)((0, _chalk().default)`Debug target {dim (Hermes only)}`, choices);
114
95
  return (_choices_find = choices.find((item)=>item.value === value)) == null ? void 0 : _choices_find.app;
115
96
  }
116
- const HIDE_FROM_INSPECTOR_ENV = 'globalThis.__expo_hide_from_inspector__';
117
- async function appShouldBeIgnoredAsync(app) {
118
- const hideFromInspector = await (0, _CdpClient.evaluateJsFromCdpAsync)(app.webSocketDebuggerUrl, HIDE_FROM_INSPECTOR_ENV);
119
- debug(`[appShouldBeIgnoredAsync] webSocketDebuggerUrl[${app.webSocketDebuggerUrl}] hideFromInspector[${hideFromInspector}]`);
120
- return hideFromInspector !== undefined;
121
- }
122
97
 
123
98
  //# sourceMappingURL=JsInspector.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/start/server/middleware/inspector/JsInspector.ts"],"sourcesContent":["import type { CustomMessageHandlerConnection } from '@react-native/dev-middleware';\nimport chalk from 'chalk';\n\nimport { evaluateJsFromCdpAsync } from './CdpClient';\nimport { selectAsync } from '../../../../utils/prompts';\nimport { pageIsSupported } from '../../metro/debugging/pageIsSupported';\n\nconst debug = require('debug')(\n 'expo:start:server:middleware:inspector:jsInspector'\n) as typeof console.log;\n\nexport interface MetroInspectorProxyApp {\n /** Unique device ID combined with the page ID */\n id: string;\n /** Information about the underlying CDP implementation, e.g. \"React Native Bridgeless [C++ connection]\" */\n title: string;\n /** The application ID that is currently running on the device, e.g. \"dev.expo.bareexpo\" */\n appId: string;\n /** The description of the runtime, e.g. \"React Native Bridgeless [C++ connection]\" */\n description: string;\n /** The CDP debugger type, which should always be \"node\" */\n type: 'node';\n /** The internal `devtools://..` URL for the debugger to connect to */\n devtoolsFrontendUrl: string;\n /** The websocket URL for the debugger to connect to */\n webSocketDebuggerUrl: string;\n /**\n * Human-readable device name\n * @since react-native@0.73\n */\n deviceName: string;\n /**\n * React Native specific information, like the unique device ID and native capabilities\n * @since react-native@0.74\n */\n reactNative?: {\n /** The unique device ID */\n logicalDeviceId: string;\n /** All supported native capabilities */\n capabilities: CustomMessageHandlerConnection['page']['capabilities'];\n };\n}\n\n/**\n * Launch the React Native DevTools by executing the `POST /open-debugger` request.\n * This endpoint is handled through `@react-native/dev-middleware`.\n */\nexport async function openJsInspector(metroBaseUrl: string, app: MetroInspectorProxyApp) {\n if (!app.reactNative?.logicalDeviceId) {\n debug('Failed to open React Native DevTools, target is missing device ID');\n return false;\n }\n\n const url = new URL('/open-debugger', metroBaseUrl);\n url.searchParams.set('target', app.id);\n\n // Request to open the React Native DevTools, but limit it to 1s\n // This is a workaround as this endpoint might not respond on some devices\n const response = await fetch(url, {\n method: 'POST',\n signal: AbortSignal.timeout(1000),\n }).catch((error) => {\n // Only swallow timeout errors\n if (error.name === 'TimeoutError') {\n return null;\n }\n\n throw error;\n });\n\n if (!response) {\n debug(`No response received from the React Native DevTools.`);\n } else if (response.ok === false) {\n debug('Failed to open React Native DevTools, received response:', response.status);\n }\n\n return response?.ok ?? true;\n}\n\nexport async function queryInspectorAppAsync(\n metroServerOrigin: string,\n appId: string\n): Promise<MetroInspectorProxyApp | null> {\n const apps = await queryAllInspectorAppsAsync(metroServerOrigin);\n return apps.find((app) => app.appId === appId) ?? null;\n}\n\nexport async function queryAllInspectorAppsAsync(\n metroServerOrigin: string\n): Promise<MetroInspectorProxyApp[]> {\n const resp = await fetch(`${metroServerOrigin}/json/list`);\n // The newest runtime will be at the end of the list,\n // reversing the result would save time from try-error.\n const apps: MetroInspectorProxyApp[] = (await resp.json()).reverse();\n const results: MetroInspectorProxyApp[] = [];\n for (const app of apps) {\n // Only use targets with better reloading support\n if (!pageIsSupported(app)) {\n continue;\n }\n\n try {\n // Hide targets that are marked as hidden from the inspector, e.g. instances from expo-dev-menu and expo-dev-launcher.\n if (await appShouldBeIgnoredAsync(app)) {\n continue;\n }\n } catch (e: unknown) {\n // If we can't evaluate the JS, we just ignore the error and skips the target.\n debug(`Can't evaluate the JS on the app:`, JSON.stringify(e, null, 2));\n continue;\n }\n\n results.push(app);\n }\n return results;\n}\n\nexport async function promptInspectorAppAsync(apps: MetroInspectorProxyApp[]) {\n if (apps.length === 1) {\n return apps[0];\n }\n\n // Check if multiple devices are connected with the same device names\n // In this case, append the actual app id (device ID + page number) to the prompt\n const hasDuplicateNames = apps.some(\n (app, index) => index !== apps.findIndex((other) => app.deviceName === other.deviceName)\n );\n\n const choices = apps.map((app) => {\n const name = app.deviceName ?? 'Unknown device';\n return {\n title: hasDuplicateNames ? chalk`${name}{dim - ${app.id}}` : name,\n value: app.id,\n app,\n };\n });\n\n const value = await selectAsync(chalk`Debug target {dim (Hermes only)}`, choices);\n\n return choices.find((item) => item.value === value)?.app;\n}\n\nconst HIDE_FROM_INSPECTOR_ENV = 'globalThis.__expo_hide_from_inspector__';\n\nasync function appShouldBeIgnoredAsync(app: MetroInspectorProxyApp): Promise<boolean> {\n const hideFromInspector = await evaluateJsFromCdpAsync(\n app.webSocketDebuggerUrl,\n HIDE_FROM_INSPECTOR_ENV\n );\n debug(\n `[appShouldBeIgnoredAsync] webSocketDebuggerUrl[${app.webSocketDebuggerUrl}] hideFromInspector[${hideFromInspector}]`\n );\n return hideFromInspector !== undefined;\n}\n"],"names":["openJsInspector","promptInspectorAppAsync","queryAllInspectorAppsAsync","queryInspectorAppAsync","debug","require","metroBaseUrl","app","reactNative","logicalDeviceId","url","URL","searchParams","set","id","response","fetch","method","signal","AbortSignal","timeout","catch","error","name","ok","status","metroServerOrigin","appId","apps","find","resp","json","reverse","results","pageIsSupported","appShouldBeIgnoredAsync","e","JSON","stringify","push","choices","length","hasDuplicateNames","some","index","findIndex","other","deviceName","map","title","chalk","value","selectAsync","item","HIDE_FROM_INSPECTOR_ENV","hideFromInspector","evaluateJsFromCdpAsync","webSocketDebuggerUrl","undefined"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../src/start/server/middleware/inspector/JsInspector.ts"],"sourcesContent":["import type { CustomMessageHandlerConnection } from '@react-native/dev-middleware';\nimport chalk from 'chalk';\n\nimport { selectAsync } from '../../../../utils/prompts';\nimport { pageIsSupported } from '../../metro/debugging/pageIsSupported';\n\nconst debug = require('debug')(\n 'expo:start:server:middleware:inspector:jsInspector'\n) as typeof console.log;\n\nexport interface MetroInspectorProxyApp {\n /** Unique device ID combined with the page ID */\n id: string;\n /** Information about the underlying CDP implementation, e.g. \"React Native Bridgeless [C++ connection]\" */\n title: string;\n /** The application ID that is currently running on the device, e.g. \"dev.expo.bareexpo\" */\n appId: string;\n /** The description of the runtime, e.g. \"React Native Bridgeless [C++ connection]\" */\n description: string;\n /** The CDP debugger type, which should always be \"node\" */\n type: 'node';\n /** The internal `devtools://..` URL for the debugger to connect to */\n devtoolsFrontendUrl: string;\n /** The websocket URL for the debugger to connect to */\n webSocketDebuggerUrl: string;\n /**\n * Human-readable device name\n * @since react-native@0.73\n */\n deviceName: string;\n /**\n * React Native specific information, like the unique device ID and native capabilities\n * @since react-native@0.74\n */\n reactNative?: {\n /** The unique device ID */\n logicalDeviceId: string;\n /** All supported native capabilities */\n capabilities: CustomMessageHandlerConnection['page']['capabilities'];\n };\n}\n\n/**\n * Launch the React Native DevTools by executing the `POST /open-debugger` request.\n * This endpoint is handled through `@react-native/dev-middleware`.\n */\nexport async function openJsInspector(metroBaseUrl: string, app: MetroInspectorProxyApp) {\n if (!app.reactNative?.logicalDeviceId) {\n debug('Failed to open React Native DevTools, target is missing device ID');\n return false;\n }\n\n const url = new URL('/open-debugger', metroBaseUrl);\n url.searchParams.set('target', app.id);\n\n // Request to open the React Native DevTools, but limit it to 1s\n // This is a workaround as this endpoint might not respond on some devices\n const response = await fetch(url, {\n method: 'POST',\n signal: AbortSignal.timeout(1000),\n }).catch((error) => {\n // Only swallow timeout errors\n if (error.name === 'TimeoutError') {\n return null;\n }\n\n throw error;\n });\n\n if (!response) {\n debug(`No response received from the React Native DevTools.`);\n } else if (response.ok === false) {\n debug('Failed to open React Native DevTools, received response:', response.status);\n }\n\n return response?.ok ?? true;\n}\n\nexport async function queryInspectorAppAsync(\n metroServerOrigin: string,\n appId: string\n): Promise<MetroInspectorProxyApp | null> {\n const apps = await queryAllInspectorAppsAsync(metroServerOrigin);\n return apps.find((app) => app.appId === appId) ?? null;\n}\n\nexport async function queryAllInspectorAppsAsync(\n metroServerOrigin: string\n): Promise<MetroInspectorProxyApp[]> {\n const resp = await fetch(`${metroServerOrigin}/json/list`);\n // The newest runtime will be at the end of the list,\n // reversing the result would save time from try-error.\n const apps: MetroInspectorProxyApp[] = (await resp.json()).reverse();\n return apps.filter((app) => pageIsSupported(app));\n}\n\nexport async function promptInspectorAppAsync(apps: MetroInspectorProxyApp[]) {\n if (apps.length === 1) {\n return apps[0];\n }\n\n // Check if multiple devices are connected with the same device names\n // In this case, append the actual app id (device ID + page number) to the prompt\n const hasDuplicateNames = apps.some(\n (app, index) => index !== apps.findIndex((other) => app.deviceName === other.deviceName)\n );\n\n const choices = apps.map((app) => {\n const name = app.deviceName ?? 'Unknown device';\n return {\n title: hasDuplicateNames ? chalk`${name}{dim - ${app.id}}` : name,\n value: app.id,\n app,\n };\n });\n\n const value = await selectAsync(chalk`Debug target {dim (Hermes only)}`, choices);\n\n return choices.find((item) => item.value === value)?.app;\n}\n"],"names":["openJsInspector","promptInspectorAppAsync","queryAllInspectorAppsAsync","queryInspectorAppAsync","debug","require","metroBaseUrl","app","reactNative","logicalDeviceId","url","URL","searchParams","set","id","response","fetch","method","signal","AbortSignal","timeout","catch","error","name","ok","status","metroServerOrigin","appId","apps","find","resp","json","reverse","filter","pageIsSupported","choices","length","hasDuplicateNames","some","index","findIndex","other","deviceName","map","title","chalk","value","selectAsync","item"],"mappings":";;;;;;;;;;;IA8CsBA,eAAe;eAAfA;;IAkDAC,uBAAuB;eAAvBA;;IAVAC,0BAA0B;eAA1BA;;IARAC,sBAAsB;eAAtBA;;;;gEA7EJ;;;;;;yBAEU;iCACI;;;;;;AAEhC,MAAMC,QAAQC,QAAQ,SACpB;AAuCK,eAAeL,gBAAgBM,YAAoB,EAAEC,GAA2B;QAChFA;IAAL,IAAI,GAACA,mBAAAA,IAAIC,WAAW,qBAAfD,iBAAiBE,eAAe,GAAE;QACrCL,MAAM;QACN,OAAO;IACT;IAEA,MAAMM,MAAM,IAAIC,IAAI,kBAAkBL;IACtCI,IAAIE,YAAY,CAACC,GAAG,CAAC,UAAUN,IAAIO,EAAE;IAErC,gEAAgE;IAChE,0EAA0E;IAC1E,MAAMC,WAAW,MAAMC,MAAMN,KAAK;QAChCO,QAAQ;QACRC,QAAQC,YAAYC,OAAO,CAAC;IAC9B,GAAGC,KAAK,CAAC,CAACC;QACR,8BAA8B;QAC9B,IAAIA,MAAMC,IAAI,KAAK,gBAAgB;YACjC,OAAO;QACT;QAEA,MAAMD;IACR;IAEA,IAAI,CAACP,UAAU;QACbX,MAAM,CAAC,oDAAoD,CAAC;IAC9D,OAAO,IAAIW,SAASS,EAAE,KAAK,OAAO;QAChCpB,MAAM,4DAA4DW,SAASU,MAAM;IACnF;IAEA,OAAOV,CAAAA,4BAAAA,SAAUS,EAAE,KAAI;AACzB;AAEO,eAAerB,uBACpBuB,iBAAyB,EACzBC,KAAa;IAEb,MAAMC,OAAO,MAAM1B,2BAA2BwB;IAC9C,OAAOE,KAAKC,IAAI,CAAC,CAACtB,MAAQA,IAAIoB,KAAK,KAAKA,UAAU;AACpD;AAEO,eAAezB,2BACpBwB,iBAAyB;IAEzB,MAAMI,OAAO,MAAMd,MAAM,GAAGU,kBAAkB,UAAU,CAAC;IACzD,qDAAqD;IACrD,uDAAuD;IACvD,MAAME,OAAiC,AAAC,CAAA,MAAME,KAAKC,IAAI,EAAC,EAAGC,OAAO;IAClE,OAAOJ,KAAKK,MAAM,CAAC,CAAC1B,MAAQ2B,IAAAA,gCAAe,EAAC3B;AAC9C;AAEO,eAAeN,wBAAwB2B,IAA8B;QAsBnEO;IArBP,IAAIP,KAAKQ,MAAM,KAAK,GAAG;QACrB,OAAOR,IAAI,CAAC,EAAE;IAChB;IAEA,qEAAqE;IACrE,iFAAiF;IACjF,MAAMS,oBAAoBT,KAAKU,IAAI,CACjC,CAAC/B,KAAKgC,QAAUA,UAAUX,KAAKY,SAAS,CAAC,CAACC,QAAUlC,IAAImC,UAAU,KAAKD,MAAMC,UAAU;IAGzF,MAAMP,UAAUP,KAAKe,GAAG,CAAC,CAACpC;QACxB,MAAMgB,OAAOhB,IAAImC,UAAU,IAAI;QAC/B,OAAO;YACLE,OAAOP,oBAAoBQ,IAAAA,gBAAK,CAAA,CAAC,EAAEtB,KAAK,QAAQ,EAAEhB,IAAIO,EAAE,CAAC,CAAC,CAAC,GAAGS;YAC9DuB,OAAOvC,IAAIO,EAAE;YACbP;QACF;IACF;IAEA,MAAMuC,QAAQ,MAAMC,IAAAA,oBAAW,EAACF,IAAAA,gBAAK,CAAA,CAAC,gCAAgC,CAAC,EAAEV;IAEzE,QAAOA,gBAAAA,QAAQN,IAAI,CAAC,CAACmB,OAASA,KAAKF,KAAK,KAAKA,2BAAtCX,cAA8C5B,GAAG;AAC1D"}
@@ -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/${"55.0.26"}`,
29
+ 'user-agent': `expo-cli/${"55.0.28"}`,
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: "55.0.26"
86
+ version: "55.0.28"
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": "55.0.26",
3
+ "version": "55.0.28",
4
4
  "description": "The Expo CLI",
5
5
  "main": "build/bin/cli",
6
6
  "bin": {
@@ -48,8 +48,8 @@
48
48
  "@expo/image-utils": "^0.8.13",
49
49
  "@expo/json-file": "^10.0.13",
50
50
  "@expo/log-box": "55.0.11",
51
- "@expo/metro": "~55.1.0",
52
- "@expo/metro-config": "~55.0.17",
51
+ "@expo/metro": "~55.1.1",
52
+ "@expo/metro-config": "~55.0.19",
53
53
  "@expo/osascript": "^2.4.2",
54
54
  "@expo/package-manager": "^1.10.4",
55
55
  "@expo/plist": "^0.5.2",
@@ -158,5 +158,5 @@
158
158
  "tree-kill": "^1.2.2",
159
159
  "tsd": "^0.28.1"
160
160
  },
161
- "gitHead": "79d9741b93539a7347411a261f3c2474d58cc4be"
161
+ "gitHead": "6ab08fe32823d60ad90b3ca2821b4d99a3ae06e9"
162
162
  }
@@ -1,81 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "evaluateJsFromCdpAsync", {
6
- enumerable: true,
7
- get: function() {
8
- return evaluateJsFromCdpAsync;
9
- }
10
- });
11
- function _ws() {
12
- const data = require("ws");
13
- _ws = function() {
14
- return data;
15
- };
16
- return data;
17
- }
18
- const debug = require('debug')('expo:start:server:middleware:inspector:CdpClient');
19
- function evaluateJsFromCdpAsync(webSocketDebuggerUrl, source, timeoutMs = 2000) {
20
- const REQUEST_ID = 0;
21
- let timeoutHandle;
22
- return new Promise((resolve, reject)=>{
23
- let settled = false;
24
- const ws = new (_ws()).WebSocket(webSocketDebuggerUrl);
25
- timeoutHandle = setTimeout(()=>{
26
- debug(`[evaluateJsFromCdpAsync] Request timeout from ${webSocketDebuggerUrl}`);
27
- reject(new Error('Request timeout'));
28
- settled = true;
29
- ws.close();
30
- // NOTE(@hassankhan): The cast to `NodeJS.Timeout` below is a hack to work around an issue
31
- // with TypeScript where React Native's types are being imported before Node types
32
- }, timeoutMs);
33
- ws.on('open', ()=>{
34
- ws.send(JSON.stringify({
35
- id: REQUEST_ID,
36
- method: 'Runtime.evaluate',
37
- params: {
38
- expression: source
39
- }
40
- }));
41
- });
42
- ws.on('error', (e)=>{
43
- debug(`[evaluateJsFromCdpAsync] Failed to connect ${webSocketDebuggerUrl}`, e);
44
- reject(e);
45
- settled = true;
46
- clearTimeout(timeoutHandle);
47
- ws.close();
48
- });
49
- ws.on('close', ()=>{
50
- if (!settled) {
51
- reject(new Error('WebSocket closed before response was received.'));
52
- clearTimeout(timeoutHandle);
53
- }
54
- });
55
- ws.on('message', (data)=>{
56
- debug(`[evaluateJsFromCdpAsync] message received from ${webSocketDebuggerUrl}: ${data.toString()}`);
57
- try {
58
- const response = JSON.parse(data.toString());
59
- if (response.id === REQUEST_ID) {
60
- if (response.error) {
61
- reject(new Error(response.error.message));
62
- } else if (response.result.result.type === 'string') {
63
- resolve(response.result.result.value);
64
- } else {
65
- resolve(undefined);
66
- }
67
- settled = true;
68
- clearTimeout(timeoutHandle);
69
- ws.close();
70
- }
71
- } catch (e) {
72
- reject(e);
73
- settled = true;
74
- clearTimeout(timeoutHandle);
75
- ws.close();
76
- }
77
- });
78
- });
79
- }
80
-
81
- //# sourceMappingURL=CdpClient.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../../../src/start/server/middleware/inspector/CdpClient.ts"],"sourcesContent":["import { WebSocket } from 'ws';\n\nconst debug = require('debug')(\n 'expo:start:server:middleware:inspector:CdpClient'\n) as typeof console.log;\n\nexport function evaluateJsFromCdpAsync(\n webSocketDebuggerUrl: string,\n source: string,\n timeoutMs: number = 2000\n): Promise<string | undefined> {\n const REQUEST_ID = 0;\n let timeoutHandle: NodeJS.Timeout;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n const ws = new WebSocket(webSocketDebuggerUrl);\n\n timeoutHandle = setTimeout(() => {\n debug(`[evaluateJsFromCdpAsync] Request timeout from ${webSocketDebuggerUrl}`);\n reject(new Error('Request timeout'));\n settled = true;\n ws.close();\n // NOTE(@hassankhan): The cast to `NodeJS.Timeout` below is a hack to work around an issue\n // with TypeScript where React Native's types are being imported before Node types\n }, timeoutMs) as unknown as NodeJS.Timeout;\n\n ws.on('open', () => {\n ws.send(\n JSON.stringify({\n id: REQUEST_ID,\n method: 'Runtime.evaluate',\n params: { expression: source },\n })\n );\n });\n\n ws.on('error', (e) => {\n debug(`[evaluateJsFromCdpAsync] Failed to connect ${webSocketDebuggerUrl}`, e);\n reject(e);\n settled = true;\n clearTimeout(timeoutHandle);\n ws.close();\n });\n\n ws.on('close', () => {\n if (!settled) {\n reject(new Error('WebSocket closed before response was received.'));\n clearTimeout(timeoutHandle);\n }\n });\n\n ws.on('message', (data) => {\n debug(\n `[evaluateJsFromCdpAsync] message received from ${webSocketDebuggerUrl}: ${data.toString()}`\n );\n try {\n const response = JSON.parse(data.toString());\n if (response.id === REQUEST_ID) {\n if (response.error) {\n reject(new Error(response.error.message));\n } else if (response.result.result.type === 'string') {\n resolve(response.result.result.value);\n } else {\n resolve(undefined);\n }\n settled = true;\n clearTimeout(timeoutHandle);\n ws.close();\n }\n } catch (e) {\n reject(e);\n settled = true;\n clearTimeout(timeoutHandle);\n ws.close();\n }\n });\n });\n}\n"],"names":["evaluateJsFromCdpAsync","debug","require","webSocketDebuggerUrl","source","timeoutMs","REQUEST_ID","timeoutHandle","Promise","resolve","reject","settled","ws","WebSocket","setTimeout","Error","close","on","send","JSON","stringify","id","method","params","expression","e","clearTimeout","data","toString","response","parse","error","message","result","type","value","undefined"],"mappings":";;;;+BAMgBA;;;eAAAA;;;;yBANU;;;;;;AAE1B,MAAMC,QAAQC,QAAQ,SACpB;AAGK,SAASF,uBACdG,oBAA4B,EAC5BC,MAAc,EACdC,YAAoB,IAAI;IAExB,MAAMC,aAAa;IACnB,IAAIC;IAEJ,OAAO,IAAIC,QAAQ,CAACC,SAASC;QAC3B,IAAIC,UAAU;QACd,MAAMC,KAAK,IAAIC,CAAAA,KAAQ,WAAC,CAACV;QAEzBI,gBAAgBO,WAAW;YACzBb,MAAM,CAAC,8CAA8C,EAAEE,sBAAsB;YAC7EO,OAAO,IAAIK,MAAM;YACjBJ,UAAU;YACVC,GAAGI,KAAK;QACR,0FAA0F;QAC1F,kFAAkF;QACpF,GAAGX;QAEHO,GAAGK,EAAE,CAAC,QAAQ;YACZL,GAAGM,IAAI,CACLC,KAAKC,SAAS,CAAC;gBACbC,IAAIf;gBACJgB,QAAQ;gBACRC,QAAQ;oBAAEC,YAAYpB;gBAAO;YAC/B;QAEJ;QAEAQ,GAAGK,EAAE,CAAC,SAAS,CAACQ;YACdxB,MAAM,CAAC,2CAA2C,EAAEE,sBAAsB,EAAEsB;YAC5Ef,OAAOe;YACPd,UAAU;YACVe,aAAanB;YACbK,GAAGI,KAAK;QACV;QAEAJ,GAAGK,EAAE,CAAC,SAAS;YACb,IAAI,CAACN,SAAS;gBACZD,OAAO,IAAIK,MAAM;gBACjBW,aAAanB;YACf;QACF;QAEAK,GAAGK,EAAE,CAAC,WAAW,CAACU;YAChB1B,MACE,CAAC,+CAA+C,EAAEE,qBAAqB,EAAE,EAAEwB,KAAKC,QAAQ,IAAI;YAE9F,IAAI;gBACF,MAAMC,WAAWV,KAAKW,KAAK,CAACH,KAAKC,QAAQ;gBACzC,IAAIC,SAASR,EAAE,KAAKf,YAAY;oBAC9B,IAAIuB,SAASE,KAAK,EAAE;wBAClBrB,OAAO,IAAIK,MAAMc,SAASE,KAAK,CAACC,OAAO;oBACzC,OAAO,IAAIH,SAASI,MAAM,CAACA,MAAM,CAACC,IAAI,KAAK,UAAU;wBACnDzB,QAAQoB,SAASI,MAAM,CAACA,MAAM,CAACE,KAAK;oBACtC,OAAO;wBACL1B,QAAQ2B;oBACV;oBACAzB,UAAU;oBACVe,aAAanB;oBACbK,GAAGI,KAAK;gBACV;YACF,EAAE,OAAOS,GAAG;gBACVf,OAAOe;gBACPd,UAAU;gBACVe,aAAanB;gBACbK,GAAGI,KAAK;YACV;QACF;IACF;AACF"}