@expo/cli 56.1.5 → 56.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/events/index.js +1 -1
  3. package/build/src/export/embed/exportEmbedAsync.js +1 -1
  4. package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
  5. package/build/src/export/embed/exportServer.js +1 -1
  6. package/build/src/export/embed/exportServer.js.map +1 -1
  7. package/build/src/export/exportApp.js +1 -1
  8. package/build/src/export/exportApp.js.map +1 -1
  9. package/build/src/export/publicFolder.js +19 -1
  10. package/build/src/export/publicFolder.js.map +1 -1
  11. package/build/src/login/index.js +25 -5
  12. package/build/src/login/index.js.map +1 -1
  13. package/build/src/run/android/resolveLaunchProps.js +4 -1
  14. package/build/src/run/android/resolveLaunchProps.js.map +1 -1
  15. package/build/src/start/doctor/dependencies/reactNativeTv.js +149 -0
  16. package/build/src/start/doctor/dependencies/reactNativeTv.js.map +1 -0
  17. package/build/src/start/doctor/dependencies/validateDependenciesVersions.js +28 -3
  18. package/build/src/start/doctor/dependencies/validateDependenciesVersions.js.map +1 -1
  19. package/build/src/start/server/DevToolsPlugin.js +26 -1
  20. package/build/src/start/server/DevToolsPlugin.js.map +1 -1
  21. package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js +57 -22
  22. package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js.map +1 -1
  23. package/build/src/start/server/DevToolsPluginCliExtensionResults.js +29 -0
  24. package/build/src/start/server/DevToolsPluginCliExtensionResults.js.map +1 -1
  25. package/build/src/start/server/MCPDevToolsPluginCLIExtensions.js +15 -5
  26. package/build/src/start/server/MCPDevToolsPluginCLIExtensions.js.map +1 -1
  27. package/build/src/start/server/UrlCreator.js +4 -0
  28. package/build/src/start/server/UrlCreator.js.map +1 -1
  29. package/build/src/start/server/createMCPDevToolsExtensionSchema.js +13 -1
  30. package/build/src/start/server/createMCPDevToolsExtensionSchema.js.map +1 -1
  31. package/build/src/start/server/metro/MetroBundlerDevServer.js +44 -0
  32. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  33. package/build/src/start/server/metro/createServerComponentsMiddleware.js +13 -13
  34. package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
  35. package/build/src/start/server/metro/dev-server/createMessageSocket.js +13 -2
  36. package/build/src/start/server/metro/dev-server/createMessageSocket.js.map +1 -1
  37. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +2 -1
  38. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
  39. package/build/src/start/server/metro/instantiateMetro.js +5 -4
  40. package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
  41. package/build/src/start/server/metro/router.js +10 -1
  42. package/build/src/start/server/metro/router.js.map +1 -1
  43. package/build/src/start/server/middleware/OpenMiddleware.js +150 -0
  44. package/build/src/start/server/middleware/OpenMiddleware.js.map +1 -0
  45. package/build/src/start/server/middleware/RuntimeRedirectMiddleware.js +13 -4
  46. package/build/src/start/server/middleware/RuntimeRedirectMiddleware.js.map +1 -1
  47. package/build/src/start/server/middleware/ServeStaticMiddleware.js +2 -9
  48. package/build/src/start/server/middleware/ServeStaticMiddleware.js.map +1 -1
  49. package/build/src/start/server/middleware/openHandlers.js +157 -0
  50. package/build/src/start/server/middleware/openHandlers.js.map +1 -0
  51. package/build/src/start/server/webTemplate.js +3 -5
  52. package/build/src/start/server/webTemplate.js.map +1 -1
  53. package/build/src/utils/net.js +7 -1
  54. package/build/src/utils/net.js.map +1 -1
  55. package/build/src/utils/tar.js +2 -2
  56. package/build/src/utils/tar.js.map +1 -1
  57. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  58. package/build/src/utils/telemetry/utils/context.js +1 -1
  59. package/package.json +14 -14
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/instantiateMetro.ts"],"sourcesContent":["import { type ExpoConfig, getConfig } 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 { mergeConfig, resolveConfig, type ConfigT } from '@expo/metro/metro-config';\nimport { Terminal } from '@expo/metro/metro-core';\nimport type { createStableModuleIdFactory } from '@expo/metro-config';\nimport { getDefaultConfig } from '@expo/metro-config';\nimport { patchTransformFileForPackedMaps } from '@expo/metro-config/build/serializer/packedMap';\nimport { patchMetroSourceMapStringForPackedMaps } from '@expo/metro-config/build/serializer/sourceMap';\nimport { resolveBabelrcName } from '@expo/metro-config/exports';\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 // Autolinking Module Resolution will be enabled by default when we're in a monorepo\n const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? isWorkspace;\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 // NOTE: Allow external tools to override the metro config. This is considered internal and unstable\n const configPath = env.EXPO_OVERRIDE_METRO_CONFIG ?? undefined;\n const resolvedConfig = await resolveConfig(configPath, projectRoot);\n const defaultConfig = getDefaultConfig(projectRoot);\n\n let config: ConfigT = resolvedConfig.isEmpty\n ? defaultConfig\n : await mergeConfig(defaultConfig, resolvedConfig.config);\n\n // Set the watchfolders to include the projectRoot, as Metro assumes this\n // Force-override the reporter\n config = {\n ...config,\n\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\n watchFolders: !config.watchFolders.includes(config.projectRoot)\n ? [config.projectRoot, ...config.watchFolders]\n : config.watchFolders,\n reporter: {\n update(event) {\n terminalReporter.update(event);\n if (reportEvent) {\n reportEvent(event);\n }\n },\n },\n };\n\n // NOTE(@kitten): Pass a hint to the transformer on where to find the Babel config\n asWritable(config.transformer).extendsBabelConfigPath =\n config.transformer.enableBabelRCLookup !== false ? resolveBabelrcName(projectRoot) : undefined;\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 // NOTE(@kitten): `useWatchman` is currently enabled by default, but it also disables `forceNodeFilesystemAPI`.\n // If we instead set it to the special value `null`, it gets enables but also bypasses the \"native find\" codepath,\n // which is slower than just using the Node filesystem API\n // See: https://github.com/facebook/metro/blob/b9c243f/packages/metro-file-map/src/index.js#L326\n // See: https://github.com/facebook/metro/blob/b9c243f/packages/metro/src/node-haste/DependencyGraph/createFileMap.js#L109\n if (config.resolver.useWatchman === true) {\n asWritable(config.resolver).useWatchman = null as any;\n }\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 // Create the core middleware stack for Metro, including websocket listeners\n const { middleware, messagesSocket, eventsSocket, websocketEndpoints } = createMetroMiddleware(\n metroConfig,\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 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());\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","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","serverActionsEnabled","reactServerFunctions","env","EXPO_UNSTABLE_SERVER_FUNCTIONS","serverComponentsEnabled","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","reactCanary","Log","terminalReporter","MetroTerminalReporter","configPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resolvedConfig","resolveConfig","defaultConfig","getDefaultConfig","isEmpty","mergeConfig","resetCache","maxWorkers","server","port","watchFolders","includes","reporter","update","transformer","extendsBabelConfigPath","enableBabelRCLookup","resolveBabelrcName","onDemandFilesystem","resolver","unstable_onDemandFilesystem","useWatchman","globalThis","__requireCycleIgnorePatterns","requireCycleIgnorePatterns","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","middleware","messagesSocket","eventsSocket","websocketEndpoints","createMetroMiddleware","serverBaseUrl","getUrlCreator","constructUrl","scheme","hostType","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","platform","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 } 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 { mergeConfig, resolveConfig, type ConfigT } from '@expo/metro/metro-config';\nimport { Terminal } from '@expo/metro/metro-core';\nimport type { createStableModuleIdFactory } from '@expo/metro-config';\nimport { getDefaultConfig } from '@expo/metro-config';\nimport { patchTransformFileForPackedMaps } from '@expo/metro-config/build/serializer/packedMap';\nimport { patchMetroSourceMapStringForPackedMaps } from '@expo/metro-config/build/serializer/sourceMap';\nimport { resolveBabelrcName } from '@expo/metro-config/exports';\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 // Autolinking Module Resolution will be enabled by default when we're in a monorepo\n const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? isWorkspace;\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 // NOTE: Allow external tools to override the metro config. This is considered internal and unstable\n const configPath = env.EXPO_OVERRIDE_METRO_CONFIG ?? undefined;\n const resolvedConfig = await resolveConfig(configPath, projectRoot);\n const defaultConfig = getDefaultConfig(projectRoot);\n\n let config: ConfigT = resolvedConfig.isEmpty\n ? defaultConfig\n : await mergeConfig(defaultConfig, resolvedConfig.config);\n\n // Set the watchfolders to include the projectRoot, as Metro assumes this\n // Force-override the reporter\n config = {\n ...config,\n\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\n watchFolders: !config.watchFolders.includes(config.projectRoot)\n ? [config.projectRoot, ...config.watchFolders]\n : config.watchFolders,\n reporter: {\n update(event) {\n terminalReporter.update(event);\n if (reportEvent) {\n reportEvent(event);\n }\n },\n },\n };\n\n // NOTE(@kitten): Pass a hint to the transformer on where to find the Babel config\n asWritable(config.transformer).extendsBabelConfigPath =\n config.transformer.enableBabelRCLookup !== false ? resolveBabelrcName(projectRoot) : undefined;\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 // NOTE(@kitten): `useWatchman` is currently enabled by default, but it also disables `forceNodeFilesystemAPI`.\n // If we instead set it to the special value `null`, it gets enables but also bypasses the \"native find\" codepath,\n // which is slower than just using the Node filesystem API\n // See: https://github.com/facebook/metro/blob/b9c243f/packages/metro-file-map/src/index.js#L326\n // See: https://github.com/facebook/metro/blob/b9c243f/packages/metro/src/node-haste/DependencyGraph/createFileMap.js#L109\n if (config.resolver.useWatchman === true) {\n asWritable(config.resolver).useWatchman = null as any;\n }\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());\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","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","serverActionsEnabled","reactServerFunctions","env","EXPO_UNSTABLE_SERVER_FUNCTIONS","serverComponentsEnabled","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","reactCanary","Log","terminalReporter","MetroTerminalReporter","configPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resolvedConfig","resolveConfig","defaultConfig","getDefaultConfig","isEmpty","mergeConfig","resetCache","maxWorkers","server","port","watchFolders","includes","reporter","update","transformer","extendsBabelConfigPath","enableBabelRCLookup","resolveBabelrcName","onDemandFilesystem","resolver","unstable_onDemandFilesystem","useWatchman","globalThis","__requireCycleIgnorePatterns","requireCycleIgnorePatterns","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","platform","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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"}
@@ -76,6 +76,7 @@ function _resolvefrom() {
76
76
  }
77
77
  const _log = require("../../../log");
78
78
  const _dir = require("../../../utils/dir");
79
+ const _errors = require("../../../utils/errors");
79
80
  const _filePath = require("../../../utils/filePath");
80
81
  const _link = require("../../../utils/link");
81
82
  function _interop_require_default(obj) {
@@ -105,7 +106,15 @@ function getAppRouterRelativeEntryPath(projectRoot, routerDirectory = getRouterD
105
106
  }
106
107
  function getRouterDirectoryModuleIdWithManifest(projectRoot, exp) {
107
108
  var _exp_extra_router, _exp_extra;
108
- return (0, _filePath.toPosixPath)(((_exp_extra = exp.extra) == null ? void 0 : (_exp_extra_router = _exp_extra.router) == null ? void 0 : _exp_extra_router.root) ?? getRouterDirectory(projectRoot));
109
+ const configured = (_exp_extra = exp.extra) == null ? void 0 : (_exp_extra_router = _exp_extra.router) == null ? void 0 : _exp_extra_router.root;
110
+ if (configured == null) {
111
+ return (0, _filePath.toPosixPath)(getRouterDirectory(projectRoot));
112
+ }
113
+ const absolute = _path().default.isAbsolute(configured) ? configured : _path().default.resolve(projectRoot, configured);
114
+ if (!(0, _dir.isPathInside)(absolute, projectRoot)) {
115
+ throw new _errors.CommandError('INVALID_ROUTER_ROOT', `The expo-router \`root\` (${configured}) resolves outside the project root. Set it to a path inside the project, or remove it to use the default.`);
116
+ }
117
+ return (0, _filePath.toPosixPath)(configured);
109
118
  }
110
119
  let hasWarnedAboutSrcDir = false;
111
120
  const logSrcDir = ()=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/router.ts"],"sourcesContent":["import type { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport type { MiddlewareMatcher } from 'expo-server';\nimport { sync as globSync } from 'glob';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { Log } from '../../../log';\nimport { directoryExistsSync } from '../../../utils/dir';\nimport { toPosixPath } from '../../../utils/filePath';\nimport { learnMore } from '../../../utils/link';\n\nconst debug = require('debug')('expo:start:server:metro:router') as typeof console.log;\n\n/**\n * Get the relative path for requiring the `/app` folder relative to the `expo-router/entry` file.\n * This mechanism does require the server to restart after the `expo-router` package is installed.\n */\nexport function getAppRouterRelativeEntryPath(\n projectRoot: string,\n routerDirectory: string = getRouterDirectory(projectRoot)\n): string | undefined {\n // Auto pick App entry\n const routerEntry =\n resolveFrom.silent(projectRoot, 'expo-router/entry') ?? getFallbackEntryRoot(projectRoot);\n if (!routerEntry) {\n return undefined;\n }\n // It doesn't matter if the app folder exists.\n const appFolder = path.join(projectRoot, routerDirectory);\n const appRoot = path.relative(path.dirname(routerEntry), appFolder);\n debug('expo-router entry', routerEntry, appFolder, appRoot);\n return appRoot;\n}\n\n/** If the `expo-router` package is not installed, then use the `expo` package to determine where the node modules are relative to the project. */\nfunction getFallbackEntryRoot(projectRoot: string): string {\n const expoRoot = resolveFrom.silent(projectRoot, 'expo/package.json');\n if (expoRoot) {\n return path.join(path.dirname(path.dirname(expoRoot)), 'expo-router/entry');\n }\n return path.join(projectRoot, 'node_modules/expo-router/entry');\n}\n\nexport function getRouterDirectoryModuleIdWithManifest(\n projectRoot: string,\n exp: ExpoConfig\n): string {\n return toPosixPath(exp.extra?.router?.root ?? getRouterDirectory(projectRoot));\n}\n\nlet hasWarnedAboutSrcDir = false;\nconst logSrcDir = () => {\n if (hasWarnedAboutSrcDir) return;\n hasWarnedAboutSrcDir = true;\n Log.log(chalk.gray('Using src/app as the root directory for Expo Router.'));\n};\n\nexport function getRouterDirectory(projectRoot: string): string {\n // more specific directories first\n if (directoryExistsSync(path.join(projectRoot, 'src', 'app'))) {\n logSrcDir();\n return path.join('src', 'app');\n }\n\n debug('Using app as the root directory for Expo Router.');\n return 'app';\n}\n\nexport function isApiRouteConvention(name: string): boolean {\n return /\\+api\\.[tj]sx?$/.test(name);\n}\n\nexport function getApiRoutesForDirectory(cwd: string) {\n return globSync('**/*+api.@(ts|tsx|js|jsx)', {\n cwd,\n absolute: true,\n dot: true,\n });\n}\n\n/**\n * Gets the +middleware file for a given directory. In\n * @param cwd\n */\nexport function getMiddlewareForDirectory(cwd: string): string | null {\n const files = globSync('+middleware.@(ts|tsx|js|jsx)', {\n cwd,\n absolute: true,\n dot: true,\n });\n\n if (files.length === 0) return null;\n\n if (files.length > 1) {\n // In development, throw an error if there are multiple root-level middleware files\n if (process.env.NODE_ENV !== 'production') {\n const relativePaths = files.map((f) => './' + path.relative(cwd, f)).sort();\n throw new Error(\n `Only one middleware file is allowed. Keep one of the conflicting files: ${relativePaths.map((p) => `\"${p}\"`).join(' or ')}`\n );\n }\n }\n\n return files[0]!;\n}\n\n// Used to emulate a context module, but way faster. TODO: May need to adjust the extensions to stay in sync with Metro.\nexport function getRoutePaths(cwd: string) {\n return globSync('**/*.@(ts|tsx|js|jsx)', {\n cwd,\n dot: true,\n }).map((p) => './' + normalizePaths(p));\n}\n\nfunction normalizePaths(p: string) {\n return p.replace(/\\\\/g, '/');\n}\n\nlet hasWarnedAboutApiRouteOutput = false;\nlet hasWarnedAboutMiddlewareOutput = false;\n\nexport function hasWarnedAboutApiRoutes() {\n return hasWarnedAboutApiRouteOutput;\n}\n\nexport function hasWarnedAboutMiddleware() {\n return hasWarnedAboutMiddlewareOutput;\n}\n\nexport function warnInvalidWebOutput() {\n if (!hasWarnedAboutApiRouteOutput) {\n Log.warn(\n chalk.yellow`Using API routes requires the {bold web.output} to be set to {bold \"server\"} in the project {bold app.json}. ${learnMore(\n 'https://docs.expo.dev/router/reference/api-routes/'\n )}`\n );\n }\n\n hasWarnedAboutApiRouteOutput = true;\n}\n\nexport function warnInvalidMiddlewareOutput() {\n if (!hasWarnedAboutMiddlewareOutput) {\n Log.warn(\n chalk.yellow`Using middleware requires the {bold web.output} to be set to {bold \"server\"} in the project {bold app.json}. ${learnMore(\n 'https://docs.expo.dev/router/reference/api-routes/'\n )}`\n );\n }\n\n hasWarnedAboutMiddlewareOutput = true;\n}\n\nexport function warnInvalidMiddlewareMatcherSettings(matcher: MiddlewareMatcher) {\n const validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];\n\n // Ensure methods are valid HTTP methods\n if (matcher.methods) {\n if (!Array.isArray(matcher.methods)) {\n Log.error(\n chalk.red`Middleware matcher methods must be an array of valid HTTP methods. Supported methods are: ${validMethods.join(', ')}`\n );\n } else {\n for (const method of matcher.methods) {\n if (!validMethods.includes(method)) {\n Log.error(\n chalk.red`Invalid middleware HTTP method: ${method}. Supported methods are: ${validMethods.join(', ')}`\n );\n }\n }\n }\n }\n\n // Ensure patterns are either a string or RegExp\n if (matcher.patterns) {\n const patterns = Array.isArray(matcher.patterns) ? matcher.patterns : [matcher.patterns];\n for (const pattern of patterns) {\n if (typeof pattern !== 'string' && !(pattern instanceof RegExp)) {\n Log.error(\n chalk.red`Middleware matcher patterns must be strings or regular expressions. Received: ${String(\n pattern\n )}`\n );\n }\n\n if (typeof pattern === 'string' && !pattern.startsWith('/')) {\n Log.error(\n chalk.red`String patterns in middleware matcher must start with '/'. Received: ${pattern}`\n );\n }\n }\n }\n}\n"],"names":["getApiRoutesForDirectory","getAppRouterRelativeEntryPath","getMiddlewareForDirectory","getRoutePaths","getRouterDirectory","getRouterDirectoryModuleIdWithManifest","hasWarnedAboutApiRoutes","hasWarnedAboutMiddleware","isApiRouteConvention","warnInvalidMiddlewareMatcherSettings","warnInvalidMiddlewareOutput","warnInvalidWebOutput","debug","require","projectRoot","routerDirectory","routerEntry","resolveFrom","silent","getFallbackEntryRoot","undefined","appFolder","path","join","appRoot","relative","dirname","expoRoot","exp","toPosixPath","extra","router","root","hasWarnedAboutSrcDir","logSrcDir","Log","log","chalk","gray","directoryExistsSync","name","test","cwd","globSync","absolute","dot","files","length","process","env","NODE_ENV","relativePaths","map","f","sort","Error","p","normalizePaths","replace","hasWarnedAboutApiRouteOutput","hasWarnedAboutMiddlewareOutput","warn","yellow","learnMore","matcher","validMethods","methods","Array","isArray","error","red","method","includes","patterns","pattern","RegExp","String","startsWith"],"mappings":";;;;;;;;;;;QAyEgBA;eAAAA;;QAvDAC;eAAAA;;QAmEAC;eAAAA;;QAuBAC;eAAAA;;QAlDAC;eAAAA;;QAdAC;eAAAA;;QA8EAC;eAAAA;;QAIAC;eAAAA;;QAzDAC;eAAAA;;QAqFAC;eAAAA;;QAZAC;eAAAA;;QAZAC;eAAAA;;;;gEAjIE;;;;;;;yBAEe;;;;;;;gEAChB;;;;;;;gEACO;;;;;;qBAEJ;qBACgB;0BACR;sBACF;;;;;;AAE1B,MAAMC,QAAQC,QAAQ,SAAS;AAMxB,SAASZ,8BACda,WAAmB,EACnBC,kBAA0BX,mBAAmBU,YAAY;IAEzD,sBAAsB;IACtB,MAAME,cACJC,sBAAW,CAACC,MAAM,CAACJ,aAAa,wBAAwBK,qBAAqBL;IAC/E,IAAI,CAACE,aAAa;QAChB,OAAOI;IACT;IACA,8CAA8C;IAC9C,MAAMC,YAAYC,eAAI,CAACC,IAAI,CAACT,aAAaC;IACzC,MAAMS,UAAUF,eAAI,CAACG,QAAQ,CAACH,eAAI,CAACI,OAAO,CAACV,cAAcK;IACzDT,MAAM,qBAAqBI,aAAaK,WAAWG;IACnD,OAAOA;AACT;AAEA,gJAAgJ,GAChJ,SAASL,qBAAqBL,WAAmB;IAC/C,MAAMa,WAAWV,sBAAW,CAACC,MAAM,CAACJ,aAAa;IACjD,IAAIa,UAAU;QACZ,OAAOL,eAAI,CAACC,IAAI,CAACD,eAAI,CAACI,OAAO,CAACJ,eAAI,CAACI,OAAO,CAACC,YAAY;IACzD;IACA,OAAOL,eAAI,CAACC,IAAI,CAACT,aAAa;AAChC;AAEO,SAAST,uCACdS,WAAmB,EACnBc,GAAe;QAEIA,mBAAAA;IAAnB,OAAOC,IAAAA,qBAAW,EAACD,EAAAA,aAAAA,IAAIE,KAAK,sBAATF,oBAAAA,WAAWG,MAAM,qBAAjBH,kBAAmBI,IAAI,KAAI5B,mBAAmBU;AACnE;AAEA,IAAImB,uBAAuB;AAC3B,MAAMC,YAAY;IAChB,IAAID,sBAAsB;IAC1BA,uBAAuB;IACvBE,QAAG,CAACC,GAAG,CAACC,gBAAK,CAACC,IAAI,CAAC;AACrB;AAEO,SAASlC,mBAAmBU,WAAmB;IACpD,kCAAkC;IAClC,IAAIyB,IAAAA,wBAAmB,EAACjB,eAAI,CAACC,IAAI,CAACT,aAAa,OAAO,SAAS;QAC7DoB;QACA,OAAOZ,eAAI,CAACC,IAAI,CAAC,OAAO;IAC1B;IAEAX,MAAM;IACN,OAAO;AACT;AAEO,SAASJ,qBAAqBgC,IAAY;IAC/C,OAAO,kBAAkBC,IAAI,CAACD;AAChC;AAEO,SAASxC,yBAAyB0C,GAAW;IAClD,OAAOC,IAAAA,YAAQ,EAAC,6BAA6B;QAC3CD;QACAE,UAAU;QACVC,KAAK;IACP;AACF;AAMO,SAAS3C,0BAA0BwC,GAAW;IACnD,MAAMI,QAAQH,IAAAA,YAAQ,EAAC,gCAAgC;QACrDD;QACAE,UAAU;QACVC,KAAK;IACP;IAEA,IAAIC,MAAMC,MAAM,KAAK,GAAG,OAAO;IAE/B,IAAID,MAAMC,MAAM,GAAG,GAAG;QACpB,mFAAmF;QACnF,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,MAAMC,gBAAgBL,MAAMM,GAAG,CAAC,CAACC,IAAM,OAAO/B,eAAI,CAACG,QAAQ,CAACiB,KAAKW,IAAIC,IAAI;YACzE,MAAM,IAAIC,MACR,CAAC,wEAAwE,EAAEJ,cAAcC,GAAG,CAAC,CAACI,IAAM,CAAC,CAAC,EAAEA,EAAE,CAAC,CAAC,EAAEjC,IAAI,CAAC,SAAS;QAEhI;IACF;IAEA,OAAOuB,KAAK,CAAC,EAAE;AACjB;AAGO,SAAS3C,cAAcuC,GAAW;IACvC,OAAOC,IAAAA,YAAQ,EAAC,yBAAyB;QACvCD;QACAG,KAAK;IACP,GAAGO,GAAG,CAAC,CAACI,IAAM,OAAOC,eAAeD;AACtC;AAEA,SAASC,eAAeD,CAAS;IAC/B,OAAOA,EAAEE,OAAO,CAAC,OAAO;AAC1B;AAEA,IAAIC,+BAA+B;AACnC,IAAIC,iCAAiC;AAE9B,SAAStD;IACd,OAAOqD;AACT;AAEO,SAASpD;IACd,OAAOqD;AACT;AAEO,SAASjD;IACd,IAAI,CAACgD,8BAA8B;QACjCxB,QAAG,CAAC0B,IAAI,CACNxB,gBAAK,CAACyB,MAAM,CAAC,6GAA6G,EAAEC,IAAAA,eAAS,EACnI,sDACA,CAAC;IAEP;IAEAJ,+BAA+B;AACjC;AAEO,SAASjD;IACd,IAAI,CAACkD,gCAAgC;QACnCzB,QAAG,CAAC0B,IAAI,CACNxB,gBAAK,CAACyB,MAAM,CAAC,6GAA6G,EAAEC,IAAAA,eAAS,EACnI,sDACA,CAAC;IAEP;IAEAH,iCAAiC;AACnC;AAEO,SAASnD,qCAAqCuD,OAA0B;IAC7E,MAAMC,eAAe;QAAC;QAAO;QAAQ;QAAO;QAAS;QAAU;QAAW;KAAO;IAEjF,wCAAwC;IACxC,IAAID,QAAQE,OAAO,EAAE;QACnB,IAAI,CAACC,MAAMC,OAAO,CAACJ,QAAQE,OAAO,GAAG;YACnC/B,QAAG,CAACkC,KAAK,CACPhC,gBAAK,CAACiC,GAAG,CAAC,0FAA0F,EAAEL,aAAa1C,IAAI,CAAC,MAAM,CAAC;QAEnI,OAAO;YACL,KAAK,MAAMgD,UAAUP,QAAQE,OAAO,CAAE;gBACpC,IAAI,CAACD,aAAaO,QAAQ,CAACD,SAAS;oBAClCpC,QAAG,CAACkC,KAAK,CACPhC,gBAAK,CAACiC,GAAG,CAAC,gCAAgC,EAAEC,OAAO,yBAAyB,EAAEN,aAAa1C,IAAI,CAAC,MAAM,CAAC;gBAE3G;YACF;QACF;IACF;IAEA,gDAAgD;IAChD,IAAIyC,QAAQS,QAAQ,EAAE;QACpB,MAAMA,WAAWN,MAAMC,OAAO,CAACJ,QAAQS,QAAQ,IAAIT,QAAQS,QAAQ,GAAG;YAACT,QAAQS,QAAQ;SAAC;QACxF,KAAK,MAAMC,WAAWD,SAAU;YAC9B,IAAI,OAAOC,YAAY,YAAY,CAAEA,CAAAA,mBAAmBC,MAAK,GAAI;gBAC/DxC,QAAG,CAACkC,KAAK,CACPhC,gBAAK,CAACiC,GAAG,CAAC,8EAA8E,EAAEM,OACxFF,SACA,CAAC;YAEP;YAEA,IAAI,OAAOA,YAAY,YAAY,CAACA,QAAQG,UAAU,CAAC,MAAM;gBAC3D1C,QAAG,CAACkC,KAAK,CACPhC,gBAAK,CAACiC,GAAG,CAAC,qEAAqE,EAAEI,QAAQ,CAAC;YAE9F;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../../src/start/server/metro/router.ts"],"sourcesContent":["import type { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport type { MiddlewareMatcher } from 'expo-server';\nimport { sync as globSync } from 'glob';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { Log } from '../../../log';\nimport { directoryExistsSync, isPathInside } from '../../../utils/dir';\nimport { CommandError } from '../../../utils/errors';\nimport { toPosixPath } from '../../../utils/filePath';\nimport { learnMore } from '../../../utils/link';\n\nconst debug = require('debug')('expo:start:server:metro:router') as typeof console.log;\n\n/**\n * Get the relative path for requiring the `/app` folder relative to the `expo-router/entry` file.\n * This mechanism does require the server to restart after the `expo-router` package is installed.\n */\nexport function getAppRouterRelativeEntryPath(\n projectRoot: string,\n routerDirectory: string = getRouterDirectory(projectRoot)\n): string | undefined {\n // Auto pick App entry\n const routerEntry =\n resolveFrom.silent(projectRoot, 'expo-router/entry') ?? getFallbackEntryRoot(projectRoot);\n if (!routerEntry) {\n return undefined;\n }\n // It doesn't matter if the app folder exists.\n const appFolder = path.join(projectRoot, routerDirectory);\n const appRoot = path.relative(path.dirname(routerEntry), appFolder);\n debug('expo-router entry', routerEntry, appFolder, appRoot);\n return appRoot;\n}\n\n/** If the `expo-router` package is not installed, then use the `expo` package to determine where the node modules are relative to the project. */\nfunction getFallbackEntryRoot(projectRoot: string): string {\n const expoRoot = resolveFrom.silent(projectRoot, 'expo/package.json');\n if (expoRoot) {\n return path.join(path.dirname(path.dirname(expoRoot)), 'expo-router/entry');\n }\n return path.join(projectRoot, 'node_modules/expo-router/entry');\n}\n\nexport function getRouterDirectoryModuleIdWithManifest(\n projectRoot: string,\n exp: ExpoConfig\n): string {\n const configured = exp.extra?.router?.root;\n if (configured == null) {\n return toPosixPath(getRouterDirectory(projectRoot));\n }\n const absolute = path.isAbsolute(configured) ? configured : path.resolve(projectRoot, configured);\n if (!isPathInside(absolute, projectRoot)) {\n throw new CommandError(\n 'INVALID_ROUTER_ROOT',\n `The expo-router \\`root\\` (${configured}) resolves outside the project root. Set it to a path inside the project, or remove it to use the default.`\n );\n }\n return toPosixPath(configured);\n}\n\nlet hasWarnedAboutSrcDir = false;\nconst logSrcDir = () => {\n if (hasWarnedAboutSrcDir) return;\n hasWarnedAboutSrcDir = true;\n Log.log(chalk.gray('Using src/app as the root directory for Expo Router.'));\n};\n\nexport function getRouterDirectory(projectRoot: string): string {\n // more specific directories first\n if (directoryExistsSync(path.join(projectRoot, 'src', 'app'))) {\n logSrcDir();\n return path.join('src', 'app');\n }\n\n debug('Using app as the root directory for Expo Router.');\n return 'app';\n}\n\nexport function isApiRouteConvention(name: string): boolean {\n return /\\+api\\.[tj]sx?$/.test(name);\n}\n\nexport function getApiRoutesForDirectory(cwd: string) {\n return globSync('**/*+api.@(ts|tsx|js|jsx)', {\n cwd,\n absolute: true,\n dot: true,\n });\n}\n\n/**\n * Gets the +middleware file for a given directory. In\n * @param cwd\n */\nexport function getMiddlewareForDirectory(cwd: string): string | null {\n const files = globSync('+middleware.@(ts|tsx|js|jsx)', {\n cwd,\n absolute: true,\n dot: true,\n });\n\n if (files.length === 0) return null;\n\n if (files.length > 1) {\n // In development, throw an error if there are multiple root-level middleware files\n if (process.env.NODE_ENV !== 'production') {\n const relativePaths = files.map((f) => './' + path.relative(cwd, f)).sort();\n throw new Error(\n `Only one middleware file is allowed. Keep one of the conflicting files: ${relativePaths.map((p) => `\"${p}\"`).join(' or ')}`\n );\n }\n }\n\n return files[0]!;\n}\n\n// Used to emulate a context module, but way faster. TODO: May need to adjust the extensions to stay in sync with Metro.\nexport function getRoutePaths(cwd: string) {\n return globSync('**/*.@(ts|tsx|js|jsx)', {\n cwd,\n dot: true,\n }).map((p) => './' + normalizePaths(p));\n}\n\nfunction normalizePaths(p: string) {\n return p.replace(/\\\\/g, '/');\n}\n\nlet hasWarnedAboutApiRouteOutput = false;\nlet hasWarnedAboutMiddlewareOutput = false;\n\nexport function hasWarnedAboutApiRoutes() {\n return hasWarnedAboutApiRouteOutput;\n}\n\nexport function hasWarnedAboutMiddleware() {\n return hasWarnedAboutMiddlewareOutput;\n}\n\nexport function warnInvalidWebOutput() {\n if (!hasWarnedAboutApiRouteOutput) {\n Log.warn(\n chalk.yellow`Using API routes requires the {bold web.output} to be set to {bold \"server\"} in the project {bold app.json}. ${learnMore(\n 'https://docs.expo.dev/router/reference/api-routes/'\n )}`\n );\n }\n\n hasWarnedAboutApiRouteOutput = true;\n}\n\nexport function warnInvalidMiddlewareOutput() {\n if (!hasWarnedAboutMiddlewareOutput) {\n Log.warn(\n chalk.yellow`Using middleware requires the {bold web.output} to be set to {bold \"server\"} in the project {bold app.json}. ${learnMore(\n 'https://docs.expo.dev/router/reference/api-routes/'\n )}`\n );\n }\n\n hasWarnedAboutMiddlewareOutput = true;\n}\n\nexport function warnInvalidMiddlewareMatcherSettings(matcher: MiddlewareMatcher) {\n const validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];\n\n // Ensure methods are valid HTTP methods\n if (matcher.methods) {\n if (!Array.isArray(matcher.methods)) {\n Log.error(\n chalk.red`Middleware matcher methods must be an array of valid HTTP methods. Supported methods are: ${validMethods.join(', ')}`\n );\n } else {\n for (const method of matcher.methods) {\n if (!validMethods.includes(method)) {\n Log.error(\n chalk.red`Invalid middleware HTTP method: ${method}. Supported methods are: ${validMethods.join(', ')}`\n );\n }\n }\n }\n }\n\n // Ensure patterns are either a string or RegExp\n if (matcher.patterns) {\n const patterns = Array.isArray(matcher.patterns) ? matcher.patterns : [matcher.patterns];\n for (const pattern of patterns) {\n if (typeof pattern !== 'string' && !(pattern instanceof RegExp)) {\n Log.error(\n chalk.red`Middleware matcher patterns must be strings or regular expressions. Received: ${String(\n pattern\n )}`\n );\n }\n\n if (typeof pattern === 'string' && !pattern.startsWith('/')) {\n Log.error(\n chalk.red`String patterns in middleware matcher must start with '/'. Received: ${pattern}`\n );\n }\n }\n }\n}\n"],"names":["getApiRoutesForDirectory","getAppRouterRelativeEntryPath","getMiddlewareForDirectory","getRoutePaths","getRouterDirectory","getRouterDirectoryModuleIdWithManifest","hasWarnedAboutApiRoutes","hasWarnedAboutMiddleware","isApiRouteConvention","warnInvalidMiddlewareMatcherSettings","warnInvalidMiddlewareOutput","warnInvalidWebOutput","debug","require","projectRoot","routerDirectory","routerEntry","resolveFrom","silent","getFallbackEntryRoot","undefined","appFolder","path","join","appRoot","relative","dirname","expoRoot","exp","configured","extra","router","root","toPosixPath","absolute","isAbsolute","resolve","isPathInside","CommandError","hasWarnedAboutSrcDir","logSrcDir","Log","log","chalk","gray","directoryExistsSync","name","test","cwd","globSync","dot","files","length","process","env","NODE_ENV","relativePaths","map","f","sort","Error","p","normalizePaths","replace","hasWarnedAboutApiRouteOutput","hasWarnedAboutMiddlewareOutput","warn","yellow","learnMore","matcher","validMethods","methods","Array","isArray","error","red","method","includes","patterns","pattern","RegExp","String","startsWith"],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get OpenEndpoint () {
13
+ return OpenEndpoint;
14
+ },
15
+ get OpenMiddleware () {
16
+ return OpenMiddleware;
17
+ }
18
+ });
19
+ const _ExpoMiddleware = require("./ExpoMiddleware");
20
+ const _resolvePlatform = require("./resolvePlatform");
21
+ const _net = require("../../../utils/net");
22
+ const OpenEndpoint = '/_expo/open';
23
+ class OpenMiddleware extends _ExpoMiddleware.ExpoMiddleware {
24
+ constructor(projectRoot, options){
25
+ super(projectRoot, [
26
+ OpenEndpoint
27
+ ]), this.options = options;
28
+ }
29
+ async handleRequestAsync(req, res) {
30
+ (0, _ExpoMiddleware.disableResponseCache)(res);
31
+ res.setHeader('Content-Type', 'application/json');
32
+ const method = (req.method ?? 'GET').toUpperCase();
33
+ const searchParams = new URL(req.url ?? '', 'http://localhost').searchParams;
34
+ const platformParam = (0, _resolvePlatform.parsePlatformHeader)(req);
35
+ const platform = normalizePlatform(platformParam);
36
+ const runtimeParam = searchParams.get('runtime') ?? undefined;
37
+ const normalizedRuntime = runtimeParam ? normalizeRequestedRuntime(runtimeParam) : 'default';
38
+ if (platformParam && !platform) {
39
+ sendError(res, 400, {
40
+ code: 'INVALID_PLATFORM',
41
+ error: `Unsupported "platform" value "${platformParam}". Must be "ios", "android", or "web".`
42
+ });
43
+ return;
44
+ }
45
+ if (runtimeParam && !normalizedRuntime) {
46
+ sendError(res, 400, {
47
+ code: 'INVALID_RUNTIME',
48
+ error: `Unsupported "runtime" value "${runtimeParam}". Must be "default", "expo", "custom", or "unknown".`
49
+ });
50
+ return;
51
+ }
52
+ const runtime = normalizedRuntime ?? 'default';
53
+ if (method === 'POST') {
54
+ const sameDeviceError = assertSameDevice(req);
55
+ if (sameDeviceError) {
56
+ sendError(res, 403, sameDeviceError);
57
+ return;
58
+ }
59
+ const sameOriginError = assertSameOrigin(req, this.options.serverBaseUrl);
60
+ if (sameOriginError) {
61
+ sendError(res, 403, sameOriginError);
62
+ return;
63
+ }
64
+ if (!platform) {
65
+ sendError(res, 400, {
66
+ code: 'MISSING_PLATFORM',
67
+ error: `POST /_expo/open requires a platform. Pass it as the "platform" query param or "expo-platform" header. Must be "ios", "android", or "web".`
68
+ });
69
+ return;
70
+ }
71
+ const support = this.options.getHostSupport(platform);
72
+ if (!support.canOpen) {
73
+ sendError(res, 501, {
74
+ code: 'HOST_CANNOT_OPEN_PLATFORM',
75
+ platform,
76
+ error: `Cannot open the project on ${platform} from this dev server host.`,
77
+ details: (support.reason ? support.reason + ' ' : '') + `Use GET /_expo/open?platform=${platform} to retrieve the deep link, then launch it from a host that supports ${platform} or hand it to a remote preview service.`
78
+ });
79
+ return;
80
+ }
81
+ try {
82
+ const result = await this.options.open({
83
+ platform
84
+ });
85
+ res.statusCode = 200;
86
+ res.end(JSON.stringify(result));
87
+ } catch (error) {
88
+ sendError(res, 500, {
89
+ code: typeof (error == null ? void 0 : error.code) === 'string' ? error.code : 'OPEN_FAILED',
90
+ platform,
91
+ error: `Failed to open the project on ${platform}.`,
92
+ details: (typeof (error == null ? void 0 : error.message) === 'string' ? error.message : String(error)) + ` Check the dev server logs for more detail, or use GET /_expo/open?platform=${platform} to launch the deep link from another environment.`
93
+ });
94
+ }
95
+ return;
96
+ }
97
+ if (method !== 'GET' && method !== 'HEAD') {
98
+ res.setHeader('Allow', 'GET, HEAD, POST');
99
+ sendError(res, 405, {
100
+ code: 'METHOD_NOT_ALLOWED',
101
+ error: `Method "${method}" not allowed. Use GET to inspect, POST to open.`
102
+ });
103
+ return;
104
+ }
105
+ const info = await this.options.getInfo({
106
+ platform,
107
+ runtime
108
+ });
109
+ res.statusCode = 200;
110
+ res.end(JSON.stringify(info));
111
+ }
112
+ }
113
+ function normalizePlatform(p) {
114
+ return p === 'ios' || p === 'android' || p === 'web' ? p : null;
115
+ }
116
+ function normalizeRequestedRuntime(r) {
117
+ return r === 'default' || r === 'expo' || r === 'custom' || r === 'unknown' ? r : null;
118
+ }
119
+ function sendError(res, statusCode, body) {
120
+ res.statusCode = statusCode;
121
+ res.end(JSON.stringify(body));
122
+ }
123
+ function assertSameDevice(req) {
124
+ if ((0, _net.isLocalSocket)(req.socket)) {
125
+ return null;
126
+ }
127
+ return {
128
+ code: 'REMOTE_DEVICE_FORBIDDEN',
129
+ error: 'POST /_expo/open is restricted to same-device requests.',
130
+ details: `The dev server only opens the project for clients connected over the loopback interface ` + `so a device on the LAN (or a tunnel client) can't launch the app on the developer's machine. ` + `Issue the POST from the dev server's host, or use GET /_expo/open to retrieve the deep link and open it from the remote device.`
131
+ };
132
+ }
133
+ function assertSameOrigin(req, serverBaseUrl) {
134
+ var _req_headers;
135
+ if ((0, _net.isMatchingOrigin)(req, serverBaseUrl)) {
136
+ return null;
137
+ }
138
+ const origin = firstHeader((_req_headers = req.headers) == null ? void 0 : _req_headers.origin) ?? 'unknown';
139
+ return {
140
+ code: 'CROSS_ORIGIN_FORBIDDEN',
141
+ error: 'POST /_expo/open is restricted to same-origin requests.',
142
+ details: `Request origin "${origin}" does not match the dev server "${serverBaseUrl}". This protects the dev server from cross-origin scripts that might try to launch the app without the developer's consent. Issue POST requests from the dev server's origin (or from a non-browser client), or use GET /_expo/open to retrieve the deep link and open it yourself.`
143
+ };
144
+ }
145
+ function firstHeader(value) {
146
+ if (Array.isArray(value)) return value[0];
147
+ return value ?? undefined;
148
+ }
149
+
150
+ //# sourceMappingURL=OpenMiddleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/start/server/middleware/OpenMiddleware.ts"],"sourcesContent":["import { disableResponseCache, ExpoMiddleware } from './ExpoMiddleware';\nimport { parsePlatformHeader } from './resolvePlatform';\nimport type { ServerRequest, ServerResponse } from './server.types';\nimport { isLocalSocket, isMatchingOrigin } from '../../../utils/net';\n\nexport const OpenEndpoint = '/_expo/open';\n\n/**\n * Resolved runtime returned by the server. Omitted when the URL is a disambiguation page (the\n * actual runtime — Expo Go vs. dev build — isn't decided until the device picks). Matches what\n * the CLI does for `i`/`a` when the project supports both Expo Go and a development build.\n */\nexport type OpenRuntime = 'expo' | 'custom' | 'web';\n\n/**\n * Runtime that a caller can request.\n * - `default` mirrors the CLI's `i`/`a` resolution.\n * - `expo` / `custom` force a direct deep link, bypassing disambiguation.\n * - `unknown` forces the disambiguation/interstitial page even when the CLI would resolve\n * directly. Useful when the caller wants the device (rather than the dev server) to decide.\n */\nexport type OpenRequestedRuntime = 'expo' | 'custom' | 'unknown' | 'default';\n\n/** Subset of {@link OpenRuntime} that represents native deep-link choices (not how to deliver them). */\nexport type OpenNativeRuntime = 'expo' | 'custom';\n\n/** Platform supported by the open endpoint. */\nexport type OpenPlatform = 'ios' | 'android' | 'web';\n\n/** Whether the dev server's host machine can launch the project on a given platform. */\nexport interface OpenHostSupportEntry {\n /** `true` when the host machine is expected to be able to open the platform locally. */\n canOpen: boolean;\n /** Human-readable explanation when `canOpen` is `false`. */\n reason?: string;\n}\n\n/** Per-platform open info — present whether the caller asked for one platform or for discovery. */\nexport interface OpenPlatformInfo {\n /**\n * Concrete runtime that the URL targets. `undefined` when the URL is a disambiguation page —\n * the device decides between Expo Go and the dev build after the user picks.\n */\n runtime?: OpenRuntime;\n /** Deep link (native), disambiguation HTML page (when `runtime` is omitted), or dev server URL (web). `null` when no URL scheme is configured for `runtime: 'custom'`. */\n url: string | null;\n /**\n * Native application identifier (iOS bundle identifier / Android package name) used to detect\n * whether the project is already installed on a target device. `null` when the platform has no\n * concept of an app ID (web), when the project's config is missing the identifier, or when\n * resolution failed. Useful for distributed preview systems that need to confirm a build is\n * present before opening a deep link.\n */\n appId: string | null;\n}\n\n/** Project-level metadata returned on every GET. */\ninterface OpenProjectMeta {\n /** URL scheme used for development build deep links (e.g. `myapp`). `null` when none is configured. */\n scheme: string | null;\n /**\n * Native runtimes the project can target. `['expo']` for Expo Go only, `['custom']` for a dev\n * client only, `['expo', 'custom']` when both are configured — in that case the caller should\n * either pick one explicitly or rely on `runtime: 'default'` (which mirrors the CLI's\n * disambiguation behavior).\n */\n availableRuntimes: OpenNativeRuntime[];\n}\n\n/** GET `/_expo/open?platform=…` — focused per-platform response. */\nexport interface OpenSinglePlatformResult extends OpenProjectMeta, OpenPlatformInfo {}\n\n/** GET `/_expo/open` — discovery response with all platforms. */\nexport interface OpenDiscoveryResult extends OpenProjectMeta {\n platforms: Record<OpenPlatform, OpenPlatformInfo>;\n}\n\nexport type OpenInfoResult = OpenSinglePlatformResult | OpenDiscoveryResult;\n\n/** Result of a POST to `/_expo/open`. */\nexport interface OpenActionResult {\n platform: OpenPlatform;\n runtime: OpenRuntime;\n /** Deep link that was opened on the local device. */\n url: string;\n}\n\nexport interface OpenMiddlewareOptions {\n /**\n * Dev server base URL (e.g. `http://localhost:8081`). Used for the POST same-origin CSRF\n * check — requests whose `Origin` header doesn't match this URL's host are rejected.\n */\n serverBaseUrl: string;\n /** Compute the dry-run information for the requested platform + runtime. */\n getInfo: (props: {\n platform: OpenPlatform | null;\n runtime: OpenRequestedRuntime;\n }) => Promise<OpenInfoResult>;\n /** Open the project locally on the requested platform — equivalent to pressing `i` / `a` in the terminal UI. */\n open: (props: { platform: OpenPlatform }) => Promise<OpenActionResult>;\n /** Whether the host can launch a given platform. */\n getHostSupport: (platform: OpenPlatform) => OpenHostSupportEntry;\n}\n\nexport class OpenMiddleware extends ExpoMiddleware {\n constructor(\n projectRoot: string,\n protected options: OpenMiddlewareOptions\n ) {\n super(projectRoot, [OpenEndpoint]);\n }\n\n async handleRequestAsync(req: ServerRequest, res: ServerResponse): Promise<void> {\n disableResponseCache(res);\n res.setHeader('Content-Type', 'application/json');\n\n const method = (req.method ?? 'GET').toUpperCase();\n const searchParams = new URL(req.url ?? '', 'http://localhost').searchParams;\n const platformParam = parsePlatformHeader(req);\n const platform = normalizePlatform(platformParam);\n const runtimeParam = searchParams.get('runtime') ?? undefined;\n const normalizedRuntime = runtimeParam ? normalizeRequestedRuntime(runtimeParam) : 'default';\n\n if (platformParam && !platform) {\n sendError(res, 400, {\n code: 'INVALID_PLATFORM',\n error: `Unsupported \"platform\" value \"${platformParam}\". Must be \"ios\", \"android\", or \"web\".`,\n });\n return;\n }\n\n if (runtimeParam && !normalizedRuntime) {\n sendError(res, 400, {\n code: 'INVALID_RUNTIME',\n error: `Unsupported \"runtime\" value \"${runtimeParam}\". Must be \"default\", \"expo\", \"custom\", or \"unknown\".`,\n });\n return;\n }\n const runtime: OpenRequestedRuntime = normalizedRuntime ?? 'default';\n\n if (method === 'POST') {\n const sameDeviceError = assertSameDevice(req);\n if (sameDeviceError) {\n sendError(res, 403, sameDeviceError);\n return;\n }\n\n const sameOriginError = assertSameOrigin(req, this.options.serverBaseUrl);\n if (sameOriginError) {\n sendError(res, 403, sameOriginError);\n return;\n }\n\n if (!platform) {\n sendError(res, 400, {\n code: 'MISSING_PLATFORM',\n error: `POST /_expo/open requires a platform. Pass it as the \"platform\" query param or \"expo-platform\" header. Must be \"ios\", \"android\", or \"web\".`,\n });\n return;\n }\n\n const support = this.options.getHostSupport(platform);\n if (!support.canOpen) {\n sendError(res, 501, {\n code: 'HOST_CANNOT_OPEN_PLATFORM',\n platform,\n error: `Cannot open the project on ${platform} from this dev server host.`,\n details:\n (support.reason ? support.reason + ' ' : '') +\n `Use GET /_expo/open?platform=${platform} to retrieve the deep link, then launch it from a host that supports ${platform} or hand it to a remote preview service.`,\n });\n return;\n }\n\n try {\n const result = await this.options.open({ platform });\n res.statusCode = 200;\n res.end(JSON.stringify(result));\n } catch (error: any) {\n sendError(res, 500, {\n code: typeof error?.code === 'string' ? error.code : 'OPEN_FAILED',\n platform,\n error: `Failed to open the project on ${platform}.`,\n details:\n (typeof error?.message === 'string' ? error.message : String(error)) +\n ` Check the dev server logs for more detail, or use GET /_expo/open?platform=${platform} to launch the deep link from another environment.`,\n });\n }\n return;\n }\n\n if (method !== 'GET' && method !== 'HEAD') {\n res.setHeader('Allow', 'GET, HEAD, POST');\n sendError(res, 405, {\n code: 'METHOD_NOT_ALLOWED',\n error: `Method \"${method}\" not allowed. Use GET to inspect, POST to open.`,\n });\n return;\n }\n\n const info = await this.options.getInfo({ platform, runtime });\n res.statusCode = 200;\n res.end(JSON.stringify(info));\n }\n}\n\nfunction normalizePlatform(p: string | null): OpenPlatform | null {\n return p === 'ios' || p === 'android' || p === 'web' ? p : null;\n}\n\nfunction normalizeRequestedRuntime(r: string | undefined): OpenRequestedRuntime | null {\n return r === 'default' || r === 'expo' || r === 'custom' || r === 'unknown' ? r : null;\n}\n\ninterface ErrorBody {\n code: string;\n error: string;\n platform?: OpenPlatform;\n details?: string;\n}\n\nfunction sendError(res: ServerResponse, statusCode: number, body: ErrorBody) {\n res.statusCode = statusCode;\n res.end(JSON.stringify(body));\n}\n\nfunction assertSameDevice(req: ServerRequest): ErrorBody | null {\n if (isLocalSocket(req.socket)) {\n return null;\n }\n return {\n code: 'REMOTE_DEVICE_FORBIDDEN',\n error: 'POST /_expo/open is restricted to same-device requests.',\n details:\n `The dev server only opens the project for clients connected over the loopback interface ` +\n `so a device on the LAN (or a tunnel client) can't launch the app on the developer's machine. ` +\n `Issue the POST from the dev server's host, or use GET /_expo/open to retrieve the deep link and open it from the remote device.`,\n };\n}\n\nfunction assertSameOrigin(req: ServerRequest, serverBaseUrl: string): ErrorBody | null {\n if (isMatchingOrigin(req, serverBaseUrl)) {\n return null;\n }\n const origin = firstHeader(req.headers?.origin) ?? 'unknown';\n return {\n code: 'CROSS_ORIGIN_FORBIDDEN',\n error: 'POST /_expo/open is restricted to same-origin requests.',\n details: `Request origin \"${origin}\" does not match the dev server \"${serverBaseUrl}\". This protects the dev server from cross-origin scripts that might try to launch the app without the developer's consent. Issue POST requests from the dev server's origin (or from a non-browser client), or use GET /_expo/open to retrieve the deep link and open it yourself.`,\n };\n}\n\nfunction firstHeader(value: string | string[] | undefined): string | undefined {\n if (Array.isArray(value)) return value[0];\n return value ?? undefined;\n}\n"],"names":["OpenEndpoint","OpenMiddleware","ExpoMiddleware","projectRoot","options","handleRequestAsync","req","res","disableResponseCache","setHeader","method","toUpperCase","searchParams","URL","url","platformParam","parsePlatformHeader","platform","normalizePlatform","runtimeParam","get","undefined","normalizedRuntime","normalizeRequestedRuntime","sendError","code","error","runtime","sameDeviceError","assertSameDevice","sameOriginError","assertSameOrigin","serverBaseUrl","support","getHostSupport","canOpen","details","reason","result","open","statusCode","end","JSON","stringify","message","String","info","getInfo","p","r","body","isLocalSocket","socket","isMatchingOrigin","origin","firstHeader","headers","value","Array","isArray"],"mappings":";;;;;;;;;;;QAKaA;eAAAA;;QAmGAC;eAAAA;;;gCAxGwC;iCACjB;qBAEY;AAEzC,MAAMD,eAAe;AAmGrB,MAAMC,uBAAuBC,8BAAc;IAChD,YACEC,WAAmB,EACnB,AAAUC,OAA8B,CACxC;QACA,KAAK,CAACD,aAAa;YAACH;SAAa,QAFvBI,UAAAA;IAGZ;IAEA,MAAMC,mBAAmBC,GAAkB,EAAEC,GAAmB,EAAiB;QAC/EC,IAAAA,oCAAoB,EAACD;QACrBA,IAAIE,SAAS,CAAC,gBAAgB;QAE9B,MAAMC,SAAS,AAACJ,CAAAA,IAAII,MAAM,IAAI,KAAI,EAAGC,WAAW;QAChD,MAAMC,eAAe,IAAIC,IAAIP,IAAIQ,GAAG,IAAI,IAAI,oBAAoBF,YAAY;QAC5E,MAAMG,gBAAgBC,IAAAA,oCAAmB,EAACV;QAC1C,MAAMW,WAAWC,kBAAkBH;QACnC,MAAMI,eAAeP,aAAaQ,GAAG,CAAC,cAAcC;QACpD,MAAMC,oBAAoBH,eAAeI,0BAA0BJ,gBAAgB;QAEnF,IAAIJ,iBAAiB,CAACE,UAAU;YAC9BO,UAAUjB,KAAK,KAAK;gBAClBkB,MAAM;gBACNC,OAAO,CAAC,8BAA8B,EAAEX,cAAc,sCAAsC,CAAC;YAC/F;YACA;QACF;QAEA,IAAII,gBAAgB,CAACG,mBAAmB;YACtCE,UAAUjB,KAAK,KAAK;gBAClBkB,MAAM;gBACNC,OAAO,CAAC,6BAA6B,EAAEP,aAAa,qDAAqD,CAAC;YAC5G;YACA;QACF;QACA,MAAMQ,UAAgCL,qBAAqB;QAE3D,IAAIZ,WAAW,QAAQ;YACrB,MAAMkB,kBAAkBC,iBAAiBvB;YACzC,IAAIsB,iBAAiB;gBACnBJ,UAAUjB,KAAK,KAAKqB;gBACpB;YACF;YAEA,MAAME,kBAAkBC,iBAAiBzB,KAAK,IAAI,CAACF,OAAO,CAAC4B,aAAa;YACxE,IAAIF,iBAAiB;gBACnBN,UAAUjB,KAAK,KAAKuB;gBACpB;YACF;YAEA,IAAI,CAACb,UAAU;gBACbO,UAAUjB,KAAK,KAAK;oBAClBkB,MAAM;oBACNC,OAAO,CAAC,0IAA0I,CAAC;gBACrJ;gBACA;YACF;YAEA,MAAMO,UAAU,IAAI,CAAC7B,OAAO,CAAC8B,cAAc,CAACjB;YAC5C,IAAI,CAACgB,QAAQE,OAAO,EAAE;gBACpBX,UAAUjB,KAAK,KAAK;oBAClBkB,MAAM;oBACNR;oBACAS,OAAO,CAAC,2BAA2B,EAAET,SAAS,2BAA2B,CAAC;oBAC1EmB,SACE,AAACH,CAAAA,QAAQI,MAAM,GAAGJ,QAAQI,MAAM,GAAG,MAAM,EAAC,IAC1C,CAAC,6BAA6B,EAAEpB,SAAS,qEAAqE,EAAEA,SAAS,wCAAwC,CAAC;gBACtK;gBACA;YACF;YAEA,IAAI;gBACF,MAAMqB,SAAS,MAAM,IAAI,CAAClC,OAAO,CAACmC,IAAI,CAAC;oBAAEtB;gBAAS;gBAClDV,IAAIiC,UAAU,GAAG;gBACjBjC,IAAIkC,GAAG,CAACC,KAAKC,SAAS,CAACL;YACzB,EAAE,OAAOZ,OAAY;gBACnBF,UAAUjB,KAAK,KAAK;oBAClBkB,MAAM,QAAOC,yBAAAA,MAAOD,IAAI,MAAK,WAAWC,MAAMD,IAAI,GAAG;oBACrDR;oBACAS,OAAO,CAAC,8BAA8B,EAAET,SAAS,CAAC,CAAC;oBACnDmB,SACE,AAAC,CAAA,QAAOV,yBAAAA,MAAOkB,OAAO,MAAK,WAAWlB,MAAMkB,OAAO,GAAGC,OAAOnB,MAAK,IAClE,CAAC,4EAA4E,EAAET,SAAS,kDAAkD,CAAC;gBAC/I;YACF;YACA;QACF;QAEA,IAAIP,WAAW,SAASA,WAAW,QAAQ;YACzCH,IAAIE,SAAS,CAAC,SAAS;YACvBe,UAAUjB,KAAK,KAAK;gBAClBkB,MAAM;gBACNC,OAAO,CAAC,QAAQ,EAAEhB,OAAO,gDAAgD,CAAC;YAC5E;YACA;QACF;QAEA,MAAMoC,OAAO,MAAM,IAAI,CAAC1C,OAAO,CAAC2C,OAAO,CAAC;YAAE9B;YAAUU;QAAQ;QAC5DpB,IAAIiC,UAAU,GAAG;QACjBjC,IAAIkC,GAAG,CAACC,KAAKC,SAAS,CAACG;IACzB;AACF;AAEA,SAAS5B,kBAAkB8B,CAAgB;IACzC,OAAOA,MAAM,SAASA,MAAM,aAAaA,MAAM,QAAQA,IAAI;AAC7D;AAEA,SAASzB,0BAA0B0B,CAAqB;IACtD,OAAOA,MAAM,aAAaA,MAAM,UAAUA,MAAM,YAAYA,MAAM,YAAYA,IAAI;AACpF;AASA,SAASzB,UAAUjB,GAAmB,EAAEiC,UAAkB,EAAEU,IAAe;IACzE3C,IAAIiC,UAAU,GAAGA;IACjBjC,IAAIkC,GAAG,CAACC,KAAKC,SAAS,CAACO;AACzB;AAEA,SAASrB,iBAAiBvB,GAAkB;IAC1C,IAAI6C,IAAAA,kBAAa,EAAC7C,IAAI8C,MAAM,GAAG;QAC7B,OAAO;IACT;IACA,OAAO;QACL3B,MAAM;QACNC,OAAO;QACPU,SACE,CAAC,wFAAwF,CAAC,GAC1F,CAAC,6FAA6F,CAAC,GAC/F,CAAC,+HAA+H,CAAC;IACrI;AACF;AAEA,SAASL,iBAAiBzB,GAAkB,EAAE0B,aAAqB;QAItC1B;IAH3B,IAAI+C,IAAAA,qBAAgB,EAAC/C,KAAK0B,gBAAgB;QACxC,OAAO;IACT;IACA,MAAMsB,SAASC,aAAYjD,eAAAA,IAAIkD,OAAO,qBAAXlD,aAAagD,MAAM,KAAK;IACnD,OAAO;QACL7B,MAAM;QACNC,OAAO;QACPU,SAAS,CAAC,gBAAgB,EAAEkB,OAAO,iCAAiC,EAAEtB,cAAc,mRAAmR,CAAC;IAC1W;AACF;AAEA,SAASuB,YAAYE,KAAoC;IACvD,IAAIC,MAAMC,OAAO,CAACF,QAAQ,OAAOA,KAAK,CAAC,EAAE;IACzC,OAAOA,SAASpC;AAClB"}
@@ -2,9 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "RuntimeRedirectMiddleware", {
6
- enumerable: true,
7
- get: function() {
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get LinkEndpoint () {
13
+ return LinkEndpoint;
14
+ },
15
+ get RuntimeRedirectMiddleware () {
8
16
  return RuntimeRedirectMiddleware;
9
17
  }
10
18
  });
@@ -60,10 +68,11 @@ function _interop_require_wildcard(obj, nodeInterop) {
60
68
  return newObj;
61
69
  }
62
70
  const debug = require('debug')('expo:start:server:middleware:runtimeRedirect');
71
+ const LinkEndpoint = '/_expo/link';
63
72
  class RuntimeRedirectMiddleware extends _ExpoMiddleware.ExpoMiddleware {
64
73
  constructor(projectRoot, options){
65
74
  super(projectRoot, [
66
- '/_expo/link'
75
+ LinkEndpoint
67
76
  ]), this.projectRoot = projectRoot, this.options = options;
68
77
  }
69
78
  async handleRequestAsync(req, res) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/middleware/RuntimeRedirectMiddleware.ts"],"sourcesContent":["import { parse } from 'url';\n\nimport { disableResponseCache, ExpoMiddleware } from './ExpoMiddleware';\nimport type { RuntimePlatform } from './resolvePlatform';\nimport {\n assertMissingRuntimePlatform,\n assertRuntimePlatform,\n parsePlatformHeader,\n resolvePlatformFromUserAgentHeader,\n} from './resolvePlatform';\nimport type { ServerRequest, ServerResponse } from './server.types';\nimport * as Log from '../../../log';\n\nconst debug = require('debug')(\n 'expo:start:server:middleware:runtimeRedirect'\n) as typeof console.log;\n\n/** Runtime to target: expo = Expo Go, custom = Dev Client. */\ntype RuntimeTarget = 'expo' | 'custom';\n\nexport type DeepLinkHandler = (props: {\n runtime: RuntimeTarget;\n platform: RuntimePlatform;\n}) => void | Promise<void>;\n\nexport class RuntimeRedirectMiddleware extends ExpoMiddleware {\n constructor(\n protected projectRoot: string,\n protected options: {\n onDeepLink?: DeepLinkHandler;\n getLocation: (props: { runtime: RuntimeTarget }) => string | null | undefined;\n }\n ) {\n super(projectRoot, ['/_expo/link']);\n }\n\n async handleRequestAsync(req: ServerRequest, res: ServerResponse): Promise<void> {\n const { query } = parse(req.url!, true);\n const isDevClient = query['choice'] === 'expo-dev-client';\n const platform = parsePlatformHeader(req) ?? resolvePlatformFromUserAgentHeader(req);\n assertMissingRuntimePlatform(platform);\n assertRuntimePlatform(platform);\n const runtime = isDevClient ? 'custom' : 'expo';\n\n debug(`props:`, { platform, runtime });\n\n this.options.onDeepLink?.({ runtime, platform });\n\n const redirect = this.options.getLocation({ runtime });\n if (!redirect) {\n Log.warn(\n `[redirect middleware]: Unable to determine redirect location for runtime '${runtime}' and platform '${platform}'`\n );\n res.statusCode = 404;\n res.end();\n return;\n }\n debug('Redirect ->', redirect);\n res.setHeader('Location', redirect);\n\n // Disable caching\n disableResponseCache(res);\n\n // 'Temporary Redirect'\n res.statusCode = 307;\n res.end();\n }\n}\n"],"names":["RuntimeRedirectMiddleware","debug","require","ExpoMiddleware","projectRoot","options","handleRequestAsync","req","res","query","parse","url","isDevClient","platform","parsePlatformHeader","resolvePlatformFromUserAgentHeader","assertMissingRuntimePlatform","assertRuntimePlatform","runtime","onDeepLink","redirect","getLocation","Log","warn","statusCode","end","setHeader","disableResponseCache"],"mappings":";;;;+BAyBaA;;;eAAAA;;;;yBAzBS;;;;;;gCAE+B;iCAO9C;6DAEc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAErB,MAAMC,QAAQC,QAAQ,SACpB;AAWK,MAAMF,kCAAkCG,8BAAc;IAC3D,YACE,AAAUC,WAAmB,EAC7B,AAAUC,OAGT,CACD;QACA,KAAK,CAACD,aAAa;YAAC;SAAc,QANxBA,cAAAA,kBACAC,UAAAA;IAMZ;IAEA,MAAMC,mBAAmBC,GAAkB,EAAEC,GAAmB,EAAiB;QAC/E,MAAM,EAAEC,KAAK,EAAE,GAAGC,IAAAA,YAAK,EAACH,IAAII,GAAG,EAAG;QAClC,MAAMC,cAAcH,KAAK,CAAC,SAAS,KAAK;QACxC,MAAMI,WAAWC,IAAAA,oCAAmB,EAACP,QAAQQ,IAAAA,mDAAkC,EAACR;QAChFS,IAAAA,6CAA4B,EAACH;QAC7BI,IAAAA,sCAAqB,EAACJ;QACtB,MAAMK,UAAUN,cAAc,WAAW;QAEzCX,MAAM,CAAC,MAAM,CAAC,EAAE;YAAEY;YAAUK;QAAQ;QAEpC,IAAI,CAACb,OAAO,CAACc,UAAU,oBAAvB,IAAI,CAACd,OAAO,CAACc,UAAU,MAAvB,IAAI,CAACd,OAAO,EAAc;YAAEa;YAASL;QAAS;QAE9C,MAAMO,WAAW,IAAI,CAACf,OAAO,CAACgB,WAAW,CAAC;YAAEH;QAAQ;QACpD,IAAI,CAACE,UAAU;YACbE,KAAIC,IAAI,CACN,CAAC,0EAA0E,EAAEL,QAAQ,gBAAgB,EAAEL,SAAS,CAAC,CAAC;YAEpHL,IAAIgB,UAAU,GAAG;YACjBhB,IAAIiB,GAAG;YACP;QACF;QACAxB,MAAM,eAAemB;QACrBZ,IAAIkB,SAAS,CAAC,YAAYN;QAE1B,kBAAkB;QAClBO,IAAAA,oCAAoB,EAACnB;QAErB,uBAAuB;QACvBA,IAAIgB,UAAU,GAAG;QACjBhB,IAAIiB,GAAG;IACT;AACF"}
1
+ {"version":3,"sources":["../../../../../src/start/server/middleware/RuntimeRedirectMiddleware.ts"],"sourcesContent":["import { parse } from 'url';\n\nimport { disableResponseCache, ExpoMiddleware } from './ExpoMiddleware';\nimport type { RuntimePlatform } from './resolvePlatform';\nimport {\n assertMissingRuntimePlatform,\n assertRuntimePlatform,\n parsePlatformHeader,\n resolvePlatformFromUserAgentHeader,\n} from './resolvePlatform';\nimport type { ServerRequest, ServerResponse } from './server.types';\nimport * as Log from '../../../log';\n\nconst debug = require('debug')(\n 'expo:start:server:middleware:runtimeRedirect'\n) as typeof console.log;\n\nexport const LinkEndpoint = '/_expo/link';\n\n/** Runtime to target: expo = Expo Go, custom = Dev Client. */\ntype RuntimeTarget = 'expo' | 'custom';\n\nexport type DeepLinkHandler = (props: {\n runtime: RuntimeTarget;\n platform: RuntimePlatform;\n}) => void | Promise<void>;\n\nexport class RuntimeRedirectMiddleware extends ExpoMiddleware {\n constructor(\n protected projectRoot: string,\n protected options: {\n onDeepLink?: DeepLinkHandler;\n getLocation: (props: { runtime: RuntimeTarget }) => string | null | undefined;\n }\n ) {\n super(projectRoot, [LinkEndpoint]);\n }\n\n async handleRequestAsync(req: ServerRequest, res: ServerResponse): Promise<void> {\n const { query } = parse(req.url!, true);\n const isDevClient = query['choice'] === 'expo-dev-client';\n const platform = parsePlatformHeader(req) ?? resolvePlatformFromUserAgentHeader(req);\n assertMissingRuntimePlatform(platform);\n assertRuntimePlatform(platform);\n const runtime = isDevClient ? 'custom' : 'expo';\n\n debug(`props:`, { platform, runtime });\n\n this.options.onDeepLink?.({ runtime, platform });\n\n const redirect = this.options.getLocation({ runtime });\n if (!redirect) {\n Log.warn(\n `[redirect middleware]: Unable to determine redirect location for runtime '${runtime}' and platform '${platform}'`\n );\n res.statusCode = 404;\n res.end();\n return;\n }\n debug('Redirect ->', redirect);\n res.setHeader('Location', redirect);\n\n // Disable caching\n disableResponseCache(res);\n\n // 'Temporary Redirect'\n res.statusCode = 307;\n res.end();\n }\n}\n"],"names":["LinkEndpoint","RuntimeRedirectMiddleware","debug","require","ExpoMiddleware","projectRoot","options","handleRequestAsync","req","res","query","parse","url","isDevClient","platform","parsePlatformHeader","resolvePlatformFromUserAgentHeader","assertMissingRuntimePlatform","assertRuntimePlatform","runtime","onDeepLink","redirect","getLocation","Log","warn","statusCode","end","setHeader","disableResponseCache"],"mappings":";;;;;;;;;;;QAiBaA;eAAAA;;QAUAC;eAAAA;;;;yBA3BS;;;;;;gCAE+B;iCAO9C;6DAEc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAErB,MAAMC,QAAQC,QAAQ,SACpB;AAGK,MAAMH,eAAe;AAUrB,MAAMC,kCAAkCG,8BAAc;IAC3D,YACE,AAAUC,WAAmB,EAC7B,AAAUC,OAGT,CACD;QACA,KAAK,CAACD,aAAa;YAACL;SAAa,QANvBK,cAAAA,kBACAC,UAAAA;IAMZ;IAEA,MAAMC,mBAAmBC,GAAkB,EAAEC,GAAmB,EAAiB;QAC/E,MAAM,EAAEC,KAAK,EAAE,GAAGC,IAAAA,YAAK,EAACH,IAAII,GAAG,EAAG;QAClC,MAAMC,cAAcH,KAAK,CAAC,SAAS,KAAK;QACxC,MAAMI,WAAWC,IAAAA,oCAAmB,EAACP,QAAQQ,IAAAA,mDAAkC,EAACR;QAChFS,IAAAA,6CAA4B,EAACH;QAC7BI,IAAAA,sCAAqB,EAACJ;QACtB,MAAMK,UAAUN,cAAc,WAAW;QAEzCX,MAAM,CAAC,MAAM,CAAC,EAAE;YAAEY;YAAUK;QAAQ;QAEpC,IAAI,CAACb,OAAO,CAACc,UAAU,oBAAvB,IAAI,CAACd,OAAO,CAACc,UAAU,MAAvB,IAAI,CAACd,OAAO,EAAc;YAAEa;YAASL;QAAS;QAE9C,MAAMO,WAAW,IAAI,CAACf,OAAO,CAACgB,WAAW,CAAC;YAAEH;QAAQ;QACpD,IAAI,CAACE,UAAU;YACbE,KAAIC,IAAI,CACN,CAAC,0EAA0E,EAAEL,QAAQ,gBAAgB,EAAEL,SAAS,CAAC,CAAC;YAEpHL,IAAIgB,UAAU,GAAG;YACjBhB,IAAIiB,GAAG;YACP;QACF;QACAxB,MAAM,eAAemB;QACrBZ,IAAIkB,SAAS,CAAC,YAAYN;QAE1B,kBAAkB;QAClBO,IAAAA,oCAAoB,EAACnB;QAErB,uBAAuB;QACvBA,IAAIgB,UAAU,GAAG;QACjBhB,IAAIiB,GAAG;IACT;AACF"}
@@ -8,13 +8,6 @@ Object.defineProperty(exports, "ServeStaticMiddleware", {
8
8
  return ServeStaticMiddleware;
9
9
  }
10
10
  });
11
- function _path() {
12
- const data = /*#__PURE__*/ _interop_require_default(require("path"));
13
- _path = function() {
14
- return data;
15
- };
16
- return data;
17
- }
18
11
  function _send() {
19
12
  const data = /*#__PURE__*/ _interop_require_default(require("send"));
20
13
  _send = function() {
@@ -30,7 +23,7 @@ function _url() {
30
23
  return data;
31
24
  }
32
25
  const _resolvePlatform = require("./resolvePlatform");
33
- const _env = require("../../../utils/env");
26
+ const _publicFolder = require("../../../export/publicFolder");
34
27
  function _interop_require_default(obj) {
35
28
  return obj && obj.__esModule ? obj : {
36
29
  default: obj
@@ -42,7 +35,7 @@ class ServeStaticMiddleware {
42
35
  this.projectRoot = projectRoot;
43
36
  }
44
37
  getHandler() {
45
- const publicPath = _path().default.join(this.projectRoot, _env.env.EXPO_PUBLIC_FOLDER);
38
+ const publicPath = (0, _publicFolder.getPublicFolderPath)(this.projectRoot);
46
39
  debug(`Serving static files from:`, publicPath);
47
40
  const opts = {
48
41
  root: publicPath
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/middleware/ServeStaticMiddleware.ts"],"sourcesContent":["import path from 'path';\nimport send from 'send';\nimport { parse } from 'url';\n\nimport { parsePlatformHeader } from './resolvePlatform';\nimport type { ServerRequest, ServerResponse } from './server.types';\nimport { env } from '../../../utils/env';\n\nconst debug = require('debug')('expo:start:server:middleware:serveStatic') as typeof console.log;\n\n/**\n * Adds support for serving the files in the static `public/` folder to web apps.\n */\nexport class ServeStaticMiddleware {\n constructor(private projectRoot: string) {}\n getHandler() {\n const publicPath = path.join(this.projectRoot, env.EXPO_PUBLIC_FOLDER);\n\n debug(`Serving static files from:`, publicPath);\n const opts = {\n root: publicPath,\n };\n return (req: ServerRequest, res: ServerResponse, next: any) => {\n if (!req?.url || (req.method !== 'GET' && req.method !== 'HEAD')) {\n return next();\n }\n\n const platform = parsePlatformHeader(req);\n // Currently this is web-only\n if (platform && platform !== 'web') {\n return next();\n }\n\n const pathname = parse(req.url).pathname;\n if (!pathname) {\n return next();\n }\n\n debug(`Maybe serve static:`, pathname);\n const stream = send(req, pathname, opts);\n\n // add file listener for fallthrough\n let forwardError = false;\n stream.on('file', function onFile() {\n // once file is determined, always forward error\n forwardError = true;\n });\n\n // forward errors\n stream.on('error', function error(err: any) {\n if (forwardError || !(err.statusCode < 500)) {\n next(err);\n return;\n }\n\n next();\n });\n\n // pipe\n stream.pipe(res);\n };\n }\n}\n"],"names":["ServeStaticMiddleware","debug","require","projectRoot","getHandler","publicPath","path","join","env","EXPO_PUBLIC_FOLDER","opts","root","req","res","next","url","method","platform","parsePlatformHeader","pathname","parse","stream","send","forwardError","on","onFile","error","err","statusCode","pipe"],"mappings":";;;;+BAaaA;;;eAAAA;;;;gEAbI;;;;;;;gEACA;;;;;;;yBACK;;;;;;iCAEc;qBAEhB;;;;;;AAEpB,MAAMC,QAAQC,QAAQ,SAAS;AAKxB,MAAMF;IACX,YAAY,AAAQG,WAAmB,CAAE;aAArBA,cAAAA;IAAsB;IAC1CC,aAAa;QACX,MAAMC,aAAaC,eAAI,CAACC,IAAI,CAAC,IAAI,CAACJ,WAAW,EAAEK,QAAG,CAACC,kBAAkB;QAErER,MAAM,CAAC,0BAA0B,CAAC,EAAEI;QACpC,MAAMK,OAAO;YACXC,MAAMN;QACR;QACA,OAAO,CAACO,KAAoBC,KAAqBC;YAC/C,IAAI,EAACF,uBAAAA,IAAKG,GAAG,KAAKH,IAAII,MAAM,KAAK,SAASJ,IAAII,MAAM,KAAK,QAAS;gBAChE,OAAOF;YACT;YAEA,MAAMG,WAAWC,IAAAA,oCAAmB,EAACN;YACrC,6BAA6B;YAC7B,IAAIK,YAAYA,aAAa,OAAO;gBAClC,OAAOH;YACT;YAEA,MAAMK,WAAWC,IAAAA,YAAK,EAACR,IAAIG,GAAG,EAAEI,QAAQ;YACxC,IAAI,CAACA,UAAU;gBACb,OAAOL;YACT;YAEAb,MAAM,CAAC,mBAAmB,CAAC,EAAEkB;YAC7B,MAAME,SAASC,IAAAA,eAAI,EAACV,KAAKO,UAAUT;YAEnC,oCAAoC;YACpC,IAAIa,eAAe;YACnBF,OAAOG,EAAE,CAAC,QAAQ,SAASC;gBACzB,gDAAgD;gBAChDF,eAAe;YACjB;YAEA,iBAAiB;YACjBF,OAAOG,EAAE,CAAC,SAAS,SAASE,MAAMC,GAAQ;gBACxC,IAAIJ,gBAAgB,CAAEI,CAAAA,IAAIC,UAAU,GAAG,GAAE,GAAI;oBAC3Cd,KAAKa;oBACL;gBACF;gBAEAb;YACF;YAEA,OAAO;YACPO,OAAOQ,IAAI,CAAChB;QACd;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../../src/start/server/middleware/ServeStaticMiddleware.ts"],"sourcesContent":["import send from 'send';\nimport { parse } from 'url';\n\nimport { parsePlatformHeader } from './resolvePlatform';\nimport type { ServerRequest, ServerResponse } from './server.types';\nimport { getPublicFolderPath } from '../../../export/publicFolder';\n\nconst debug = require('debug')('expo:start:server:middleware:serveStatic') as typeof console.log;\n\n/**\n * Adds support for serving the files in the static `public/` folder to web apps.\n */\nexport class ServeStaticMiddleware {\n constructor(private projectRoot: string) {}\n getHandler() {\n const publicPath = getPublicFolderPath(this.projectRoot);\n\n debug(`Serving static files from:`, publicPath);\n const opts = {\n root: publicPath,\n };\n return (req: ServerRequest, res: ServerResponse, next: any) => {\n if (!req?.url || (req.method !== 'GET' && req.method !== 'HEAD')) {\n return next();\n }\n\n const platform = parsePlatformHeader(req);\n // Currently this is web-only\n if (platform && platform !== 'web') {\n return next();\n }\n\n const pathname = parse(req.url).pathname;\n if (!pathname) {\n return next();\n }\n\n debug(`Maybe serve static:`, pathname);\n const stream = send(req, pathname, opts);\n\n // add file listener for fallthrough\n let forwardError = false;\n stream.on('file', function onFile() {\n // once file is determined, always forward error\n forwardError = true;\n });\n\n // forward errors\n stream.on('error', function error(err: any) {\n if (forwardError || !(err.statusCode < 500)) {\n next(err);\n return;\n }\n\n next();\n });\n\n // pipe\n stream.pipe(res);\n };\n }\n}\n"],"names":["ServeStaticMiddleware","debug","require","projectRoot","getHandler","publicPath","getPublicFolderPath","opts","root","req","res","next","url","method","platform","parsePlatformHeader","pathname","parse","stream","send","forwardError","on","onFile","error","err","statusCode","pipe"],"mappings":";;;;+BAYaA;;;eAAAA;;;;gEAZI;;;;;;;yBACK;;;;;;iCAEc;8BAEA;;;;;;AAEpC,MAAMC,QAAQC,QAAQ,SAAS;AAKxB,MAAMF;IACX,YAAY,AAAQG,WAAmB,CAAE;aAArBA,cAAAA;IAAsB;IAC1CC,aAAa;QACX,MAAMC,aAAaC,IAAAA,iCAAmB,EAAC,IAAI,CAACH,WAAW;QAEvDF,MAAM,CAAC,0BAA0B,CAAC,EAAEI;QACpC,MAAME,OAAO;YACXC,MAAMH;QACR;QACA,OAAO,CAACI,KAAoBC,KAAqBC;YAC/C,IAAI,EAACF,uBAAAA,IAAKG,GAAG,KAAKH,IAAII,MAAM,KAAK,SAASJ,IAAII,MAAM,KAAK,QAAS;gBAChE,OAAOF;YACT;YAEA,MAAMG,WAAWC,IAAAA,oCAAmB,EAACN;YACrC,6BAA6B;YAC7B,IAAIK,YAAYA,aAAa,OAAO;gBAClC,OAAOH;YACT;YAEA,MAAMK,WAAWC,IAAAA,YAAK,EAACR,IAAIG,GAAG,EAAEI,QAAQ;YACxC,IAAI,CAACA,UAAU;gBACb,OAAOL;YACT;YAEAV,MAAM,CAAC,mBAAmB,CAAC,EAAEe;YAC7B,MAAME,SAASC,IAAAA,eAAI,EAACV,KAAKO,UAAUT;YAEnC,oCAAoC;YACpC,IAAIa,eAAe;YACnBF,OAAOG,EAAE,CAAC,QAAQ,SAASC;gBACzB,gDAAgD;gBAChDF,eAAe;YACjB;YAEA,iBAAiB;YACjBF,OAAOG,EAAE,CAAC,SAAS,SAASE,MAAMC,GAAQ;gBACxC,IAAIJ,gBAAgB,CAAEI,CAAAA,IAAIC,UAAU,GAAG,GAAE,GAAI;oBAC3Cd,KAAKa;oBACL;gBACF;gBAEAb;YACF;YAEA,OAAO;YACPO,OAAOQ,IAAI,CAAChB;QACd;IACF;AACF"}