@expo/cli 54.1.0-canary-20251023-4c86f95 → 54.1.0-canary-20251031-b135dff
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin/cli +1 -1
- package/build/src/export/exportStaticAsync.js.map +1 -1
- package/build/src/start/interface/commandsTable.js.map +1 -1
- package/build/src/start/interface/startInterface.js +3 -0
- package/build/src/start/interface/startInterface.js.map +1 -1
- package/build/src/start/server/MCP.js +15 -4
- package/build/src/start/server/MCP.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/createServerComponentsMiddleware.js +16 -16
- package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
- package/build/src/start/server/metro/fetchRouterManifest.js.map +1 -1
- package/build/src/start/server/metro/withMetroMultiPlatform.js +19 -2
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/middleware/DataLoaderModuleMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/inspector/CdpClient.js +2 -0
- package/build/src/start/server/middleware/inspector/CdpClient.js.map +1 -1
- package/build/src/start/server/type-generation/routes.js +3 -1
- package/build/src/start/server/type-generation/routes.js.map +1 -1
- package/build/src/start/startAsync.js +11 -8
- package/build/src/start/startAsync.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +19 -19
- package/static/template/[...rsc]+api.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/withMetroMultiPlatform.ts"],"sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport type { ExpoConfig, Platform } from '@expo/config';\nimport type Bundler from '@expo/metro/metro/Bundler';\nimport type { ConfigT } from '@expo/metro/metro-config';\nimport type {\n Resolution,\n ResolutionContext,\n CustomResolutionContext,\n} from '@expo/metro/metro-resolver';\nimport { resolve as metroResolver } from '@expo/metro/metro-resolver';\nimport type { SourceFileResolution } from '@expo/metro/metro-resolver/types';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport {\n createAutolinkingModuleResolverInput,\n createAutolinkingModuleResolver,\n AutolinkingModuleResolverInput,\n} from './createExpoAutolinkingResolver';\nimport { createFallbackModuleResolver } from './createExpoFallbackResolver';\nimport { createFastResolver, FailedToResolvePathError } from './createExpoMetroResolver';\nimport { isNodeExternal, shouldCreateVirtualShim } from './externals';\nimport { isFailedToResolveNameError, isFailedToResolvePathError } from './metroErrors';\nimport { getMetroBundlerWithVirtualModules } from './metroVirtualModules';\nimport { withMetroErrorReportingResolver } from './withMetroErrorReportingResolver';\nimport { withMetroMutatedResolverContext, withMetroResolvers } from './withMetroResolvers';\nimport { withMetroSupervisingTransformWorker } from './withMetroSupervisingTransformWorker';\nimport { Log } from '../../../log';\nimport { FileNotifier } from '../../../utils/FileNotifier';\nimport { env } from '../../../utils/env';\nimport { installExitHooks } from '../../../utils/exit';\nimport { isInteractive } from '../../../utils/interactive';\nimport { loadTsConfigPathsAsync, TsConfigPaths } from '../../../utils/tsconfig/loadTsConfigPaths';\nimport { resolveWithTsConfigPaths } from '../../../utils/tsconfig/resolveWithTsConfigPaths';\nimport { isServerEnvironment } from '../middleware/metroOptions';\nimport { PlatformBundlers } from '../platformBundlers';\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport type StrictResolver = (moduleName: string) => Resolution;\nexport type StrictResolverFactory = (\n context: ResolutionContext,\n platform: string | null\n) => StrictResolver;\n\nconst ASSET_REGISTRY_SRC = `const assets=[];module.exports={registerAsset:s=>assets.push(s),getAssetByID:s=>assets[s-1]};`;\n\nconst debug = require('debug')('expo:start:server:metro:multi-platform') as typeof console.log;\n\nfunction withWebPolyfills(\n config: ConfigT,\n {\n getMetroBundler,\n }: {\n getMetroBundler: () => Bundler;\n }\n): ConfigT {\n const originalGetPolyfills = config.serializer.getPolyfills\n ? config.serializer.getPolyfills.bind(config.serializer)\n : () => [];\n\n const getPolyfills = (ctx: { platform?: string | null }): readonly string[] => {\n const virtualEnvVarId = `\\0polyfill:environment-variables`;\n\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualEnvVarId,\n (() => {\n return `//`;\n })()\n );\n\n const virtualModuleId = `\\0polyfill:external-require`;\n\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n (() => {\n if (ctx.platform === 'web') {\n return `global.$$require_external = typeof require !== \"undefined\" ? require : () => null;`;\n } else {\n // Wrap in try/catch to support Android.\n return 'try { global.$$require_external = typeof expo === \"undefined\" ? require : (moduleId) => { throw new Error(`Node.js standard library module ${moduleId} is not available in this JavaScript environment`);} } catch { global.$$require_external = (moduleId) => { throw new Error(`Node.js standard library module ${moduleId} is not available in this JavaScript environment`);} }';\n }\n })()\n );\n\n const virtualModulesPolyfills = [virtualModuleId, virtualEnvVarId];\n\n if (ctx.platform === 'web') {\n try {\n const rnGetPolyfills: () => string[] = require('react-native/rn-get-polyfills');\n return [\n ...virtualModulesPolyfills,\n // Ensure that the error-guard polyfill is included in the web polyfills to\n // make metro-runtime work correctly.\n // TODO: This module is pretty big for a function that simply re-throws an error that doesn't need to be caught.\n // NOTE(@kitten): This is technically the public API to get polyfills rather than resolving directly into\n // `@react-native/js-polyfills`. We should really just start vendoring these, but for now, this exclusion works\n ...rnGetPolyfills().filter((x: string) => !x.includes('/console')),\n ];\n } catch (error: any) {\n if ('code' in error && error.code === 'MODULE_NOT_FOUND') {\n // If react-native is not installed, because we're targeting web, we still continue\n // This should be rare, but we add it so we don't unnecessarily have a fixed peer dependency on react-native\n debug(\n 'Skipping react-native/rn-get-polyfills from getPolyfills. react-native is not installed.'\n );\n return virtualModulesPolyfills;\n } else {\n throw error;\n }\n }\n }\n\n // Generally uses `@expo/metro-config`'s `getPolyfills` function, unless overridden\n const polyfills = originalGetPolyfills(ctx);\n return [\n ...polyfills,\n ...virtualModulesPolyfills,\n // Removed on server platforms during the transform.\n require.resolve('expo/virtual/streams.js'),\n ];\n };\n\n return {\n ...config,\n serializer: {\n ...config.serializer,\n getPolyfills,\n },\n };\n}\n\nfunction normalizeSlashes(p: string) {\n return p.replace(/\\\\/g, '/');\n}\n\nexport function getNodejsExtensions(srcExts: readonly string[]): string[] {\n const mjsExts = srcExts.filter((ext) => /mjs$/.test(ext));\n const nodejsSourceExtensions = srcExts.filter((ext) => !/mjs$/.test(ext));\n // find index of last `*.js` extension\n const jsIndex = nodejsSourceExtensions.reduce((index, ext, i) => {\n return /jsx?$/.test(ext) ? i : index;\n }, -1);\n\n // insert `*.mjs` extensions after `*.js` extensions\n nodejsSourceExtensions.splice(jsIndex + 1, 0, ...mjsExts);\n\n return nodejsSourceExtensions;\n}\n\n/**\n * Apply custom resolvers to do the following:\n * - Disable `.native.js` extensions on web.\n * - Alias `react-native` to `react-native-web` on web.\n * - Redirect `react-native-web/dist/modules/AssetRegistry/index.js` to `@react-native/assets/registry.js` on web.\n * - Add support for `tsconfig.json`/`jsconfig.json` aliases via `compilerOptions.paths`.\n */\nexport function withExtendedResolver(\n config: ConfigT,\n {\n tsconfig,\n autolinkingModuleResolverInput,\n isTsconfigPathsEnabled,\n isFastResolverEnabled,\n isExporting,\n isReactServerComponentsEnabled,\n getMetroBundler,\n }: {\n tsconfig: TsConfigPaths | null;\n autolinkingModuleResolverInput?: AutolinkingModuleResolverInput;\n isTsconfigPathsEnabled?: boolean;\n isFastResolverEnabled?: boolean;\n isExporting?: boolean;\n isReactServerComponentsEnabled?: boolean;\n getMetroBundler: () => Bundler;\n }\n) {\n if (isReactServerComponentsEnabled) {\n Log.warn(`React Server Components (beta) is enabled.`);\n }\n if (isFastResolverEnabled) {\n Log.log(chalk.dim`Fast resolver is enabled.`);\n }\n\n const defaultResolver = metroResolver;\n const resolver = isFastResolverEnabled\n ? createFastResolver({\n preserveSymlinks: true,\n blockList: !config.resolver?.blockList\n ? []\n : Array.isArray(config.resolver?.blockList)\n ? config.resolver?.blockList\n : [config.resolver?.blockList],\n })\n : defaultResolver;\n\n const aliases: { [key: string]: Record<string, string> } = {\n web: {\n 'react-native': 'react-native-web',\n 'react-native/index': 'react-native-web',\n 'react-native/Libraries/Image/resolveAssetSource': 'expo-asset/build/resolveAssetSource',\n },\n };\n\n let _universalAliases: [RegExp, string][] | null;\n\n function getUniversalAliases() {\n if (_universalAliases) {\n return _universalAliases;\n }\n\n _universalAliases = [];\n\n // This package is currently always installed as it is included in the `expo` package.\n if (resolveFrom.silent(config.projectRoot, '@expo/vector-icons')) {\n debug('Enabling alias: react-native-vector-icons -> @expo/vector-icons');\n _universalAliases.push([/^react-native-vector-icons(\\/.*)?/, '@expo/vector-icons$1']);\n }\n if (isReactServerComponentsEnabled) {\n if (resolveFrom.silent(config.projectRoot, 'expo-router/rsc')) {\n debug('Enabling bridge alias: expo-router -> expo-router/rsc');\n _universalAliases.push([/^expo-router$/, 'expo-router/rsc']);\n // Bridge the internal entry point which is a standalone import to ensure package.json resolution works as expected.\n _universalAliases.push([/^expo-router\\/entry-classic$/, 'expo-router/rsc/entry']);\n }\n }\n return _universalAliases;\n }\n\n // used to resolve externals in `requestCustomExternals` from the project root\n const projectRootOriginPath = path.join(config.projectRoot, 'package.json');\n\n const preferredMainFields: { [key: string]: string[] } = {\n // Defaults from Expo Webpack. Most packages using `react-native` don't support web\n // in the `react-native` field, so we should prefer the `browser` field.\n // https://github.com/expo/router/issues/37\n web: ['browser', 'module', 'main'],\n };\n\n let tsConfigResolve =\n isTsconfigPathsEnabled && (tsconfig?.paths || tsconfig?.baseUrl != null)\n ? resolveWithTsConfigPaths.bind(resolveWithTsConfigPaths, {\n paths: tsconfig.paths ?? {},\n baseUrl: tsconfig.baseUrl ?? config.projectRoot,\n hasBaseUrl: !!tsconfig.baseUrl,\n })\n : null;\n\n // TODO: Move this to be a transform key for invalidation.\n if (!isExporting && isInteractive()) {\n if (isTsconfigPathsEnabled) {\n // TODO: We should track all the files that used imports and invalidate them\n // currently the user will need to save all the files that use imports to\n // use the new aliases.\n const configWatcher = new FileNotifier(config.projectRoot, [\n './tsconfig.json',\n './jsconfig.json',\n ]);\n configWatcher.startObserving(() => {\n debug('Reloading tsconfig.json');\n loadTsConfigPathsAsync(config.projectRoot).then((tsConfigPaths) => {\n if (tsConfigPaths?.paths && !!Object.keys(tsConfigPaths.paths).length) {\n debug('Enabling tsconfig.json paths support');\n tsConfigResolve = resolveWithTsConfigPaths.bind(resolveWithTsConfigPaths, {\n paths: tsConfigPaths.paths ?? {},\n baseUrl: tsConfigPaths.baseUrl ?? config.projectRoot,\n hasBaseUrl: !!tsConfigPaths.baseUrl,\n });\n } else {\n debug('Disabling tsconfig.json paths support');\n tsConfigResolve = null;\n }\n });\n });\n\n // TODO: This probably prevents the process from exiting.\n installExitHooks(() => {\n configWatcher.stopObserving();\n });\n } else {\n debug('Skipping tsconfig.json paths support');\n }\n }\n\n let nodejsSourceExtensions: string[] | null = null;\n\n const getStrictResolver: StrictResolverFactory = (\n { resolveRequest, ...context },\n platform\n ): StrictResolver => {\n return function doResolve(moduleName: string): Resolution {\n return resolver(context, moduleName, platform);\n };\n };\n\n function getOptionalResolver(context: ResolutionContext, platform: string | null) {\n const doResolve = getStrictResolver(context, platform);\n return function optionalResolve(moduleName: string): Resolution | null {\n try {\n return doResolve(moduleName);\n } catch (error) {\n // If the error is directly related to a resolver not being able to resolve a module, then\n // we can ignore the error and try the next resolver. Otherwise, we should throw the error.\n const isResolutionError =\n isFailedToResolveNameError(error) || isFailedToResolvePathError(error);\n if (!isResolutionError) {\n throw error;\n }\n }\n return null;\n };\n }\n\n // TODO: This is a hack to get resolveWeak working.\n const idFactory = (config.serializer?.createModuleIdFactory?.() ??\n ((id: number | string, context: { platform: string; environment?: string }): number | string =>\n id)) as (\n id: number | string,\n context: { platform: string; environment?: string }\n ) => number | string;\n\n const getAssetRegistryModule = () => {\n const virtualModuleId = `\\0polyfill:assets-registry`;\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n ASSET_REGISTRY_SRC\n );\n return {\n type: 'sourceFile',\n filePath: virtualModuleId,\n } as const;\n };\n\n // If Node.js pass-through, then remap to a module like `module.exports = $$require_external(<module>)`.\n // If module should be shimmed, remap to an empty module.\n const externals: {\n match: (context: ResolutionContext, moduleName: string, platform: string | null) => boolean;\n replace: 'empty' | 'node' | 'weak';\n }[] = [\n {\n match: (context: ResolutionContext, moduleName: string) => {\n if (\n // Disable internal externals when exporting for production.\n context.customResolverOptions.exporting ||\n // These externals are only for Node.js environments.\n !isServerEnvironment(context.customResolverOptions?.environment)\n ) {\n return false;\n }\n\n if (context.customResolverOptions?.environment === 'react-server') {\n // Ensure these non-react-server modules are excluded when bundling for React Server Components in development.\n return /^(source-map-support(\\/.*)?|@babel\\/runtime\\/.+|debug|metro-runtime\\/src\\/modules\\/HMRClient|metro|acorn-loose|acorn|chalk|ws|ansi-styles|supports-color|color-convert|has-flag|utf-8-validate|color-name|react-refresh\\/runtime|@remix-run\\/node\\/.+)$/.test(\n moduleName\n );\n }\n\n // TODO: Windows doesn't support externals somehow.\n if (process.platform === 'win32') {\n return /^(source-map-support(\\/.*)?)$/.test(moduleName);\n }\n\n // Extern these modules in standard Node.js environments in development to prevent API routes side-effects\n // from leaking into the dev server process.\n return /^(source-map-support(\\/.*)?|react|@radix-ui\\/.+|@babel\\/runtime\\/.+|react-dom(\\/.+)?|debug|acorn-loose|acorn|css-in-js-utils\\/lib\\/.+|hyphenate-style-name|color|color-string|color-convert|color-name|fontfaceobserver|fast-deep-equal|query-string|escape-string-regexp|invariant|postcss-value-parser|memoize-one|nullthrows|strict-uri-encode|decode-uri-component|split-on-first|filter-obj|warn-once|simple-swizzle|is-arrayish|inline-style-prefixer\\/.+)$/.test(\n moduleName\n );\n },\n replace: 'node',\n },\n // Externals to speed up async split chunks by extern-ing common packages that appear in the root client chunk.\n {\n match: (context: ResolutionContext, moduleName: string, platform: string | null) => {\n if (\n // Disable internal externals when exporting for production.\n context.customResolverOptions.exporting ||\n // These externals are only for client environments.\n isServerEnvironment(context.customResolverOptions?.environment) ||\n // Only enable for client boundaries\n !context.customResolverOptions.clientboundary\n ) {\n return false;\n }\n\n // We don't support this in the resolver at the moment.\n if (moduleName.endsWith('/package.json')) {\n return false;\n }\n\n const isExternal = // Extern these modules in standard Node.js environments.\n /^(deprecated-react-native-prop-types|react|react\\/jsx-dev-runtime|scheduler|react-native|react-dom(\\/.+)?|metro-runtime(\\/.+)?)$/.test(\n moduleName\n ) ||\n // TODO: Add more\n /^@babel\\/runtime\\/helpers\\/(wrapNativeSuper)$/.test(moduleName);\n\n return isExternal;\n },\n replace: 'weak',\n },\n ];\n\n const metroConfigWithCustomResolver = withMetroResolvers(config, [\n // Mock out production react imports in development.\n function requestDevMockProdReact(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n // This resolution is dev-only to prevent bundling the production React packages in development.\n if (!context.dev) return null;\n\n if (\n // Match react-native renderers.\n (platform !== 'web' &&\n context.originModulePath.match(/[\\\\/]node_modules[\\\\/]react-native[\\\\/]/) &&\n moduleName.match(/([\\\\/]ReactFabric|ReactNativeRenderer)-prod/)) ||\n // Match react production imports.\n (moduleName.match(/\\.production(\\.min)?\\.js$/) &&\n // Match if the import originated from a react package.\n context.originModulePath.match(/[\\\\/]node_modules[\\\\/](react[-\\\\/]|scheduler[\\\\/])/))\n ) {\n debug(`Skipping production module: ${moduleName}`);\n // /Users/path/to/expo/node_modules/react/index.js ./cjs/react.production.min.js\n // /Users/path/to/expo/node_modules/react/jsx-dev-runtime.js ./cjs/react-jsx-dev-runtime.production.min.js\n // /Users/path/to/expo/node_modules/react-is/index.js ./cjs/react-is.production.min.js\n // /Users/path/to/expo/node_modules/react-refresh/runtime.js ./cjs/react-refresh-runtime.production.min.js\n // /Users/path/to/expo/node_modules/react-native/node_modules/scheduler/index.native.js ./cjs/scheduler.native.production.min.js\n // /Users/path/to/expo/node_modules/react-native/node_modules/react-is/index.js ./cjs/react-is.production.min.js\n return {\n type: 'empty',\n };\n }\n return null;\n },\n // tsconfig paths\n function requestTsconfigPaths(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n return (\n tsConfigResolve?.(\n {\n originModulePath: context.originModulePath,\n moduleName,\n },\n getOptionalResolver(context, platform)\n ) ?? null\n );\n },\n\n // Node.js externals support\n function requestNodeExternals(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n const isServer =\n context.customResolverOptions?.environment === 'node' ||\n context.customResolverOptions?.environment === 'react-server';\n\n const moduleId = isNodeExternal(moduleName);\n if (!moduleId) {\n return null;\n }\n\n if (\n // In browser runtimes, we want to either resolve a local node module by the same name, or shim the module to\n // prevent crashing when Node.js built-ins are imported.\n !isServer\n ) {\n // Perform optional resolve first. If the module doesn't exist (no module in the node_modules)\n // then we can mock the file to use an empty module.\n const result = getOptionalResolver(context, platform)(moduleName);\n\n if (!result && platform !== 'web') {\n // Preserve previous behavior where native throws an error on node.js internals.\n return null;\n }\n\n return (\n result ?? {\n // In this case, mock the file to use an empty module.\n type: 'empty',\n }\n );\n }\n const contents = `module.exports=$$require_external('node:${moduleId}');`;\n debug(`Virtualizing Node.js \"${moduleId}\"`);\n const virtualModuleId = `\\0node:${moduleId}`;\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n contents\n );\n return {\n type: 'sourceFile',\n filePath: virtualModuleId,\n };\n },\n\n // Custom externals support\n function requestCustomExternals(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n // We don't support this in the resolver at the moment.\n if (moduleName.endsWith('/package.json')) {\n return null;\n }\n // Skip applying JS externals for CSS files.\n if (/\\.(s?css|sass)$/.test(context.originModulePath)) {\n return null;\n }\n\n for (const external of externals) {\n if (external.match(context, moduleName, platform)) {\n if (external.replace === 'empty') {\n debug(`Redirecting external \"${moduleName}\" to \"${external.replace}\"`);\n return {\n type: external.replace,\n };\n } else if (external.replace === 'weak') {\n // TODO: Make this use require.resolveWeak again. Previously this was just resolving to the same path.\n const realModule = getStrictResolver(context, platform)(moduleName);\n const realPath = realModule.type === 'sourceFile' ? realModule.filePath : moduleName;\n const opaqueId = idFactory(realPath, {\n platform: platform!,\n environment: context.customResolverOptions?.environment,\n });\n const contents =\n typeof opaqueId === 'number'\n ? `module.exports=/*${moduleName}*/__r(${opaqueId})`\n : `module.exports=/*${moduleName}*/__r(${JSON.stringify(opaqueId)})`;\n // const contents = `module.exports=/*${moduleName}*/__r(require.resolveWeak('${moduleName}'))`;\n // const generatedModuleId = fastHashMemoized(contents);\n const virtualModuleId = `\\0weak:${opaqueId}`;\n debug('Virtualizing module:', moduleName, '->', virtualModuleId);\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n contents\n );\n return {\n type: 'sourceFile',\n filePath: virtualModuleId,\n };\n } else if (external.replace === 'node') {\n // TODO(@kitten): Temporary workaround. Our externals logic here isn't generic and only works\n // for development and not exports. We never intend to use it in exported production bundles,\n // however, this is still a dangerous implementation. To protect us from externalizing modules\n // that aren't available to the app, we force any resolution to happen via the project root\n const projectRootContext: ResolutionContext = {\n ...context,\n nodeModulesPaths: [],\n originModulePath: projectRootOriginPath,\n disableHierarchicalLookup: false,\n };\n const externModule = getStrictResolver(projectRootContext, platform)(moduleName);\n if (externModule.type !== 'sourceFile') {\n return null;\n }\n const contents = `module.exports=$$require_external('${moduleName}')`;\n const virtualModuleId = `\\0node:${moduleName}`;\n debug('Virtualizing Node.js (custom):', moduleName, '->', virtualModuleId);\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n contents\n );\n return {\n type: 'sourceFile',\n filePath: virtualModuleId,\n };\n } else {\n external.replace satisfies never;\n }\n }\n }\n return null;\n },\n\n // Basic moduleId aliases\n function requestAlias(context: ResolutionContext, moduleName: string, platform: string | null) {\n // Conditionally remap `react-native` to `react-native-web` on web in\n // a way that doesn't require Babel to resolve the alias.\n if (platform && platform in aliases && aliases[platform][moduleName]) {\n const redirectedModuleName = aliases[platform][moduleName];\n return getStrictResolver(context, platform)(redirectedModuleName);\n }\n\n for (const [matcher, alias] of getUniversalAliases()) {\n const match = moduleName.match(matcher);\n if (match) {\n const aliasedModule = alias.replace(\n /\\$(\\d+)/g,\n (_, index) => match[parseInt(index, 10)] ?? ''\n );\n const doResolve = getStrictResolver(context, platform);\n debug(`Alias \"${moduleName}\" to \"${aliasedModule}\"`);\n return doResolve(aliasedModule);\n }\n }\n\n return null;\n },\n\n // Polyfill for asset registry\n function requestStableAssetRegistry(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n if (/^@react-native\\/assets-registry\\/registry(\\.js)?$/.test(moduleName)) {\n return getAssetRegistryModule();\n }\n\n if (\n platform === 'web' &&\n context.originModulePath.match(/node_modules[\\\\/]react-native-web[\\\\/]/) &&\n moduleName.includes('/modules/AssetRegistry')\n ) {\n return getAssetRegistryModule();\n }\n\n return null;\n },\n\n createAutolinkingModuleResolver(autolinkingModuleResolverInput, {\n getStrictResolver,\n }),\n\n // TODO: Reduce these as much as possible in the future.\n // Complex post-resolution rewrites.\n function requestPostRewrites(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n const doResolve = getStrictResolver(context, platform);\n\n const result = doResolve(moduleName);\n\n if (result.type !== 'sourceFile') {\n return result;\n }\n\n const normalizedPath = normalizeSlashes(result.filePath);\n\n const doReplace = (from: string, to: string | undefined, options?: { throws?: boolean }) =>\n doReplaceHelper(from, to, {\n normalizedPath,\n doResolve,\n ...options,\n });\n const doReplaceStrict = (from: string, to: string | undefined) =>\n doReplace(from, to, { throws: true });\n\n if (env.EXPO_UNSTABLE_WEB_MODAL) {\n const webModalModule = doReplace(\n 'expo-router/build/layouts/_web-modal.js',\n 'expo-router/build/layouts/ExperimentalModalStack.js'\n );\n if (webModalModule) {\n debug('Using `_unstable-web-modal` implementation.');\n return webModalModule;\n }\n }\n\n if (platform === 'web') {\n if (result.filePath.includes('node_modules')) {\n // Disallow importing confusing native modules on web\n if (\n [\n 'react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore',\n 'react-native/Libraries/Utilities/codegenNativeCommands',\n 'react-native/Libraries/Utilities/codegenNativeComponent',\n ].some((matcher) =>\n // Support absolute and modules with .js extensions.\n moduleName.includes(matcher)\n )\n ) {\n throw new FailedToResolvePathError(\n `Importing native-only module \"${moduleName}\" on web from: ${path.relative(config.projectRoot, context.originModulePath)}`\n );\n }\n\n // Replace with static shims\n\n // Drop everything up until the `node_modules` folder.\n const normalName = normalizedPath.replace(/.*node_modules\\//, '');\n\n const shimFile = shouldCreateVirtualShim(normalName);\n if (shimFile) {\n const virtualId = `\\0shim:${normalName}`;\n const bundler = getMetroBundlerWithVirtualModules(getMetroBundler());\n if (!bundler.hasVirtualModule(virtualId)) {\n bundler.setVirtualModule(virtualId, fs.readFileSync(shimFile, 'utf8'));\n }\n debug(`Redirecting module \"${result.filePath}\" to shim`);\n\n return {\n ...result,\n filePath: virtualId,\n };\n }\n }\n } else {\n const isServer =\n context.customResolverOptions?.environment === 'node' ||\n context.customResolverOptions?.environment === 'react-server';\n\n // Shim out React Native native runtime globals in server mode for native.\n if (isServer) {\n const emptyModule = doReplace('react-native/Libraries/Core/InitializeCore.js', undefined);\n if (emptyModule) {\n debug('Shimming out InitializeCore for React Native in native SSR bundle');\n return emptyModule;\n }\n }\n\n const hmrModule = doReplaceStrict(\n 'react-native/Libraries/Utilities/HMRClient.js',\n 'expo/src/async-require/hmr.ts'\n );\n if (hmrModule) return hmrModule;\n\n if (env.EXPO_UNSTABLE_LOG_BOX) {\n const logBoxModule = doReplace(\n 'react-native/Libraries/LogBox/LogBoxInspectorContainer.js',\n '@expo/log-box/swap-rn-logbox.js'\n );\n if (logBoxModule) return logBoxModule;\n\n const logBoxParserModule = doReplace(\n 'react-native/Libraries/LogBox/Data/parseLogBoxLog.js',\n '@expo/log-box/swap-rn-logbox-parser.js'\n );\n if (logBoxParserModule) return logBoxParserModule;\n }\n }\n\n return result;\n },\n\n // If at this point, we haven't resolved a module yet, if it's a module specifier for a known dependency\n // of either `expo` or `expo-router`, attempt to resolve it from these origin modules instead\n createFallbackModuleResolver({\n projectRoot: config.projectRoot,\n originModuleNames: ['expo', 'expo-router'],\n getStrictResolver,\n }),\n ]);\n\n // Ensure we mutate the resolution context to include the custom resolver options for server and web.\n const metroConfigWithCustomContext = withMetroMutatedResolverContext(\n metroConfigWithCustomResolver,\n (\n immutableContext: CustomResolutionContext,\n moduleName: string,\n platform: string | null\n ): CustomResolutionContext => {\n const context: Mutable<CustomResolutionContext> = {\n ...immutableContext,\n preferNativePlatform: platform !== 'web',\n };\n\n if (isServerEnvironment(context.customResolverOptions?.environment)) {\n // Adjust nodejs source extensions to sort mjs after js, including platform variants.\n if (nodejsSourceExtensions === null) {\n nodejsSourceExtensions = getNodejsExtensions(context.sourceExts);\n }\n context.sourceExts = nodejsSourceExtensions;\n\n context.unstable_enablePackageExports = true;\n context.unstable_conditionsByPlatform = {};\n\n const isReactServerComponents =\n context.customResolverOptions?.environment === 'react-server';\n\n if (isReactServerComponents) {\n // NOTE: Align the behavior across server and client. This is a breaking change so we'll just roll it out with React Server Components.\n // This ensures that react-server and client code both resolve `module` and `main` in the same order.\n if (platform === 'web') {\n // Node.js runtimes should only be importing main at the moment.\n // This is a temporary fix until we can support the package.json exports.\n context.mainFields = ['module', 'main'];\n } else {\n // In Node.js + native, use the standard main fields.\n context.mainFields = ['react-native', 'module', 'main'];\n }\n } else {\n if (platform === 'web') {\n // Node.js runtimes should only be importing main at the moment.\n // This is a temporary fix until we can support the package.json exports.\n context.mainFields = ['main', 'module'];\n } else {\n // In Node.js + native, use the standard main fields.\n context.mainFields = ['react-native', 'main', 'module'];\n }\n }\n\n // Enable react-server import conditions.\n if (context.customResolverOptions?.environment === 'react-server') {\n context.unstable_conditionNames = ['node', 'react-server', 'workerd'];\n } else {\n context.unstable_conditionNames = ['node'];\n }\n } else {\n // Non-server changes\n\n if (!env.EXPO_METRO_NO_MAIN_FIELD_OVERRIDE && platform && platform in preferredMainFields) {\n context.mainFields = preferredMainFields[platform];\n }\n }\n\n return context;\n }\n );\n\n return withMetroErrorReportingResolver(\n withMetroSupervisingTransformWorker(metroConfigWithCustomContext)\n );\n}\n\nfunction doReplaceHelper(\n from: string,\n to: string | undefined,\n {\n throws = false,\n normalizedPath,\n doResolve,\n }: {\n throws?: boolean;\n normalizedPath: string;\n doResolve: StrictResolver;\n }\n): SourceFileResolution | { type: 'empty' } | undefined {\n if (!normalizedPath.endsWith(from)) {\n return undefined;\n }\n\n if (to === undefined) {\n return {\n type: 'empty',\n };\n }\n\n try {\n const hmrModule = doResolve(to);\n if (hmrModule.type === 'sourceFile') {\n debug(`Using \\`${to}\\` implementation.`);\n return hmrModule;\n }\n } catch (resolutionError) {\n if (throws) {\n throw new Error(`Failed to replace ${from} with ${to}. Resolution of ${to} failed.`, {\n cause: resolutionError,\n });\n }\n\n debug(`Failed to resolve ${to} when swapping from ${from}: ${resolutionError}`);\n }\n return undefined;\n}\n\n/** @returns `true` if the incoming resolution should be swapped. */\nexport function shouldAliasModule(\n input: {\n platform: string | null;\n result: Resolution;\n },\n alias: { platform: string; output: string }\n): boolean {\n return (\n input.platform === alias.platform &&\n input.result?.type === 'sourceFile' &&\n typeof input.result?.filePath === 'string' &&\n normalizeSlashes(input.result.filePath).endsWith(alias.output)\n );\n}\n\n/** Add support for `react-native-web` and the Web platform. */\nexport async function withMetroMultiPlatformAsync(\n projectRoot: string,\n {\n config,\n exp,\n platformBundlers,\n isTsconfigPathsEnabled,\n isAutolinkingResolverEnabled,\n isFastResolverEnabled,\n isExporting,\n\n isReactServerComponentsEnabled,\n getMetroBundler,\n }: {\n config: ConfigT;\n exp: ExpoConfig;\n isTsconfigPathsEnabled: boolean;\n platformBundlers: PlatformBundlers;\n isAutolinkingResolverEnabled?: boolean;\n isFastResolverEnabled?: boolean;\n isExporting?: boolean;\n\n isReactServerComponentsEnabled: boolean;\n isNamedRequiresEnabled: boolean;\n getMetroBundler: () => Bundler;\n }\n) {\n // Change the default metro-runtime to a custom one that supports bundle splitting.\n // NOTE(@kitten): This is now always active and EXPO_USE_METRO_REQUIRE / isNamedRequiresEnabled is disregarded\n const metroDefaults: Mutable<\n typeof import('@expo/metro/metro-config/defaults/defaults')\n > = require('@expo/metro/metro-config/defaults/defaults');\n metroDefaults.moduleSystem = require.resolve('@expo/cli/build/metro-require/require');\n\n if (!config.projectRoot) {\n // @ts-expect-error: read-only types\n config.projectRoot = projectRoot;\n }\n\n // Required for @expo/metro-runtime to format paths in the web LogBox.\n process.env.EXPO_PUBLIC_PROJECT_ROOT = process.env.EXPO_PUBLIC_PROJECT_ROOT ?? projectRoot;\n\n // This is used for running Expo CLI in development against projects outside the monorepo.\n if (!isDirectoryIn(__dirname, projectRoot)) {\n // TODO(@kitten): Remove ts-export-errors here and replace with cast for type safety\n if (!config.watchFolders) {\n // @ts-expect-error: watchFolders is readonly\n config.watchFolders = [];\n }\n // @ts-expect-error: watchFolders is readonly\n config.watchFolders.push(path.join(require.resolve('metro-runtime/package.json'), '../..'));\n // @ts-expect-error: watchFolders is readonly\n config.watchFolders.push(\n path.join(require.resolve('@expo/metro-config/package.json'), '../..'),\n // For virtual modules\n path.join(require.resolve('expo/package.json'), '..')\n );\n }\n\n let tsconfig: null | TsConfigPaths = null;\n\n if (isTsconfigPathsEnabled) {\n tsconfig = await loadTsConfigPathsAsync(projectRoot);\n }\n\n let expoConfigPlatforms = Object.entries(platformBundlers)\n .filter(\n ([platform, bundler]) => bundler === 'metro' && exp.platforms?.includes(platform as Platform)\n )\n .map(([platform]) => platform);\n\n if (Array.isArray(config.resolver.platforms)) {\n expoConfigPlatforms = [...new Set(expoConfigPlatforms.concat(config.resolver.platforms))];\n }\n\n // @ts-expect-error: typed as `readonly`.\n config.resolver.platforms = expoConfigPlatforms;\n\n config = withWebPolyfills(config, { getMetroBundler });\n\n let autolinkingModuleResolverInput: AutolinkingModuleResolverInput | undefined;\n if (isAutolinkingResolverEnabled) {\n autolinkingModuleResolverInput = await createAutolinkingModuleResolverInput({\n platforms: expoConfigPlatforms,\n projectRoot,\n });\n }\n\n return withExtendedResolver(config, {\n autolinkingModuleResolverInput,\n tsconfig,\n isExporting,\n isTsconfigPathsEnabled,\n isFastResolverEnabled,\n isReactServerComponentsEnabled,\n getMetroBundler,\n });\n}\n\nfunction isDirectoryIn(targetPath: string, rootPath: string) {\n return targetPath.startsWith(rootPath) && targetPath.length >= rootPath.length;\n}\n"],"names":["getNodejsExtensions","shouldAliasModule","withExtendedResolver","withMetroMultiPlatformAsync","ASSET_REGISTRY_SRC","debug","require","withWebPolyfills","config","getMetroBundler","originalGetPolyfills","serializer","getPolyfills","bind","ctx","virtualEnvVarId","getMetroBundlerWithVirtualModules","setVirtualModule","virtualModuleId","platform","virtualModulesPolyfills","rnGetPolyfills","filter","x","includes","error","code","polyfills","resolve","normalizeSlashes","p","replace","srcExts","mjsExts","ext","test","nodejsSourceExtensions","jsIndex","reduce","index","i","splice","tsconfig","autolinkingModuleResolverInput","isTsconfigPathsEnabled","isFastResolverEnabled","isExporting","isReactServerComponentsEnabled","Log","warn","log","chalk","dim","defaultResolver","metroResolver","resolver","createFastResolver","preserveSymlinks","blockList","Array","isArray","aliases","web","_universalAliases","getUniversalAliases","resolveFrom","silent","projectRoot","push","projectRootOriginPath","path","join","preferredMainFields","tsConfigResolve","paths","baseUrl","resolveWithTsConfigPaths","hasBaseUrl","isInteractive","configWatcher","FileNotifier","startObserving","loadTsConfigPathsAsync","then","tsConfigPaths","Object","keys","length","installExitHooks","stopObserving","getStrictResolver","resolveRequest","context","doResolve","moduleName","getOptionalResolver","optionalResolve","isResolutionError","isFailedToResolveNameError","isFailedToResolvePathError","idFactory","createModuleIdFactory","id","getAssetRegistryModule","type","filePath","externals","match","customResolverOptions","exporting","isServerEnvironment","environment","process","clientboundary","endsWith","isExternal","metroConfigWithCustomResolver","withMetroResolvers","requestDevMockProdReact","dev","originModulePath","requestTsconfigPaths","requestNodeExternals","isServer","moduleId","isNodeExternal","result","contents","requestCustomExternals","external","realModule","realPath","opaqueId","JSON","stringify","projectRootContext","nodeModulesPaths","disableHierarchicalLookup","externModule","requestAlias","redirectedModuleName","matcher","alias","aliasedModule","_","parseInt","requestStableAssetRegistry","createAutolinkingModuleResolver","requestPostRewrites","normalizedPath","doReplace","from","to","options","doReplaceHelper","doReplaceStrict","throws","env","EXPO_UNSTABLE_WEB_MODAL","webModalModule","some","FailedToResolvePathError","relative","normalName","shimFile","shouldCreateVirtualShim","virtualId","bundler","hasVirtualModule","fs","readFileSync","emptyModule","undefined","hmrModule","EXPO_UNSTABLE_LOG_BOX","logBoxModule","logBoxParserModule","createFallbackModuleResolver","originModuleNames","metroConfigWithCustomContext","withMetroMutatedResolverContext","immutableContext","preferNativePlatform","sourceExts","unstable_enablePackageExports","unstable_conditionsByPlatform","isReactServerComponents","mainFields","unstable_conditionNames","EXPO_METRO_NO_MAIN_FIELD_OVERRIDE","withMetroErrorReportingResolver","withMetroSupervisingTransformWorker","resolutionError","Error","cause","input","output","exp","platformBundlers","isAutolinkingResolverEnabled","metroDefaults","moduleSystem","EXPO_PUBLIC_PROJECT_ROOT","isDirectoryIn","__dirname","watchFolders","expoConfigPlatforms","entries","platforms","map","Set","concat","createAutolinkingModuleResolverInput","targetPath","rootPath","startsWith"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/withMetroMultiPlatform.ts"],"sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport type { ExpoConfig, Platform } from '@expo/config';\nimport type Bundler from '@expo/metro/metro/Bundler';\nimport type { ConfigT } from '@expo/metro/metro-config';\nimport type {\n Resolution,\n ResolutionContext,\n CustomResolutionContext,\n} from '@expo/metro/metro-resolver';\nimport { resolve as metroResolver } from '@expo/metro/metro-resolver';\nimport type { SourceFileResolution } from '@expo/metro/metro-resolver/types';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport {\n createAutolinkingModuleResolverInput,\n createAutolinkingModuleResolver,\n AutolinkingModuleResolverInput,\n} from './createExpoAutolinkingResolver';\nimport { createFallbackModuleResolver } from './createExpoFallbackResolver';\nimport { createFastResolver, FailedToResolvePathError } from './createExpoMetroResolver';\nimport { isNodeExternal, shouldCreateVirtualShim } from './externals';\nimport { isFailedToResolveNameError, isFailedToResolvePathError } from './metroErrors';\nimport { getMetroBundlerWithVirtualModules } from './metroVirtualModules';\nimport { withMetroErrorReportingResolver } from './withMetroErrorReportingResolver';\nimport { withMetroMutatedResolverContext, withMetroResolvers } from './withMetroResolvers';\nimport { withMetroSupervisingTransformWorker } from './withMetroSupervisingTransformWorker';\nimport { Log } from '../../../log';\nimport { FileNotifier } from '../../../utils/FileNotifier';\nimport { env } from '../../../utils/env';\nimport { installExitHooks } from '../../../utils/exit';\nimport { isInteractive } from '../../../utils/interactive';\nimport { loadTsConfigPathsAsync, TsConfigPaths } from '../../../utils/tsconfig/loadTsConfigPaths';\nimport { resolveWithTsConfigPaths } from '../../../utils/tsconfig/resolveWithTsConfigPaths';\nimport { isServerEnvironment } from '../middleware/metroOptions';\nimport { PlatformBundlers } from '../platformBundlers';\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport type StrictResolver = (moduleName: string) => Resolution;\nexport type StrictResolverFactory = (\n context: ResolutionContext,\n platform: string | null\n) => StrictResolver;\n\nconst ASSET_REGISTRY_SRC = `const assets=[];module.exports={registerAsset:s=>assets.push(s),getAssetByID:s=>assets[s-1]};`;\n\nconst debug = require('debug')('expo:start:server:metro:multi-platform') as typeof console.log;\n\nfunction withWebPolyfills(\n config: ConfigT,\n {\n getMetroBundler,\n }: {\n getMetroBundler: () => Bundler;\n }\n): ConfigT {\n const originalGetPolyfills = config.serializer.getPolyfills\n ? config.serializer.getPolyfills.bind(config.serializer)\n : () => [];\n\n const getPolyfills = (ctx: { platform?: string | null }): readonly string[] => {\n const virtualEnvVarId = `\\0polyfill:environment-variables`;\n\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualEnvVarId,\n (() => {\n return `//`;\n })()\n );\n\n const virtualModuleId = `\\0polyfill:external-require`;\n\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n (() => {\n if (ctx.platform === 'web') {\n return `global.$$require_external = typeof require !== \"undefined\" ? require : () => null;`;\n } else {\n // Wrap in try/catch to support Android.\n return 'try { global.$$require_external = typeof expo === \"undefined\" ? require : (moduleId) => { throw new Error(`Node.js standard library module ${moduleId} is not available in this JavaScript environment`);} } catch { global.$$require_external = (moduleId) => { throw new Error(`Node.js standard library module ${moduleId} is not available in this JavaScript environment`);} }';\n }\n })()\n );\n\n const virtualModulesPolyfills = [virtualModuleId, virtualEnvVarId];\n\n if (ctx.platform === 'web') {\n try {\n const rnGetPolyfills: () => string[] = require('react-native/rn-get-polyfills');\n return [\n ...virtualModulesPolyfills,\n // Ensure that the error-guard polyfill is included in the web polyfills to\n // make metro-runtime work correctly.\n // TODO: This module is pretty big for a function that simply re-throws an error that doesn't need to be caught.\n // NOTE(@kitten): This is technically the public API to get polyfills rather than resolving directly into\n // `@react-native/js-polyfills`. We should really just start vendoring these, but for now, this exclusion works\n ...rnGetPolyfills().filter((x: string) => !x.includes('/console')),\n ];\n } catch (error: any) {\n if ('code' in error && error.code === 'MODULE_NOT_FOUND') {\n // If react-native is not installed, because we're targeting web, we still continue\n // This should be rare, but we add it so we don't unnecessarily have a fixed peer dependency on react-native\n debug(\n 'Skipping react-native/rn-get-polyfills from getPolyfills. react-native is not installed.'\n );\n return virtualModulesPolyfills;\n } else {\n throw error;\n }\n }\n }\n\n // Generally uses `@expo/metro-config`'s `getPolyfills` function, unless overridden\n const polyfills = originalGetPolyfills(ctx);\n return [\n ...polyfills,\n ...virtualModulesPolyfills,\n // Removed on server platforms during the transform.\n require.resolve('expo/virtual/streams.js'),\n ];\n };\n\n return {\n ...config,\n serializer: {\n ...config.serializer,\n getPolyfills,\n },\n };\n}\n\nfunction normalizeSlashes(p: string) {\n return p.replace(/\\\\/g, '/');\n}\n\nexport function getNodejsExtensions(srcExts: readonly string[]): string[] {\n const mjsExts = srcExts.filter((ext) => /mjs$/.test(ext));\n const nodejsSourceExtensions = srcExts.filter((ext) => !/mjs$/.test(ext));\n // find index of last `*.js` extension\n const jsIndex = nodejsSourceExtensions.reduce((index, ext, i) => {\n return /jsx?$/.test(ext) ? i : index;\n }, -1);\n\n // insert `*.mjs` extensions after `*.js` extensions\n nodejsSourceExtensions.splice(jsIndex + 1, 0, ...mjsExts);\n\n return nodejsSourceExtensions;\n}\n\n/**\n * Apply custom resolvers to do the following:\n * - Disable `.native.js` extensions on web.\n * - Alias `react-native` to `react-native-web` on web.\n * - Redirect `react-native-web/dist/modules/AssetRegistry/index.js` to `@react-native/assets/registry.js` on web.\n * - Add support for `tsconfig.json`/`jsconfig.json` aliases via `compilerOptions.paths`.\n */\nexport function withExtendedResolver(\n config: ConfigT,\n {\n tsconfig,\n autolinkingModuleResolverInput,\n isTsconfigPathsEnabled,\n isFastResolverEnabled,\n isExporting,\n isReactServerComponentsEnabled,\n getMetroBundler,\n }: {\n tsconfig: TsConfigPaths | null;\n autolinkingModuleResolverInput?: AutolinkingModuleResolverInput;\n isTsconfigPathsEnabled?: boolean;\n isFastResolverEnabled?: boolean;\n isExporting?: boolean;\n isReactServerComponentsEnabled?: boolean;\n getMetroBundler: () => Bundler;\n }\n) {\n if (isReactServerComponentsEnabled) {\n Log.warn(`React Server Components (beta) is enabled.`);\n }\n if (isFastResolverEnabled) {\n Log.log(chalk.dim`Fast resolver is enabled.`);\n }\n\n const defaultResolver = metroResolver;\n const resolver = isFastResolverEnabled\n ? createFastResolver({\n preserveSymlinks: true,\n blockList: !config.resolver?.blockList\n ? []\n : Array.isArray(config.resolver?.blockList)\n ? config.resolver?.blockList\n : [config.resolver?.blockList],\n })\n : defaultResolver;\n\n const aliases: { [key: string]: Record<string, string> } = {\n web: {\n 'react-native': 'react-native-web',\n 'react-native/index': 'react-native-web',\n 'react-native/Libraries/Image/resolveAssetSource': 'expo-asset/build/resolveAssetSource',\n },\n };\n\n let _universalAliases: [RegExp, string][] | null;\n\n function getUniversalAliases() {\n if (_universalAliases) {\n return _universalAliases;\n }\n\n _universalAliases = [];\n\n // This package is currently always installed as it is included in the `expo` package.\n if (resolveFrom.silent(config.projectRoot, '@expo/vector-icons')) {\n debug('Enabling alias: react-native-vector-icons -> @expo/vector-icons');\n _universalAliases.push([/^react-native-vector-icons(\\/.*)?/, '@expo/vector-icons$1']);\n }\n if (isReactServerComponentsEnabled) {\n if (resolveFrom.silent(config.projectRoot, 'expo-router/rsc')) {\n debug('Enabling bridge alias: expo-router -> expo-router/rsc');\n _universalAliases.push([/^expo-router$/, 'expo-router/rsc']);\n // Bridge the internal entry point which is a standalone import to ensure package.json resolution works as expected.\n _universalAliases.push([/^expo-router\\/entry-classic$/, 'expo-router/rsc/entry']);\n }\n }\n return _universalAliases;\n }\n\n // used to resolve externals in `requestCustomExternals` from the project root\n const projectRootOriginPath = path.join(config.projectRoot, 'package.json');\n\n const preferredMainFields: { [key: string]: string[] } = {\n // Defaults from Expo Webpack. Most packages using `react-native` don't support web\n // in the `react-native` field, so we should prefer the `browser` field.\n // https://github.com/expo/router/issues/37\n web: ['browser', 'module', 'main'],\n };\n\n let tsConfigResolve =\n isTsconfigPathsEnabled && (tsconfig?.paths || tsconfig?.baseUrl != null)\n ? resolveWithTsConfigPaths.bind(resolveWithTsConfigPaths, {\n paths: tsconfig.paths ?? {},\n baseUrl: tsconfig.baseUrl ?? config.projectRoot,\n hasBaseUrl: !!tsconfig.baseUrl,\n })\n : null;\n\n // TODO: Move this to be a transform key for invalidation.\n if (!isExporting && isInteractive()) {\n if (isTsconfigPathsEnabled) {\n // TODO: We should track all the files that used imports and invalidate them\n // currently the user will need to save all the files that use imports to\n // use the new aliases.\n const configWatcher = new FileNotifier(config.projectRoot, [\n './tsconfig.json',\n './jsconfig.json',\n ]);\n configWatcher.startObserving(() => {\n debug('Reloading tsconfig.json');\n loadTsConfigPathsAsync(config.projectRoot).then((tsConfigPaths) => {\n if (tsConfigPaths?.paths && !!Object.keys(tsConfigPaths.paths).length) {\n debug('Enabling tsconfig.json paths support');\n tsConfigResolve = resolveWithTsConfigPaths.bind(resolveWithTsConfigPaths, {\n paths: tsConfigPaths.paths ?? {},\n baseUrl: tsConfigPaths.baseUrl ?? config.projectRoot,\n hasBaseUrl: !!tsConfigPaths.baseUrl,\n });\n } else {\n debug('Disabling tsconfig.json paths support');\n tsConfigResolve = null;\n }\n });\n });\n\n // TODO: This probably prevents the process from exiting.\n installExitHooks(() => {\n configWatcher.stopObserving();\n });\n } else {\n debug('Skipping tsconfig.json paths support');\n }\n }\n\n let nodejsSourceExtensions: string[] | null = null;\n\n const getStrictResolver: StrictResolverFactory = (\n { resolveRequest, ...context },\n platform\n ): StrictResolver => {\n return function doResolve(moduleName: string): Resolution {\n return resolver(context, moduleName, platform);\n };\n };\n\n function getOptionalResolver(context: ResolutionContext, platform: string | null) {\n const doResolve = getStrictResolver(context, platform);\n return function optionalResolve(moduleName: string): Resolution | null {\n try {\n return doResolve(moduleName);\n } catch (error) {\n // If the error is directly related to a resolver not being able to resolve a module, then\n // we can ignore the error and try the next resolver. Otherwise, we should throw the error.\n const isResolutionError =\n isFailedToResolveNameError(error) || isFailedToResolvePathError(error);\n if (!isResolutionError) {\n throw error;\n }\n }\n return null;\n };\n }\n\n // TODO: This is a hack to get resolveWeak working.\n const idFactory = (config.serializer?.createModuleIdFactory?.() ??\n ((id: number | string, context: { platform: string; environment?: string }): number | string =>\n id)) as (\n id: number | string,\n context: { platform: string; environment?: string }\n ) => number | string;\n\n // We're manually resolving the `asyncRequireModulePath` since it's a module request\n // However, in isolated installations it might not resolve from all paths, so we're resolving\n // it from the project root manually\n let _asyncRequireModuleResolvedPath: string | null | undefined;\n const getAsyncRequireModule = () => {\n if (_asyncRequireModuleResolvedPath === undefined) {\n _asyncRequireModuleResolvedPath =\n resolveFrom.silent(config.projectRoot, config.transformer.asyncRequireModulePath) ?? null;\n }\n return _asyncRequireModuleResolvedPath\n ? ({ type: 'sourceFile', filePath: _asyncRequireModuleResolvedPath } as const)\n : null;\n };\n\n const getAssetRegistryModule = () => {\n const virtualModuleId = `\\0polyfill:assets-registry`;\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n ASSET_REGISTRY_SRC\n );\n return {\n type: 'sourceFile',\n filePath: virtualModuleId,\n } as const;\n };\n\n // If Node.js pass-through, then remap to a module like `module.exports = $$require_external(<module>)`.\n // If module should be shimmed, remap to an empty module.\n const externals: {\n match: (context: ResolutionContext, moduleName: string, platform: string | null) => boolean;\n replace: 'empty' | 'node' | 'weak';\n }[] = [\n {\n match: (context: ResolutionContext, moduleName: string) => {\n if (\n // Disable internal externals when exporting for production.\n context.customResolverOptions.exporting ||\n // These externals are only for Node.js environments.\n !isServerEnvironment(context.customResolverOptions?.environment)\n ) {\n return false;\n }\n\n if (context.customResolverOptions?.environment === 'react-server') {\n // Ensure these non-react-server modules are excluded when bundling for React Server Components in development.\n return /^(source-map-support(\\/.*)?|@babel\\/runtime\\/.+|debug|metro-runtime\\/src\\/modules\\/HMRClient|metro|acorn-loose|acorn|chalk|ws|ansi-styles|supports-color|color-convert|has-flag|utf-8-validate|color-name|react-refresh\\/runtime|@remix-run\\/node\\/.+)$/.test(\n moduleName\n );\n }\n\n // TODO: Windows doesn't support externals somehow.\n if (process.platform === 'win32') {\n return /^(source-map-support(\\/.*)?)$/.test(moduleName);\n }\n\n // Extern these modules in standard Node.js environments in development to prevent API routes side-effects\n // from leaking into the dev server process.\n return /^(source-map-support(\\/.*)?|react|@radix-ui\\/.+|@babel\\/runtime\\/.+|react-dom(\\/.+)?|debug|acorn-loose|acorn|css-in-js-utils\\/lib\\/.+|hyphenate-style-name|color|color-string|color-convert|color-name|fontfaceobserver|fast-deep-equal|query-string|escape-string-regexp|invariant|postcss-value-parser|memoize-one|nullthrows|strict-uri-encode|decode-uri-component|split-on-first|filter-obj|warn-once|simple-swizzle|is-arrayish|inline-style-prefixer\\/.+)$/.test(\n moduleName\n );\n },\n replace: 'node',\n },\n // Externals to speed up async split chunks by extern-ing common packages that appear in the root client chunk.\n {\n match: (context: ResolutionContext, moduleName: string, platform: string | null) => {\n if (\n // Disable internal externals when exporting for production.\n context.customResolverOptions.exporting ||\n // These externals are only for client environments.\n isServerEnvironment(context.customResolverOptions?.environment) ||\n // Only enable for client boundaries\n !context.customResolverOptions.clientboundary\n ) {\n return false;\n }\n\n // We don't support this in the resolver at the moment.\n if (moduleName.endsWith('/package.json')) {\n return false;\n }\n\n const isExternal = // Extern these modules in standard Node.js environments.\n /^(deprecated-react-native-prop-types|react|react\\/jsx-dev-runtime|scheduler|react-native|react-dom(\\/.+)?|metro-runtime(\\/.+)?)$/.test(\n moduleName\n ) ||\n // TODO: Add more\n /^@babel\\/runtime\\/helpers\\/(wrapNativeSuper)$/.test(moduleName);\n\n return isExternal;\n },\n replace: 'weak',\n },\n ];\n\n const metroConfigWithCustomResolver = withMetroResolvers(config, [\n // Mock out production react imports in development.\n function requestDevMockProdReact(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n // This resolution is dev-only to prevent bundling the production React packages in development.\n if (!context.dev) return null;\n\n if (\n // Match react-native renderers.\n (platform !== 'web' &&\n context.originModulePath.match(/[\\\\/]node_modules[\\\\/]react-native[\\\\/]/) &&\n moduleName.match(/([\\\\/]ReactFabric|ReactNativeRenderer)-prod/)) ||\n // Match react production imports.\n (moduleName.match(/\\.production(\\.min)?\\.js$/) &&\n // Match if the import originated from a react package.\n context.originModulePath.match(/[\\\\/]node_modules[\\\\/](react[-\\\\/]|scheduler[\\\\/])/))\n ) {\n debug(`Skipping production module: ${moduleName}`);\n // /Users/path/to/expo/node_modules/react/index.js ./cjs/react.production.min.js\n // /Users/path/to/expo/node_modules/react/jsx-dev-runtime.js ./cjs/react-jsx-dev-runtime.production.min.js\n // /Users/path/to/expo/node_modules/react-is/index.js ./cjs/react-is.production.min.js\n // /Users/path/to/expo/node_modules/react-refresh/runtime.js ./cjs/react-refresh-runtime.production.min.js\n // /Users/path/to/expo/node_modules/react-native/node_modules/scheduler/index.native.js ./cjs/scheduler.native.production.min.js\n // /Users/path/to/expo/node_modules/react-native/node_modules/react-is/index.js ./cjs/react-is.production.min.js\n return {\n type: 'empty',\n };\n }\n return null;\n },\n // tsconfig paths\n function requestTsconfigPaths(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n return (\n tsConfigResolve?.(\n {\n originModulePath: context.originModulePath,\n moduleName,\n },\n getOptionalResolver(context, platform)\n ) ?? null\n );\n },\n\n // Node.js externals support\n function requestNodeExternals(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n const isServer =\n context.customResolverOptions?.environment === 'node' ||\n context.customResolverOptions?.environment === 'react-server';\n\n const moduleId = isNodeExternal(moduleName);\n if (!moduleId) {\n return null;\n }\n\n if (\n // In browser runtimes, we want to either resolve a local node module by the same name, or shim the module to\n // prevent crashing when Node.js built-ins are imported.\n !isServer\n ) {\n // Perform optional resolve first. If the module doesn't exist (no module in the node_modules)\n // then we can mock the file to use an empty module.\n const result = getOptionalResolver(context, platform)(moduleName);\n\n if (!result && platform !== 'web') {\n // Preserve previous behavior where native throws an error on node.js internals.\n return null;\n }\n\n return (\n result ?? {\n // In this case, mock the file to use an empty module.\n type: 'empty',\n }\n );\n }\n const contents = `module.exports=$$require_external('node:${moduleId}');`;\n debug(`Virtualizing Node.js \"${moduleId}\"`);\n const virtualModuleId = `\\0node:${moduleId}`;\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n contents\n );\n return {\n type: 'sourceFile',\n filePath: virtualModuleId,\n };\n },\n\n // Custom externals support\n function requestCustomExternals(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n // We don't support this in the resolver at the moment.\n if (moduleName.endsWith('/package.json')) {\n return null;\n }\n // Skip applying JS externals for CSS files.\n if (/\\.(s?css|sass)$/.test(context.originModulePath)) {\n return null;\n }\n\n for (const external of externals) {\n if (external.match(context, moduleName, platform)) {\n if (external.replace === 'empty') {\n debug(`Redirecting external \"${moduleName}\" to \"${external.replace}\"`);\n return {\n type: external.replace,\n };\n } else if (external.replace === 'weak') {\n // TODO: Make this use require.resolveWeak again. Previously this was just resolving to the same path.\n const realModule = getStrictResolver(context, platform)(moduleName);\n const realPath = realModule.type === 'sourceFile' ? realModule.filePath : moduleName;\n const opaqueId = idFactory(realPath, {\n platform: platform!,\n environment: context.customResolverOptions?.environment,\n });\n const contents =\n typeof opaqueId === 'number'\n ? `module.exports=/*${moduleName}*/__r(${opaqueId})`\n : `module.exports=/*${moduleName}*/__r(${JSON.stringify(opaqueId)})`;\n // const contents = `module.exports=/*${moduleName}*/__r(require.resolveWeak('${moduleName}'))`;\n // const generatedModuleId = fastHashMemoized(contents);\n const virtualModuleId = `\\0weak:${opaqueId}`;\n debug('Virtualizing module:', moduleName, '->', virtualModuleId);\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n contents\n );\n return {\n type: 'sourceFile',\n filePath: virtualModuleId,\n };\n } else if (external.replace === 'node') {\n // TODO(@kitten): Temporary workaround. Our externals logic here isn't generic and only works\n // for development and not exports. We never intend to use it in exported production bundles,\n // however, this is still a dangerous implementation. To protect us from externalizing modules\n // that aren't available to the app, we force any resolution to happen via the project root\n const projectRootContext: ResolutionContext = {\n ...context,\n nodeModulesPaths: [],\n originModulePath: projectRootOriginPath,\n disableHierarchicalLookup: false,\n };\n const externModule = getStrictResolver(projectRootContext, platform)(moduleName);\n if (externModule.type !== 'sourceFile') {\n return null;\n }\n const contents = `module.exports=$$require_external('${moduleName}')`;\n const virtualModuleId = `\\0node:${moduleName}`;\n debug('Virtualizing Node.js (custom):', moduleName, '->', virtualModuleId);\n getMetroBundlerWithVirtualModules(getMetroBundler()).setVirtualModule(\n virtualModuleId,\n contents\n );\n return {\n type: 'sourceFile',\n filePath: virtualModuleId,\n };\n } else {\n external.replace satisfies never;\n }\n }\n }\n return null;\n },\n\n // Basic moduleId aliases\n function requestAlias(context: ResolutionContext, moduleName: string, platform: string | null) {\n // Conditionally remap `react-native` to `react-native-web` on web in\n // a way that doesn't require Babel to resolve the alias.\n if (platform && platform in aliases && aliases[platform][moduleName]) {\n const redirectedModuleName = aliases[platform][moduleName];\n return getStrictResolver(context, platform)(redirectedModuleName);\n }\n\n for (const [matcher, alias] of getUniversalAliases()) {\n const match = moduleName.match(matcher);\n if (match) {\n const aliasedModule = alias.replace(\n /\\$(\\d+)/g,\n (_, index) => match[parseInt(index, 10)] ?? ''\n );\n const doResolve = getStrictResolver(context, platform);\n debug(`Alias \"${moduleName}\" to \"${aliasedModule}\"`);\n return doResolve(aliasedModule);\n }\n }\n\n return null;\n },\n\n // Polyfill for asset registry (assetRegistryPath) and async require module (asyncRequireModulePath)\n function requestStableConfigModules(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n if (moduleName === config.transformer.asyncRequireModulePath) {\n return getAsyncRequireModule();\n }\n\n // TODO(@kitten): Compare against `config.transformer.assetRegistryPath`\n if (/^@react-native\\/assets-registry\\/registry(\\.js)?$/.test(moduleName)) {\n return getAssetRegistryModule();\n }\n\n if (\n platform === 'web' &&\n context.originModulePath.match(/node_modules[\\\\/]react-native-web[\\\\/]/) &&\n moduleName.includes('/modules/AssetRegistry')\n ) {\n return getAssetRegistryModule();\n }\n\n return null;\n },\n\n createAutolinkingModuleResolver(autolinkingModuleResolverInput, {\n getStrictResolver,\n }),\n\n // TODO: Reduce these as much as possible in the future.\n // Complex post-resolution rewrites.\n function requestPostRewrites(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null\n ) {\n const doResolve = getStrictResolver(context, platform);\n\n const result = doResolve(moduleName);\n\n if (result.type !== 'sourceFile') {\n return result;\n }\n\n const normalizedPath = normalizeSlashes(result.filePath);\n\n const doReplace = (from: string, to: string | undefined, options?: { throws?: boolean }) =>\n doReplaceHelper(from, to, {\n normalizedPath,\n doResolve,\n ...options,\n });\n const doReplaceStrict = (from: string, to: string | undefined) =>\n doReplace(from, to, { throws: true });\n\n if (env.EXPO_UNSTABLE_WEB_MODAL) {\n const webModalModule = doReplace(\n 'expo-router/build/layouts/_web-modal.js',\n 'expo-router/build/layouts/ExperimentalModalStack.js'\n );\n if (webModalModule) {\n debug('Using `_unstable-web-modal` implementation.');\n return webModalModule;\n }\n }\n\n if (platform === 'web') {\n if (result.filePath.includes('node_modules')) {\n // Disallow importing confusing native modules on web\n if (\n [\n 'react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore',\n 'react-native/Libraries/Utilities/codegenNativeCommands',\n 'react-native/Libraries/Utilities/codegenNativeComponent',\n ].some((matcher) =>\n // Support absolute and modules with .js extensions.\n moduleName.includes(matcher)\n )\n ) {\n throw new FailedToResolvePathError(\n `Importing native-only module \"${moduleName}\" on web from: ${path.relative(config.projectRoot, context.originModulePath)}`\n );\n }\n\n // Replace with static shims\n\n // Drop everything up until the `node_modules` folder.\n const normalName = normalizedPath.replace(/.*node_modules\\//, '');\n\n const shimFile = shouldCreateVirtualShim(normalName);\n if (shimFile) {\n const virtualId = `\\0shim:${normalName}`;\n const bundler = getMetroBundlerWithVirtualModules(getMetroBundler());\n if (!bundler.hasVirtualModule(virtualId)) {\n bundler.setVirtualModule(virtualId, fs.readFileSync(shimFile, 'utf8'));\n }\n debug(`Redirecting module \"${result.filePath}\" to shim`);\n\n return {\n ...result,\n filePath: virtualId,\n };\n }\n }\n } else {\n const isServer =\n context.customResolverOptions?.environment === 'node' ||\n context.customResolverOptions?.environment === 'react-server';\n\n // Shim out React Native native runtime globals in server mode for native.\n if (isServer) {\n const emptyModule = doReplace('react-native/Libraries/Core/InitializeCore.js', undefined);\n if (emptyModule) {\n debug('Shimming out InitializeCore for React Native in native SSR bundle');\n return emptyModule;\n }\n }\n\n const hmrModule = doReplaceStrict(\n 'react-native/Libraries/Utilities/HMRClient.js',\n 'expo/src/async-require/hmr.ts'\n );\n if (hmrModule) return hmrModule;\n\n if (env.EXPO_UNSTABLE_LOG_BOX) {\n const logBoxModule = doReplace(\n 'react-native/Libraries/LogBox/LogBoxInspectorContainer.js',\n '@expo/log-box/swap-rn-logbox.js'\n );\n if (logBoxModule) return logBoxModule;\n\n const logBoxParserModule = doReplace(\n 'react-native/Libraries/LogBox/Data/parseLogBoxLog.js',\n '@expo/log-box/swap-rn-logbox-parser.js'\n );\n if (logBoxParserModule) return logBoxParserModule;\n }\n }\n\n return result;\n },\n\n // If at this point, we haven't resolved a module yet, if it's a module specifier for a known dependency\n // of either `expo` or `expo-router`, attempt to resolve it from these origin modules instead\n createFallbackModuleResolver({\n projectRoot: config.projectRoot,\n originModuleNames: ['expo', 'expo-router'],\n getStrictResolver,\n }),\n ]);\n\n // Ensure we mutate the resolution context to include the custom resolver options for server and web.\n const metroConfigWithCustomContext = withMetroMutatedResolverContext(\n metroConfigWithCustomResolver,\n (\n immutableContext: CustomResolutionContext,\n moduleName: string,\n platform: string | null\n ): CustomResolutionContext => {\n const context: Mutable<CustomResolutionContext> = {\n ...immutableContext,\n preferNativePlatform: platform !== 'web',\n };\n\n if (isServerEnvironment(context.customResolverOptions?.environment)) {\n // Adjust nodejs source extensions to sort mjs after js, including platform variants.\n if (nodejsSourceExtensions === null) {\n nodejsSourceExtensions = getNodejsExtensions(context.sourceExts);\n }\n context.sourceExts = nodejsSourceExtensions;\n\n context.unstable_enablePackageExports = true;\n context.unstable_conditionsByPlatform = {};\n\n const isReactServerComponents =\n context.customResolverOptions?.environment === 'react-server';\n\n if (isReactServerComponents) {\n // NOTE: Align the behavior across server and client. This is a breaking change so we'll just roll it out with React Server Components.\n // This ensures that react-server and client code both resolve `module` and `main` in the same order.\n if (platform === 'web') {\n // Node.js runtimes should only be importing main at the moment.\n // This is a temporary fix until we can support the package.json exports.\n context.mainFields = ['module', 'main'];\n } else {\n // In Node.js + native, use the standard main fields.\n context.mainFields = ['react-native', 'module', 'main'];\n }\n } else {\n if (platform === 'web') {\n // Node.js runtimes should only be importing main at the moment.\n // This is a temporary fix until we can support the package.json exports.\n context.mainFields = ['main', 'module'];\n } else {\n // In Node.js + native, use the standard main fields.\n context.mainFields = ['react-native', 'main', 'module'];\n }\n }\n\n // Enable react-server import conditions.\n if (context.customResolverOptions?.environment === 'react-server') {\n context.unstable_conditionNames = ['node', 'react-server', 'workerd'];\n } else {\n context.unstable_conditionNames = ['node'];\n }\n } else {\n // Non-server changes\n\n if (!env.EXPO_METRO_NO_MAIN_FIELD_OVERRIDE && platform && platform in preferredMainFields) {\n context.mainFields = preferredMainFields[platform];\n }\n }\n\n return context;\n }\n );\n\n return withMetroErrorReportingResolver(\n withMetroSupervisingTransformWorker(metroConfigWithCustomContext)\n );\n}\n\nfunction doReplaceHelper(\n from: string,\n to: string | undefined,\n {\n throws = false,\n normalizedPath,\n doResolve,\n }: {\n throws?: boolean;\n normalizedPath: string;\n doResolve: StrictResolver;\n }\n): SourceFileResolution | { type: 'empty' } | undefined {\n if (!normalizedPath.endsWith(from)) {\n return undefined;\n }\n\n if (to === undefined) {\n return {\n type: 'empty',\n };\n }\n\n try {\n const hmrModule = doResolve(to);\n if (hmrModule.type === 'sourceFile') {\n debug(`Using \\`${to}\\` implementation.`);\n return hmrModule;\n }\n } catch (resolutionError) {\n if (throws) {\n throw new Error(`Failed to replace ${from} with ${to}. Resolution of ${to} failed.`, {\n cause: resolutionError,\n });\n }\n\n debug(`Failed to resolve ${to} when swapping from ${from}: ${resolutionError}`);\n }\n return undefined;\n}\n\n/** @returns `true` if the incoming resolution should be swapped. */\nexport function shouldAliasModule(\n input: {\n platform: string | null;\n result: Resolution;\n },\n alias: { platform: string; output: string }\n): boolean {\n return (\n input.platform === alias.platform &&\n input.result?.type === 'sourceFile' &&\n typeof input.result?.filePath === 'string' &&\n normalizeSlashes(input.result.filePath).endsWith(alias.output)\n );\n}\n\n/** Add support for `react-native-web` and the Web platform. */\nexport async function withMetroMultiPlatformAsync(\n projectRoot: string,\n {\n config,\n exp,\n platformBundlers,\n isTsconfigPathsEnabled,\n isAutolinkingResolverEnabled,\n isFastResolverEnabled,\n isExporting,\n\n isReactServerComponentsEnabled,\n getMetroBundler,\n }: {\n config: ConfigT;\n exp: ExpoConfig;\n isTsconfigPathsEnabled: boolean;\n platformBundlers: PlatformBundlers;\n isAutolinkingResolverEnabled?: boolean;\n isFastResolverEnabled?: boolean;\n isExporting?: boolean;\n\n isReactServerComponentsEnabled: boolean;\n isNamedRequiresEnabled: boolean;\n getMetroBundler: () => Bundler;\n }\n) {\n // Change the default metro-runtime to a custom one that supports bundle splitting.\n // NOTE(@kitten): This is now always active and EXPO_USE_METRO_REQUIRE / isNamedRequiresEnabled is disregarded\n const metroDefaults: Mutable<\n typeof import('@expo/metro/metro-config/defaults/defaults')\n > = require('@expo/metro/metro-config/defaults/defaults');\n metroDefaults.moduleSystem = require.resolve('@expo/cli/build/metro-require/require');\n\n if (!config.projectRoot) {\n // @ts-expect-error: read-only types\n config.projectRoot = projectRoot;\n }\n\n // Required for @expo/metro-runtime to format paths in the web LogBox.\n process.env.EXPO_PUBLIC_PROJECT_ROOT = process.env.EXPO_PUBLIC_PROJECT_ROOT ?? projectRoot;\n\n // This is used for running Expo CLI in development against projects outside the monorepo.\n if (!isDirectoryIn(__dirname, projectRoot)) {\n // TODO(@kitten): Remove ts-export-errors here and replace with cast for type safety\n if (!config.watchFolders) {\n // @ts-expect-error: watchFolders is readonly\n config.watchFolders = [];\n }\n // @ts-expect-error: watchFolders is readonly\n config.watchFolders.push(path.join(require.resolve('metro-runtime/package.json'), '../..'));\n // @ts-expect-error: watchFolders is readonly\n config.watchFolders.push(\n path.join(require.resolve('@expo/metro-config/package.json'), '../..'),\n // For virtual modules\n path.join(require.resolve('expo/package.json'), '..')\n );\n }\n\n let tsconfig: null | TsConfigPaths = null;\n\n if (isTsconfigPathsEnabled) {\n tsconfig = await loadTsConfigPathsAsync(projectRoot);\n }\n\n let expoConfigPlatforms = Object.entries(platformBundlers)\n .filter(\n ([platform, bundler]) => bundler === 'metro' && exp.platforms?.includes(platform as Platform)\n )\n .map(([platform]) => platform);\n\n if (Array.isArray(config.resolver.platforms)) {\n expoConfigPlatforms = [...new Set(expoConfigPlatforms.concat(config.resolver.platforms))];\n }\n\n // @ts-expect-error: typed as `readonly`.\n config.resolver.platforms = expoConfigPlatforms;\n\n config = withWebPolyfills(config, { getMetroBundler });\n\n let autolinkingModuleResolverInput: AutolinkingModuleResolverInput | undefined;\n if (isAutolinkingResolverEnabled) {\n autolinkingModuleResolverInput = await createAutolinkingModuleResolverInput({\n platforms: expoConfigPlatforms,\n projectRoot,\n });\n }\n\n return withExtendedResolver(config, {\n autolinkingModuleResolverInput,\n tsconfig,\n isExporting,\n isTsconfigPathsEnabled,\n isFastResolverEnabled,\n isReactServerComponentsEnabled,\n getMetroBundler,\n });\n}\n\nfunction isDirectoryIn(targetPath: string, rootPath: string) {\n return targetPath.startsWith(rootPath) && targetPath.length >= rootPath.length;\n}\n"],"names":["getNodejsExtensions","shouldAliasModule","withExtendedResolver","withMetroMultiPlatformAsync","ASSET_REGISTRY_SRC","debug","require","withWebPolyfills","config","getMetroBundler","originalGetPolyfills","serializer","getPolyfills","bind","ctx","virtualEnvVarId","getMetroBundlerWithVirtualModules","setVirtualModule","virtualModuleId","platform","virtualModulesPolyfills","rnGetPolyfills","filter","x","includes","error","code","polyfills","resolve","normalizeSlashes","p","replace","srcExts","mjsExts","ext","test","nodejsSourceExtensions","jsIndex","reduce","index","i","splice","tsconfig","autolinkingModuleResolverInput","isTsconfigPathsEnabled","isFastResolverEnabled","isExporting","isReactServerComponentsEnabled","Log","warn","log","chalk","dim","defaultResolver","metroResolver","resolver","createFastResolver","preserveSymlinks","blockList","Array","isArray","aliases","web","_universalAliases","getUniversalAliases","resolveFrom","silent","projectRoot","push","projectRootOriginPath","path","join","preferredMainFields","tsConfigResolve","paths","baseUrl","resolveWithTsConfigPaths","hasBaseUrl","isInteractive","configWatcher","FileNotifier","startObserving","loadTsConfigPathsAsync","then","tsConfigPaths","Object","keys","length","installExitHooks","stopObserving","getStrictResolver","resolveRequest","context","doResolve","moduleName","getOptionalResolver","optionalResolve","isResolutionError","isFailedToResolveNameError","isFailedToResolvePathError","idFactory","createModuleIdFactory","id","_asyncRequireModuleResolvedPath","getAsyncRequireModule","undefined","transformer","asyncRequireModulePath","type","filePath","getAssetRegistryModule","externals","match","customResolverOptions","exporting","isServerEnvironment","environment","process","clientboundary","endsWith","isExternal","metroConfigWithCustomResolver","withMetroResolvers","requestDevMockProdReact","dev","originModulePath","requestTsconfigPaths","requestNodeExternals","isServer","moduleId","isNodeExternal","result","contents","requestCustomExternals","external","realModule","realPath","opaqueId","JSON","stringify","projectRootContext","nodeModulesPaths","disableHierarchicalLookup","externModule","requestAlias","redirectedModuleName","matcher","alias","aliasedModule","_","parseInt","requestStableConfigModules","createAutolinkingModuleResolver","requestPostRewrites","normalizedPath","doReplace","from","to","options","doReplaceHelper","doReplaceStrict","throws","env","EXPO_UNSTABLE_WEB_MODAL","webModalModule","some","FailedToResolvePathError","relative","normalName","shimFile","shouldCreateVirtualShim","virtualId","bundler","hasVirtualModule","fs","readFileSync","emptyModule","hmrModule","EXPO_UNSTABLE_LOG_BOX","logBoxModule","logBoxParserModule","createFallbackModuleResolver","originModuleNames","metroConfigWithCustomContext","withMetroMutatedResolverContext","immutableContext","preferNativePlatform","sourceExts","unstable_enablePackageExports","unstable_conditionsByPlatform","isReactServerComponents","mainFields","unstable_conditionNames","EXPO_METRO_NO_MAIN_FIELD_OVERRIDE","withMetroErrorReportingResolver","withMetroSupervisingTransformWorker","resolutionError","Error","cause","input","output","exp","platformBundlers","isAutolinkingResolverEnabled","metroDefaults","moduleSystem","EXPO_PUBLIC_PROJECT_ROOT","isDirectoryIn","__dirname","watchFolders","expoConfigPlatforms","entries","platforms","map","Set","concat","createAutolinkingModuleResolverInput","targetPath","rootPath","startsWith"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/middleware/DataLoaderModuleMiddleware.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\n\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport { ServerNext, ServerRequest, ServerResponse } from './server.types';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/middleware/DataLoaderModuleMiddleware.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport { type RouteInfo } from 'expo-server/private';\n\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport { ServerNext, ServerRequest, ServerResponse } from './server.types';\nimport { fetchManifest } from '../metro/fetchRouterManifest';\n\nconst LOADER_MODULE_ENDPOINT = '/_expo/loaders';\n\n/**\n * Middleware for serving loader data modules dynamically during development. This allows\n * client-side navigation to fetch loader data on-demand.\n *\n * In production, these modules are pre-generated as static files.\n */\nexport class DataLoaderModuleMiddleware extends ExpoMiddleware {\n constructor(\n protected projectRoot: string,\n protected appDir: string,\n private executeServerDataLoaderAsync: (url: URL, route: RouteInfo<RegExp>) => Promise<any>,\n private getDevServerUrl: () => string\n ) {\n super(projectRoot, [LOADER_MODULE_ENDPOINT]);\n }\n\n /**\n * Only handles a request if `req.pathname` begins with `/_expo/loaders/` and if the request\n * headers include `Accept: application/json`.\n */\n override shouldHandleRequest(req: ServerRequest): boolean {\n if (!req.url) return false;\n const { pathname } = new URL(req.url, 'http://localhost');\n\n if (!pathname.startsWith(`${LOADER_MODULE_ENDPOINT}/`)) {\n return false;\n }\n\n if (req.headers.accept !== 'application/json') {\n return false;\n }\n\n const { exp } = getConfig(this.projectRoot);\n return !!exp.extra?.router?.unstable_useServerDataLoaders;\n }\n\n async handleRequestAsync(\n req: ServerRequest,\n res: ServerResponse,\n next: ServerNext\n ): Promise<void> {\n if (!['GET', 'HEAD'].includes(req.method ?? '')) {\n return next();\n }\n\n const manifest = await fetchManifest<RegExp>(this.projectRoot, {\n appDir: this.appDir,\n });\n\n const { pathname } = new URL(req.url!, 'http://localhost');\n\n try {\n const routePath = pathname.replace('/_expo/loaders', '').replace('/index', '/') || '/';\n\n const matchingRoute = manifest?.htmlRoutes.find((route) => {\n return route.namedRegex.test(routePath);\n });\n\n if (!matchingRoute) {\n throw new Error(`No matching route for ${routePath}`);\n }\n\n const loaderData = await this.executeServerDataLoaderAsync(\n new URL(routePath, this.getDevServerUrl()),\n matchingRoute\n );\n\n res.setHeader('Content-Type', 'application/javascript; charset=utf-8');\n res.setHeader('Cache-Control', 'no-cache');\n res.statusCode = 200;\n res.end(JSON.stringify(loaderData ?? {}));\n } catch (error) {\n console.error(`Failed to generate loader module for ${pathname}:`, error);\n res.statusCode = 500;\n res.end(`{}`);\n }\n }\n}\n"],"names":["DataLoaderModuleMiddleware","LOADER_MODULE_ENDPOINT","ExpoMiddleware","constructor","projectRoot","appDir","executeServerDataLoaderAsync","getDevServerUrl","shouldHandleRequest","req","exp","url","pathname","URL","startsWith","headers","accept","getConfig","extra","router","unstable_useServerDataLoaders","handleRequestAsync","res","next","includes","method","manifest","fetchManifest","routePath","replace","matchingRoute","htmlRoutes","find","route","namedRegex","test","Error","loaderData","setHeader","statusCode","end","JSON","stringify","error","console"],"mappings":";;;;+BAeaA;;;eAAAA;;;;yBAfa;;;;;;gCAGK;qCAED;AAE9B,MAAMC,yBAAyB;AAQxB,MAAMD,mCAAmCE,8BAAc;IAC5DC,YACE,AAAUC,WAAmB,EAC7B,AAAUC,MAAc,EACxB,AAAQC,4BAAkF,EAC1F,AAAQC,eAA6B,CACrC;QACA,KAAK,CAACH,aAAa;YAACH;SAAuB,QALjCG,cAAAA,kBACAC,SAAAA,aACFC,+BAAAA,mCACAC,kBAAAA;IAGV;IAEA;;;GAGC,GACD,AAASC,oBAAoBC,GAAkB,EAAW;YAa/CC,mBAAAA;QAZT,IAAI,CAACD,IAAIE,GAAG,EAAE,OAAO;QACrB,MAAM,EAAEC,QAAQ,EAAE,GAAG,IAAIC,IAAIJ,IAAIE,GAAG,EAAE;QAEtC,IAAI,CAACC,SAASE,UAAU,CAAC,GAAGb,uBAAuB,CAAC,CAAC,GAAG;YACtD,OAAO;QACT;QAEA,IAAIQ,IAAIM,OAAO,CAACC,MAAM,KAAK,oBAAoB;YAC7C,OAAO;QACT;QAEA,MAAM,EAAEN,GAAG,EAAE,GAAGO,IAAAA,mBAAS,EAAC,IAAI,CAACb,WAAW;QAC1C,OAAO,CAAC,GAACM,aAAAA,IAAIQ,KAAK,sBAATR,oBAAAA,WAAWS,MAAM,qBAAjBT,kBAAmBU,6BAA6B;IAC3D;IAEA,MAAMC,mBACJZ,GAAkB,EAClBa,GAAmB,EACnBC,IAAgB,EACD;QACf,IAAI,CAAC;YAAC;YAAO;SAAO,CAACC,QAAQ,CAACf,IAAIgB,MAAM,IAAI,KAAK;YAC/C,OAAOF;QACT;QAEA,MAAMG,WAAW,MAAMC,IAAAA,kCAAa,EAAS,IAAI,CAACvB,WAAW,EAAE;YAC7DC,QAAQ,IAAI,CAACA,MAAM;QACrB;QAEA,MAAM,EAAEO,QAAQ,EAAE,GAAG,IAAIC,IAAIJ,IAAIE,GAAG,EAAG;QAEvC,IAAI;YACF,MAAMiB,YAAYhB,SAASiB,OAAO,CAAC,kBAAkB,IAAIA,OAAO,CAAC,UAAU,QAAQ;YAEnF,MAAMC,gBAAgBJ,4BAAAA,SAAUK,UAAU,CAACC,IAAI,CAAC,CAACC;gBAC/C,OAAOA,MAAMC,UAAU,CAACC,IAAI,CAACP;YAC/B;YAEA,IAAI,CAACE,eAAe;gBAClB,MAAM,IAAIM,MAAM,CAAC,sBAAsB,EAAER,WAAW;YACtD;YAEA,MAAMS,aAAa,MAAM,IAAI,CAAC/B,4BAA4B,CACxD,IAAIO,IAAIe,WAAW,IAAI,CAACrB,eAAe,KACvCuB;YAGFR,IAAIgB,SAAS,CAAC,gBAAgB;YAC9BhB,IAAIgB,SAAS,CAAC,iBAAiB;YAC/BhB,IAAIiB,UAAU,GAAG;YACjBjB,IAAIkB,GAAG,CAACC,KAAKC,SAAS,CAACL,cAAc,CAAC;QACxC,EAAE,OAAOM,OAAO;YACdC,QAAQD,KAAK,CAAC,CAAC,qCAAqC,EAAE/B,SAAS,CAAC,CAAC,EAAE+B;YACnErB,IAAIiB,UAAU,GAAG;YACjBjB,IAAIkB,GAAG,CAAC,CAAC,EAAE,CAAC;QACd;IACF;AACF"}
|
|
@@ -27,6 +27,8 @@ function evaluateJsFromCdpAsync(webSocketDebuggerUrl, source, timeoutMs = 2000)
|
|
|
27
27
|
reject(new Error('Request timeout'));
|
|
28
28
|
settled = true;
|
|
29
29
|
ws.close();
|
|
30
|
+
// NOTE(@hassankhan): The cast to `NodeJS.Timeout` below is a hack to work around an issue
|
|
31
|
+
// with TypeScript where React Native's types are being imported before Node types
|
|
30
32
|
}, timeoutMs);
|
|
31
33
|
ws.on('open', ()=>{
|
|
32
34
|
ws.send(JSON.stringify({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/start/server/middleware/inspector/CdpClient.ts"],"sourcesContent":["import { WebSocket } from 'ws';\n\nconst debug = require('debug')(\n 'expo:start:server:middleware:inspector:CdpClient'\n) as typeof console.log;\n\nexport function evaluateJsFromCdpAsync(\n webSocketDebuggerUrl: string,\n source: string,\n timeoutMs: number = 2000\n): Promise<string | undefined> {\n const REQUEST_ID = 0;\n let timeoutHandle: NodeJS.Timeout;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n const ws = new WebSocket(webSocketDebuggerUrl);\n\n timeoutHandle = setTimeout(() => {\n debug(`[evaluateJsFromCdpAsync] Request timeout from ${webSocketDebuggerUrl}`);\n reject(new Error('Request timeout'));\n settled = true;\n ws.close();\n }, timeoutMs);\n\n ws.on('open', () => {\n ws.send(\n JSON.stringify({\n id: REQUEST_ID,\n method: 'Runtime.evaluate',\n params: { expression: source },\n })\n );\n });\n\n ws.on('error', (e) => {\n debug(`[evaluateJsFromCdpAsync] Failed to connect ${webSocketDebuggerUrl}`, e);\n reject(e);\n settled = true;\n clearTimeout(timeoutHandle);\n ws.close();\n });\n\n ws.on('close', () => {\n if (!settled) {\n reject(new Error('WebSocket closed before response was received.'));\n clearTimeout(timeoutHandle);\n }\n });\n\n ws.on('message', (data) => {\n debug(\n `[evaluateJsFromCdpAsync] message received from ${webSocketDebuggerUrl}: ${data.toString()}`\n );\n try {\n const response = JSON.parse(data.toString());\n if (response.id === REQUEST_ID) {\n if (response.error) {\n reject(new Error(response.error.message));\n } else if (response.result.result.type === 'string') {\n resolve(response.result.result.value);\n } else {\n resolve(undefined);\n }\n settled = true;\n clearTimeout(timeoutHandle);\n ws.close();\n }\n } catch (e) {\n reject(e);\n settled = true;\n clearTimeout(timeoutHandle);\n ws.close();\n }\n });\n });\n}\n"],"names":["evaluateJsFromCdpAsync","debug","require","webSocketDebuggerUrl","source","timeoutMs","REQUEST_ID","timeoutHandle","Promise","resolve","reject","settled","ws","WebSocket","setTimeout","Error","close","on","send","JSON","stringify","id","method","params","expression","e","clearTimeout","data","toString","response","parse","error","message","result","type","value","undefined"],"mappings":";;;;+BAMgBA;;;eAAAA;;;;yBANU;;;;;;AAE1B,MAAMC,QAAQC,QAAQ,SACpB;AAGK,SAASF,uBACdG,oBAA4B,EAC5BC,MAAc,EACdC,YAAoB,IAAI;IAExB,MAAMC,aAAa;IACnB,IAAIC;IAEJ,OAAO,IAAIC,QAAQ,CAACC,SAASC;QAC3B,IAAIC,UAAU;QACd,MAAMC,KAAK,IAAIC,CAAAA,KAAQ,WAAC,CAACV;QAEzBI,gBAAgBO,WAAW;YACzBb,MAAM,CAAC,8CAA8C,EAAEE,sBAAsB;YAC7EO,OAAO,IAAIK,MAAM;YACjBJ,UAAU;YACVC,GAAGI,KAAK;
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/start/server/middleware/inspector/CdpClient.ts"],"sourcesContent":["import { WebSocket } from 'ws';\n\nconst debug = require('debug')(\n 'expo:start:server:middleware:inspector:CdpClient'\n) as typeof console.log;\n\nexport function evaluateJsFromCdpAsync(\n webSocketDebuggerUrl: string,\n source: string,\n timeoutMs: number = 2000\n): Promise<string | undefined> {\n const REQUEST_ID = 0;\n let timeoutHandle: NodeJS.Timeout;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n const ws = new WebSocket(webSocketDebuggerUrl);\n\n timeoutHandle = setTimeout(() => {\n debug(`[evaluateJsFromCdpAsync] Request timeout from ${webSocketDebuggerUrl}`);\n reject(new Error('Request timeout'));\n settled = true;\n ws.close();\n // NOTE(@hassankhan): The cast to `NodeJS.Timeout` below is a hack to work around an issue\n // with TypeScript where React Native's types are being imported before Node types\n }, timeoutMs) as unknown as NodeJS.Timeout;\n\n ws.on('open', () => {\n ws.send(\n JSON.stringify({\n id: REQUEST_ID,\n method: 'Runtime.evaluate',\n params: { expression: source },\n })\n );\n });\n\n ws.on('error', (e) => {\n debug(`[evaluateJsFromCdpAsync] Failed to connect ${webSocketDebuggerUrl}`, e);\n reject(e);\n settled = true;\n clearTimeout(timeoutHandle);\n ws.close();\n });\n\n ws.on('close', () => {\n if (!settled) {\n reject(new Error('WebSocket closed before response was received.'));\n clearTimeout(timeoutHandle);\n }\n });\n\n ws.on('message', (data) => {\n debug(\n `[evaluateJsFromCdpAsync] message received from ${webSocketDebuggerUrl}: ${data.toString()}`\n );\n try {\n const response = JSON.parse(data.toString());\n if (response.id === REQUEST_ID) {\n if (response.error) {\n reject(new Error(response.error.message));\n } else if (response.result.result.type === 'string') {\n resolve(response.result.result.value);\n } else {\n resolve(undefined);\n }\n settled = true;\n clearTimeout(timeoutHandle);\n ws.close();\n }\n } catch (e) {\n reject(e);\n settled = true;\n clearTimeout(timeoutHandle);\n ws.close();\n }\n });\n });\n}\n"],"names":["evaluateJsFromCdpAsync","debug","require","webSocketDebuggerUrl","source","timeoutMs","REQUEST_ID","timeoutHandle","Promise","resolve","reject","settled","ws","WebSocket","setTimeout","Error","close","on","send","JSON","stringify","id","method","params","expression","e","clearTimeout","data","toString","response","parse","error","message","result","type","value","undefined"],"mappings":";;;;+BAMgBA;;;eAAAA;;;;yBANU;;;;;;AAE1B,MAAMC,QAAQC,QAAQ,SACpB;AAGK,SAASF,uBACdG,oBAA4B,EAC5BC,MAAc,EACdC,YAAoB,IAAI;IAExB,MAAMC,aAAa;IACnB,IAAIC;IAEJ,OAAO,IAAIC,QAAQ,CAACC,SAASC;QAC3B,IAAIC,UAAU;QACd,MAAMC,KAAK,IAAIC,CAAAA,KAAQ,WAAC,CAACV;QAEzBI,gBAAgBO,WAAW;YACzBb,MAAM,CAAC,8CAA8C,EAAEE,sBAAsB;YAC7EO,OAAO,IAAIK,MAAM;YACjBJ,UAAU;YACVC,GAAGI,KAAK;QACR,0FAA0F;QAC1F,kFAAkF;QACpF,GAAGX;QAEHO,GAAGK,EAAE,CAAC,QAAQ;YACZL,GAAGM,IAAI,CACLC,KAAKC,SAAS,CAAC;gBACbC,IAAIf;gBACJgB,QAAQ;gBACRC,QAAQ;oBAAEC,YAAYpB;gBAAO;YAC/B;QAEJ;QAEAQ,GAAGK,EAAE,CAAC,SAAS,CAACQ;YACdxB,MAAM,CAAC,2CAA2C,EAAEE,sBAAsB,EAAEsB;YAC5Ef,OAAOe;YACPd,UAAU;YACVe,aAAanB;YACbK,GAAGI,KAAK;QACV;QAEAJ,GAAGK,EAAE,CAAC,SAAS;YACb,IAAI,CAACN,SAAS;gBACZD,OAAO,IAAIK,MAAM;gBACjBW,aAAanB;YACf;QACF;QAEAK,GAAGK,EAAE,CAAC,WAAW,CAACU;YAChB1B,MACE,CAAC,+CAA+C,EAAEE,qBAAqB,EAAE,EAAEwB,KAAKC,QAAQ,IAAI;YAE9F,IAAI;gBACF,MAAMC,WAAWV,KAAKW,KAAK,CAACH,KAAKC,QAAQ;gBACzC,IAAIC,SAASR,EAAE,KAAKf,YAAY;oBAC9B,IAAIuB,SAASE,KAAK,EAAE;wBAClBrB,OAAO,IAAIK,MAAMc,SAASE,KAAK,CAACC,OAAO;oBACzC,OAAO,IAAIH,SAASI,MAAM,CAACA,MAAM,CAACC,IAAI,KAAK,UAAU;wBACnDzB,QAAQoB,SAASI,MAAM,CAACA,MAAM,CAACE,KAAK;oBACtC,OAAO;wBACL1B,QAAQ2B;oBACV;oBACAzB,UAAU;oBACVe,aAAanB;oBACbK,GAAGI,KAAK;gBACV;YACF,EAAE,OAAOS,GAAG;gBACVf,OAAOe;gBACPd,UAAU;gBACVe,aAAanB;gBACbK,GAAGI,KAAK;YACV;QACF;IACF;AACF"}
|
|
@@ -84,7 +84,7 @@ async function setupTypedRoutes(options) {
|
|
|
84
84
|
* the legacy and new versions of TypedRoutes.
|
|
85
85
|
*
|
|
86
86
|
* TODO (@marklawlor): Remove this check in SDK 53, only support Expo Router v4 and above.
|
|
87
|
-
*/ const typedRoutesModule = _resolvefrom().default.silent(options.projectRoot, 'expo-
|
|
87
|
+
*/ const typedRoutesModule = _resolvefrom().default.silent(options.projectRoot, '@expo/router-server/build/typed-routes');
|
|
88
88
|
return typedRoutesModule ? typedRoutes(typedRoutesModule, options) : legacyTypedRoutes(options);
|
|
89
89
|
}
|
|
90
90
|
async function typedRoutes(typedRoutesModulePath, { server, metro, typesDirectory, projectRoot, routerDirectory, plugin }) {
|
|
@@ -173,6 +173,8 @@ function debounce(fn, delay) {
|
|
|
173
173
|
let timeoutId;
|
|
174
174
|
return function(...args) {
|
|
175
175
|
clearTimeout(timeoutId);
|
|
176
|
+
// NOTE(@hassankhan): The cast to `NodeJS.Timeout` below is a hack to work around an issue
|
|
177
|
+
// with TypeScript where React Native's types are being imported before Node types
|
|
176
178
|
timeoutId = setTimeout(()=>fn.apply(this, args), delay);
|
|
177
179
|
};
|
|
178
180
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/type-generation/routes.ts"],"sourcesContent":["import type Server from '@expo/metro/metro/Server';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { directoryExistsAsync } from '../../../utils/dir';\nimport { unsafeTemplate } from '../../../utils/template';\nimport { ServerLike } from '../BundlerDevServer';\nimport { metroWatchTypeScriptFiles } from '../metro/metroWatchTypeScriptFiles';\n\n// /test/[...param1]/[param2]/[param3] - captures [\"param1\", \"param2\", \"param3\"]\nexport const CAPTURE_DYNAMIC_PARAMS = /\\[(?:\\.{3})?(\\w*?)[\\]$]/g;\n// /[...param1]/ - Match [...param1]\nexport const CATCH_ALL = /\\[\\.\\.\\..+?\\]/g;\n// /[param1] - Match [param1]\nexport const SLUG = /\\[.+?\\]/g;\n// /(group1,group2,group3)/test - match (group1,group2,group3)\nexport const ARRAY_GROUP_REGEX = /\\(\\s*\\w[\\w\\s]*?,.*?\\)/g;\n// /(group1,group2,group3)/test - captures [\"group1\", \"group2\", \"group3\"]\nexport const CAPTURE_GROUP_REGEX = /[\\\\(,]\\s*(\\w[\\w\\s]*?)\\s*(?=[,\\\\)])/g;\n/**\n * Match:\n * - _layout files, +html, +not-found, string+api, etc\n * - Routes can still use `+`, but it cannot be in the last segment.\n */\nexport const TYPED_ROUTES_EXCLUSION_REGEX = /(_layout|[^/]*?\\+[^/]*?)\\.[tj]sx?$/;\n\nexport interface SetupTypedRoutesOptions {\n server?: ServerLike;\n metro?: Server | null;\n typesDirectory: string;\n projectRoot: string;\n /** Absolute expo router routes directory. */\n routerDirectory: string;\n plugin?: Record<string, any>;\n}\n\nexport async function setupTypedRoutes(options: SetupTypedRoutesOptions) {\n /*\n * In SDK 51, TypedRoutes was moved out of cli and into expo-router. For now we need to support both\n * the legacy and new versions of TypedRoutes.\n *\n * TODO (@marklawlor): Remove this check in SDK 53, only support Expo Router v4 and above.\n */\n const typedRoutesModule = resolveFrom.silent(\n options.projectRoot,\n 'expo-router/build/typed-routes'\n );\n return typedRoutesModule ? typedRoutes(typedRoutesModule, options) : legacyTypedRoutes(options);\n}\n\nasync function typedRoutes(\n typedRoutesModulePath: any,\n { server, metro, typesDirectory, projectRoot, routerDirectory, plugin }: SetupTypedRoutesOptions\n) {\n /*\n * Expo Router uses EXPO_ROUTER_APP_ROOT in multiple places to determine the root of the project.\n * In apps compiled by Metro, this code is compiled away. But Typed Routes run in NodeJS with no compilation\n * so we need to explicitly set it.\n */\n process.env.EXPO_ROUTER_APP_ROOT = routerDirectory;\n\n const typedRoutesModule = require(typedRoutesModulePath);\n\n /*\n * Typed Routes can be run with out Metro or a Server, e.g. `expo customize tsconfig.json`\n */\n if (metro && server) {\n // Setup out watcher first\n metroWatchTypeScriptFiles({\n projectRoot,\n server,\n metro,\n eventTypes: ['add', 'delete', 'change'],\n callback: typedRoutesModule.getWatchHandler(typesDirectory),\n });\n }\n\n /*\n * In SDK 52, the `regenerateDeclarations` was changed to accept plugin options.\n * This function has an optional parameter that we cannot override, so we need to ensure the user\n * is using a compatible version of `expo-router`. Otherwise, we will fallback to the old method.\n *\n * TODO(@marklawlor): In SDK53+ we should remove this check and always use the new method.\n */\n if ('version' in typedRoutesModule && typedRoutesModule.version >= 52) {\n typedRoutesModule.regenerateDeclarations(typesDirectory, plugin);\n } else {\n typedRoutesModule.regenerateDeclarations(typesDirectory);\n }\n}\n\nasync function legacyTypedRoutes({\n server,\n metro,\n typesDirectory,\n projectRoot,\n routerDirectory,\n}: SetupTypedRoutesOptions) {\n const { filePathToRoute, staticRoutes, dynamicRoutes, addFilePath, isRouteFile } =\n getTypedRoutesUtils(routerDirectory);\n\n // Typed Routes can be run with out Metro or a Server, e.g. `expo customize tsconfig.json`\n if (metro && server) {\n metroWatchTypeScriptFiles({\n projectRoot,\n server,\n metro,\n eventTypes: ['add', 'delete', 'change'],\n async callback({ filePath, type }) {\n if (!isRouteFile(filePath)) {\n return;\n }\n\n let shouldRegenerate = false;\n\n if (type === 'delete') {\n const route = filePathToRoute(filePath);\n staticRoutes.delete(route);\n dynamicRoutes.delete(route);\n shouldRegenerate = true;\n } else {\n shouldRegenerate = addFilePath(filePath);\n }\n\n if (shouldRegenerate) {\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n }\n },\n });\n }\n\n if (await directoryExistsAsync(routerDirectory)) {\n // Do we need to walk the entire tree on startup?\n // Idea: Store the list of files in the last write, then simply check Git for what files have changed\n await walk(routerDirectory, addFilePath);\n }\n\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n}\n\nfunction debounce<U, T extends (this: U, ...args: any[]) => void>(fn: T, delay: number): T {\n let timeoutId: NodeJS.Timeout | undefined;\n return function (this: U, ...args: any[]) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn.apply(this, args), delay);\n } as T;\n}\n\n/**\n * Generate a router.d.ts file that contains all of the routes in the project.\n * Should be debounced as its very common for developers to make changes to multiple files at once (eg Save All)\n */\nconst regenerateRouterDotTS = debounce(\n async (\n typesDir: string,\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n ) => {\n await fs.mkdir(typesDir, { recursive: true });\n await fs.writeFile(\n path.resolve(typesDir, './router.d.ts'),\n getTemplateString(staticRoutes, dynamicRoutes, dynamicRouteTemplates)\n );\n },\n 100\n);\n\n/*\n * This is exported for testing purposes\n */\nexport function getTemplateString(\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n) {\n return routerDotTSTemplate({\n staticRoutes: setToUnionType(staticRoutes),\n dynamicRoutes: setToUnionType(dynamicRoutes),\n dynamicRouteParams: setToUnionType(dynamicRouteTemplates),\n });\n}\n\n/**\n * Utility functions for typed routes\n *\n * These are extracted for easier testing\n */\nexport function getTypedRoutesUtils(appRoot: string, filePathSeperator = path.sep) {\n /*\n * staticRoutes are a map where the key if the route without groups and the value\n * is another set of all group versions of the route. e.g,\n * Map([\n * [\"/\", [\"/(app)/(notes)\", \"/(app)/(profile)\"]\n * ])\n */\n const staticRoutes = new Map<string, Set<string>>([['/', new Set('/')]]);\n /*\n * dynamicRoutes are the same as staticRoutes (key if the resolved route,\n * and the value is a set of possible routes). e.g:\n *\n * /[...fruits] -> /${CatchAllRoutePart<T>}\n * /color/[color] -> /color/${SingleRoutePart<T>}\n *\n * The keys of this map are also important, as they can be used as \"static\" types\n * <Link href={{ pathname: \"/[...fruits]\",params: { fruits: [\"apple\"] } }} />\n */\n const dynamicRoutes = new Map<string, Set<string>>();\n\n function normalizedFilePath(filePath: string) {\n return filePath.replaceAll(filePathSeperator, '/');\n }\n\n const normalizedAppRoot = normalizedFilePath(appRoot);\n\n const filePathToRoute = (filePath: string) => {\n return normalizedFilePath(filePath)\n .replace(normalizedAppRoot, '')\n .replace(/index\\.[jt]sx?/, '')\n .replace(/\\.[jt]sx?$/, '');\n };\n\n const isRouteFile = (filePath: string) => {\n if (filePath.match(TYPED_ROUTES_EXCLUSION_REGEX)) {\n return false;\n }\n\n // Route files must be nested with in the appRoot\n const relative = path.relative(appRoot, filePath);\n return relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n };\n\n const addFilePath = (filePath: string): boolean => {\n if (!isRouteFile(filePath)) {\n return false;\n }\n\n const route = filePathToRoute(filePath);\n\n // We have already processed this file\n if (staticRoutes.has(route) || dynamicRoutes.has(route)) {\n return false;\n }\n\n const dynamicParams = new Set(\n [...route.matchAll(CAPTURE_DYNAMIC_PARAMS)].map((match) => match[1])\n );\n const isDynamic = dynamicParams.size > 0;\n\n const addRoute = (originalRoute: string, route: string) => {\n if (isDynamic) {\n let set = dynamicRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n dynamicRoutes.set(originalRoute, set);\n }\n\n set.add(\n route\n .replaceAll(CATCH_ALL, '${CatchAllRoutePart<T>}')\n .replaceAll(SLUG, '${SingleRoutePart<T>}')\n );\n } else {\n let set = staticRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n staticRoutes.set(originalRoute, set);\n }\n\n set.add(route);\n }\n };\n\n if (!route.match(ARRAY_GROUP_REGEX)) {\n addRoute(route, route);\n }\n\n // Does this route have a group? eg /(group)\n if (route.includes('/(')) {\n const routeWithoutGroups = route.replace(/\\/\\(.+?\\)/g, '');\n addRoute(route, routeWithoutGroups);\n\n // If there are multiple groups, we need to expand them\n // eg /(test1,test2)/page => /test1/page & /test2/page\n for (const routeWithSingleGroup of extrapolateGroupRoutes(route)) {\n addRoute(route, routeWithSingleGroup);\n }\n }\n\n return true;\n };\n\n return {\n staticRoutes,\n dynamicRoutes,\n filePathToRoute,\n addFilePath,\n isRouteFile,\n };\n}\n\nexport const setToUnionType = <T>(set: Set<T>) => {\n return set.size > 0 ? [...set].map((s) => `\\`${s}\\``).join(' | ') : 'never';\n};\n\n/**\n * Recursively walk a directory and call the callback with the file path.\n */\nasync function walk(directory: string, callback: (filePath: string) => void) {\n const files = await fs.readdir(directory);\n for (const file of files) {\n const p = path.join(directory, file);\n if ((await fs.stat(p)).isDirectory()) {\n await walk(p, callback);\n } else {\n // Normalise the paths so they are easier to convert to URLs\n const normalizedPath = p.replaceAll(path.sep, '/');\n callback(normalizedPath);\n }\n }\n}\n\n/**\n * Given a route, return all possible routes that could be generated from it.\n */\nexport function extrapolateGroupRoutes(\n route: string,\n routes: Set<string> = new Set()\n): Set<string> {\n // Create a version with no groups. We will then need to cleanup double and/or trailing slashes\n routes.add(route.replaceAll(ARRAY_GROUP_REGEX, '').replaceAll(/\\/+/g, '/').replace(/\\/$/, ''));\n\n const match = route.match(ARRAY_GROUP_REGEX);\n\n if (!match) {\n routes.add(route);\n return routes;\n }\n\n const groupsMatch = match[0];\n\n for (const group of groupsMatch.matchAll(CAPTURE_GROUP_REGEX)) {\n extrapolateGroupRoutes(route.replace(groupsMatch, `(${group[1].trim()})`), routes);\n }\n\n return routes;\n}\n\n/**\n * NOTE: This code refers to a specific version of `expo-router` and is therefore unsafe to\n * mix with arbitrary versions.\n * TODO: Version this code with `expo-router` or version expo-router with `@expo/cli`.\n */\nconst routerDotTSTemplate = unsafeTemplate`/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable import/export */\n/* eslint-disable @typescript-eslint/ban-types */\ndeclare module \"expo-router\" {\n import type { LinkProps as OriginalLinkProps } from 'expo-router/build/link/Link';\n import type { Router as OriginalRouter } from 'expo-router/build/types';\n export * from 'expo-router/build';\n\n // prettier-ignore\n type StaticRoutes = ${'staticRoutes'};\n // prettier-ignore\n type DynamicRoutes<T extends string> = ${'dynamicRoutes'};\n // prettier-ignore\n type DynamicRouteTemplate = ${'dynamicRouteParams'};\n\n type RelativePathString = \\`./\\${string}\\` | \\`../\\${string}\\` | '..';\n type AbsoluteRoute = DynamicRouteTemplate | StaticRoutes;\n type ExternalPathString = \\`\\${string}:\\${string}\\`;\n\n type ExpoRouterRoutes = DynamicRouteTemplate | StaticRoutes | RelativePathString;\n export type AllRoutes = ExpoRouterRoutes | ExternalPathString;\n\n /****************\n * Route Utils *\n ****************/\n\n type SearchOrHash = \\`?\\${string}\\` | \\`#\\${string}\\`;\n type UnknownInputParams = Record<string, string | number | (string | number)[]>;\n type UnknownOutputParams = Record<string, string | string[]>;\n\n /**\n * Return only the RoutePart of a string. If the string has multiple parts return never\n *\n * string | type\n * ---------|------\n * 123 | 123\n * /123/abc | never\n * 123?abc | never\n * ./123 | never\n * /123 | never\n * 123/../ | never\n */\n type SingleRoutePart<S extends string> = S extends \\`\\${string}/\\${string}\\`\n ? never\n : S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends ''\n ? never\n : S extends \\`(\\${string})\\`\n ? never\n : S extends \\`[\\${string}]\\`\n ? never\n : S;\n\n /**\n * Return only the CatchAll router part. If the string has search parameters or a hash return never\n */\n type CatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends ''\n ? never\n : S extends \\`\\${string}(\\${string})\\${string}\\`\n ? never\n : S extends \\`\\${string}[\\${string}]\\${string}\\`\n ? never\n : S;\n\n // type OptionalCatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\` ? never : S\n\n /**\n * Return the name of a route parameter\n * '[test]' -> 'test'\n * 'test' -> never\n * '[...test]' -> '...test'\n */\n type IsParameter<Part> = Part extends \\`[\\${infer ParamName}]\\` ? ParamName : never;\n\n /**\n * Return a union of all parameter names. If there are no names return never\n *\n * /[test] -> 'test'\n * /[abc]/[...def] -> 'abc'|'...def'\n */\n type ParameterNames<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? IsParameter<PartA> | ParameterNames<PartB>\n : IsParameter<Path>;\n\n /**\n * Returns all segements of a route.\n *\n * /(group)/123/abc/[id]/[...rest] -> ['(group)', '123', 'abc', '[id]', '[...rest]'\n */\n type RouteSegments<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? PartA extends '' | '.'\n ? [...RouteSegments<PartB>]\n : [PartA, ...RouteSegments<PartB>]\n : Path extends ''\n ? []\n : [Path];\n\n /**\n * Returns a Record of the routes parameters as strings and CatchAll parameters\n *\n * There are two versions, input and output, as you can input 'string | number' but\n * the output will always be 'string'\n *\n * /[id]/[...rest] -> { id: string, rest: string[] }\n * /no-params -> {}\n */\n type InputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends \\`...\\${infer Name}\\`\n ? Name\n : Key]: Key extends \\`...\\${string}\\` ? (string | number)[] : string | number;\n } & UnknownInputParams;\n\n type OutputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends \\`...\\${infer Name}\\`\n ? Name\n : Key]: Key extends \\`...\\${string}\\` ? string[] : string;\n } & UnknownOutputParams;\n\n /**\n * Returns the search parameters for a route.\n */\n export type SearchParams<T extends AllRoutes> = T extends DynamicRouteTemplate\n ? OutputRouteParams<T>\n : T extends StaticRoutes\n ? never\n : UnknownOutputParams;\n\n /**\n * Route is mostly used as part of Href to ensure that a valid route is provided\n *\n * Given a dynamic route, this will return never. This is helpful for conditional logic\n *\n * /test -> /test, /test2, etc\n * /test/[abc] -> never\n * /test/resolve -> /test, /test2, etc\n *\n * Note that if we provide a value for [abc] then the route is allowed\n *\n * This is named Route to prevent confusion, as users they will often see it in tooltips\n */\n export type Route<T> = T extends string\n ? T extends DynamicRouteTemplate\n ? never\n :\n | StaticRoutes\n | RelativePathString\n | ExternalPathString\n | (T extends \\`\\${infer P}\\${SearchOrHash}\\`\n ? P extends DynamicRoutes<infer _>\n ? T\n : never\n : T extends DynamicRoutes<infer _>\n ? T\n : never)\n : never;\n\n /*********\n * Href *\n *********/\n\n export type Href<T> = T extends Record<'pathname', string> ? HrefObject<T> : Route<T>;\n\n export type HrefObject<\n R extends Record<'pathname', string>,\n P = R['pathname'],\n > = P extends DynamicRouteTemplate\n ? { pathname: P; params: InputRouteParams<P> }\n : P extends Route<P>\n ? { pathname: Route<P> | DynamicRouteTemplate; params?: never | InputRouteParams<never> }\n : never;\n\n /***********************\n * Expo Router Exports *\n ***********************/\n\n export type Router = Omit<OriginalRouter, 'push' | 'replace' | 'setParams'> & {\n /** Navigate to the provided href. */\n push: <T>(href: Href<T>) => void;\n /** Navigate to route without appending to the history. */\n replace: <T>(href: Href<T>) => void;\n /** Update the current route query params. */\n setParams: <T = ''>(params?: T extends '' ? Record<string, string> : InputRouteParams<T>) => void;\n };\n\n /** The imperative router. */\n export const router: Router;\n\n /************\n * <Link /> *\n ************/\n export interface LinkProps<T> extends OriginalLinkProps {\n href: Href<T>;\n }\n\n export interface LinkComponent {\n <T>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: <T>(href: Href<T>) => string;\n }\n\n /**\n * Component to render link to another route using a path.\n * Uses an anchor tag on the web.\n *\n * @param props.href Absolute path to route (e.g. \\`/feeds/hot\\`).\n * @param props.replace Should replace the current route without adding to the history.\n * @param props.asChild Forward props to child component. Useful for custom buttons.\n * @param props.children Child elements to render the content.\n * @param props.className On web, this sets the HTML \\`class\\` directly. On native, this can be used with CSS interop tools like Nativewind.\n */\n export const Link: LinkComponent;\n\n /** Redirects to the href as soon as the component is mounted. */\n export const Redirect: <T>(\n props: React.PropsWithChildren<{ href: Href<T> }>\n ) => JSX.Element;\n\n /************\n * Hooks *\n ************/\n export function useRouter(): Router;\n\n export function useLocalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n /** @deprecated renamed to \\`useGlobalSearchParams\\` */\n export function useSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useGlobalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useSegments<\n T extends AbsoluteRoute | RouteSegments<AbsoluteRoute> | RelativePathString,\n >(): T extends AbsoluteRoute ? RouteSegments<T> : T extends string ? string[] : T;\n}\n`;\n"],"names":["ARRAY_GROUP_REGEX","CAPTURE_DYNAMIC_PARAMS","CAPTURE_GROUP_REGEX","CATCH_ALL","SLUG","TYPED_ROUTES_EXCLUSION_REGEX","extrapolateGroupRoutes","getTemplateString","getTypedRoutesUtils","setToUnionType","setupTypedRoutes","options","typedRoutesModule","resolveFrom","silent","projectRoot","typedRoutes","legacyTypedRoutes","typedRoutesModulePath","server","metro","typesDirectory","routerDirectory","plugin","process","env","EXPO_ROUTER_APP_ROOT","require","metroWatchTypeScriptFiles","eventTypes","callback","getWatchHandler","version","regenerateDeclarations","filePathToRoute","staticRoutes","dynamicRoutes","addFilePath","isRouteFile","filePath","type","shouldRegenerate","route","delete","regenerateRouterDotTS","Set","values","flatMap","v","Array","from","keys","directoryExistsAsync","walk","debounce","fn","delay","timeoutId","args","clearTimeout","setTimeout","apply","typesDir","dynamicRouteTemplates","fs","mkdir","recursive","writeFile","path","resolve","routerDotTSTemplate","dynamicRouteParams","appRoot","filePathSeperator","sep","Map","normalizedFilePath","replaceAll","normalizedAppRoot","replace","match","relative","startsWith","isAbsolute","has","dynamicParams","matchAll","map","isDynamic","size","addRoute","originalRoute","set","get","add","includes","routeWithoutGroups","routeWithSingleGroup","s","join","directory","files","readdir","file","p","stat","isDirectory","normalizedPath","routes","groupsMatch","group","trim","unsafeTemplate"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/type-generation/routes.ts"],"sourcesContent":["import type Server from '@expo/metro/metro/Server';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { directoryExistsAsync } from '../../../utils/dir';\nimport { unsafeTemplate } from '../../../utils/template';\nimport { ServerLike } from '../BundlerDevServer';\nimport { metroWatchTypeScriptFiles } from '../metro/metroWatchTypeScriptFiles';\n\n// /test/[...param1]/[param2]/[param3] - captures [\"param1\", \"param2\", \"param3\"]\nexport const CAPTURE_DYNAMIC_PARAMS = /\\[(?:\\.{3})?(\\w*?)[\\]$]/g;\n// /[...param1]/ - Match [...param1]\nexport const CATCH_ALL = /\\[\\.\\.\\..+?\\]/g;\n// /[param1] - Match [param1]\nexport const SLUG = /\\[.+?\\]/g;\n// /(group1,group2,group3)/test - match (group1,group2,group3)\nexport const ARRAY_GROUP_REGEX = /\\(\\s*\\w[\\w\\s]*?,.*?\\)/g;\n// /(group1,group2,group3)/test - captures [\"group1\", \"group2\", \"group3\"]\nexport const CAPTURE_GROUP_REGEX = /[\\\\(,]\\s*(\\w[\\w\\s]*?)\\s*(?=[,\\\\)])/g;\n/**\n * Match:\n * - _layout files, +html, +not-found, string+api, etc\n * - Routes can still use `+`, but it cannot be in the last segment.\n */\nexport const TYPED_ROUTES_EXCLUSION_REGEX = /(_layout|[^/]*?\\+[^/]*?)\\.[tj]sx?$/;\n\nexport interface SetupTypedRoutesOptions {\n server?: ServerLike;\n metro?: Server | null;\n typesDirectory: string;\n projectRoot: string;\n /** Absolute expo router routes directory. */\n routerDirectory: string;\n plugin?: Record<string, any>;\n}\n\nexport async function setupTypedRoutes(options: SetupTypedRoutesOptions) {\n /*\n * In SDK 51, TypedRoutes was moved out of cli and into expo-router. For now we need to support both\n * the legacy and new versions of TypedRoutes.\n *\n * TODO (@marklawlor): Remove this check in SDK 53, only support Expo Router v4 and above.\n */\n const typedRoutesModule = resolveFrom.silent(\n options.projectRoot,\n '@expo/router-server/build/typed-routes'\n );\n return typedRoutesModule ? typedRoutes(typedRoutesModule, options) : legacyTypedRoutes(options);\n}\n\nasync function typedRoutes(\n typedRoutesModulePath: any,\n { server, metro, typesDirectory, projectRoot, routerDirectory, plugin }: SetupTypedRoutesOptions\n) {\n /*\n * Expo Router uses EXPO_ROUTER_APP_ROOT in multiple places to determine the root of the project.\n * In apps compiled by Metro, this code is compiled away. But Typed Routes run in NodeJS with no compilation\n * so we need to explicitly set it.\n */\n process.env.EXPO_ROUTER_APP_ROOT = routerDirectory;\n\n const typedRoutesModule = require(typedRoutesModulePath);\n\n /*\n * Typed Routes can be run with out Metro or a Server, e.g. `expo customize tsconfig.json`\n */\n if (metro && server) {\n // Setup out watcher first\n metroWatchTypeScriptFiles({\n projectRoot,\n server,\n metro,\n eventTypes: ['add', 'delete', 'change'],\n callback: typedRoutesModule.getWatchHandler(typesDirectory),\n });\n }\n\n /*\n * In SDK 52, the `regenerateDeclarations` was changed to accept plugin options.\n * This function has an optional parameter that we cannot override, so we need to ensure the user\n * is using a compatible version of `expo-router`. Otherwise, we will fallback to the old method.\n *\n * TODO(@marklawlor): In SDK53+ we should remove this check and always use the new method.\n */\n if ('version' in typedRoutesModule && typedRoutesModule.version >= 52) {\n typedRoutesModule.regenerateDeclarations(typesDirectory, plugin);\n } else {\n typedRoutesModule.regenerateDeclarations(typesDirectory);\n }\n}\n\nasync function legacyTypedRoutes({\n server,\n metro,\n typesDirectory,\n projectRoot,\n routerDirectory,\n}: SetupTypedRoutesOptions) {\n const { filePathToRoute, staticRoutes, dynamicRoutes, addFilePath, isRouteFile } =\n getTypedRoutesUtils(routerDirectory);\n\n // Typed Routes can be run with out Metro or a Server, e.g. `expo customize tsconfig.json`\n if (metro && server) {\n metroWatchTypeScriptFiles({\n projectRoot,\n server,\n metro,\n eventTypes: ['add', 'delete', 'change'],\n async callback({ filePath, type }) {\n if (!isRouteFile(filePath)) {\n return;\n }\n\n let shouldRegenerate = false;\n\n if (type === 'delete') {\n const route = filePathToRoute(filePath);\n staticRoutes.delete(route);\n dynamicRoutes.delete(route);\n shouldRegenerate = true;\n } else {\n shouldRegenerate = addFilePath(filePath);\n }\n\n if (shouldRegenerate) {\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n }\n },\n });\n }\n\n if (await directoryExistsAsync(routerDirectory)) {\n // Do we need to walk the entire tree on startup?\n // Idea: Store the list of files in the last write, then simply check Git for what files have changed\n await walk(routerDirectory, addFilePath);\n }\n\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n}\n\nfunction debounce<U, T extends (this: U, ...args: any[]) => void>(fn: T, delay: number): T {\n let timeoutId: NodeJS.Timeout | undefined;\n return function (this: U, ...args: any[]) {\n clearTimeout(timeoutId);\n // NOTE(@hassankhan): The cast to `NodeJS.Timeout` below is a hack to work around an issue\n // with TypeScript where React Native's types are being imported before Node types\n timeoutId = setTimeout(() => fn.apply(this, args), delay) as unknown as NodeJS.Timeout;\n } as T;\n}\n\n/**\n * Generate a router.d.ts file that contains all of the routes in the project.\n * Should be debounced as its very common for developers to make changes to multiple files at once (eg Save All)\n */\nconst regenerateRouterDotTS = debounce(\n async (\n typesDir: string,\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n ) => {\n await fs.mkdir(typesDir, { recursive: true });\n await fs.writeFile(\n path.resolve(typesDir, './router.d.ts'),\n getTemplateString(staticRoutes, dynamicRoutes, dynamicRouteTemplates)\n );\n },\n 100\n);\n\n/*\n * This is exported for testing purposes\n */\nexport function getTemplateString(\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n) {\n return routerDotTSTemplate({\n staticRoutes: setToUnionType(staticRoutes),\n dynamicRoutes: setToUnionType(dynamicRoutes),\n dynamicRouteParams: setToUnionType(dynamicRouteTemplates),\n });\n}\n\n/**\n * Utility functions for typed routes\n *\n * These are extracted for easier testing\n */\nexport function getTypedRoutesUtils(appRoot: string, filePathSeperator = path.sep) {\n /*\n * staticRoutes are a map where the key if the route without groups and the value\n * is another set of all group versions of the route. e.g,\n * Map([\n * [\"/\", [\"/(app)/(notes)\", \"/(app)/(profile)\"]\n * ])\n */\n const staticRoutes = new Map<string, Set<string>>([['/', new Set('/')]]);\n /*\n * dynamicRoutes are the same as staticRoutes (key if the resolved route,\n * and the value is a set of possible routes). e.g:\n *\n * /[...fruits] -> /${CatchAllRoutePart<T>}\n * /color/[color] -> /color/${SingleRoutePart<T>}\n *\n * The keys of this map are also important, as they can be used as \"static\" types\n * <Link href={{ pathname: \"/[...fruits]\",params: { fruits: [\"apple\"] } }} />\n */\n const dynamicRoutes = new Map<string, Set<string>>();\n\n function normalizedFilePath(filePath: string) {\n return filePath.replaceAll(filePathSeperator, '/');\n }\n\n const normalizedAppRoot = normalizedFilePath(appRoot);\n\n const filePathToRoute = (filePath: string) => {\n return normalizedFilePath(filePath)\n .replace(normalizedAppRoot, '')\n .replace(/index\\.[jt]sx?/, '')\n .replace(/\\.[jt]sx?$/, '');\n };\n\n const isRouteFile = (filePath: string) => {\n if (filePath.match(TYPED_ROUTES_EXCLUSION_REGEX)) {\n return false;\n }\n\n // Route files must be nested with in the appRoot\n const relative = path.relative(appRoot, filePath);\n return relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n };\n\n const addFilePath = (filePath: string): boolean => {\n if (!isRouteFile(filePath)) {\n return false;\n }\n\n const route = filePathToRoute(filePath);\n\n // We have already processed this file\n if (staticRoutes.has(route) || dynamicRoutes.has(route)) {\n return false;\n }\n\n const dynamicParams = new Set(\n [...route.matchAll(CAPTURE_DYNAMIC_PARAMS)].map((match) => match[1])\n );\n const isDynamic = dynamicParams.size > 0;\n\n const addRoute = (originalRoute: string, route: string) => {\n if (isDynamic) {\n let set = dynamicRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n dynamicRoutes.set(originalRoute, set);\n }\n\n set.add(\n route\n .replaceAll(CATCH_ALL, '${CatchAllRoutePart<T>}')\n .replaceAll(SLUG, '${SingleRoutePart<T>}')\n );\n } else {\n let set = staticRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n staticRoutes.set(originalRoute, set);\n }\n\n set.add(route);\n }\n };\n\n if (!route.match(ARRAY_GROUP_REGEX)) {\n addRoute(route, route);\n }\n\n // Does this route have a group? eg /(group)\n if (route.includes('/(')) {\n const routeWithoutGroups = route.replace(/\\/\\(.+?\\)/g, '');\n addRoute(route, routeWithoutGroups);\n\n // If there are multiple groups, we need to expand them\n // eg /(test1,test2)/page => /test1/page & /test2/page\n for (const routeWithSingleGroup of extrapolateGroupRoutes(route)) {\n addRoute(route, routeWithSingleGroup);\n }\n }\n\n return true;\n };\n\n return {\n staticRoutes,\n dynamicRoutes,\n filePathToRoute,\n addFilePath,\n isRouteFile,\n };\n}\n\nexport const setToUnionType = <T>(set: Set<T>) => {\n return set.size > 0 ? [...set].map((s) => `\\`${s}\\``).join(' | ') : 'never';\n};\n\n/**\n * Recursively walk a directory and call the callback with the file path.\n */\nasync function walk(directory: string, callback: (filePath: string) => void) {\n const files = await fs.readdir(directory);\n for (const file of files) {\n const p = path.join(directory, file);\n if ((await fs.stat(p)).isDirectory()) {\n await walk(p, callback);\n } else {\n // Normalise the paths so they are easier to convert to URLs\n const normalizedPath = p.replaceAll(path.sep, '/');\n callback(normalizedPath);\n }\n }\n}\n\n/**\n * Given a route, return all possible routes that could be generated from it.\n */\nexport function extrapolateGroupRoutes(\n route: string,\n routes: Set<string> = new Set()\n): Set<string> {\n // Create a version with no groups. We will then need to cleanup double and/or trailing slashes\n routes.add(route.replaceAll(ARRAY_GROUP_REGEX, '').replaceAll(/\\/+/g, '/').replace(/\\/$/, ''));\n\n const match = route.match(ARRAY_GROUP_REGEX);\n\n if (!match) {\n routes.add(route);\n return routes;\n }\n\n const groupsMatch = match[0];\n\n for (const group of groupsMatch.matchAll(CAPTURE_GROUP_REGEX)) {\n extrapolateGroupRoutes(route.replace(groupsMatch, `(${group[1].trim()})`), routes);\n }\n\n return routes;\n}\n\n/**\n * NOTE: This code refers to a specific version of `expo-router` and is therefore unsafe to\n * mix with arbitrary versions.\n * TODO: Version this code with `expo-router` or version expo-router with `@expo/cli`.\n */\nconst routerDotTSTemplate = unsafeTemplate`/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable import/export */\n/* eslint-disable @typescript-eslint/ban-types */\ndeclare module \"expo-router\" {\n import type { LinkProps as OriginalLinkProps } from 'expo-router/build/link/Link';\n import type { Router as OriginalRouter } from 'expo-router/build/types';\n export * from 'expo-router/build';\n\n // prettier-ignore\n type StaticRoutes = ${'staticRoutes'};\n // prettier-ignore\n type DynamicRoutes<T extends string> = ${'dynamicRoutes'};\n // prettier-ignore\n type DynamicRouteTemplate = ${'dynamicRouteParams'};\n\n type RelativePathString = \\`./\\${string}\\` | \\`../\\${string}\\` | '..';\n type AbsoluteRoute = DynamicRouteTemplate | StaticRoutes;\n type ExternalPathString = \\`\\${string}:\\${string}\\`;\n\n type ExpoRouterRoutes = DynamicRouteTemplate | StaticRoutes | RelativePathString;\n export type AllRoutes = ExpoRouterRoutes | ExternalPathString;\n\n /****************\n * Route Utils *\n ****************/\n\n type SearchOrHash = \\`?\\${string}\\` | \\`#\\${string}\\`;\n type UnknownInputParams = Record<string, string | number | (string | number)[]>;\n type UnknownOutputParams = Record<string, string | string[]>;\n\n /**\n * Return only the RoutePart of a string. If the string has multiple parts return never\n *\n * string | type\n * ---------|------\n * 123 | 123\n * /123/abc | never\n * 123?abc | never\n * ./123 | never\n * /123 | never\n * 123/../ | never\n */\n type SingleRoutePart<S extends string> = S extends \\`\\${string}/\\${string}\\`\n ? never\n : S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends ''\n ? never\n : S extends \\`(\\${string})\\`\n ? never\n : S extends \\`[\\${string}]\\`\n ? never\n : S;\n\n /**\n * Return only the CatchAll router part. If the string has search parameters or a hash return never\n */\n type CatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends ''\n ? never\n : S extends \\`\\${string}(\\${string})\\${string}\\`\n ? never\n : S extends \\`\\${string}[\\${string}]\\${string}\\`\n ? never\n : S;\n\n // type OptionalCatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\` ? never : S\n\n /**\n * Return the name of a route parameter\n * '[test]' -> 'test'\n * 'test' -> never\n * '[...test]' -> '...test'\n */\n type IsParameter<Part> = Part extends \\`[\\${infer ParamName}]\\` ? ParamName : never;\n\n /**\n * Return a union of all parameter names. If there are no names return never\n *\n * /[test] -> 'test'\n * /[abc]/[...def] -> 'abc'|'...def'\n */\n type ParameterNames<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? IsParameter<PartA> | ParameterNames<PartB>\n : IsParameter<Path>;\n\n /**\n * Returns all segements of a route.\n *\n * /(group)/123/abc/[id]/[...rest] -> ['(group)', '123', 'abc', '[id]', '[...rest]'\n */\n type RouteSegments<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? PartA extends '' | '.'\n ? [...RouteSegments<PartB>]\n : [PartA, ...RouteSegments<PartB>]\n : Path extends ''\n ? []\n : [Path];\n\n /**\n * Returns a Record of the routes parameters as strings and CatchAll parameters\n *\n * There are two versions, input and output, as you can input 'string | number' but\n * the output will always be 'string'\n *\n * /[id]/[...rest] -> { id: string, rest: string[] }\n * /no-params -> {}\n */\n type InputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends \\`...\\${infer Name}\\`\n ? Name\n : Key]: Key extends \\`...\\${string}\\` ? (string | number)[] : string | number;\n } & UnknownInputParams;\n\n type OutputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends \\`...\\${infer Name}\\`\n ? Name\n : Key]: Key extends \\`...\\${string}\\` ? string[] : string;\n } & UnknownOutputParams;\n\n /**\n * Returns the search parameters for a route.\n */\n export type SearchParams<T extends AllRoutes> = T extends DynamicRouteTemplate\n ? OutputRouteParams<T>\n : T extends StaticRoutes\n ? never\n : UnknownOutputParams;\n\n /**\n * Route is mostly used as part of Href to ensure that a valid route is provided\n *\n * Given a dynamic route, this will return never. This is helpful for conditional logic\n *\n * /test -> /test, /test2, etc\n * /test/[abc] -> never\n * /test/resolve -> /test, /test2, etc\n *\n * Note that if we provide a value for [abc] then the route is allowed\n *\n * This is named Route to prevent confusion, as users they will often see it in tooltips\n */\n export type Route<T> = T extends string\n ? T extends DynamicRouteTemplate\n ? never\n :\n | StaticRoutes\n | RelativePathString\n | ExternalPathString\n | (T extends \\`\\${infer P}\\${SearchOrHash}\\`\n ? P extends DynamicRoutes<infer _>\n ? T\n : never\n : T extends DynamicRoutes<infer _>\n ? T\n : never)\n : never;\n\n /*********\n * Href *\n *********/\n\n export type Href<T> = T extends Record<'pathname', string> ? HrefObject<T> : Route<T>;\n\n export type HrefObject<\n R extends Record<'pathname', string>,\n P = R['pathname'],\n > = P extends DynamicRouteTemplate\n ? { pathname: P; params: InputRouteParams<P> }\n : P extends Route<P>\n ? { pathname: Route<P> | DynamicRouteTemplate; params?: never | InputRouteParams<never> }\n : never;\n\n /***********************\n * Expo Router Exports *\n ***********************/\n\n export type Router = Omit<OriginalRouter, 'push' | 'replace' | 'setParams'> & {\n /** Navigate to the provided href. */\n push: <T>(href: Href<T>) => void;\n /** Navigate to route without appending to the history. */\n replace: <T>(href: Href<T>) => void;\n /** Update the current route query params. */\n setParams: <T = ''>(params?: T extends '' ? Record<string, string> : InputRouteParams<T>) => void;\n };\n\n /** The imperative router. */\n export const router: Router;\n\n /************\n * <Link /> *\n ************/\n export interface LinkProps<T> extends OriginalLinkProps {\n href: Href<T>;\n }\n\n export interface LinkComponent {\n <T>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: <T>(href: Href<T>) => string;\n }\n\n /**\n * Component to render link to another route using a path.\n * Uses an anchor tag on the web.\n *\n * @param props.href Absolute path to route (e.g. \\`/feeds/hot\\`).\n * @param props.replace Should replace the current route without adding to the history.\n * @param props.asChild Forward props to child component. Useful for custom buttons.\n * @param props.children Child elements to render the content.\n * @param props.className On web, this sets the HTML \\`class\\` directly. On native, this can be used with CSS interop tools like Nativewind.\n */\n export const Link: LinkComponent;\n\n /** Redirects to the href as soon as the component is mounted. */\n export const Redirect: <T>(\n props: React.PropsWithChildren<{ href: Href<T> }>\n ) => JSX.Element;\n\n /************\n * Hooks *\n ************/\n export function useRouter(): Router;\n\n export function useLocalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n /** @deprecated renamed to \\`useGlobalSearchParams\\` */\n export function useSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useGlobalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useSegments<\n T extends AbsoluteRoute | RouteSegments<AbsoluteRoute> | RelativePathString,\n >(): T extends AbsoluteRoute ? RouteSegments<T> : T extends string ? string[] : T;\n}\n`;\n"],"names":["ARRAY_GROUP_REGEX","CAPTURE_DYNAMIC_PARAMS","CAPTURE_GROUP_REGEX","CATCH_ALL","SLUG","TYPED_ROUTES_EXCLUSION_REGEX","extrapolateGroupRoutes","getTemplateString","getTypedRoutesUtils","setToUnionType","setupTypedRoutes","options","typedRoutesModule","resolveFrom","silent","projectRoot","typedRoutes","legacyTypedRoutes","typedRoutesModulePath","server","metro","typesDirectory","routerDirectory","plugin","process","env","EXPO_ROUTER_APP_ROOT","require","metroWatchTypeScriptFiles","eventTypes","callback","getWatchHandler","version","regenerateDeclarations","filePathToRoute","staticRoutes","dynamicRoutes","addFilePath","isRouteFile","filePath","type","shouldRegenerate","route","delete","regenerateRouterDotTS","Set","values","flatMap","v","Array","from","keys","directoryExistsAsync","walk","debounce","fn","delay","timeoutId","args","clearTimeout","setTimeout","apply","typesDir","dynamicRouteTemplates","fs","mkdir","recursive","writeFile","path","resolve","routerDotTSTemplate","dynamicRouteParams","appRoot","filePathSeperator","sep","Map","normalizedFilePath","replaceAll","normalizedAppRoot","replace","match","relative","startsWith","isAbsolute","has","dynamicParams","matchAll","map","isDynamic","size","addRoute","originalRoute","set","get","add","includes","routeWithoutGroups","routeWithSingleGroup","s","join","directory","files","readdir","file","p","stat","isDirectory","normalizedPath","routes","groupsMatch","group","trim","unsafeTemplate"],"mappings":"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"}
|
|
@@ -124,7 +124,7 @@ async function getMultiBundlerStartOptions(projectRoot, options, settings, platf
|
|
|
124
124
|
];
|
|
125
125
|
}
|
|
126
126
|
async function startAsync(projectRoot, options, settings) {
|
|
127
|
-
var _exp_platforms;
|
|
127
|
+
var _exp_platforms, _devServerManager_getDefaultDevServer;
|
|
128
128
|
_log.log(_chalk().default.gray(`Starting project at ${projectRoot}`));
|
|
129
129
|
const { exp, pkg } = (0, _profile.profile)(_config().getConfig)(projectRoot);
|
|
130
130
|
if (((_exp_platforms = exp.platforms) == null ? void 0 : _exp_platforms.includes('ios')) && process.platform !== 'win32') {
|
|
@@ -156,29 +156,32 @@ async function startAsync(projectRoot, options, settings) {
|
|
|
156
156
|
}
|
|
157
157
|
// Open project on devices.
|
|
158
158
|
await (0, _profile.profile)(_openPlatforms.openPlatformsAsync)(devServerManager, options);
|
|
159
|
+
const defaultServerUrl = ((_devServerManager_getDefaultDevServer = devServerManager.getDefaultDevServer()) == null ? void 0 : _devServerManager_getDefaultDevServer.getDevServerUrl()) ?? '';
|
|
159
160
|
// Present the Terminal UI.
|
|
160
161
|
if ((0, _interactive.isInteractive)()) {
|
|
161
|
-
const mcpServer = await (0, _profile.profile)(_MCP.maybeCreateMCPServerAsync)(
|
|
162
|
+
const mcpServer = await (0, _profile.profile)(_MCP.maybeCreateMCPServerAsync)({
|
|
163
|
+
projectRoot,
|
|
164
|
+
devServerUrl: defaultServerUrl
|
|
165
|
+
}) ?? undefined;
|
|
162
166
|
await (0, _profile.profile)(_startInterface.startInterfaceAsync)(devServerManager, {
|
|
163
167
|
platforms: exp.platforms ?? [
|
|
164
168
|
'ios',
|
|
165
169
|
'android',
|
|
166
170
|
'web'
|
|
167
|
-
]
|
|
171
|
+
],
|
|
172
|
+
mcpServer
|
|
168
173
|
});
|
|
169
174
|
mcpServer == null ? void 0 : mcpServer.start();
|
|
170
175
|
} else {
|
|
171
|
-
var _devServerManager_getDefaultDevServer;
|
|
172
176
|
// Display the server location in CI...
|
|
173
|
-
|
|
174
|
-
if (url) {
|
|
177
|
+
if (defaultServerUrl) {
|
|
175
178
|
if (_env.env.__EXPO_E2E_TEST) {
|
|
176
179
|
// Print the URL to stdout for tests
|
|
177
180
|
console.info(`[__EXPO_E2E_TEST:server] ${JSON.stringify({
|
|
178
|
-
url
|
|
181
|
+
url: defaultServerUrl
|
|
179
182
|
})}`);
|
|
180
183
|
}
|
|
181
|
-
_log.log((0, _chalk().default)`Waiting on {underline ${
|
|
184
|
+
_log.log((0, _chalk().default)`Waiting on {underline ${defaultServerUrl}}`);
|
|
182
185
|
}
|
|
183
186
|
}
|
|
184
187
|
// Final note about closing the server.
|