@expo/cli 57.0.3 → 57.0.5

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 (36) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/events/index.js +1 -1
  3. package/build/src/export/publicFolder.js +2 -8
  4. package/build/src/export/publicFolder.js.map +1 -1
  5. package/build/src/start/interface/interactiveActions.js +42 -5
  6. package/build/src/start/interface/interactiveActions.js.map +1 -1
  7. package/build/src/start/interface/startInterface.js +4 -4
  8. package/build/src/start/interface/startInterface.js.map +1 -1
  9. package/build/src/start/server/DevToolsPlugin.js +57 -22
  10. package/build/src/start/server/DevToolsPlugin.js.map +1 -1
  11. package/build/src/start/server/DevToolsPlugin.schema.js +5 -0
  12. package/build/src/start/server/DevToolsPlugin.schema.js.map +1 -1
  13. package/build/src/start/server/DevToolsPluginManager.js +17 -3
  14. package/build/src/start/server/DevToolsPluginManager.js.map +1 -1
  15. package/build/src/start/server/DevToolsPluginServerHelpers.js +83 -0
  16. package/build/src/start/server/DevToolsPluginServerHelpers.js.map +1 -0
  17. package/build/src/start/server/MCP.js +10 -3
  18. package/build/src/start/server/MCP.js.map +1 -1
  19. package/build/src/start/server/metro/MetroBundlerDevServer.js +2 -1
  20. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  21. package/build/src/start/server/metro/instantiateMetro.js +18 -1
  22. package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
  23. package/build/src/start/server/middleware/DevToolsPluginMiddleware.js +57 -6
  24. package/build/src/start/server/middleware/DevToolsPluginMiddleware.js.map +1 -1
  25. package/build/src/start/startAsync.js +3 -0
  26. package/build/src/start/startAsync.js.map +1 -1
  27. package/build/src/utils/dir.js +10 -0
  28. package/build/src/utils/dir.js.map +1 -1
  29. package/build/src/utils/telemetry/Telemetry.js +5 -0
  30. package/build/src/utils/telemetry/Telemetry.js.map +1 -1
  31. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  32. package/build/src/utils/telemetry/utils/agent.js +42 -0
  33. package/build/src/utils/telemetry/utils/agent.js.map +1 -0
  34. package/build/src/utils/telemetry/utils/context.js +1 -1
  35. package/package.json +18 -18
  36. package/add-module.js +0 -8
@@ -104,6 +104,7 @@ const _events = require("../../../events");
104
104
  const _log = require("../../../log");
105
105
  const _env = require("../../../utils/env");
106
106
  const _errors = require("../../../utils/errors");
107
+ const _DevToolsPluginManager = require("../DevToolsPluginManager");
107
108
  const _CorsMiddleware = require("../middleware/CorsMiddleware");
108
109
  const _createJsInspectorMiddleware = require("../middleware/inspector/createJsInspectorMiddleware");
109
110
  const _mutations = require("../middleware/mutations");
@@ -316,7 +317,7 @@ async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, ge
316
317
  }
317
318
  async function instantiateMetroAsync(metroBundler, options, { isExporting, exp = (0, _config().getConfig)(metroBundler.projectRoot, {
318
319
  skipSDKVersionRequirement: true
319
- }).exp }) {
320
+ }).exp, devToolsPluginManager }) {
320
321
  var _metroConfig_server;
321
322
  const projectRoot = metroBundler.projectRoot;
322
323
  const getMetroBundler = ()=>metro.getBundler().getBundler();
@@ -360,6 +361,22 @@ async function instantiateMetroAsync(metroBundler, options, { isExporting, exp =
360
361
  };
361
362
  const devtoolsWebsocketEndpoints = (0, _DevToolsPluginWebsocketEndpoint.createDevToolsPluginWebsocketEndpoint)();
362
363
  Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);
364
+ // Register WebSocket endpoints contributed by DevTools plugins. A plugin's `serverEntryPoint`
365
+ // exports a `webSocketHandlers` map (route -> connection handler); each becomes a `ws` server
366
+ // mounted at `/_expo/plugins/<name>/<route>`, reusing Metro's exact-path upgrade dispatch (and
367
+ // its shutdown cleanup). Endpoints must be known before the server starts, so unlike the
368
+ // fetch-based request handler, plugin server modules are loaded eagerly here.
369
+ for (const plugin of (await devToolsPluginManager.queryPluginsAsync())){
370
+ try {
371
+ for (const [route, server] of Object.entries(await plugin.getWebSocketServersAsync())){
372
+ Object.assign(websocketEndpoints, {
373
+ [`${_DevToolsPluginManager.DevToolsPluginEndpoint}/${plugin.packageName}${route}`]: server
374
+ });
375
+ }
376
+ } catch (error) {
377
+ _log.Log.warn(`Skipping WebSocket endpoints for DevTools plugin "${plugin.packageName}": ${error.message ?? error}`);
378
+ }
379
+ }
363
380
  }
364
381
  // Attach Expo Atlas if enabled
365
382
  await (0, _attachAtlas.attachAtlasAsync)({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/instantiateMetro.ts"],"sourcesContent":["import { type ExpoConfig, getConfig, getPlatformsFromConfig } from '@expo/config';\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport type { Reporter } from '@expo/metro/metro';\nimport type Bundler from '@expo/metro/metro/Bundler';\nimport type { ReadOnlyGraph } from '@expo/metro/metro/DeltaBundler';\nimport type { TransformOptions } from '@expo/metro/metro/DeltaBundler/Worker';\nimport type { Client as MetroHmrClient } from '@expo/metro/metro/HmrServer';\nimport type MetroHmrServer from '@expo/metro/metro/HmrServer';\nimport RevisionNotFoundError from '@expo/metro/metro/IncrementalBundler/RevisionNotFoundError';\nimport type MetroServer from '@expo/metro/metro/Server';\nimport formatBundlingError from '@expo/metro/metro/lib/formatBundlingError';\nimport { Terminal } from '@expo/metro/metro-core';\nimport type { createStableModuleIdFactory } from '@expo/metro-config';\nimport { loadUserConfig } from '@expo/metro-config';\nimport { patchTransformFileForPackedMaps } from '@expo/metro-config/build/serializer/packedMap';\nimport { patchMetroSourceMapStringForPackedMaps } from '@expo/metro-config/build/serializer/sourceMap';\nimport chalk from 'chalk';\nimport type http from 'http';\nimport path from 'path';\n\nimport { createDevToolsPluginWebsocketEndpoint } from './DevToolsPluginWebsocketEndpoint';\nimport type { MetroBundlerDevServer } from './MetroBundlerDevServer';\nimport { MetroTerminalReporter } from './MetroTerminalReporter';\nimport { replaceMetroFileMap } from './createFileMap-fork';\nimport { attachAtlasAsync } from './debugging/attachAtlas';\nimport { createDebugMiddleware } from './debugging/createDebugMiddleware';\nimport { createMetroMiddleware } from './dev-server/createMetroMiddleware';\nimport { runServer, type ServerAddressInfo, type SecureServerOptions } from './runServer-fork';\nimport { withMetroMultiPlatformAsync } from './withMetroMultiPlatform';\nimport { events, shouldReduceLogs } from '../../../events';\nimport { Log } from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { createCorsMiddleware } from '../middleware/CorsMiddleware';\nimport { createJsInspectorMiddleware } from '../middleware/inspector/createJsInspectorMiddleware';\nimport { prependMiddleware } from '../middleware/mutations';\nimport { getPlatformBundlers } from '../platformBundlers';\n\n// prettier-ignore\nexport const event = events('metro', (t) => [\n t.event<'config', {\n serverRoot: string;\n projectRoot: string;\n exporting: boolean;\n flags: {\n autolinkingModuleResolution: boolean;\n serverActions: boolean;\n serverComponents: boolean;\n reactCompiler: boolean;\n optimizeGraph?: boolean;\n treeshaking?: boolean;\n logbox?: boolean;\n };\n }>(),\n t.event<'instantiate', {\n atlas: boolean;\n workers: number | null;\n host: string | null;\n port: number | null;\n }>(),\n]);\n\n// NOTE(@kitten): We pass a custom createStableModuleIdFactory function into the Metro module ID factory sometimes\ninterface MetroServerWithModuleIdMod extends MetroServer {\n _createModuleId: ReturnType<typeof createStableModuleIdFactory> & ((path: string) => number);\n}\ninterface MetroHmrServerWithModuleIdMod extends MetroHmrServer<MetroHmrClient> {\n _createModuleId: ReturnType<typeof createStableModuleIdFactory> & ((path: string) => number);\n}\n\n// From expo/dev-server but with ability to use custom logger.\ntype MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\n// TODO(@kitten): We assign this here to run server-side code bundled by metro\n// It's not isolated into a worker thread yet\n// Check `metro-require/require.ts` for how this setting is used\ndeclare namespace globalThis {\n let __requireCycleIgnorePatterns: readonly RegExp[] | undefined;\n}\n\nfunction asWritable<T>(input: T): { -readonly [K in keyof T]: T[K] } {\n return input;\n}\n\n/**\n * Extends Metro's Terminal to intercept all console methods so they don't\n * corrupt the progress bar status lines.\n *\n * console.log/info are routed through terminal.log() (stdout, managed).\n * console.warn/error are routed through logStderr() which clears the\n * status from stdout before writing to stderr, then restores it.\n * Without this, unmanaged stderr writes shift the cursor and cause\n * progress bars to get stuck as permanent output.\n */\nclass LogRespectingTerminal extends Terminal {\n #stderrQueue: string[] = [];\n #drainingStderr = false;\n\n constructor(stream: import('node:net').Socket | import('node:stream').Writable) {\n super(stream, { ttyPrint: true });\n\n const sendLog = (...msg: any[]) => {\n if (!msg.length) {\n this.log('');\n } else {\n const [format, ...args] = msg;\n this.log(format, ...args);\n }\n // Flush the logs to the terminal immediately so logs at the end of the process are not lost.\n this.flush();\n };\n\n const sendStderr = (...msg: any[]) => {\n if (!msg.length) {\n this.logStderr('');\n } else {\n const [format, ...args] = msg;\n this.logStderr(require('util').format(format, ...args));\n }\n };\n\n console.log = sendLog;\n console.info = sendLog;\n console.warn = sendStderr;\n console.error = sendStderr;\n\n // NOTE(@kitten): We flush the stderr queue immediately when we're about to exit\n process.on('exit', () => {\n if (!this.#drainingStderr && this.#stderrQueue.length) {\n this.#drainingStderr = true;\n this.status('');\n const lines = this.#stderrQueue.splice(0);\n process.stderr.write(lines.join('\\n') + '\\n');\n }\n });\n }\n\n /** Write to stderr without corrupting Terminal's cursor tracking. */\n logStderr(line: string): void {\n if (!(process.stdout as any).isTTY) {\n process.stderr.write(line + '\\n');\n return;\n }\n this.#stderrQueue.push(line);\n this.#drainStderr();\n }\n\n async #drainStderr(): Promise<void> {\n if (this.#drainingStderr) return;\n this.#drainingStderr = true;\n\n while (this.#stderrQueue.length > 0) {\n // Clear status, flush to ensure it's removed from screen\n const prev = this.status('');\n await this.flush();\n\n // Write to stderr while status is cleared\n const lines = this.#stderrQueue.splice(0);\n process.stderr.write(lines.join('\\n') + '\\n');\n\n // Restore status\n this.status(prev);\n }\n\n this.#drainingStderr = false;\n }\n}\n\n// Share one instance of Terminal for all instances of Metro.\nconst terminal = new LogRespectingTerminal(process.stdout);\n\ninterface LoadMetroConfigOptions {\n maxWorkers?: number;\n port?: number;\n reporter?: Reporter;\n resetCache?: boolean;\n}\n\nexport async function loadMetroConfigAsync(\n projectRoot: string,\n options: LoadMetroConfigOptions,\n {\n exp,\n isExporting,\n getMetroBundler,\n }: { exp: ExpoConfig; isExporting: boolean; getMetroBundler: () => Bundler }\n) {\n let reportEvent: ((event: any) => void) | undefined;\n\n // We're resolving a monorepo root, higher up than the `projectRoot`. If this\n // folder is different (presumably a parent) we're in a monorepo\n const serverRoot = getMetroServerRoot(projectRoot);\n const isWorkspace = serverRoot !== projectRoot;\n\n // Out-of-tree platforms (tvos/macos) rely on the autolinking module resolver to remap the\n // react-native package to their support package, and require autolinking module resolution\n const targetsOutOfTreePlatform = getPlatformsFromConfig(projectRoot, exp).some(\n (platform) => platform === 'tvos' || platform === 'macos'\n );\n\n // Autolinking Module Resolution is enabled by default in a monorepo or for out-of-tree platforms.\n const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? (isWorkspace || targetsOutOfTreePlatform);\n\n const serverActionsEnabled =\n exp.experiments?.reactServerFunctions ?? env.EXPO_UNSTABLE_SERVER_FUNCTIONS;\n const serverComponentsEnabled = !!exp.experiments?.reactServerComponentRoutes;\n if (serverActionsEnabled) {\n process.env.EXPO_UNSTABLE_SERVER_FUNCTIONS = '1';\n }\n\n // NOTE: Enable all the experimental Metro flags when RSC is enabled.\n if (serverComponentsEnabled || serverActionsEnabled) {\n process.env.EXPO_USE_METRO_REQUIRE = '1';\n }\n\n if (exp.experiments?.reactCanary) {\n Log.warn(`React 19 is enabled by default. Remove unused experiments.reactCanary flag.`);\n }\n\n const terminalReporter = new MetroTerminalReporter(serverRoot, terminal);\n\n let config = await loadUserConfig({\n projectRoot,\n serverRoot,\n // NOTE: Allow external tools to override the metro config. This is considered internal and unstable\n overrideConfigPath: env.EXPO_OVERRIDE_METRO_CONFIG ?? undefined,\n });\n\n config = {\n ...config,\n // See: `overrideConfigWithArguments` https://github.com/facebook/metro/blob/5059e26/packages/metro-config/src/loadConfig.js#L274-L339\n // Compare to `LoadOptions` type (disregard `reporter` as we don't expose this)\n resetCache: !!options.resetCache,\n maxWorkers: options.maxWorkers ?? config.maxWorkers,\n server: {\n ...config.server,\n port: options.port ?? config.server.port,\n },\n // Force-override the reporter\n reporter: {\n update(event) {\n terminalReporter.update(event);\n if (reportEvent) {\n reportEvent(event);\n }\n },\n },\n };\n\n // On-Demand Filesystem is enabled by default\n // TODO(@kitten): Add to config-types JSON schema\n const onDemandFilesystem = exp.experiments?.onDemandFilesystem ?? true;\n asWritable(config.resolver).unstable_onDemandFilesystem = onDemandFilesystem;\n\n globalThis.__requireCycleIgnorePatterns = config.resolver?.requireCycleIgnorePatterns;\n\n if (isExporting) {\n // This token will be used in the asset plugin to ensure the path is correct for writing locally.\n asWritable(config.transformer).publicPath = `/assets?export_path=${\n (exp.experiments?.baseUrl ?? '') + '/assets'\n }`;\n } else {\n asWritable(config.transformer).publicPath = '/assets/?unstable_path=.';\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n const reduceLogs = shouldReduceLogs();\n\n const reactCompilerEnabled = !!exp.experiments?.reactCompiler;\n if (!reduceLogs && reactCompilerEnabled) {\n Log.log(chalk.gray`React Compiler enabled`);\n }\n\n if (!reduceLogs && autolinkingModuleResolutionEnabled) {\n Log.log(chalk.gray`Expo Autolinking module resolution enabled`);\n }\n\n if (env.EXPO_UNSTABLE_TREE_SHAKING && !env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n throw new CommandError(\n 'EXPO_UNSTABLE_TREE_SHAKING requires EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH to be enabled.'\n );\n }\n\n if (!reduceLogs && env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n Log.warn(`Experimental bundle optimization is enabled.`);\n }\n if (!reduceLogs && env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental tree shaking is enabled.`);\n }\n if (!reduceLogs && env.EXPO_UNSTABLE_LOG_BOX) {\n Log.warn(`Experimental Expo LogBox is enabled.`);\n }\n\n if (!reduceLogs && serverActionsEnabled) {\n Log.warn(\n `React Server Functions (beta) are enabled. Route rendering mode: ${exp.experiments?.reactServerComponentRoutes ? 'server' : 'client'}`\n );\n }\n\n config = await withMetroMultiPlatformAsync(projectRoot, {\n config,\n exp,\n platformBundlers,\n serverRoot,\n isTsconfigPathsEnabled: exp.experiments?.tsconfigPaths ?? true,\n isAutolinkingResolverEnabled: autolinkingModuleResolutionEnabled,\n isExporting,\n isNamedRequiresEnabled: env.EXPO_USE_METRO_REQUIRE,\n isReactServerComponentsEnabled: serverComponentsEnabled,\n getMetroBundler,\n });\n\n event('config', {\n serverRoot: event.path(serverRoot),\n projectRoot: event.path(projectRoot),\n exporting: isExporting,\n flags: {\n autolinkingModuleResolution: autolinkingModuleResolutionEnabled,\n serverActions: serverActionsEnabled,\n serverComponents: serverComponentsEnabled,\n reactCompiler: reactCompilerEnabled,\n optimizeGraph: env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH,\n treeshaking: env.EXPO_UNSTABLE_TREE_SHAKING,\n logbox: env.EXPO_UNSTABLE_LOG_BOX,\n },\n });\n\n return {\n config,\n setEventReporter: (logger: (event: any) => void) => (reportEvent = logger),\n reporter: terminalReporter,\n };\n}\n\ninterface InstantiateMetroConfigOptions extends LoadMetroConfigOptions {\n host?: string;\n}\n\n/** The most generic possible setup for Metro bundler. */\nexport async function instantiateMetroAsync(\n metroBundler: MetroBundlerDevServer,\n options: InstantiateMetroConfigOptions,\n {\n isExporting,\n exp = getConfig(metroBundler.projectRoot, {\n skipSDKVersionRequirement: true,\n }).exp,\n }: { isExporting: boolean; exp?: ExpoConfig }\n): Promise<{\n metro: MetroServer;\n hmrServer: MetroHmrServer<MetroHmrClient> | null;\n server: http.Server;\n address: ServerAddressInfo | null;\n middleware: any;\n messageSocket: MessageSocket;\n}> {\n const projectRoot = metroBundler.projectRoot;\n const getMetroBundler = () => metro.getBundler().getBundler();\n\n const {\n config: metroConfig,\n setEventReporter,\n reporter,\n } = await loadMetroConfigAsync(projectRoot, options, {\n exp,\n isExporting,\n getMetroBundler,\n });\n\n // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)\n const serverBaseUrl = metroBundler\n .getUrlCreator()\n .constructUrl({ scheme: 'http', hostType: 'localhost' });\n\n // Create the core middleware stack for Metro, including websocket listeners\n const { middleware, messagesSocket, eventsSocket, websocketEndpoints } = createMetroMiddleware(\n metroConfig,\n { getMetroBundler, serverBaseUrl }\n );\n\n if (!isExporting) {\n // Enable correct CORS headers for Expo Router features\n prependMiddleware(middleware, createCorsMiddleware(exp));\n\n // Enable debug middleware for CDP-related debugging\n const { debugMiddleware, debugWebsocketEndpoints } = createDebugMiddleware({\n serverBaseUrl,\n reporter,\n });\n Object.assign(websocketEndpoints, debugWebsocketEndpoints);\n middleware.use(debugMiddleware);\n middleware.use('/_expo/debugger', createJsInspectorMiddleware({ serverBaseUrl }));\n\n // TODO(cedric): `enhanceMiddleware` is deprecated, but is currently used to unify the middleware stacks\n // See: https://github.com/facebook/metro/commit/22e85fde85ec454792a1b70eba4253747a2587a9\n // See: https://github.com/facebook/metro/commit/d0d554381f119bb80ab09dbd6a1d310b54737e52\n const customEnhanceMiddleware = metroConfig.server.enhanceMiddleware;\n asWritable(metroConfig.server).enhanceMiddleware = (\n metroMiddleware: any,\n server: MetroServer\n ) => {\n if (customEnhanceMiddleware) {\n metroMiddleware = customEnhanceMiddleware(metroMiddleware, server);\n }\n return middleware.use(metroMiddleware);\n };\n\n const devtoolsWebsocketEndpoints = createDevToolsPluginWebsocketEndpoint();\n Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);\n }\n\n // Attach Expo Atlas if enabled\n await attachAtlasAsync({\n isExporting,\n exp,\n projectRoot,\n middleware,\n metroConfig,\n // NOTE(cedric): reset the Atlas file once, and reuse it for static exports\n resetAtlasFile: isExporting,\n });\n\n // Support HTTPS based on the metro's tls server config\n // TODO(@kitten): Remove cast once `@expo/metro` is updated to a Metro version that supports the tls config\n const tls = (metroConfig.server as typeof metroConfig.server & { tls?: SecureServerOptions })\n ?.tls;\n const secureServerOptions = tls\n ? {\n key: tls.key,\n cert: tls.cert,\n ca: tls.ca,\n requestCert: tls.requestCert,\n }\n : undefined;\n\n const watch = !isExporting && isWatchEnabled();\n\n const { address, server, hmrServer, metro } = await replaceMetroFileMap(() => {\n return runServer(\n metroBundler,\n metroConfig,\n {\n host: options.host,\n websocketEndpoints,\n watch,\n secureServerOptions,\n },\n {\n mockServer: isExporting,\n }\n );\n });\n\n event('instantiate', {\n atlas: env.EXPO_ATLAS,\n workers: metroConfig.maxWorkers ?? null,\n host: address?.address ?? null,\n port: address?.port ?? null,\n });\n\n // Patch transform file to remove inconvenient customTransformOptions which are only used in single well-known files.\n const originalTransformFile = metro\n .getBundler()\n .getBundler()\n .transformFile.bind(metro.getBundler().getBundler());\n\n metro.getBundler().getBundler().transformFile = async function (\n filePath: string,\n transformOptions: TransformOptions,\n fileBuffer?: Buffer\n ) {\n return originalTransformFile(\n filePath,\n pruneCustomTransformOptions(\n projectRoot,\n filePath,\n // Clone the options so we don't mutate the original.\n {\n ...transformOptions,\n customTransformOptions: {\n __proto__: null,\n ...transformOptions.customTransformOptions,\n },\n }\n ),\n fileBuffer\n );\n };\n\n // Layered on top of the prune patch above. Both fresh worker results\n // and cache hits flow through `Bundler.transformFile`, so wrapping\n // here covers both.\n patchTransformFileForPackedMaps(metro.getBundler().getBundler());\n patchMetroSourceMapStringForPackedMaps();\n\n setEventReporter(eventsSocket.reportMetroEvent);\n\n // This function ensures that modules in source maps are sorted in the same\n // order as in a plain JS bundle.\n metro._getSortedModules = function (this: MetroServerWithModuleIdMod, graph: ReadOnlyGraph) {\n const modules = [...graph.dependencies.values()];\n\n const ctx = {\n // TODO(@kitten): Increase type-safety here\n platform: graph.transformOptions.platform!,\n environment: graph.transformOptions.customTransformOptions?.environment,\n };\n // Assign IDs to modules in a consistent order\n for (const module of modules) {\n this._createModuleId(module.path, ctx);\n }\n // Sort by IDs\n return modules.sort(\n (a, b) => this._createModuleId(a.path, ctx) - this._createModuleId(b.path, ctx)\n );\n };\n\n if (hmrServer) {\n let hmrJSBundle:\n | typeof import('@expo/metro-config/build/serializer/fork/hmrJSBundle').default\n | typeof import('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle').default;\n\n try {\n hmrJSBundle = require('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n } catch {\n // TODO: Add fallback for monorepo tests up until the fork is merged.\n Log.warn('Failed to load HMR serializer from @expo/metro-config, using fallback version.');\n hmrJSBundle = require('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle');\n }\n\n // Patch HMR Server to send more info to the `_createModuleId` function for deterministic module IDs and add support for serializing HMR updates the same as all other bundles.\n hmrServer._prepareMessage = async function (\n this: MetroHmrServerWithModuleIdMod,\n group,\n options,\n changeEvent\n ) {\n // Fork of https://github.com/facebook/metro/blob/3b3e0aaf725cfa6907bf2c8b5fbc0da352d29efe/packages/metro/src/HmrServer.js#L327-L393\n // with patch for `_createModuleId`.\n const logger = !options.isInitialUpdate ? changeEvent?.logger : null;\n try {\n const revPromise = this._bundler.getRevision(group.revisionId);\n if (!revPromise) {\n return {\n type: 'error',\n body: formatBundlingError(new RevisionNotFoundError(group.revisionId)),\n };\n }\n logger?.point('updateGraph_start');\n const { revision, delta } = await this._bundler.updateGraph(await revPromise, false);\n logger?.point('updateGraph_end');\n this._clientGroups.delete(group.revisionId);\n group.revisionId = revision.id;\n for (const client of group.clients) {\n client.revisionIds = client.revisionIds.filter(\n (revisionId) => revisionId !== group.revisionId\n );\n client.revisionIds.push(revision.id);\n }\n this._clientGroups.set(group.revisionId, group);\n logger?.point('serialize_start');\n // NOTE(EvanBacon): This is the patch\n const moduleIdContext = {\n // TODO(@kitten): Increase type-safety here\n platform: revision.graph.transformOptions.platform!,\n environment: revision.graph.transformOptions.customTransformOptions?.environment,\n };\n const hmrUpdate = hmrJSBundle(delta, revision.graph, {\n clientUrl: group.clientUrl,\n // NOTE(EvanBacon): This is also the patch\n createModuleId: (moduleId: string) => {\n return this._createModuleId(moduleId, moduleIdContext);\n },\n includeAsyncPaths: group.graphOptions.lazy,\n projectRoot: this._config.projectRoot,\n serverRoot: this._config.server.unstable_serverRoot ?? this._config.projectRoot,\n });\n logger?.point('serialize_end');\n return {\n type: 'update',\n body: {\n revisionId: revision.id,\n isInitialUpdate: options.isInitialUpdate,\n ...hmrUpdate,\n },\n };\n } catch (error: any) {\n const formattedError = formatBundlingError(error);\n this._config.reporter.update({\n type: 'bundling_error',\n error,\n });\n return {\n type: 'error',\n body: formattedError,\n };\n }\n };\n }\n\n return {\n metro,\n hmrServer,\n server,\n middleware,\n messageSocket: messagesSocket,\n address,\n };\n}\n\n// TODO: Fork the entire transform function so we can simply regex the file contents for keywords instead.\nfunction pruneCustomTransformOptions(\n projectRoot: string,\n filePath: string,\n transformOptions: TransformOptions\n): TransformOptions {\n // Normalize the filepath for cross platform checking.\n filePath = filePath.split(path.sep).join('/');\n\n if (\n transformOptions.customTransformOptions?.dom &&\n // The only generated file that needs the dom root is `expo/dom/entry.js`\n !filePath.match(/expo\\/dom\\/entry\\.js$/)\n ) {\n // Clear the dom root option if we aren't transforming the magic entry file, this ensures\n // that cached artifacts from other DOM component bundles can be reused.\n transformOptions.customTransformOptions.dom = 'true';\n }\n\n const routerRoot = transformOptions.customTransformOptions?.routerRoot;\n if (typeof routerRoot === 'string') {\n const isRouterEntry = /\\/expo-router\\/_ctx/.test(filePath);\n // The router root is used all over expo-router (`process.env.EXPO_ROUTER_ABS_APP_ROOT`, `process.env.EXPO_ROUTER_APP_ROOT`) so we'll just ignore the entire package.\n const isRouterModule = /\\/expo-router\\/build\\//.test(filePath);\n // Any page/router inside the expo-router app folder may access the `routerRoot` option to determine whether it's in the app folder\n const resolvedRouterRoot = path.resolve(projectRoot, routerRoot).split(path.sep).join('/');\n const isRouterRoute = path.isAbsolute(filePath) && filePath.startsWith(resolvedRouterRoot);\n\n // In any other file than the above, we enforce that we mustn't use `routerRoot`, and set it to an arbitrary value here (the default)\n // to ensure that the cache never invalidates when this value is changed\n if (!isRouterEntry && !isRouterModule && !isRouterRoute) {\n transformOptions.customTransformOptions!.routerRoot = 'app';\n }\n }\n\n if (\n transformOptions.customTransformOptions?.asyncRoutes &&\n // The async routes settings are also used in `expo-router/_ctx.ios.js` (and other platform variants) via `process.env.EXPO_ROUTER_IMPORT_MODE`\n !(filePath.match(/\\/expo-router\\/_ctx/) || filePath.match(/\\/expo-router\\/build\\//))\n ) {\n delete transformOptions.customTransformOptions.asyncRoutes;\n }\n\n if (\n transformOptions.customTransformOptions?.clientBoundaries &&\n // The client boundaries are only used in `expo/virtual/rsc.js` for production RSC exports.\n !filePath.match(/\\/expo\\/virtual\\/rsc\\.js$/)\n ) {\n delete transformOptions.customTransformOptions.clientBoundaries;\n }\n\n return transformOptions;\n}\n\n/**\n * Simplify and communicate if Metro is running without watching file updates,.\n * Exposed for testing.\n */\nexport function isWatchEnabled() {\n if (env.CI) {\n Log.log(\n chalk`Metro is running in CI mode, reloads are disabled. Remove {bold CI=true} to enable watch mode.`\n );\n }\n\n return !env.CI;\n}\n"],"names":["event","instantiateMetroAsync","isWatchEnabled","loadMetroConfigAsync","events","t","asWritable","input","LogRespectingTerminal","Terminal","stream","ttyPrint","sendLog","msg","length","log","format","args","flush","sendStderr","logStderr","require","console","info","warn","error","process","on","status","lines","splice","stderr","write","join","line","stdout","isTTY","push","prev","terminal","projectRoot","options","exp","isExporting","getMetroBundler","config","reportEvent","serverRoot","getMetroServerRoot","isWorkspace","targetsOutOfTreePlatform","getPlatformsFromConfig","some","platform","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","serverActionsEnabled","reactServerFunctions","env","EXPO_UNSTABLE_SERVER_FUNCTIONS","serverComponentsEnabled","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","reactCanary","Log","terminalReporter","MetroTerminalReporter","loadUserConfig","overrideConfigPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resetCache","maxWorkers","server","port","reporter","update","onDemandFilesystem","resolver","unstable_onDemandFilesystem","globalThis","__requireCycleIgnorePatterns","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reduceLogs","shouldReduceLogs","reactCompilerEnabled","reactCompiler","chalk","gray","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","EXPO_UNSTABLE_LOG_BOX","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isAutolinkingResolverEnabled","isNamedRequiresEnabled","isReactServerComponentsEnabled","path","exporting","flags","serverActions","serverComponents","optimizeGraph","treeshaking","logbox","setEventReporter","logger","metroBundler","getConfig","skipSDKVersionRequirement","metroConfig","metro","getBundler","serverBaseUrl","getUrlCreator","constructUrl","scheme","hostType","middleware","messagesSocket","eventsSocket","websocketEndpoints","createMetroMiddleware","prependMiddleware","createCorsMiddleware","debugMiddleware","debugWebsocketEndpoints","createDebugMiddleware","Object","assign","use","createJsInspectorMiddleware","customEnhanceMiddleware","enhanceMiddleware","metroMiddleware","devtoolsWebsocketEndpoints","createDevToolsPluginWebsocketEndpoint","attachAtlasAsync","resetAtlasFile","tls","secureServerOptions","key","cert","ca","requestCert","watch","address","hmrServer","replaceMetroFileMap","runServer","host","mockServer","atlas","EXPO_ATLAS","workers","originalTransformFile","transformFile","bind","filePath","transformOptions","fileBuffer","pruneCustomTransformOptions","customTransformOptions","__proto__","patchTransformFileForPackedMaps","patchMetroSourceMapStringForPackedMaps","reportMetroEvent","_getSortedModules","graph","modules","dependencies","values","ctx","environment","module","_createModuleId","sort","a","b","hmrJSBundle","default","_prepareMessage","group","changeEvent","isInitialUpdate","revision","revPromise","_bundler","getRevision","revisionId","type","body","formatBundlingError","RevisionNotFoundError","point","delta","updateGraph","_clientGroups","delete","id","client","clients","revisionIds","filter","set","moduleIdContext","hmrUpdate","clientUrl","createModuleId","moduleId","includeAsyncPaths","graphOptions","lazy","_config","unstable_serverRoot","formattedError","messageSocket","split","sep","dom","match","routerRoot","isRouterEntry","test","isRouterModule","resolvedRouterRoot","resolve","isRouterRoute","isAbsolute","startsWith","asyncRoutes","clientBoundaries","CI"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/server/metro/instantiateMetro.ts"],"sourcesContent":["import { type ExpoConfig, getConfig, getPlatformsFromConfig } from '@expo/config';\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport type { Reporter } from '@expo/metro/metro';\nimport type Bundler from '@expo/metro/metro/Bundler';\nimport type { ReadOnlyGraph } from '@expo/metro/metro/DeltaBundler';\nimport type { TransformOptions } from '@expo/metro/metro/DeltaBundler/Worker';\nimport type { Client as MetroHmrClient } from '@expo/metro/metro/HmrServer';\nimport type MetroHmrServer from '@expo/metro/metro/HmrServer';\nimport RevisionNotFoundError from '@expo/metro/metro/IncrementalBundler/RevisionNotFoundError';\nimport type MetroServer from '@expo/metro/metro/Server';\nimport formatBundlingError from '@expo/metro/metro/lib/formatBundlingError';\nimport { Terminal } from '@expo/metro/metro-core';\nimport type { createStableModuleIdFactory } from '@expo/metro-config';\nimport { loadUserConfig } from '@expo/metro-config';\nimport { patchTransformFileForPackedMaps } from '@expo/metro-config/build/serializer/packedMap';\nimport { patchMetroSourceMapStringForPackedMaps } from '@expo/metro-config/build/serializer/sourceMap';\nimport chalk from 'chalk';\nimport type http from 'http';\nimport path from 'path';\n\nimport { createDevToolsPluginWebsocketEndpoint } from './DevToolsPluginWebsocketEndpoint';\nimport type { MetroBundlerDevServer } from './MetroBundlerDevServer';\nimport { MetroTerminalReporter } from './MetroTerminalReporter';\nimport { replaceMetroFileMap } from './createFileMap-fork';\nimport { attachAtlasAsync } from './debugging/attachAtlas';\nimport { createDebugMiddleware } from './debugging/createDebugMiddleware';\nimport { createMetroMiddleware } from './dev-server/createMetroMiddleware';\nimport { runServer, type ServerAddressInfo, type SecureServerOptions } from './runServer-fork';\nimport { withMetroMultiPlatformAsync } from './withMetroMultiPlatform';\nimport { events, shouldReduceLogs } from '../../../events';\nimport { Log } from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport type DevToolsPluginManager from '../DevToolsPluginManager';\nimport { DevToolsPluginEndpoint } from '../DevToolsPluginManager';\nimport { createCorsMiddleware } from '../middleware/CorsMiddleware';\nimport { createJsInspectorMiddleware } from '../middleware/inspector/createJsInspectorMiddleware';\nimport { prependMiddleware } from '../middleware/mutations';\nimport { getPlatformBundlers } from '../platformBundlers';\n\n// prettier-ignore\nexport const event = events('metro', (t) => [\n t.event<'config', {\n serverRoot: string;\n projectRoot: string;\n exporting: boolean;\n flags: {\n autolinkingModuleResolution: boolean;\n serverActions: boolean;\n serverComponents: boolean;\n reactCompiler: boolean;\n optimizeGraph?: boolean;\n treeshaking?: boolean;\n logbox?: boolean;\n };\n }>(),\n t.event<'instantiate', {\n atlas: boolean;\n workers: number | null;\n host: string | null;\n port: number | null;\n }>(),\n]);\n\n// NOTE(@kitten): We pass a custom createStableModuleIdFactory function into the Metro module ID factory sometimes\ninterface MetroServerWithModuleIdMod extends MetroServer {\n _createModuleId: ReturnType<typeof createStableModuleIdFactory> & ((path: string) => number);\n}\ninterface MetroHmrServerWithModuleIdMod extends MetroHmrServer<MetroHmrClient> {\n _createModuleId: ReturnType<typeof createStableModuleIdFactory> & ((path: string) => number);\n}\n\n// From expo/dev-server but with ability to use custom logger.\ntype MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\n// TODO(@kitten): We assign this here to run server-side code bundled by metro\n// It's not isolated into a worker thread yet\n// Check `metro-require/require.ts` for how this setting is used\ndeclare namespace globalThis {\n let __requireCycleIgnorePatterns: readonly RegExp[] | undefined;\n}\n\nfunction asWritable<T>(input: T): { -readonly [K in keyof T]: T[K] } {\n return input;\n}\n\n/**\n * Extends Metro's Terminal to intercept all console methods so they don't\n * corrupt the progress bar status lines.\n *\n * console.log/info are routed through terminal.log() (stdout, managed).\n * console.warn/error are routed through logStderr() which clears the\n * status from stdout before writing to stderr, then restores it.\n * Without this, unmanaged stderr writes shift the cursor and cause\n * progress bars to get stuck as permanent output.\n */\nclass LogRespectingTerminal extends Terminal {\n #stderrQueue: string[] = [];\n #drainingStderr = false;\n\n constructor(stream: import('node:net').Socket | import('node:stream').Writable) {\n super(stream, { ttyPrint: true });\n\n const sendLog = (...msg: any[]) => {\n if (!msg.length) {\n this.log('');\n } else {\n const [format, ...args] = msg;\n this.log(format, ...args);\n }\n // Flush the logs to the terminal immediately so logs at the end of the process are not lost.\n this.flush();\n };\n\n const sendStderr = (...msg: any[]) => {\n if (!msg.length) {\n this.logStderr('');\n } else {\n const [format, ...args] = msg;\n this.logStderr(require('util').format(format, ...args));\n }\n };\n\n console.log = sendLog;\n console.info = sendLog;\n console.warn = sendStderr;\n console.error = sendStderr;\n\n // NOTE(@kitten): We flush the stderr queue immediately when we're about to exit\n process.on('exit', () => {\n if (!this.#drainingStderr && this.#stderrQueue.length) {\n this.#drainingStderr = true;\n this.status('');\n const lines = this.#stderrQueue.splice(0);\n process.stderr.write(lines.join('\\n') + '\\n');\n }\n });\n }\n\n /** Write to stderr without corrupting Terminal's cursor tracking. */\n logStderr(line: string): void {\n if (!(process.stdout as any).isTTY) {\n process.stderr.write(line + '\\n');\n return;\n }\n this.#stderrQueue.push(line);\n this.#drainStderr();\n }\n\n async #drainStderr(): Promise<void> {\n if (this.#drainingStderr) return;\n this.#drainingStderr = true;\n\n while (this.#stderrQueue.length > 0) {\n // Clear status, flush to ensure it's removed from screen\n const prev = this.status('');\n await this.flush();\n\n // Write to stderr while status is cleared\n const lines = this.#stderrQueue.splice(0);\n process.stderr.write(lines.join('\\n') + '\\n');\n\n // Restore status\n this.status(prev);\n }\n\n this.#drainingStderr = false;\n }\n}\n\n// Share one instance of Terminal for all instances of Metro.\nconst terminal = new LogRespectingTerminal(process.stdout);\n\ninterface LoadMetroConfigOptions {\n maxWorkers?: number;\n port?: number;\n reporter?: Reporter;\n resetCache?: boolean;\n}\n\nexport async function loadMetroConfigAsync(\n projectRoot: string,\n options: LoadMetroConfigOptions,\n {\n exp,\n isExporting,\n getMetroBundler,\n }: { exp: ExpoConfig; isExporting: boolean; getMetroBundler: () => Bundler }\n) {\n let reportEvent: ((event: any) => void) | undefined;\n\n // We're resolving a monorepo root, higher up than the `projectRoot`. If this\n // folder is different (presumably a parent) we're in a monorepo\n const serverRoot = getMetroServerRoot(projectRoot);\n const isWorkspace = serverRoot !== projectRoot;\n\n // Out-of-tree platforms (tvos/macos) rely on the autolinking module resolver to remap the\n // react-native package to their support package, and require autolinking module resolution\n const targetsOutOfTreePlatform = getPlatformsFromConfig(projectRoot, exp).some(\n (platform) => platform === 'tvos' || platform === 'macos'\n );\n\n // Autolinking Module Resolution is enabled by default in a monorepo or for out-of-tree platforms.\n const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? (isWorkspace || targetsOutOfTreePlatform);\n\n const serverActionsEnabled =\n exp.experiments?.reactServerFunctions ?? env.EXPO_UNSTABLE_SERVER_FUNCTIONS;\n const serverComponentsEnabled = !!exp.experiments?.reactServerComponentRoutes;\n if (serverActionsEnabled) {\n process.env.EXPO_UNSTABLE_SERVER_FUNCTIONS = '1';\n }\n\n // NOTE: Enable all the experimental Metro flags when RSC is enabled.\n if (serverComponentsEnabled || serverActionsEnabled) {\n process.env.EXPO_USE_METRO_REQUIRE = '1';\n }\n\n if (exp.experiments?.reactCanary) {\n Log.warn(`React 19 is enabled by default. Remove unused experiments.reactCanary flag.`);\n }\n\n const terminalReporter = new MetroTerminalReporter(serverRoot, terminal);\n\n let config = await loadUserConfig({\n projectRoot,\n serverRoot,\n // NOTE: Allow external tools to override the metro config. This is considered internal and unstable\n overrideConfigPath: env.EXPO_OVERRIDE_METRO_CONFIG ?? undefined,\n });\n\n config = {\n ...config,\n // See: `overrideConfigWithArguments` https://github.com/facebook/metro/blob/5059e26/packages/metro-config/src/loadConfig.js#L274-L339\n // Compare to `LoadOptions` type (disregard `reporter` as we don't expose this)\n resetCache: !!options.resetCache,\n maxWorkers: options.maxWorkers ?? config.maxWorkers,\n server: {\n ...config.server,\n port: options.port ?? config.server.port,\n },\n // Force-override the reporter\n reporter: {\n update(event) {\n terminalReporter.update(event);\n if (reportEvent) {\n reportEvent(event);\n }\n },\n },\n };\n\n // On-Demand Filesystem is enabled by default\n // TODO(@kitten): Add to config-types JSON schema\n const onDemandFilesystem = exp.experiments?.onDemandFilesystem ?? true;\n asWritable(config.resolver).unstable_onDemandFilesystem = onDemandFilesystem;\n\n globalThis.__requireCycleIgnorePatterns = config.resolver?.requireCycleIgnorePatterns;\n\n if (isExporting) {\n // This token will be used in the asset plugin to ensure the path is correct for writing locally.\n asWritable(config.transformer).publicPath = `/assets?export_path=${\n (exp.experiments?.baseUrl ?? '') + '/assets'\n }`;\n } else {\n asWritable(config.transformer).publicPath = '/assets/?unstable_path=.';\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n const reduceLogs = shouldReduceLogs();\n\n const reactCompilerEnabled = !!exp.experiments?.reactCompiler;\n if (!reduceLogs && reactCompilerEnabled) {\n Log.log(chalk.gray`React Compiler enabled`);\n }\n\n if (!reduceLogs && autolinkingModuleResolutionEnabled) {\n Log.log(chalk.gray`Expo Autolinking module resolution enabled`);\n }\n\n if (env.EXPO_UNSTABLE_TREE_SHAKING && !env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n throw new CommandError(\n 'EXPO_UNSTABLE_TREE_SHAKING requires EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH to be enabled.'\n );\n }\n\n if (!reduceLogs && env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n Log.warn(`Experimental bundle optimization is enabled.`);\n }\n if (!reduceLogs && env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental tree shaking is enabled.`);\n }\n if (!reduceLogs && env.EXPO_UNSTABLE_LOG_BOX) {\n Log.warn(`Experimental Expo LogBox is enabled.`);\n }\n\n if (!reduceLogs && serverActionsEnabled) {\n Log.warn(\n `React Server Functions (beta) are enabled. Route rendering mode: ${exp.experiments?.reactServerComponentRoutes ? 'server' : 'client'}`\n );\n }\n\n config = await withMetroMultiPlatformAsync(projectRoot, {\n config,\n exp,\n platformBundlers,\n serverRoot,\n isTsconfigPathsEnabled: exp.experiments?.tsconfigPaths ?? true,\n isAutolinkingResolverEnabled: autolinkingModuleResolutionEnabled,\n isExporting,\n isNamedRequiresEnabled: env.EXPO_USE_METRO_REQUIRE,\n isReactServerComponentsEnabled: serverComponentsEnabled,\n getMetroBundler,\n });\n\n event('config', {\n serverRoot: event.path(serverRoot),\n projectRoot: event.path(projectRoot),\n exporting: isExporting,\n flags: {\n autolinkingModuleResolution: autolinkingModuleResolutionEnabled,\n serverActions: serverActionsEnabled,\n serverComponents: serverComponentsEnabled,\n reactCompiler: reactCompilerEnabled,\n optimizeGraph: env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH,\n treeshaking: env.EXPO_UNSTABLE_TREE_SHAKING,\n logbox: env.EXPO_UNSTABLE_LOG_BOX,\n },\n });\n\n return {\n config,\n setEventReporter: (logger: (event: any) => void) => (reportEvent = logger),\n reporter: terminalReporter,\n };\n}\n\ninterface InstantiateMetroConfigOptions extends LoadMetroConfigOptions {\n host?: string;\n}\n\n/** The most generic possible setup for Metro bundler. */\nexport async function instantiateMetroAsync(\n metroBundler: MetroBundlerDevServer,\n options: InstantiateMetroConfigOptions,\n {\n isExporting,\n exp = getConfig(metroBundler.projectRoot, {\n skipSDKVersionRequirement: true,\n }).exp,\n devToolsPluginManager,\n }: {\n isExporting: boolean;\n exp?: ExpoConfig;\n devToolsPluginManager: DevToolsPluginManager;\n }\n): Promise<{\n metro: MetroServer;\n hmrServer: MetroHmrServer<MetroHmrClient> | null;\n server: http.Server;\n address: ServerAddressInfo | null;\n middleware: any;\n messageSocket: MessageSocket;\n}> {\n const projectRoot = metroBundler.projectRoot;\n const getMetroBundler = () => metro.getBundler().getBundler();\n\n const {\n config: metroConfig,\n setEventReporter,\n reporter,\n } = await loadMetroConfigAsync(projectRoot, options, {\n exp,\n isExporting,\n getMetroBundler,\n });\n\n // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)\n const serverBaseUrl = metroBundler\n .getUrlCreator()\n .constructUrl({ scheme: 'http', hostType: 'localhost' });\n\n // Create the core middleware stack for Metro, including websocket listeners\n const { middleware, messagesSocket, eventsSocket, websocketEndpoints } = createMetroMiddleware(\n metroConfig,\n { getMetroBundler, serverBaseUrl }\n );\n\n if (!isExporting) {\n // Enable correct CORS headers for Expo Router features\n prependMiddleware(middleware, createCorsMiddleware(exp));\n\n // Enable debug middleware for CDP-related debugging\n const { debugMiddleware, debugWebsocketEndpoints } = createDebugMiddleware({\n serverBaseUrl,\n reporter,\n });\n Object.assign(websocketEndpoints, debugWebsocketEndpoints);\n middleware.use(debugMiddleware);\n middleware.use('/_expo/debugger', createJsInspectorMiddleware({ serverBaseUrl }));\n\n // TODO(cedric): `enhanceMiddleware` is deprecated, but is currently used to unify the middleware stacks\n // See: https://github.com/facebook/metro/commit/22e85fde85ec454792a1b70eba4253747a2587a9\n // See: https://github.com/facebook/metro/commit/d0d554381f119bb80ab09dbd6a1d310b54737e52\n const customEnhanceMiddleware = metroConfig.server.enhanceMiddleware;\n asWritable(metroConfig.server).enhanceMiddleware = (\n metroMiddleware: any,\n server: MetroServer\n ) => {\n if (customEnhanceMiddleware) {\n metroMiddleware = customEnhanceMiddleware(metroMiddleware, server);\n }\n return middleware.use(metroMiddleware);\n };\n\n const devtoolsWebsocketEndpoints = createDevToolsPluginWebsocketEndpoint();\n Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);\n\n // Register WebSocket endpoints contributed by DevTools plugins. A plugin's `serverEntryPoint`\n // exports a `webSocketHandlers` map (route -> connection handler); each becomes a `ws` server\n // mounted at `/_expo/plugins/<name>/<route>`, reusing Metro's exact-path upgrade dispatch (and\n // its shutdown cleanup). Endpoints must be known before the server starts, so unlike the\n // fetch-based request handler, plugin server modules are loaded eagerly here.\n for (const plugin of await devToolsPluginManager.queryPluginsAsync()) {\n try {\n for (const [route, server] of Object.entries(await plugin.getWebSocketServersAsync())) {\n Object.assign(websocketEndpoints, {\n [`${DevToolsPluginEndpoint}/${plugin.packageName}${route}`]: server,\n });\n }\n } catch (error: any) {\n Log.warn(\n `Skipping WebSocket endpoints for DevTools plugin \"${plugin.packageName}\": ${error.message ?? error}`\n );\n }\n }\n }\n\n // Attach Expo Atlas if enabled\n await attachAtlasAsync({\n isExporting,\n exp,\n projectRoot,\n middleware,\n metroConfig,\n // NOTE(cedric): reset the Atlas file once, and reuse it for static exports\n resetAtlasFile: isExporting,\n });\n\n // Support HTTPS based on the metro's tls server config\n // TODO(@kitten): Remove cast once `@expo/metro` is updated to a Metro version that supports the tls config\n const tls = (metroConfig.server as typeof metroConfig.server & { tls?: SecureServerOptions })\n ?.tls;\n const secureServerOptions = tls\n ? {\n key: tls.key,\n cert: tls.cert,\n ca: tls.ca,\n requestCert: tls.requestCert,\n }\n : undefined;\n\n const watch = !isExporting && isWatchEnabled();\n\n const { address, server, hmrServer, metro } = await replaceMetroFileMap(() => {\n return runServer(\n metroBundler,\n metroConfig,\n {\n host: options.host,\n websocketEndpoints,\n watch,\n secureServerOptions,\n },\n {\n mockServer: isExporting,\n }\n );\n });\n\n event('instantiate', {\n atlas: env.EXPO_ATLAS,\n workers: metroConfig.maxWorkers ?? null,\n host: address?.address ?? null,\n port: address?.port ?? null,\n });\n\n // Patch transform file to remove inconvenient customTransformOptions which are only used in single well-known files.\n const originalTransformFile = metro\n .getBundler()\n .getBundler()\n .transformFile.bind(metro.getBundler().getBundler());\n\n metro.getBundler().getBundler().transformFile = async function (\n filePath: string,\n transformOptions: TransformOptions,\n fileBuffer?: Buffer\n ) {\n return originalTransformFile(\n filePath,\n pruneCustomTransformOptions(\n projectRoot,\n filePath,\n // Clone the options so we don't mutate the original.\n {\n ...transformOptions,\n customTransformOptions: {\n __proto__: null,\n ...transformOptions.customTransformOptions,\n },\n }\n ),\n fileBuffer\n );\n };\n\n // Layered on top of the prune patch above. Both fresh worker results\n // and cache hits flow through `Bundler.transformFile`, so wrapping\n // here covers both.\n patchTransformFileForPackedMaps(metro.getBundler().getBundler());\n patchMetroSourceMapStringForPackedMaps();\n\n setEventReporter(eventsSocket.reportMetroEvent);\n\n // This function ensures that modules in source maps are sorted in the same\n // order as in a plain JS bundle.\n metro._getSortedModules = function (this: MetroServerWithModuleIdMod, graph: ReadOnlyGraph) {\n const modules = [...graph.dependencies.values()];\n\n const ctx = {\n // TODO(@kitten): Increase type-safety here\n platform: graph.transformOptions.platform!,\n environment: graph.transformOptions.customTransformOptions?.environment,\n };\n // Assign IDs to modules in a consistent order\n for (const module of modules) {\n this._createModuleId(module.path, ctx);\n }\n // Sort by IDs\n return modules.sort(\n (a, b) => this._createModuleId(a.path, ctx) - this._createModuleId(b.path, ctx)\n );\n };\n\n if (hmrServer) {\n let hmrJSBundle:\n | typeof import('@expo/metro-config/build/serializer/fork/hmrJSBundle').default\n | typeof import('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle').default;\n\n try {\n hmrJSBundle = require('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n } catch {\n // TODO: Add fallback for monorepo tests up until the fork is merged.\n Log.warn('Failed to load HMR serializer from @expo/metro-config, using fallback version.');\n hmrJSBundle = require('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle');\n }\n\n // Patch HMR Server to send more info to the `_createModuleId` function for deterministic module IDs and add support for serializing HMR updates the same as all other bundles.\n hmrServer._prepareMessage = async function (\n this: MetroHmrServerWithModuleIdMod,\n group,\n options,\n changeEvent\n ) {\n // Fork of https://github.com/facebook/metro/blob/3b3e0aaf725cfa6907bf2c8b5fbc0da352d29efe/packages/metro/src/HmrServer.js#L327-L393\n // with patch for `_createModuleId`.\n const logger = !options.isInitialUpdate ? changeEvent?.logger : null;\n try {\n const revPromise = this._bundler.getRevision(group.revisionId);\n if (!revPromise) {\n return {\n type: 'error',\n body: formatBundlingError(new RevisionNotFoundError(group.revisionId)),\n };\n }\n logger?.point('updateGraph_start');\n const { revision, delta } = await this._bundler.updateGraph(await revPromise, false);\n logger?.point('updateGraph_end');\n this._clientGroups.delete(group.revisionId);\n group.revisionId = revision.id;\n for (const client of group.clients) {\n client.revisionIds = client.revisionIds.filter(\n (revisionId) => revisionId !== group.revisionId\n );\n client.revisionIds.push(revision.id);\n }\n this._clientGroups.set(group.revisionId, group);\n logger?.point('serialize_start');\n // NOTE(EvanBacon): This is the patch\n const moduleIdContext = {\n // TODO(@kitten): Increase type-safety here\n platform: revision.graph.transformOptions.platform!,\n environment: revision.graph.transformOptions.customTransformOptions?.environment,\n };\n const hmrUpdate = hmrJSBundle(delta, revision.graph, {\n clientUrl: group.clientUrl,\n // NOTE(EvanBacon): This is also the patch\n createModuleId: (moduleId: string) => {\n return this._createModuleId(moduleId, moduleIdContext);\n },\n includeAsyncPaths: group.graphOptions.lazy,\n projectRoot: this._config.projectRoot,\n serverRoot: this._config.server.unstable_serverRoot ?? this._config.projectRoot,\n });\n logger?.point('serialize_end');\n return {\n type: 'update',\n body: {\n revisionId: revision.id,\n isInitialUpdate: options.isInitialUpdate,\n ...hmrUpdate,\n },\n };\n } catch (error: any) {\n const formattedError = formatBundlingError(error);\n this._config.reporter.update({\n type: 'bundling_error',\n error,\n });\n return {\n type: 'error',\n body: formattedError,\n };\n }\n };\n }\n\n return {\n metro,\n hmrServer,\n server,\n middleware,\n messageSocket: messagesSocket,\n address,\n };\n}\n\n// TODO: Fork the entire transform function so we can simply regex the file contents for keywords instead.\nfunction pruneCustomTransformOptions(\n projectRoot: string,\n filePath: string,\n transformOptions: TransformOptions\n): TransformOptions {\n // Normalize the filepath for cross platform checking.\n filePath = filePath.split(path.sep).join('/');\n\n if (\n transformOptions.customTransformOptions?.dom &&\n // The only generated file that needs the dom root is `expo/dom/entry.js`\n !filePath.match(/expo\\/dom\\/entry\\.js$/)\n ) {\n // Clear the dom root option if we aren't transforming the magic entry file, this ensures\n // that cached artifacts from other DOM component bundles can be reused.\n transformOptions.customTransformOptions.dom = 'true';\n }\n\n const routerRoot = transformOptions.customTransformOptions?.routerRoot;\n if (typeof routerRoot === 'string') {\n const isRouterEntry = /\\/expo-router\\/_ctx/.test(filePath);\n // The router root is used all over expo-router (`process.env.EXPO_ROUTER_ABS_APP_ROOT`, `process.env.EXPO_ROUTER_APP_ROOT`) so we'll just ignore the entire package.\n const isRouterModule = /\\/expo-router\\/build\\//.test(filePath);\n // Any page/router inside the expo-router app folder may access the `routerRoot` option to determine whether it's in the app folder\n const resolvedRouterRoot = path.resolve(projectRoot, routerRoot).split(path.sep).join('/');\n const isRouterRoute = path.isAbsolute(filePath) && filePath.startsWith(resolvedRouterRoot);\n\n // In any other file than the above, we enforce that we mustn't use `routerRoot`, and set it to an arbitrary value here (the default)\n // to ensure that the cache never invalidates when this value is changed\n if (!isRouterEntry && !isRouterModule && !isRouterRoute) {\n transformOptions.customTransformOptions!.routerRoot = 'app';\n }\n }\n\n if (\n transformOptions.customTransformOptions?.asyncRoutes &&\n // The async routes settings are also used in `expo-router/_ctx.ios.js` (and other platform variants) via `process.env.EXPO_ROUTER_IMPORT_MODE`\n !(filePath.match(/\\/expo-router\\/_ctx/) || filePath.match(/\\/expo-router\\/build\\//))\n ) {\n delete transformOptions.customTransformOptions.asyncRoutes;\n }\n\n if (\n transformOptions.customTransformOptions?.clientBoundaries &&\n // The client boundaries are only used in `expo/virtual/rsc.js` for production RSC exports.\n !filePath.match(/\\/expo\\/virtual\\/rsc\\.js$/)\n ) {\n delete transformOptions.customTransformOptions.clientBoundaries;\n }\n\n return transformOptions;\n}\n\n/**\n * Simplify and communicate if Metro is running without watching file updates,.\n * Exposed for testing.\n */\nexport function isWatchEnabled() {\n if (env.CI) {\n Log.log(\n chalk`Metro is running in CI mode, reloads are disabled. Remove {bold CI=true} to enable watch mode.`\n );\n }\n\n return !env.CI;\n}\n"],"names":["event","instantiateMetroAsync","isWatchEnabled","loadMetroConfigAsync","events","t","asWritable","input","LogRespectingTerminal","Terminal","stream","ttyPrint","sendLog","msg","length","log","format","args","flush","sendStderr","logStderr","require","console","info","warn","error","process","on","status","lines","splice","stderr","write","join","line","stdout","isTTY","push","prev","terminal","projectRoot","options","exp","isExporting","getMetroBundler","config","reportEvent","serverRoot","getMetroServerRoot","isWorkspace","targetsOutOfTreePlatform","getPlatformsFromConfig","some","platform","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","serverActionsEnabled","reactServerFunctions","env","EXPO_UNSTABLE_SERVER_FUNCTIONS","serverComponentsEnabled","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","reactCanary","Log","terminalReporter","MetroTerminalReporter","loadUserConfig","overrideConfigPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resetCache","maxWorkers","server","port","reporter","update","onDemandFilesystem","resolver","unstable_onDemandFilesystem","globalThis","__requireCycleIgnorePatterns","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reduceLogs","shouldReduceLogs","reactCompilerEnabled","reactCompiler","chalk","gray","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","EXPO_UNSTABLE_LOG_BOX","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isAutolinkingResolverEnabled","isNamedRequiresEnabled","isReactServerComponentsEnabled","path","exporting","flags","serverActions","serverComponents","optimizeGraph","treeshaking","logbox","setEventReporter","logger","metroBundler","getConfig","skipSDKVersionRequirement","devToolsPluginManager","metroConfig","metro","getBundler","serverBaseUrl","getUrlCreator","constructUrl","scheme","hostType","middleware","messagesSocket","eventsSocket","websocketEndpoints","createMetroMiddleware","prependMiddleware","createCorsMiddleware","debugMiddleware","debugWebsocketEndpoints","createDebugMiddleware","Object","assign","use","createJsInspectorMiddleware","customEnhanceMiddleware","enhanceMiddleware","metroMiddleware","devtoolsWebsocketEndpoints","createDevToolsPluginWebsocketEndpoint","plugin","queryPluginsAsync","route","entries","getWebSocketServersAsync","DevToolsPluginEndpoint","packageName","message","attachAtlasAsync","resetAtlasFile","tls","secureServerOptions","key","cert","ca","requestCert","watch","address","hmrServer","replaceMetroFileMap","runServer","host","mockServer","atlas","EXPO_ATLAS","workers","originalTransformFile","transformFile","bind","filePath","transformOptions","fileBuffer","pruneCustomTransformOptions","customTransformOptions","__proto__","patchTransformFileForPackedMaps","patchMetroSourceMapStringForPackedMaps","reportMetroEvent","_getSortedModules","graph","modules","dependencies","values","ctx","environment","module","_createModuleId","sort","a","b","hmrJSBundle","default","_prepareMessage","group","changeEvent","isInitialUpdate","revision","revPromise","_bundler","getRevision","revisionId","type","body","formatBundlingError","RevisionNotFoundError","point","delta","updateGraph","_clientGroups","delete","id","client","clients","revisionIds","filter","set","moduleIdContext","hmrUpdate","clientUrl","createModuleId","moduleId","includeAsyncPaths","graphOptions","lazy","_config","unstable_serverRoot","formattedError","messageSocket","split","sep","dom","match","routerRoot","isRouterEntry","test","isRouterModule","resolvedRouterRoot","resolve","isRouterRoute","isAbsolute","startsWith","asyncRoutes","clientBoundaries","CI"],"mappings":"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"}
@@ -23,6 +23,13 @@ function _assert() {
23
23
  };
24
24
  return data;
25
25
  }
26
+ function _http() {
27
+ const data = require("expo-server/adapter/http");
28
+ _http = function() {
29
+ return data;
30
+ };
31
+ return data;
32
+ }
26
33
  function _send() {
27
34
  const data = /*#__PURE__*/ _interop_require_default(require("send"));
28
35
  _send = function() {
@@ -37,6 +44,7 @@ function _interop_require_default(obj) {
37
44
  default: obj
38
45
  };
39
46
  }
47
+ const debug = require('debug')('expo:start:server:middleware:devToolsPlugin');
40
48
  class DevToolsPluginMiddleware extends _ExpoMiddleware.ExpoMiddleware {
41
49
  constructor(projectRoot, pluginManager){
42
50
  super(projectRoot, [
@@ -52,18 +60,61 @@ class DevToolsPluginMiddleware extends _ExpoMiddleware.ExpoMiddleware {
52
60
  }
53
61
  async handleRequestAsync(req, res) {
54
62
  (0, _assert().default)(req.headers.host, 'Request headers must include host');
55
- const { pathname } = new URL(req.url ?? '/', `http://${req.headers.host}`);
63
+ const { pathname, search } = new URL(req.url ?? '/', `http://${req.headers.host}`);
56
64
  const pluginName = this.queryPossiblePluginName(pathname.substring(_DevToolsPluginManager.DevToolsPluginEndpoint.length + 1));
57
- const webpageRoot = await this.pluginManager.queryPluginWebpageRootAsync(pluginName);
58
- if (!webpageRoot) {
65
+ const plugin = await this.pluginManager.queryPluginAsync(pluginName);
66
+ if (!plugin) {
59
67
  res.statusCode = 404;
60
68
  res.end();
61
69
  return;
62
70
  }
63
71
  const pathInPluginRoot = pathname.substring(_DevToolsPluginManager.DevToolsPluginEndpoint.length + pluginName.length + 1) || '/';
64
- (0, _send().default)(req, pathInPluginRoot, {
65
- root: webpageRoot
66
- }).pipe(res);
72
+ if (plugin.serverEntryPoint != null) {
73
+ const handled = await this.handleWithPluginServerAsync(plugin, req, res, `${pathInPluginRoot}${search}`);
74
+ if (handled) {
75
+ return;
76
+ }
77
+ }
78
+ if (plugin.webpageRoot != null) {
79
+ (0, _send().default)(req, pathInPluginRoot, {
80
+ root: plugin.webpageRoot
81
+ }).pipe(res);
82
+ return;
83
+ }
84
+ res.statusCode = 404;
85
+ res.end();
86
+ }
87
+ /**
88
+ * Passes the request to the plugin's `serverEntryPoint` fetch handler with the plugin
89
+ * endpoint prefix stripped from the URL. Returns false when the handler returns no
90
+ * response, so the request falls through to static `webpageRoot` serving.
91
+ */ async handleWithPluginServerAsync(plugin, req, res, urlInPluginRoot) {
92
+ const originalUrl = req.url;
93
+ let request;
94
+ try {
95
+ req.url = urlInPluginRoot;
96
+ request = (0, _http().convertRequest)(req, res);
97
+ const handler = await plugin.getRequestHandlerAsync();
98
+ const response = await (handler == null ? void 0 : handler(request));
99
+ if (response == null) {
100
+ return false;
101
+ }
102
+ await (0, _http().respond)(res, response, {
103
+ signal: request.signal
104
+ });
105
+ return true;
106
+ } catch (error) {
107
+ debug('DevTools plugin server request failed: %O', error);
108
+ if (res.headersSent || res.writableEnded || res.destroyed || (request == null ? void 0 : request.signal.aborted)) {
109
+ return true;
110
+ }
111
+ res.statusCode = 500;
112
+ res.setHeader('Content-Type', 'text/plain');
113
+ res.end(`The DevTools plugin "${plugin.packageName}" failed to handle the request to "${urlInPluginRoot}": ` + `${(error == null ? void 0 : error.message) ?? error}. This is likely a bug in the plugin's server entry point ` + `(${plugin.serverEntryPoint}); report it to the plugin author.`);
114
+ return true;
115
+ } finally{
116
+ req.url = originalUrl;
117
+ }
67
118
  }
68
119
  queryPossiblePluginName(pathname) {
69
120
  const parts = pathname.split('/');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/middleware/DevToolsPluginMiddleware.ts"],"sourcesContent":["import assert from 'assert';\nimport send from 'send';\n\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport type { ServerRequest, ServerResponse } from './server.types';\nimport type DevToolsPluginManager from '../DevToolsPluginManager';\nimport { DevToolsPluginEndpoint } from '../DevToolsPluginManager';\n\nexport { DevToolsPluginEndpoint };\n\nexport class DevToolsPluginMiddleware extends ExpoMiddleware {\n constructor(\n projectRoot: string,\n private readonly pluginManager: DevToolsPluginManager\n ) {\n super(projectRoot, [DevToolsPluginEndpoint]);\n }\n\n override shouldHandleRequest(req: ServerRequest): boolean {\n if (!req.url?.startsWith(DevToolsPluginEndpoint)) {\n return false;\n }\n return true;\n }\n\n async handleRequestAsync(req: ServerRequest, res: ServerResponse): Promise<void> {\n assert(req.headers.host, 'Request headers must include host');\n const { pathname } = new URL(req.url ?? '/', `http://${req.headers.host}`);\n const pluginName = this.queryPossiblePluginName(\n pathname.substring(DevToolsPluginEndpoint.length + 1)\n );\n const webpageRoot = await this.pluginManager.queryPluginWebpageRootAsync(pluginName);\n if (!webpageRoot) {\n res.statusCode = 404;\n res.end();\n return;\n }\n\n const pathInPluginRoot =\n pathname.substring(DevToolsPluginEndpoint.length + pluginName.length + 1) || '/';\n send(req, pathInPluginRoot, { root: webpageRoot }).pipe(res);\n }\n\n private queryPossiblePluginName(pathname: string): string {\n const parts = pathname.split('/');\n if (parts[0]![0] === '@' && parts.length > 1) {\n // Scoped package name\n return `${parts[0]}/${parts[1]}`;\n }\n return parts[0]!;\n }\n}\n"],"names":["DevToolsPluginEndpoint","DevToolsPluginMiddleware","ExpoMiddleware","projectRoot","pluginManager","shouldHandleRequest","req","url","startsWith","handleRequestAsync","res","assert","headers","host","pathname","URL","pluginName","queryPossiblePluginName","substring","length","webpageRoot","queryPluginWebpageRootAsync","statusCode","end","pathInPluginRoot","send","root","pipe","parts","split"],"mappings":";;;;;;;;;;;QAQSA;eAAAA,6CAAsB;;QAElBC;eAAAA;;;;gEAVM;;;;;;;gEACF;;;;;;gCAEc;uCAGQ;;;;;;AAIhC,MAAMA,iCAAiCC,8BAAc;IAC1D,YACEC,WAAmB,EACnB,AAAiBC,aAAoC,CACrD;QACA,KAAK,CAACD,aAAa;YAACH,6CAAsB;SAAC,QAF1BI,gBAAAA;IAGnB;IAESC,oBAAoBC,GAAkB,EAAW;YACnDA;QAAL,IAAI,GAACA,WAAAA,IAAIC,GAAG,qBAAPD,SAASE,UAAU,CAACR,6CAAsB,IAAG;YAChD,OAAO;QACT;QACA,OAAO;IACT;IAEA,MAAMS,mBAAmBH,GAAkB,EAAEI,GAAmB,EAAiB;QAC/EC,IAAAA,iBAAM,EAACL,IAAIM,OAAO,CAACC,IAAI,EAAE;QACzB,MAAM,EAAEC,QAAQ,EAAE,GAAG,IAAIC,IAAIT,IAAIC,GAAG,IAAI,KAAK,CAAC,OAAO,EAAED,IAAIM,OAAO,CAACC,IAAI,EAAE;QACzE,MAAMG,aAAa,IAAI,CAACC,uBAAuB,CAC7CH,SAASI,SAAS,CAAClB,6CAAsB,CAACmB,MAAM,GAAG;QAErD,MAAMC,cAAc,MAAM,IAAI,CAAChB,aAAa,CAACiB,2BAA2B,CAACL;QACzE,IAAI,CAACI,aAAa;YAChBV,IAAIY,UAAU,GAAG;YACjBZ,IAAIa,GAAG;YACP;QACF;QAEA,MAAMC,mBACJV,SAASI,SAAS,CAAClB,6CAAsB,CAACmB,MAAM,GAAGH,WAAWG,MAAM,GAAG,MAAM;QAC/EM,IAAAA,eAAI,EAACnB,KAAKkB,kBAAkB;YAAEE,MAAMN;QAAY,GAAGO,IAAI,CAACjB;IAC1D;IAEQO,wBAAwBH,QAAgB,EAAU;QACxD,MAAMc,QAAQd,SAASe,KAAK,CAAC;QAC7B,IAAID,KAAK,CAAC,EAAE,AAAC,CAAC,EAAE,KAAK,OAAOA,MAAMT,MAAM,GAAG,GAAG;YAC5C,sBAAsB;YACtB,OAAO,GAAGS,KAAK,CAAC,EAAE,CAAC,CAAC,EAAEA,KAAK,CAAC,EAAE,EAAE;QAClC;QACA,OAAOA,KAAK,CAAC,EAAE;IACjB;AACF"}
1
+ {"version":3,"sources":["../../../../../src/start/server/middleware/DevToolsPluginMiddleware.ts"],"sourcesContent":["import assert from 'assert';\nimport { convertRequest, respond } from 'expo-server/adapter/http';\nimport type * as http from 'http';\nimport send from 'send';\n\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport type { ServerRequest, ServerResponse } from './server.types';\nimport type { DevToolsPlugin } from '../DevToolsPlugin';\nimport type DevToolsPluginManager from '../DevToolsPluginManager';\nimport { DevToolsPluginEndpoint } from '../DevToolsPluginManager';\n\nconst debug = require('debug')('expo:start:server:middleware:devToolsPlugin') as typeof console.log;\n\nexport { DevToolsPluginEndpoint };\n\nexport class DevToolsPluginMiddleware extends ExpoMiddleware {\n constructor(\n projectRoot: string,\n private readonly pluginManager: DevToolsPluginManager\n ) {\n super(projectRoot, [DevToolsPluginEndpoint]);\n }\n\n override shouldHandleRequest(req: ServerRequest): boolean {\n if (!req.url?.startsWith(DevToolsPluginEndpoint)) {\n return false;\n }\n return true;\n }\n\n async handleRequestAsync(req: ServerRequest, res: ServerResponse): Promise<void> {\n assert(req.headers.host, 'Request headers must include host');\n const { pathname, search } = new URL(req.url ?? '/', `http://${req.headers.host}`);\n const pluginName = this.queryPossiblePluginName(\n pathname.substring(DevToolsPluginEndpoint.length + 1)\n );\n const plugin = await this.pluginManager.queryPluginAsync(pluginName);\n if (!plugin) {\n res.statusCode = 404;\n res.end();\n return;\n }\n\n const pathInPluginRoot =\n pathname.substring(DevToolsPluginEndpoint.length + pluginName.length + 1) || '/';\n\n if (plugin.serverEntryPoint != null) {\n const handled = await this.handleWithPluginServerAsync(\n plugin,\n req,\n res,\n `${pathInPluginRoot}${search}`\n );\n if (handled) {\n return;\n }\n }\n\n if (plugin.webpageRoot != null) {\n send(req, pathInPluginRoot, { root: plugin.webpageRoot }).pipe(res);\n return;\n }\n\n res.statusCode = 404;\n res.end();\n }\n\n /**\n * Passes the request to the plugin's `serverEntryPoint` fetch handler with the plugin\n * endpoint prefix stripped from the URL. Returns false when the handler returns no\n * response, so the request falls through to static `webpageRoot` serving.\n */\n private async handleWithPluginServerAsync(\n plugin: DevToolsPlugin,\n req: ServerRequest,\n res: ServerResponse,\n urlInPluginRoot: string\n ): Promise<boolean> {\n const originalUrl = req.url;\n let request: Request | undefined;\n try {\n req.url = urlInPluginRoot;\n request = convertRequest(req as http.IncomingMessage, res as http.ServerResponse);\n const handler = await plugin.getRequestHandlerAsync();\n const response = await handler?.(request);\n if (response == null) {\n return false;\n }\n await respond(res as http.ServerResponse, response, { signal: request.signal });\n return true;\n } catch (error: any) {\n debug('DevTools plugin server request failed: %O', error);\n if (res.headersSent || res.writableEnded || res.destroyed || request?.signal.aborted) {\n return true;\n }\n res.statusCode = 500;\n res.setHeader('Content-Type', 'text/plain');\n res.end(\n `The DevTools plugin \"${plugin.packageName}\" failed to handle the request to \"${urlInPluginRoot}\": ` +\n `${error?.message ?? error}. This is likely a bug in the plugin's server entry point ` +\n `(${plugin.serverEntryPoint}); report it to the plugin author.`\n );\n return true;\n } finally {\n req.url = originalUrl;\n }\n }\n\n private queryPossiblePluginName(pathname: string): string {\n const parts = pathname.split('/');\n if (parts[0]![0] === '@' && parts.length > 1) {\n // Scoped package name\n return `${parts[0]}/${parts[1]}`;\n }\n return parts[0]!;\n }\n}\n"],"names":["DevToolsPluginEndpoint","DevToolsPluginMiddleware","debug","require","ExpoMiddleware","projectRoot","pluginManager","shouldHandleRequest","req","url","startsWith","handleRequestAsync","res","assert","headers","host","pathname","search","URL","pluginName","queryPossiblePluginName","substring","length","plugin","queryPluginAsync","statusCode","end","pathInPluginRoot","serverEntryPoint","handled","handleWithPluginServerAsync","webpageRoot","send","root","pipe","urlInPluginRoot","originalUrl","request","convertRequest","handler","getRequestHandlerAsync","response","respond","signal","error","headersSent","writableEnded","destroyed","aborted","setHeader","packageName","message","parts","split"],"mappings":"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"}
@@ -27,6 +27,7 @@ const _checkDependenciesOnStart = require("./checkDependenciesOnStart");
27
27
  const _SimulatorAppPrerequisite = require("./doctor/apple/SimulatorAppPrerequisite");
28
28
  const _XcodePrerequisite = require("./doctor/apple/XcodePrerequisite");
29
29
  const _WebSupportProjectPrerequisite = require("./doctor/web/WebSupportProjectPrerequisite");
30
+ const _interactiveActions = require("./interface/interactiveActions");
30
31
  const _startInterface = require("./interface/startInterface");
31
32
  const _resolveOptions = require("./resolveOptions");
32
33
  const _log = /*#__PURE__*/ _interop_require_wildcard(require("../log"));
@@ -193,6 +194,8 @@ async function startAsync(projectRoot, options, settings) {
193
194
  })}`);
194
195
  }
195
196
  _log.log((0, _chalk().default)`Waiting on {underline ${defaultServerUrl}}`);
197
+ _log.log();
198
+ await (0, _interactiveActions.printDevToolsPluginCliBannersAsync)(devServerManager);
196
199
  }
197
200
  // In non-interactive mode, print the check outside of an interface, if it's available
198
201
  if (dependencyCheckRef == null ? void 0 : dependencyCheckRef.result) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/start/startAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport chalk from 'chalk';\n\nimport { getLogFile, shouldReduceLogs } from '../events';\nimport {\n checkDependencies,\n printDependencyCheckResult,\n type DependencyCheckRef,\n} from './checkDependenciesOnStart';\nimport { SimulatorAppPrerequisite } from './doctor/apple/SimulatorAppPrerequisite';\nimport { getXcodeVersionAsync } from './doctor/apple/XcodePrerequisite';\nimport { WebSupportProjectPrerequisite } from './doctor/web/WebSupportProjectPrerequisite';\nimport { startInterfaceAsync } from './interface/startInterface';\nimport type { Options } from './resolveOptions';\nimport { resolvePortsAsync } from './resolveOptions';\nimport * as Log from '../log';\nimport type { BundlerStartOptions } from './server/BundlerDevServer';\nimport type { MultiBundlerStartOptions } from './server/DevServerManager';\nimport { DevServerManager } from './server/DevServerManager';\nimport { maybeCreateMCPServerAsync } from './server/MCP';\nimport { openPlatformsAsync } from './server/openPlatforms';\nimport type { PlatformBundlers } from './server/platformBundlers';\nimport { getPlatformBundlers } from './server/platformBundlers';\nimport { env } from '../utils/env';\nimport { isInteractive } from '../utils/interactive';\nimport { profile } from '../utils/profile';\nimport { addMcpCapabilities } from './server/MCPDevToolsPluginCLIExtensions';\n\nasync function getMultiBundlerStartOptions(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean },\n platformBundlers: PlatformBundlers\n): Promise<[BundlerStartOptions, MultiBundlerStartOptions]> {\n const commonOptions: BundlerStartOptions = {\n mode: options.dev ? 'development' : 'production',\n devClient: options.devClient,\n privateKeyPath: options.privateKeyPath ?? undefined,\n https: options.https,\n maxWorkers: options.maxWorkers,\n resetDevServer: options.clear,\n minify: options.minify,\n location: {\n hostType: options.host,\n scheme: options.scheme,\n },\n };\n const multiBundlerSettings = await resolvePortsAsync(projectRoot, options, settings);\n\n const optionalBundlers: Partial<PlatformBundlers> = { ...platformBundlers };\n // In the default case, we don't want to start multiple bundlers since this is\n // a bit slower. Our priority (for legacy) is native platforms.\n if (!options.web) {\n delete optionalBundlers['web'];\n }\n\n const bundlers = [...new Set(Object.values(optionalBundlers))];\n const multiBundlerStartOptions = bundlers.map((bundler) => {\n const port =\n bundler === 'webpack' ? multiBundlerSettings.webpackPort : multiBundlerSettings.metroPort;\n return {\n type: bundler,\n options: {\n ...commonOptions,\n port,\n },\n };\n });\n\n return [commonOptions, multiBundlerStartOptions];\n}\n\nexport async function startAsync(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean }\n) {\n if (!shouldReduceLogs()) {\n Log.log(chalk.gray(`Starting project at ${projectRoot}`));\n const logFile = getLogFile();\n if (!isInteractive() && logFile) {\n Log.log(chalk.gray(`Logs: ${logFile}`));\n }\n }\n\n const { exp, pkg } = profile(getConfig)(projectRoot);\n\n // Start dependency version check in the background as early as possible (non-blocking).\n // The result will be displayed in the TUI once it resolves.\n let dependencyCheckRef: DependencyCheckRef | undefined;\n if (!env.EXPO_OFFLINE && !env.EXPO_NO_DEPENDENCY_VALIDATION && !settings.webOnly) {\n dependencyCheckRef = checkDependencies(projectRoot, exp, pkg);\n }\n\n if (exp.platforms?.includes('ios') && process.platform !== 'win32') {\n // If Xcode could potentially be used, then we should eagerly perform the\n // assertions since they can take a while on cold boots.\n getXcodeVersionAsync({ silent: true });\n SimulatorAppPrerequisite.instance.assertAsync().catch(() => {\n // noop -- this will be thrown again when the user attempts to open the project.\n });\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n const [defaultOptions, startOptions] = await getMultiBundlerStartOptions(\n projectRoot,\n options,\n settings,\n platformBundlers\n );\n\n const devServerManager = new DevServerManager(projectRoot, defaultOptions);\n\n // Validations\n\n if (options.web || settings.webOnly) {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n }\n\n // Start the server as soon as possible.\n await profile(devServerManager.startAsync.bind(devServerManager))(startOptions);\n\n if (!settings.webOnly) {\n await devServerManager.watchEnvironmentVariables();\n\n // After the server starts, we can start attempting to bootstrap TypeScript.\n await devServerManager.bootstrapTypeScriptAsync();\n }\n\n // Open project on devices.\n await profile(openPlatformsAsync)(devServerManager, options);\n\n const defaultServerUrl = devServerManager.getDefaultDevServer()?.getDevServerUrl() ?? '';\n const mcpServer =\n (await profile(maybeCreateMCPServerAsync)({\n projectRoot,\n devServerUrl: defaultServerUrl,\n })) ?? undefined;\n\n // Present the Terminal UI.\n if (isInteractive()) {\n await profile(startInterfaceAsync)(devServerManager, {\n platforms: exp.platforms ?? ['ios', 'android', 'web'],\n mcpServer,\n dependencyCheckRef,\n });\n } else {\n // Display the server location in CI...\n if (defaultServerUrl) {\n if (env.__EXPO_E2E_TEST) {\n // Print the URL to stdout for tests\n console.info(`[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: defaultServerUrl })}`);\n }\n Log.log(chalk`Waiting on {underline ${defaultServerUrl}}`);\n }\n // In non-interactive mode, print the check outside of an interface, if it's available\n if (dependencyCheckRef?.result) {\n printDependencyCheckResult(dependencyCheckRef.result);\n }\n }\n\n if (mcpServer) {\n addMcpCapabilities(mcpServer, devServerManager);\n mcpServer.start();\n }\n\n // Final note about closing the server.\n const logLocation = settings.webOnly ? 'in the browser console' : 'below';\n Log.log(\n chalk`Logs for your project will appear ${logLocation}.${\n isInteractive() ? chalk.dim(` Press Ctrl+C to exit.`) : ''\n }`\n );\n}\n"],"names":["startAsync","getMultiBundlerStartOptions","projectRoot","options","settings","platformBundlers","commonOptions","mode","dev","devClient","privateKeyPath","undefined","https","maxWorkers","resetDevServer","clear","minify","location","hostType","host","scheme","multiBundlerSettings","resolvePortsAsync","optionalBundlers","web","bundlers","Set","Object","values","multiBundlerStartOptions","map","bundler","port","webpackPort","metroPort","type","exp","devServerManager","shouldReduceLogs","Log","log","chalk","gray","logFile","getLogFile","isInteractive","pkg","profile","getConfig","dependencyCheckRef","env","EXPO_OFFLINE","EXPO_NO_DEPENDENCY_VALIDATION","webOnly","checkDependencies","platforms","includes","process","platform","getXcodeVersionAsync","silent","SimulatorAppPrerequisite","instance","assertAsync","catch","getPlatformBundlers","defaultOptions","startOptions","DevServerManager","ensureProjectPrerequisiteAsync","WebSupportProjectPrerequisite","bind","watchEnvironmentVariables","bootstrapTypeScriptAsync","openPlatformsAsync","defaultServerUrl","getDefaultDevServer","getDevServerUrl","mcpServer","maybeCreateMCPServerAsync","devServerUrl","startInterfaceAsync","__EXPO_E2E_TEST","console","info","JSON","stringify","url","result","printDependencyCheckResult","addMcpCapabilities","start","logLocation","dim"],"mappings":";;;;+BAwEsBA;;;eAAAA;;;;yBAxEI;;;;;;;gEACR;;;;;;wBAE2B;0CAKtC;0CACkC;mCACJ;+CACS;gCACV;gCAEF;6DACb;kCAGY;qBACS;+BACP;kCAEC;qBAChB;6BACU;yBACN;gDACW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEnC,eAAeC,4BACbC,WAAmB,EACnBC,OAAgB,EAChBC,QAA+B,EAC/BC,gBAAkC;IAElC,MAAMC,gBAAqC;QACzCC,MAAMJ,QAAQK,GAAG,GAAG,gBAAgB;QACpCC,WAAWN,QAAQM,SAAS;QAC5BC,gBAAgBP,QAAQO,cAAc,IAAIC;QAC1CC,OAAOT,QAAQS,KAAK;QACpBC,YAAYV,QAAQU,UAAU;QAC9BC,gBAAgBX,QAAQY,KAAK;QAC7BC,QAAQb,QAAQa,MAAM;QACtBC,UAAU;YACRC,UAAUf,QAAQgB,IAAI;YACtBC,QAAQjB,QAAQiB,MAAM;QACxB;IACF;IACA,MAAMC,uBAAuB,MAAMC,IAAAA,iCAAiB,EAACpB,aAAaC,SAASC;IAE3E,MAAMmB,mBAA8C;QAAE,GAAGlB,gBAAgB;IAAC;IAC1E,8EAA8E;IAC9E,+DAA+D;IAC/D,IAAI,CAACF,QAAQqB,GAAG,EAAE;QAChB,OAAOD,gBAAgB,CAAC,MAAM;IAChC;IAEA,MAAME,WAAW;WAAI,IAAIC,IAAIC,OAAOC,MAAM,CAACL;KAAmB;IAC9D,MAAMM,2BAA2BJ,SAASK,GAAG,CAAC,CAACC;QAC7C,MAAMC,OACJD,YAAY,YAAYV,qBAAqBY,WAAW,GAAGZ,qBAAqBa,SAAS;QAC3F,OAAO;YACLC,MAAMJ;YACN5B,SAAS;gBACP,GAAGG,aAAa;gBAChB0B;YACF;QACF;IACF;IAEA,OAAO;QAAC1B;QAAeuB;KAAyB;AAClD;AAEO,eAAe7B,WACpBE,WAAmB,EACnBC,OAAgB,EAChBC,QAA+B;QAmB3BgC,gBAuCqBC;IAxDzB,IAAI,CAACC,IAAAA,wBAAgB,KAAI;QACvBC,KAAIC,GAAG,CAACC,gBAAK,CAACC,IAAI,CAAC,CAAC,oBAAoB,EAAExC,aAAa;QACvD,MAAMyC,UAAUC,IAAAA,kBAAU;QAC1B,IAAI,CAACC,IAAAA,0BAAa,OAAMF,SAAS;YAC/BJ,KAAIC,GAAG,CAACC,gBAAK,CAACC,IAAI,CAAC,CAAC,MAAM,EAAEC,SAAS;QACvC;IACF;IAEA,MAAM,EAAEP,GAAG,EAAEU,GAAG,EAAE,GAAGC,IAAAA,gBAAO,EAACC,mBAAS,EAAE9C;IAExC,wFAAwF;IACxF,4DAA4D;IAC5D,IAAI+C;IACJ,IAAI,CAACC,QAAG,CAACC,YAAY,IAAI,CAACD,QAAG,CAACE,6BAA6B,IAAI,CAAChD,SAASiD,OAAO,EAAE;QAChFJ,qBAAqBK,IAAAA,2CAAiB,EAACpD,aAAakC,KAAKU;IAC3D;IAEA,IAAIV,EAAAA,iBAAAA,IAAImB,SAAS,qBAAbnB,eAAeoB,QAAQ,CAAC,WAAUC,QAAQC,QAAQ,KAAK,SAAS;QAClE,yEAAyE;QACzE,wDAAwD;QACxDC,IAAAA,uCAAoB,EAAC;YAAEC,QAAQ;QAAK;QACpCC,kDAAwB,CAACC,QAAQ,CAACC,WAAW,GAAGC,KAAK,CAAC;QACpD,gFAAgF;QAClF;IACF;IAEA,MAAM3D,mBAAmB4D,IAAAA,qCAAmB,EAAC/D,aAAakC;IAE1D,MAAM,CAAC8B,gBAAgBC,aAAa,GAAG,MAAMlE,4BAC3CC,aACAC,SACAC,UACAC;IAGF,MAAMgC,mBAAmB,IAAI+B,kCAAgB,CAAClE,aAAagE;IAE3D,cAAc;IAEd,IAAI/D,QAAQqB,GAAG,IAAIpB,SAASiD,OAAO,EAAE;QACnC,MAAMhB,iBAAiBgC,8BAA8B,CAACC,4DAA6B;IACrF;IAEA,wCAAwC;IACxC,MAAMvB,IAAAA,gBAAO,EAACV,iBAAiBrC,UAAU,CAACuE,IAAI,CAAClC,mBAAmB8B;IAElE,IAAI,CAAC/D,SAASiD,OAAO,EAAE;QACrB,MAAMhB,iBAAiBmC,yBAAyB;QAEhD,4EAA4E;QAC5E,MAAMnC,iBAAiBoC,wBAAwB;IACjD;IAEA,2BAA2B;IAC3B,MAAM1B,IAAAA,gBAAO,EAAC2B,iCAAkB,EAAErC,kBAAkBlC;IAEpD,MAAMwE,mBAAmBtC,EAAAA,wCAAAA,iBAAiBuC,mBAAmB,uBAApCvC,sCAAwCwC,eAAe,OAAM;IACtF,MAAMC,YACJ,AAAC,MAAM/B,IAAAA,gBAAO,EAACgC,8BAAyB,EAAE;QACxC7E;QACA8E,cAAcL;IAChB,MAAOhE;IAET,2BAA2B;IAC3B,IAAIkC,IAAAA,0BAAa,KAAI;QACnB,MAAME,IAAAA,gBAAO,EAACkC,mCAAmB,EAAE5C,kBAAkB;YACnDkB,WAAWnB,IAAImB,SAAS,IAAI;gBAAC;gBAAO;gBAAW;aAAM;YACrDuB;YACA7B;QACF;IACF,OAAO;QACL,uCAAuC;QACvC,IAAI0B,kBAAkB;YACpB,IAAIzB,QAAG,CAACgC,eAAe,EAAE;gBACvB,oCAAoC;gBACpCC,QAAQC,IAAI,CAAC,CAAC,yBAAyB,EAAEC,KAAKC,SAAS,CAAC;oBAAEC,KAAKZ;gBAAiB,IAAI;YACtF;YACApC,KAAIC,GAAG,CAACC,IAAAA,gBAAK,CAAA,CAAC,sBAAsB,EAAEkC,iBAAiB,CAAC,CAAC;QAC3D;QACA,sFAAsF;QACtF,IAAI1B,sCAAAA,mBAAoBuC,MAAM,EAAE;YAC9BC,IAAAA,oDAA0B,EAACxC,mBAAmBuC,MAAM;QACtD;IACF;IAEA,IAAIV,WAAW;QACbY,IAAAA,kDAAkB,EAACZ,WAAWzC;QAC9ByC,UAAUa,KAAK;IACjB;IAEA,uCAAuC;IACvC,MAAMC,cAAcxF,SAASiD,OAAO,GAAG,2BAA2B;IAClEd,KAAIC,GAAG,CACLC,IAAAA,gBAAK,CAAA,CAAC,kCAAkC,EAAEmD,YAAY,CAAC,EACrD/C,IAAAA,0BAAa,MAAKJ,gBAAK,CAACoD,GAAG,CAAC,CAAC,sBAAsB,CAAC,IAAI,GACzD,CAAC;AAEN"}
1
+ {"version":3,"sources":["../../../src/start/startAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport chalk from 'chalk';\n\nimport { getLogFile, shouldReduceLogs } from '../events';\nimport {\n checkDependencies,\n printDependencyCheckResult,\n type DependencyCheckRef,\n} from './checkDependenciesOnStart';\nimport { SimulatorAppPrerequisite } from './doctor/apple/SimulatorAppPrerequisite';\nimport { getXcodeVersionAsync } from './doctor/apple/XcodePrerequisite';\nimport { WebSupportProjectPrerequisite } from './doctor/web/WebSupportProjectPrerequisite';\nimport { printDevToolsPluginCliBannersAsync } from './interface/interactiveActions';\nimport { startInterfaceAsync } from './interface/startInterface';\nimport type { Options } from './resolveOptions';\nimport { resolvePortsAsync } from './resolveOptions';\nimport * as Log from '../log';\nimport type { BundlerStartOptions } from './server/BundlerDevServer';\nimport type { MultiBundlerStartOptions } from './server/DevServerManager';\nimport { DevServerManager } from './server/DevServerManager';\nimport { maybeCreateMCPServerAsync } from './server/MCP';\nimport { openPlatformsAsync } from './server/openPlatforms';\nimport type { PlatformBundlers } from './server/platformBundlers';\nimport { getPlatformBundlers } from './server/platformBundlers';\nimport { env } from '../utils/env';\nimport { isInteractive } from '../utils/interactive';\nimport { profile } from '../utils/profile';\nimport { addMcpCapabilities } from './server/MCPDevToolsPluginCLIExtensions';\n\nasync function getMultiBundlerStartOptions(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean },\n platformBundlers: PlatformBundlers\n): Promise<[BundlerStartOptions, MultiBundlerStartOptions]> {\n const commonOptions: BundlerStartOptions = {\n mode: options.dev ? 'development' : 'production',\n devClient: options.devClient,\n privateKeyPath: options.privateKeyPath ?? undefined,\n https: options.https,\n maxWorkers: options.maxWorkers,\n resetDevServer: options.clear,\n minify: options.minify,\n location: {\n hostType: options.host,\n scheme: options.scheme,\n },\n };\n const multiBundlerSettings = await resolvePortsAsync(projectRoot, options, settings);\n\n const optionalBundlers: Partial<PlatformBundlers> = { ...platformBundlers };\n // In the default case, we don't want to start multiple bundlers since this is\n // a bit slower. Our priority (for legacy) is native platforms.\n if (!options.web) {\n delete optionalBundlers['web'];\n }\n\n const bundlers = [...new Set(Object.values(optionalBundlers))];\n const multiBundlerStartOptions = bundlers.map((bundler) => {\n const port =\n bundler === 'webpack' ? multiBundlerSettings.webpackPort : multiBundlerSettings.metroPort;\n return {\n type: bundler,\n options: {\n ...commonOptions,\n port,\n },\n };\n });\n\n return [commonOptions, multiBundlerStartOptions];\n}\n\nexport async function startAsync(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean }\n) {\n if (!shouldReduceLogs()) {\n Log.log(chalk.gray(`Starting project at ${projectRoot}`));\n const logFile = getLogFile();\n if (!isInteractive() && logFile) {\n Log.log(chalk.gray(`Logs: ${logFile}`));\n }\n }\n\n const { exp, pkg } = profile(getConfig)(projectRoot);\n\n // Start dependency version check in the background as early as possible (non-blocking).\n // The result will be displayed in the TUI once it resolves.\n let dependencyCheckRef: DependencyCheckRef | undefined;\n if (!env.EXPO_OFFLINE && !env.EXPO_NO_DEPENDENCY_VALIDATION && !settings.webOnly) {\n dependencyCheckRef = checkDependencies(projectRoot, exp, pkg);\n }\n\n if (exp.platforms?.includes('ios') && process.platform !== 'win32') {\n // If Xcode could potentially be used, then we should eagerly perform the\n // assertions since they can take a while on cold boots.\n getXcodeVersionAsync({ silent: true });\n SimulatorAppPrerequisite.instance.assertAsync().catch(() => {\n // noop -- this will be thrown again when the user attempts to open the project.\n });\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n const [defaultOptions, startOptions] = await getMultiBundlerStartOptions(\n projectRoot,\n options,\n settings,\n platformBundlers\n );\n\n const devServerManager = new DevServerManager(projectRoot, defaultOptions);\n\n // Validations\n\n if (options.web || settings.webOnly) {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n }\n\n // Start the server as soon as possible.\n await profile(devServerManager.startAsync.bind(devServerManager))(startOptions);\n\n if (!settings.webOnly) {\n await devServerManager.watchEnvironmentVariables();\n\n // After the server starts, we can start attempting to bootstrap TypeScript.\n await devServerManager.bootstrapTypeScriptAsync();\n }\n\n // Open project on devices.\n await profile(openPlatformsAsync)(devServerManager, options);\n\n const defaultServerUrl = devServerManager.getDefaultDevServer()?.getDevServerUrl() ?? '';\n const mcpServer =\n (await profile(maybeCreateMCPServerAsync)({\n projectRoot,\n devServerUrl: defaultServerUrl,\n })) ?? undefined;\n\n // Present the Terminal UI.\n if (isInteractive()) {\n await profile(startInterfaceAsync)(devServerManager, {\n platforms: exp.platforms ?? ['ios', 'android', 'web'],\n mcpServer,\n dependencyCheckRef,\n });\n } else {\n // Display the server location in CI...\n if (defaultServerUrl) {\n if (env.__EXPO_E2E_TEST) {\n // Print the URL to stdout for tests\n console.info(`[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: defaultServerUrl })}`);\n }\n Log.log(chalk`Waiting on {underline ${defaultServerUrl}}`);\n Log.log();\n await printDevToolsPluginCliBannersAsync(devServerManager);\n }\n // In non-interactive mode, print the check outside of an interface, if it's available\n if (dependencyCheckRef?.result) {\n printDependencyCheckResult(dependencyCheckRef.result);\n }\n }\n\n if (mcpServer) {\n addMcpCapabilities(mcpServer, devServerManager);\n mcpServer.start();\n }\n\n // Final note about closing the server.\n const logLocation = settings.webOnly ? 'in the browser console' : 'below';\n Log.log(\n chalk`Logs for your project will appear ${logLocation}.${\n isInteractive() ? chalk.dim(` Press Ctrl+C to exit.`) : ''\n }`\n );\n}\n"],"names":["startAsync","getMultiBundlerStartOptions","projectRoot","options","settings","platformBundlers","commonOptions","mode","dev","devClient","privateKeyPath","undefined","https","maxWorkers","resetDevServer","clear","minify","location","hostType","host","scheme","multiBundlerSettings","resolvePortsAsync","optionalBundlers","web","bundlers","Set","Object","values","multiBundlerStartOptions","map","bundler","port","webpackPort","metroPort","type","exp","devServerManager","shouldReduceLogs","Log","log","chalk","gray","logFile","getLogFile","isInteractive","pkg","profile","getConfig","dependencyCheckRef","env","EXPO_OFFLINE","EXPO_NO_DEPENDENCY_VALIDATION","webOnly","checkDependencies","platforms","includes","process","platform","getXcodeVersionAsync","silent","SimulatorAppPrerequisite","instance","assertAsync","catch","getPlatformBundlers","defaultOptions","startOptions","DevServerManager","ensureProjectPrerequisiteAsync","WebSupportProjectPrerequisite","bind","watchEnvironmentVariables","bootstrapTypeScriptAsync","openPlatformsAsync","defaultServerUrl","getDefaultDevServer","getDevServerUrl","mcpServer","maybeCreateMCPServerAsync","devServerUrl","startInterfaceAsync","__EXPO_E2E_TEST","console","info","JSON","stringify","url","printDevToolsPluginCliBannersAsync","result","printDependencyCheckResult","addMcpCapabilities","start","logLocation","dim"],"mappings":"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"}
@@ -36,6 +36,9 @@ _export(exports, {
36
36
  get isPathInside () {
37
37
  return isPathInside;
38
38
  },
39
+ get maybeRealpathSync () {
40
+ return maybeRealpathSync;
41
+ },
39
42
  get removeAsync () {
40
43
  return removeAsync;
41
44
  }
@@ -113,6 +116,13 @@ const removeAsync = (path)=>{
113
116
  force: true
114
117
  });
115
118
  };
119
+ function maybeRealpathSync(target) {
120
+ try {
121
+ return _fs().default.realpathSync(target);
122
+ } catch {
123
+ return null;
124
+ }
125
+ }
116
126
  function isPathInside(child, parent) {
117
127
  const relative = _path().default.relative(parent, child);
118
128
  return !!relative && !relative.startsWith('..') && !_path().default.isAbsolute(relative);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/dir.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nexport function fileExistsSync(file: string): boolean {\n return !!fs\n .statSync(file, {\n throwIfNoEntry: false,\n })\n ?.isFile();\n}\n\nexport function directoryExistsSync(file: string): boolean {\n return !!fs\n .statSync(file, {\n throwIfNoEntry: false,\n })\n ?.isDirectory();\n}\n\nexport async function directoryExistsAsync(file: string): Promise<boolean> {\n return (await fs.promises.stat(file).catch(() => null))?.isDirectory() ?? false;\n}\n\nexport async function fileExistsAsync(file: string): Promise<boolean> {\n return (await fs.promises.stat(file).catch(() => null))?.isFile() ?? false;\n}\n\nexport const ensureDirectoryAsync = (path: string) => fs.promises.mkdir(path, { recursive: true });\n\nexport const ensureDirectory = (path: string): void => {\n fs.mkdirSync(path, {\n recursive: true,\n });\n};\n\nexport const copySync = (src: string, dest: string): void => {\n const destParent = path.dirname(dest);\n if (!fs.existsSync(destParent)) ensureDirectory(destParent);\n fs.cpSync(src, dest, {\n recursive: true,\n force: true,\n });\n};\n\nexport const copyAsync = async (src: string, dest: string): Promise<void> => {\n const destParent = path.dirname(dest);\n if (!fs.existsSync(destParent)) {\n await fs.promises.mkdir(destParent, { recursive: true });\n }\n await fs.promises.cp(src, dest, {\n recursive: true,\n force: true,\n });\n};\n\nexport const removeAsync = (path: string): Promise<void> => {\n return fs.promises.rm(path, {\n recursive: true,\n force: true,\n });\n};\n\nexport function isPathInside(child: string, parent: string): boolean {\n const relative = path.relative(parent, child);\n return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n}\n"],"names":["copyAsync","copySync","directoryExistsAsync","directoryExistsSync","ensureDirectory","ensureDirectoryAsync","fileExistsAsync","fileExistsSync","isPathInside","removeAsync","file","fs","statSync","throwIfNoEntry","isFile","isDirectory","promises","stat","catch","path","mkdir","recursive","mkdirSync","src","dest","destParent","dirname","existsSync","cpSync","force","cp","rm","child","parent","relative","startsWith","isAbsolute"],"mappings":";;;;;;;;;;;QA4CaA;eAAAA;;QATAC;eAAAA;;QAhBSC;eAAAA;;QARNC;eAAAA;;QAkBHC;eAAAA;;QAFAC;eAAAA;;QAJSC;eAAAA;;QApBNC;eAAAA;;QA2DAC;eAAAA;;QAPHC;eAAAA;;;;gEAvDE;;;;;;;gEACE;;;;;;;;;;;AAEV,SAASF,eAAeG,IAAY;QAChCC;IAAT,OAAO,CAAC,GAACA,eAAAA,aAAE,CACRC,QAAQ,CAACF,MAAM;QACdG,gBAAgB;IAClB,uBAHOF,aAILG,MAAM;AACZ;AAEO,SAASX,oBAAoBO,IAAY;QACrCC;IAAT,OAAO,CAAC,GAACA,eAAAA,aAAE,CACRC,QAAQ,CAACF,MAAM;QACdG,gBAAgB;IAClB,uBAHOF,aAILI,WAAW;AACjB;AAEO,eAAeb,qBAAqBQ,IAAY;QAC7C;IAAR,OAAO,EAAC,QAAA,MAAMC,aAAE,CAACK,QAAQ,CAACC,IAAI,CAACP,MAAMQ,KAAK,CAAC,IAAM,0BAA1C,AAAC,MAAiDH,WAAW,OAAM;AAC5E;AAEO,eAAeT,gBAAgBI,IAAY;QACxC;IAAR,OAAO,EAAC,QAAA,MAAMC,aAAE,CAACK,QAAQ,CAACC,IAAI,CAACP,MAAMQ,KAAK,CAAC,IAAM,0BAA1C,AAAC,MAAiDJ,MAAM,OAAM;AACvE;AAEO,MAAMT,uBAAuB,CAACc,OAAiBR,aAAE,CAACK,QAAQ,CAACI,KAAK,CAACD,MAAM;QAAEE,WAAW;IAAK;AAEzF,MAAMjB,kBAAkB,CAACe;IAC9BR,aAAE,CAACW,SAAS,CAACH,MAAM;QACjBE,WAAW;IACb;AACF;AAEO,MAAMpB,WAAW,CAACsB,KAAaC;IACpC,MAAMC,aAAaN,eAAI,CAACO,OAAO,CAACF;IAChC,IAAI,CAACb,aAAE,CAACgB,UAAU,CAACF,aAAarB,gBAAgBqB;IAChDd,aAAE,CAACiB,MAAM,CAACL,KAAKC,MAAM;QACnBH,WAAW;QACXQ,OAAO;IACT;AACF;AAEO,MAAM7B,YAAY,OAAOuB,KAAaC;IAC3C,MAAMC,aAAaN,eAAI,CAACO,OAAO,CAACF;IAChC,IAAI,CAACb,aAAE,CAACgB,UAAU,CAACF,aAAa;QAC9B,MAAMd,aAAE,CAACK,QAAQ,CAACI,KAAK,CAACK,YAAY;YAAEJ,WAAW;QAAK;IACxD;IACA,MAAMV,aAAE,CAACK,QAAQ,CAACc,EAAE,CAACP,KAAKC,MAAM;QAC9BH,WAAW;QACXQ,OAAO;IACT;AACF;AAEO,MAAMpB,cAAc,CAACU;IAC1B,OAAOR,aAAE,CAACK,QAAQ,CAACe,EAAE,CAACZ,MAAM;QAC1BE,WAAW;QACXQ,OAAO;IACT;AACF;AAEO,SAASrB,aAAawB,KAAa,EAAEC,MAAc;IACxD,MAAMC,WAAWf,eAAI,CAACe,QAAQ,CAACD,QAAQD;IACvC,OAAO,CAAC,CAACE,YAAY,CAACA,SAASC,UAAU,CAAC,SAAS,CAAChB,eAAI,CAACiB,UAAU,CAACF;AACtE"}
1
+ {"version":3,"sources":["../../../src/utils/dir.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nexport function fileExistsSync(file: string): boolean {\n return !!fs\n .statSync(file, {\n throwIfNoEntry: false,\n })\n ?.isFile();\n}\n\nexport function directoryExistsSync(file: string): boolean {\n return !!fs\n .statSync(file, {\n throwIfNoEntry: false,\n })\n ?.isDirectory();\n}\n\nexport async function directoryExistsAsync(file: string): Promise<boolean> {\n return (await fs.promises.stat(file).catch(() => null))?.isDirectory() ?? false;\n}\n\nexport async function fileExistsAsync(file: string): Promise<boolean> {\n return (await fs.promises.stat(file).catch(() => null))?.isFile() ?? false;\n}\n\nexport const ensureDirectoryAsync = (path: string) => fs.promises.mkdir(path, { recursive: true });\n\nexport const ensureDirectory = (path: string): void => {\n fs.mkdirSync(path, {\n recursive: true,\n });\n};\n\nexport const copySync = (src: string, dest: string): void => {\n const destParent = path.dirname(dest);\n if (!fs.existsSync(destParent)) ensureDirectory(destParent);\n fs.cpSync(src, dest, {\n recursive: true,\n force: true,\n });\n};\n\nexport const copyAsync = async (src: string, dest: string): Promise<void> => {\n const destParent = path.dirname(dest);\n if (!fs.existsSync(destParent)) {\n await fs.promises.mkdir(destParent, { recursive: true });\n }\n await fs.promises.cp(src, dest, {\n recursive: true,\n force: true,\n });\n};\n\nexport const removeAsync = (path: string): Promise<void> => {\n return fs.promises.rm(path, {\n recursive: true,\n force: true,\n });\n};\n\nexport function maybeRealpathSync(target: string): string | null {\n try {\n return fs.realpathSync(target);\n } catch {\n return null;\n }\n}\n\nexport function isPathInside(child: string, parent: string): boolean {\n const relative = path.relative(parent, child);\n return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n}\n"],"names":["copyAsync","copySync","directoryExistsAsync","directoryExistsSync","ensureDirectory","ensureDirectoryAsync","fileExistsAsync","fileExistsSync","isPathInside","maybeRealpathSync","removeAsync","file","fs","statSync","throwIfNoEntry","isFile","isDirectory","promises","stat","catch","path","mkdir","recursive","mkdirSync","src","dest","destParent","dirname","existsSync","cpSync","force","cp","rm","target","realpathSync","child","parent","relative","startsWith","isAbsolute"],"mappings":";;;;;;;;;;;QA4CaA;eAAAA;;QATAC;eAAAA;;QAhBSC;eAAAA;;QARNC;eAAAA;;QAkBHC;eAAAA;;QAFAC;eAAAA;;QAJSC;eAAAA;;QApBNC;eAAAA;;QAmEAC;eAAAA;;QARAC;eAAAA;;QAPHC;eAAAA;;;;gEAvDE;;;;;;;gEACE;;;;;;;;;;;AAEV,SAASH,eAAeI,IAAY;QAChCC;IAAT,OAAO,CAAC,GAACA,eAAAA,aAAE,CACRC,QAAQ,CAACF,MAAM;QACdG,gBAAgB;IAClB,uBAHOF,aAILG,MAAM;AACZ;AAEO,SAASZ,oBAAoBQ,IAAY;QACrCC;IAAT,OAAO,CAAC,GAACA,eAAAA,aAAE,CACRC,QAAQ,CAACF,MAAM;QACdG,gBAAgB;IAClB,uBAHOF,aAILI,WAAW;AACjB;AAEO,eAAed,qBAAqBS,IAAY;QAC7C;IAAR,OAAO,EAAC,QAAA,MAAMC,aAAE,CAACK,QAAQ,CAACC,IAAI,CAACP,MAAMQ,KAAK,CAAC,IAAM,0BAA1C,AAAC,MAAiDH,WAAW,OAAM;AAC5E;AAEO,eAAeV,gBAAgBK,IAAY;QACxC;IAAR,OAAO,EAAC,QAAA,MAAMC,aAAE,CAACK,QAAQ,CAACC,IAAI,CAACP,MAAMQ,KAAK,CAAC,IAAM,0BAA1C,AAAC,MAAiDJ,MAAM,OAAM;AACvE;AAEO,MAAMV,uBAAuB,CAACe,OAAiBR,aAAE,CAACK,QAAQ,CAACI,KAAK,CAACD,MAAM;QAAEE,WAAW;IAAK;AAEzF,MAAMlB,kBAAkB,CAACgB;IAC9BR,aAAE,CAACW,SAAS,CAACH,MAAM;QACjBE,WAAW;IACb;AACF;AAEO,MAAMrB,WAAW,CAACuB,KAAaC;IACpC,MAAMC,aAAaN,eAAI,CAACO,OAAO,CAACF;IAChC,IAAI,CAACb,aAAE,CAACgB,UAAU,CAACF,aAAatB,gBAAgBsB;IAChDd,aAAE,CAACiB,MAAM,CAACL,KAAKC,MAAM;QACnBH,WAAW;QACXQ,OAAO;IACT;AACF;AAEO,MAAM9B,YAAY,OAAOwB,KAAaC;IAC3C,MAAMC,aAAaN,eAAI,CAACO,OAAO,CAACF;IAChC,IAAI,CAACb,aAAE,CAACgB,UAAU,CAACF,aAAa;QAC9B,MAAMd,aAAE,CAACK,QAAQ,CAACI,KAAK,CAACK,YAAY;YAAEJ,WAAW;QAAK;IACxD;IACA,MAAMV,aAAE,CAACK,QAAQ,CAACc,EAAE,CAACP,KAAKC,MAAM;QAC9BH,WAAW;QACXQ,OAAO;IACT;AACF;AAEO,MAAMpB,cAAc,CAACU;IAC1B,OAAOR,aAAE,CAACK,QAAQ,CAACe,EAAE,CAACZ,MAAM;QAC1BE,WAAW;QACXQ,OAAO;IACT;AACF;AAEO,SAASrB,kBAAkBwB,MAAc;IAC9C,IAAI;QACF,OAAOrB,aAAE,CAACsB,YAAY,CAACD;IACzB,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEO,SAASzB,aAAa2B,KAAa,EAAEC,MAAc;IACxD,MAAMC,WAAWjB,eAAI,CAACiB,QAAQ,CAACD,QAAQD;IACvC,OAAO,CAAC,CAACE,YAAY,CAACA,SAASC,UAAU,CAAC,SAAS,CAAClB,eAAI,CAACmB,UAAU,CAACF;AACtE"}
@@ -17,6 +17,7 @@ function _nodecrypto() {
17
17
  }
18
18
  const _FetchClient = require("./clients/FetchClient");
19
19
  const _FetchDetachedClient = require("./clients/FetchDetachedClient");
20
+ const _agent = require("./utils/agent");
20
21
  const _context = require("./utils/context");
21
22
  const _UserSettings = require("../../api/user/UserSettings");
22
23
  const _env = require("../env");
@@ -74,6 +75,7 @@ class Telemetry {
74
75
  }
75
76
  }
76
77
  recordInternal(records) {
78
+ const agent = (0, _agent.getAgentTelemetryContext)();
77
79
  return this.client.record(records.map((record)=>({
78
80
  ...record,
79
81
  type: 'track',
@@ -84,6 +86,9 @@ class Telemetry {
84
86
  context: {
85
87
  ...this.context,
86
88
  sessionId: this.actor.sessionId,
89
+ ...agent ? {
90
+ agent
91
+ } : {},
87
92
  client: {
88
93
  mode: this.client.strategy
89
94
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/utils/telemetry/Telemetry.ts"],"sourcesContent":["import crypto from 'node:crypto';\n\nimport { FetchClient } from './clients/FetchClient';\nimport { FetchDetachedClient } from './clients/FetchDetachedClient';\nimport type { TelemetryClient, TelemetryClientStrategy, TelemetryRecord } from './types';\nimport { createContext } from './utils/context';\nimport { getAnonymousId } from '../../api/user/UserSettings';\nimport { env } from '../env';\n\nconst debug = require('debug')('expo:telemetry') as typeof console.log;\n\ntype TelemetryOptions = {\n /** A locally generated ID, untracable to an actual user */\n anonymousId?: string;\n /** A locally generated ID, per CLI invocation */\n sessionId?: string;\n /** The authenticated user ID, this is used to generate an untracable hash */\n userId?: string;\n /** The underlying telemetry strategy to use */\n strategy?: TelemetryClientStrategy;\n};\n\ntype TelemetryActor = Required<Pick<TelemetryOptions, 'anonymousId' | 'sessionId'>> & {\n /**\n * Hashed version of the user ID, untracable to an actual user.\n * If this value is set to `undefined`, telemetry is considered uninitialized and will wait until its set.\n * If this value is set to `null`, telemetry is considered initialized without an authenticated user.\n * If this value is set to a string, telemetry is considered initialized with an authenticated user.\n */\n userHash?: string | null;\n};\n\nexport class Telemetry {\n private context = createContext();\n private client: TelemetryClient = new FetchDetachedClient();\n private actor: TelemetryActor;\n\n /** A list of all events, recorded before the telemetry was fully initialized */\n private earlyRecords: TelemetryRecord[] = [];\n\n constructor({\n anonymousId = getAnonymousId(),\n sessionId = crypto.randomUUID(),\n userId,\n strategy = 'detached',\n }: TelemetryOptions = {}) {\n this.actor = { anonymousId, sessionId };\n this.setStrategy(env.EXPO_NO_TELEMETRY_DETACH ? 'debug' : strategy);\n\n if (userId) {\n this.initialize({ userId });\n }\n }\n\n get strategy() {\n return this.client.strategy;\n }\n\n setStrategy(strategy: TelemetryOptions['strategy']) {\n // Abort when client is already using the correct strategy\n if (this.client.strategy === strategy) return;\n // Abort when debugging the telemetry\n if (env.EXPO_NO_TELEMETRY_DETACH && strategy !== 'debug') return;\n\n debug('Switching strategy from %s to %s', this.client.strategy, strategy);\n\n // Load and instantiate the correct client, based on strategy\n const client = createClientFromStrategy(strategy);\n // Replace the client, and re-record any pending records\n this.client.abort().forEach((record) => client.record([record]));\n this.client = client;\n\n return this;\n }\n\n get isInitialized() {\n return this.actor.userHash !== undefined;\n }\n\n initialize({ userId }: { userId: string | null }) {\n this.actor.userHash = userId ? hashUserId(userId) : null;\n this.flushEarlyRecords();\n }\n\n private flushEarlyRecords() {\n if (this.earlyRecords.length) {\n this.recordInternal(this.earlyRecords);\n this.earlyRecords = [];\n }\n }\n\n private recordInternal(records: TelemetryRecord[]) {\n return this.client.record(\n records.map((record) => ({\n ...record,\n type: 'track' as const,\n sentAt: new Date(),\n messageId: createMessageId(record),\n anonymousId: this.actor.anonymousId,\n userHash: this.actor.userHash,\n context: {\n ...this.context,\n sessionId: this.actor.sessionId,\n client: { mode: this.client.strategy },\n },\n }))\n );\n }\n\n record(record: TelemetryRecord | TelemetryRecord[]) {\n const records = Array.isArray(record) ? record : [record];\n\n debug('Recording %d event(s)', records.length);\n\n if (!this.isInitialized) {\n this.earlyRecords.push(...records);\n return;\n }\n\n return this.recordInternal(records);\n }\n\n flush() {\n debug('Flushing events...');\n this.flushEarlyRecords();\n return this.client.flush();\n }\n\n flushOnExit() {\n this.setStrategy('detached');\n this.flushEarlyRecords();\n return this.client.flush();\n }\n}\n\nfunction createClientFromStrategy(strategy: TelemetryOptions['strategy']) {\n // When debugging, use the actual Rudderstack client, but lazy load it\n if (env.EXPO_NO_TELEMETRY_DETACH || strategy === 'debug' || strategy === 'instant') {\n return new FetchClient();\n }\n\n return new FetchDetachedClient();\n}\n\n/** Generate a unique message ID using a random hash and UUID */\nfunction createMessageId(record: TelemetryRecord) {\n const uuid = crypto.randomUUID();\n const md5 = crypto.createHash('md5').update(JSON.stringify(record)).digest('hex');\n\n return `node-${md5}-${uuid}`;\n}\n\n/** Hash the user identifier to make it untracable */\nfunction hashUserId(userId: string) {\n return crypto.createHash('sha256').update(userId).digest('hex');\n}\n"],"names":["Telemetry","debug","require","anonymousId","getAnonymousId","sessionId","crypto","randomUUID","userId","strategy","context","createContext","client","FetchDetachedClient","earlyRecords","actor","setStrategy","env","EXPO_NO_TELEMETRY_DETACH","initialize","createClientFromStrategy","abort","forEach","record","isInitialized","userHash","undefined","hashUserId","flushEarlyRecords","length","recordInternal","records","map","type","sentAt","Date","messageId","createMessageId","mode","Array","isArray","push","flush","flushOnExit","FetchClient","uuid","md5","createHash","update","JSON","stringify","digest"],"mappings":";;;;+BAgCaA;;;eAAAA;;;;gEAhCM;;;;;;6BAES;qCACQ;yBAEN;8BACC;qBACX;;;;;;AAEpB,MAAMC,QAAQC,QAAQ,SAAS;AAuBxB,MAAMF;IAQX,YAAY,EACVG,cAAcC,IAAAA,4BAAc,GAAE,EAC9BC,YAAYC,qBAAM,CAACC,UAAU,EAAE,EAC/BC,MAAM,EACNC,WAAW,UAAU,EACJ,GAAG,CAAC,CAAC,CAAE;aAZlBC,UAAUC,IAAAA,sBAAa;aACvBC,SAA0B,IAAIC,wCAAmB;QAGzD,8EAA8E,QACtEC,eAAkC,EAAE;QAQ1C,IAAI,CAACC,KAAK,GAAG;YAAEZ;YAAaE;QAAU;QACtC,IAAI,CAACW,WAAW,CAACC,QAAG,CAACC,wBAAwB,GAAG,UAAUT;QAE1D,IAAID,QAAQ;YACV,IAAI,CAACW,UAAU,CAAC;gBAAEX;YAAO;QAC3B;IACF;IAEA,IAAIC,WAAW;QACb,OAAO,IAAI,CAACG,MAAM,CAACH,QAAQ;IAC7B;IAEAO,YAAYP,QAAsC,EAAE;QAClD,0DAA0D;QAC1D,IAAI,IAAI,CAACG,MAAM,CAACH,QAAQ,KAAKA,UAAU;QACvC,qCAAqC;QACrC,IAAIQ,QAAG,CAACC,wBAAwB,IAAIT,aAAa,SAAS;QAE1DR,MAAM,oCAAoC,IAAI,CAACW,MAAM,CAACH,QAAQ,EAAEA;QAEhE,6DAA6D;QAC7D,MAAMG,SAASQ,yBAAyBX;QACxC,wDAAwD;QACxD,IAAI,CAACG,MAAM,CAACS,KAAK,GAAGC,OAAO,CAAC,CAACC,SAAWX,OAAOW,MAAM,CAAC;gBAACA;aAAO;QAC9D,IAAI,CAACX,MAAM,GAAGA;QAEd,OAAO,IAAI;IACb;IAEA,IAAIY,gBAAgB;QAClB,OAAO,IAAI,CAACT,KAAK,CAACU,QAAQ,KAAKC;IACjC;IAEAP,WAAW,EAAEX,MAAM,EAA6B,EAAE;QAChD,IAAI,CAACO,KAAK,CAACU,QAAQ,GAAGjB,SAASmB,WAAWnB,UAAU;QACpD,IAAI,CAACoB,iBAAiB;IACxB;IAEQA,oBAAoB;QAC1B,IAAI,IAAI,CAACd,YAAY,CAACe,MAAM,EAAE;YAC5B,IAAI,CAACC,cAAc,CAAC,IAAI,CAAChB,YAAY;YACrC,IAAI,CAACA,YAAY,GAAG,EAAE;QACxB;IACF;IAEQgB,eAAeC,OAA0B,EAAE;QACjD,OAAO,IAAI,CAACnB,MAAM,CAACW,MAAM,CACvBQ,QAAQC,GAAG,CAAC,CAACT,SAAY,CAAA;gBACvB,GAAGA,MAAM;gBACTU,MAAM;gBACNC,QAAQ,IAAIC;gBACZC,WAAWC,gBAAgBd;gBAC3BpB,aAAa,IAAI,CAACY,KAAK,CAACZ,WAAW;gBACnCsB,UAAU,IAAI,CAACV,KAAK,CAACU,QAAQ;gBAC7Bf,SAAS;oBACP,GAAG,IAAI,CAACA,OAAO;oBACfL,WAAW,IAAI,CAACU,KAAK,CAACV,SAAS;oBAC/BO,QAAQ;wBAAE0B,MAAM,IAAI,CAAC1B,MAAM,CAACH,QAAQ;oBAAC;gBACvC;YACF,CAAA;IAEJ;IAEAc,OAAOA,MAA2C,EAAE;QAClD,MAAMQ,UAAUQ,MAAMC,OAAO,CAACjB,UAAUA,SAAS;YAACA;SAAO;QAEzDtB,MAAM,yBAAyB8B,QAAQF,MAAM;QAE7C,IAAI,CAAC,IAAI,CAACL,aAAa,EAAE;YACvB,IAAI,CAACV,YAAY,CAAC2B,IAAI,IAAIV;YAC1B;QACF;QAEA,OAAO,IAAI,CAACD,cAAc,CAACC;IAC7B;IAEAW,QAAQ;QACNzC,MAAM;QACN,IAAI,CAAC2B,iBAAiB;QACtB,OAAO,IAAI,CAAChB,MAAM,CAAC8B,KAAK;IAC1B;IAEAC,cAAc;QACZ,IAAI,CAAC3B,WAAW,CAAC;QACjB,IAAI,CAACY,iBAAiB;QACtB,OAAO,IAAI,CAAChB,MAAM,CAAC8B,KAAK;IAC1B;AACF;AAEA,SAAStB,yBAAyBX,QAAsC;IACtE,sEAAsE;IACtE,IAAIQ,QAAG,CAACC,wBAAwB,IAAIT,aAAa,WAAWA,aAAa,WAAW;QAClF,OAAO,IAAImC,wBAAW;IACxB;IAEA,OAAO,IAAI/B,wCAAmB;AAChC;AAEA,8DAA8D,GAC9D,SAASwB,gBAAgBd,MAAuB;IAC9C,MAAMsB,OAAOvC,qBAAM,CAACC,UAAU;IAC9B,MAAMuC,MAAMxC,qBAAM,CAACyC,UAAU,CAAC,OAAOC,MAAM,CAACC,KAAKC,SAAS,CAAC3B,SAAS4B,MAAM,CAAC;IAE3E,OAAO,CAAC,KAAK,EAAEL,IAAI,CAAC,EAAED,MAAM;AAC9B;AAEA,mDAAmD,GACnD,SAASlB,WAAWnB,MAAc;IAChC,OAAOF,qBAAM,CAACyC,UAAU,CAAC,UAAUC,MAAM,CAACxC,QAAQ2C,MAAM,CAAC;AAC3D"}
1
+ {"version":3,"sources":["../../../../src/utils/telemetry/Telemetry.ts"],"sourcesContent":["import crypto from 'node:crypto';\n\nimport { FetchClient } from './clients/FetchClient';\nimport { FetchDetachedClient } from './clients/FetchDetachedClient';\nimport type { TelemetryClient, TelemetryClientStrategy, TelemetryRecord } from './types';\nimport { getAgentTelemetryContext } from './utils/agent';\nimport { createContext } from './utils/context';\nimport { getAnonymousId } from '../../api/user/UserSettings';\nimport { env } from '../env';\n\nconst debug = require('debug')('expo:telemetry') as typeof console.log;\n\ntype TelemetryOptions = {\n /** A locally generated ID, untracable to an actual user */\n anonymousId?: string;\n /** A locally generated ID, per CLI invocation */\n sessionId?: string;\n /** The authenticated user ID, this is used to generate an untracable hash */\n userId?: string;\n /** The underlying telemetry strategy to use */\n strategy?: TelemetryClientStrategy;\n};\n\ntype TelemetryActor = Required<Pick<TelemetryOptions, 'anonymousId' | 'sessionId'>> & {\n /**\n * Hashed version of the user ID, untracable to an actual user.\n * If this value is set to `undefined`, telemetry is considered uninitialized and will wait until its set.\n * If this value is set to `null`, telemetry is considered initialized without an authenticated user.\n * If this value is set to a string, telemetry is considered initialized with an authenticated user.\n */\n userHash?: string | null;\n};\n\nexport class Telemetry {\n private context = createContext();\n private client: TelemetryClient = new FetchDetachedClient();\n private actor: TelemetryActor;\n\n /** A list of all events, recorded before the telemetry was fully initialized */\n private earlyRecords: TelemetryRecord[] = [];\n\n constructor({\n anonymousId = getAnonymousId(),\n sessionId = crypto.randomUUID(),\n userId,\n strategy = 'detached',\n }: TelemetryOptions = {}) {\n this.actor = { anonymousId, sessionId };\n this.setStrategy(env.EXPO_NO_TELEMETRY_DETACH ? 'debug' : strategy);\n\n if (userId) {\n this.initialize({ userId });\n }\n }\n\n get strategy() {\n return this.client.strategy;\n }\n\n setStrategy(strategy: TelemetryOptions['strategy']) {\n // Abort when client is already using the correct strategy\n if (this.client.strategy === strategy) return;\n // Abort when debugging the telemetry\n if (env.EXPO_NO_TELEMETRY_DETACH && strategy !== 'debug') return;\n\n debug('Switching strategy from %s to %s', this.client.strategy, strategy);\n\n // Load and instantiate the correct client, based on strategy\n const client = createClientFromStrategy(strategy);\n // Replace the client, and re-record any pending records\n this.client.abort().forEach((record) => client.record([record]));\n this.client = client;\n\n return this;\n }\n\n get isInitialized() {\n return this.actor.userHash !== undefined;\n }\n\n initialize({ userId }: { userId: string | null }) {\n this.actor.userHash = userId ? hashUserId(userId) : null;\n this.flushEarlyRecords();\n }\n\n private flushEarlyRecords() {\n if (this.earlyRecords.length) {\n this.recordInternal(this.earlyRecords);\n this.earlyRecords = [];\n }\n }\n\n private recordInternal(records: TelemetryRecord[]) {\n const agent = getAgentTelemetryContext();\n\n return this.client.record(\n records.map((record) => ({\n ...record,\n type: 'track' as const,\n sentAt: new Date(),\n messageId: createMessageId(record),\n anonymousId: this.actor.anonymousId,\n userHash: this.actor.userHash,\n context: {\n ...this.context,\n sessionId: this.actor.sessionId,\n ...(agent ? { agent } : {}),\n client: { mode: this.client.strategy },\n },\n }))\n );\n }\n\n record(record: TelemetryRecord | TelemetryRecord[]) {\n const records = Array.isArray(record) ? record : [record];\n\n debug('Recording %d event(s)', records.length);\n\n if (!this.isInitialized) {\n this.earlyRecords.push(...records);\n return;\n }\n\n return this.recordInternal(records);\n }\n\n flush() {\n debug('Flushing events...');\n this.flushEarlyRecords();\n return this.client.flush();\n }\n\n flushOnExit() {\n this.setStrategy('detached');\n this.flushEarlyRecords();\n return this.client.flush();\n }\n}\n\nfunction createClientFromStrategy(strategy: TelemetryOptions['strategy']) {\n // When debugging, use the actual Rudderstack client, but lazy load it\n if (env.EXPO_NO_TELEMETRY_DETACH || strategy === 'debug' || strategy === 'instant') {\n return new FetchClient();\n }\n\n return new FetchDetachedClient();\n}\n\n/** Generate a unique message ID using a random hash and UUID */\nfunction createMessageId(record: TelemetryRecord) {\n const uuid = crypto.randomUUID();\n const md5 = crypto.createHash('md5').update(JSON.stringify(record)).digest('hex');\n\n return `node-${md5}-${uuid}`;\n}\n\n/** Hash the user identifier to make it untracable */\nfunction hashUserId(userId: string) {\n return crypto.createHash('sha256').update(userId).digest('hex');\n}\n"],"names":["Telemetry","debug","require","anonymousId","getAnonymousId","sessionId","crypto","randomUUID","userId","strategy","context","createContext","client","FetchDetachedClient","earlyRecords","actor","setStrategy","env","EXPO_NO_TELEMETRY_DETACH","initialize","createClientFromStrategy","abort","forEach","record","isInitialized","userHash","undefined","hashUserId","flushEarlyRecords","length","recordInternal","records","agent","getAgentTelemetryContext","map","type","sentAt","Date","messageId","createMessageId","mode","Array","isArray","push","flush","flushOnExit","FetchClient","uuid","md5","createHash","update","JSON","stringify","digest"],"mappings":"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"}
@@ -26,7 +26,7 @@ class FetchClient {
26
26
  this.headers = {
27
27
  accept: 'application/json',
28
28
  'content-type': 'application/json',
29
- 'user-agent': `expo-cli/${"57.0.3"}`,
29
+ 'user-agent': `expo-cli/${"57.0.5"}`,
30
30
  authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
31
31
  };
32
32
  }