@expo/cli 0.26.7 → 0.26.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/bin/cli CHANGED
@@ -123,7 +123,7 @@ const args = (0, _arg().default)({
123
123
  });
124
124
  if (args['--version']) {
125
125
  // Version is added in the build script.
126
- console.log("0.26.7");
126
+ console.log("0.26.9");
127
127
  process.exit(0);
128
128
  }
129
129
  if (args['--non-interactive']) {
@@ -117,7 +117,7 @@ class ExpoGoInstaller {
117
117
  // Only prompt once per device, per run.
118
118
  const confirm = await (0, _prompts.confirmAsync)({
119
119
  initial: true,
120
- message: `Expo Go ${expectedExpoGoVersion} is recommended for SDK ${this.sdkVersion} (${deviceManager.name} is using ${installedExpoGoVersion}). ${(0, _link.learnMore)('https://docs.expo.dev/get-started/expo-go/#sdk-versions')}. Install the recommended Expo Go version?`
120
+ message: `Expo Go ${expectedExpoGoVersion} is recommended for SDK ${this.sdkVersion} (${deviceManager.name} is using ${installedExpoGoVersion}). ${(0, _link.learnMore)('https://docs.expo.dev/develop/tools/#expo-go')}. Install the recommended Expo Go version?`
121
121
  });
122
122
  if (confirm) {
123
123
  // Don't need to uninstall to update on iOS.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/platforms/ExpoGoInstaller.ts"],"sourcesContent":["import semver from 'semver';\n\nimport type { DeviceManager } from './DeviceManager';\nimport { getVersionsAsync } from '../../api/getVersions';\nimport * as Log from '../../log';\nimport { downloadExpoGoAsync } from '../../utils/downloadExpoGoAsync';\nimport { env } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { learnMore } from '../../utils/link';\nimport { logNewSection } from '../../utils/ora';\nimport { confirmAsync } from '../../utils/prompts';\n\nconst debug = require('debug')('expo:utils:ExpoGoInstaller') as typeof console.log;\n\n/** Given a platform, appId, and sdkVersion, this module will ensure that Expo Go is up-to-date on the provided device. */\nexport class ExpoGoInstaller<IDevice> {\n // Keep a list of [platform-deviceId] so we can prevent asking multiple times if a user wants to upgrade.\n // This can prevent annoying interactions when they don't want to upgrade for whatever reason.\n static cache: Record<string, boolean> = {};\n\n constructor(\n private platform: 'ios' | 'android',\n // Ultimately this should be inlined since we know the platform.\n private appId: string,\n private sdkVersion: string\n ) {}\n\n /** Returns true if the installed app matching the previously provided `appId` is outdated. */\n isInstalledClientVersionMismatched(\n installedVersion: string | null,\n expectedExpoGoVersion: string | null\n ): boolean {\n if (!installedVersion) {\n return true;\n }\n\n debug(\n `Expected Expo Go version: ${expectedExpoGoVersion}, installed version: ${installedVersion}`\n );\n return expectedExpoGoVersion ? !semver.eq(installedVersion, expectedExpoGoVersion) : true;\n }\n\n /** Returns the expected version of Expo Go given the project SDK Version. Exposed for testing. */\n async getExpectedExpoGoClientVersionAsync(): Promise<string | null> {\n const versions = await getVersionsAsync();\n // Like `sdkVersions['44.0.0']['androidClientVersion'] = '1.0.0'`\n const specificVersion =\n versions?.sdkVersions?.[this.sdkVersion]?.[`${this.platform}ClientVersion`];\n const latestVersion = versions[`${this.platform}Version`];\n return specificVersion ?? latestVersion ?? null;\n }\n\n /** Returns a boolean indicating if Expo Go should be installed. Returns `true` if the app was uninstalled. */\n async promptForUninstallExpoGoIfInstalledClientVersionMismatchedAndReturnShouldInstallAsync(\n deviceManager: DeviceManager<IDevice>,\n { containerPath }: { containerPath?: string } = {}\n ): Promise<boolean> {\n const cacheId = `${this.platform}-${deviceManager.identifier}`;\n\n if (ExpoGoInstaller.cache[cacheId]) {\n debug('skipping subsequent upgrade check');\n return false;\n }\n ExpoGoInstaller.cache[cacheId] = true;\n\n const [installedExpoGoVersion, expectedExpoGoVersion] = await Promise.all([\n deviceManager.getAppVersionAsync(this.appId, {\n containerPath,\n }),\n this.getExpectedExpoGoClientVersionAsync(),\n ]);\n\n if (this.isInstalledClientVersionMismatched(installedExpoGoVersion, expectedExpoGoVersion)) {\n if (this.sdkVersion === 'UNVERSIONED') {\n // This should only happen in the expo/expo repo, e.g. `apps/test-suite`\n Log.log(\n `Skipping Expo Go upgrade check for UNVERSIONED project. Manually ensure the Expo Go app is built from source.`\n );\n return false;\n }\n\n // Only prompt once per device, per run.\n const confirm = await confirmAsync({\n initial: true,\n message: `Expo Go ${expectedExpoGoVersion} is recommended for SDK ${this.sdkVersion} (${\n deviceManager.name\n } is using ${installedExpoGoVersion}). ${learnMore(\n 'https://docs.expo.dev/get-started/expo-go/#sdk-versions'\n )}. Install the recommended Expo Go version?`,\n });\n\n if (confirm) {\n // Don't need to uninstall to update on iOS.\n if (this.platform !== 'ios') {\n Log.log(`Uninstalling Expo Go from ${this.platform} device ${deviceManager.name}.`);\n await deviceManager.uninstallAppAsync(this.appId);\n }\n return true;\n }\n }\n return false;\n }\n\n /** Check if a given device has Expo Go installed, if not then download and install it. */\n async ensureAsync(deviceManager: DeviceManager<IDevice>): Promise<boolean> {\n const isExpoGoInstalledAndIfSoContainerPathForIOS =\n await deviceManager.isAppInstalledAndIfSoReturnContainerPathForIOSAsync(this.appId);\n let shouldInstall = !isExpoGoInstalledAndIfSoContainerPathForIOS;\n if (env.EXPO_OFFLINE) {\n if (isExpoGoInstalledAndIfSoContainerPathForIOS) {\n Log.warn(`Skipping Expo Go version validation in offline mode`);\n return false;\n }\n throw new CommandError(\n 'NO_EXPO_GO',\n `Expo Go is not installed on device \"${deviceManager.name}\", while running in offline mode. Manually install Expo Go or run without --offline flag (or EXPO_OFFLINE environment variable).`\n );\n }\n\n if (isExpoGoInstalledAndIfSoContainerPathForIOS) {\n shouldInstall =\n await this.promptForUninstallExpoGoIfInstalledClientVersionMismatchedAndReturnShouldInstallAsync(\n deviceManager,\n {\n // iOS optimization to prevent duplicate calls to `getContainerPathAsync`.\n containerPath:\n typeof isExpoGoInstalledAndIfSoContainerPathForIOS === 'string'\n ? isExpoGoInstalledAndIfSoContainerPathForIOS\n : undefined,\n }\n );\n }\n\n if (shouldInstall) {\n // Download the Expo Go app from the Expo servers.\n const binaryPath = await downloadExpoGoAsync(this.platform, { sdkVersion: this.sdkVersion });\n // Install the app on the device.\n const ora = logNewSection(`Installing Expo Go on ${deviceManager.name}`);\n try {\n await deviceManager.installAppAsync(binaryPath);\n } finally {\n ora.stop();\n }\n return true;\n }\n return false;\n }\n}\n"],"names":["ExpoGoInstaller","debug","require","cache","constructor","platform","appId","sdkVersion","isInstalledClientVersionMismatched","installedVersion","expectedExpoGoVersion","semver","eq","getExpectedExpoGoClientVersionAsync","versions","getVersionsAsync","specificVersion","sdkVersions","latestVersion","promptForUninstallExpoGoIfInstalledClientVersionMismatchedAndReturnShouldInstallAsync","deviceManager","containerPath","cacheId","identifier","installedExpoGoVersion","Promise","all","getAppVersionAsync","Log","log","confirm","confirmAsync","initial","message","name","learnMore","uninstallAppAsync","ensureAsync","isExpoGoInstalledAndIfSoContainerPathForIOS","isAppInstalledAndIfSoReturnContainerPathForIOSAsync","shouldInstall","env","EXPO_OFFLINE","warn","CommandError","undefined","binaryPath","downloadExpoGoAsync","ora","logNewSection","installAppAsync","stop"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/start/platforms/ExpoGoInstaller.ts"],"sourcesContent":["import semver from 'semver';\n\nimport type { DeviceManager } from './DeviceManager';\nimport { getVersionsAsync } from '../../api/getVersions';\nimport * as Log from '../../log';\nimport { downloadExpoGoAsync } from '../../utils/downloadExpoGoAsync';\nimport { env } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { learnMore } from '../../utils/link';\nimport { logNewSection } from '../../utils/ora';\nimport { confirmAsync } from '../../utils/prompts';\n\nconst debug = require('debug')('expo:utils:ExpoGoInstaller') as typeof console.log;\n\n/** Given a platform, appId, and sdkVersion, this module will ensure that Expo Go is up-to-date on the provided device. */\nexport class ExpoGoInstaller<IDevice> {\n // Keep a list of [platform-deviceId] so we can prevent asking multiple times if a user wants to upgrade.\n // This can prevent annoying interactions when they don't want to upgrade for whatever reason.\n static cache: Record<string, boolean> = {};\n\n constructor(\n private platform: 'ios' | 'android',\n // Ultimately this should be inlined since we know the platform.\n private appId: string,\n private sdkVersion: string\n ) {}\n\n /** Returns true if the installed app matching the previously provided `appId` is outdated. */\n isInstalledClientVersionMismatched(\n installedVersion: string | null,\n expectedExpoGoVersion: string | null\n ): boolean {\n if (!installedVersion) {\n return true;\n }\n\n debug(\n `Expected Expo Go version: ${expectedExpoGoVersion}, installed version: ${installedVersion}`\n );\n return expectedExpoGoVersion ? !semver.eq(installedVersion, expectedExpoGoVersion) : true;\n }\n\n /** Returns the expected version of Expo Go given the project SDK Version. Exposed for testing. */\n async getExpectedExpoGoClientVersionAsync(): Promise<string | null> {\n const versions = await getVersionsAsync();\n // Like `sdkVersions['44.0.0']['androidClientVersion'] = '1.0.0'`\n const specificVersion =\n versions?.sdkVersions?.[this.sdkVersion]?.[`${this.platform}ClientVersion`];\n const latestVersion = versions[`${this.platform}Version`];\n return specificVersion ?? latestVersion ?? null;\n }\n\n /** Returns a boolean indicating if Expo Go should be installed. Returns `true` if the app was uninstalled. */\n async promptForUninstallExpoGoIfInstalledClientVersionMismatchedAndReturnShouldInstallAsync(\n deviceManager: DeviceManager<IDevice>,\n { containerPath }: { containerPath?: string } = {}\n ): Promise<boolean> {\n const cacheId = `${this.platform}-${deviceManager.identifier}`;\n\n if (ExpoGoInstaller.cache[cacheId]) {\n debug('skipping subsequent upgrade check');\n return false;\n }\n ExpoGoInstaller.cache[cacheId] = true;\n\n const [installedExpoGoVersion, expectedExpoGoVersion] = await Promise.all([\n deviceManager.getAppVersionAsync(this.appId, {\n containerPath,\n }),\n this.getExpectedExpoGoClientVersionAsync(),\n ]);\n\n if (this.isInstalledClientVersionMismatched(installedExpoGoVersion, expectedExpoGoVersion)) {\n if (this.sdkVersion === 'UNVERSIONED') {\n // This should only happen in the expo/expo repo, e.g. `apps/test-suite`\n Log.log(\n `Skipping Expo Go upgrade check for UNVERSIONED project. Manually ensure the Expo Go app is built from source.`\n );\n return false;\n }\n\n // Only prompt once per device, per run.\n const confirm = await confirmAsync({\n initial: true,\n message: `Expo Go ${expectedExpoGoVersion} is recommended for SDK ${this.sdkVersion} (${\n deviceManager.name\n } is using ${installedExpoGoVersion}). ${learnMore(\n 'https://docs.expo.dev/develop/tools/#expo-go'\n )}. Install the recommended Expo Go version?`,\n });\n\n if (confirm) {\n // Don't need to uninstall to update on iOS.\n if (this.platform !== 'ios') {\n Log.log(`Uninstalling Expo Go from ${this.platform} device ${deviceManager.name}.`);\n await deviceManager.uninstallAppAsync(this.appId);\n }\n return true;\n }\n }\n return false;\n }\n\n /** Check if a given device has Expo Go installed, if not then download and install it. */\n async ensureAsync(deviceManager: DeviceManager<IDevice>): Promise<boolean> {\n const isExpoGoInstalledAndIfSoContainerPathForIOS =\n await deviceManager.isAppInstalledAndIfSoReturnContainerPathForIOSAsync(this.appId);\n let shouldInstall = !isExpoGoInstalledAndIfSoContainerPathForIOS;\n if (env.EXPO_OFFLINE) {\n if (isExpoGoInstalledAndIfSoContainerPathForIOS) {\n Log.warn(`Skipping Expo Go version validation in offline mode`);\n return false;\n }\n throw new CommandError(\n 'NO_EXPO_GO',\n `Expo Go is not installed on device \"${deviceManager.name}\", while running in offline mode. Manually install Expo Go or run without --offline flag (or EXPO_OFFLINE environment variable).`\n );\n }\n\n if (isExpoGoInstalledAndIfSoContainerPathForIOS) {\n shouldInstall =\n await this.promptForUninstallExpoGoIfInstalledClientVersionMismatchedAndReturnShouldInstallAsync(\n deviceManager,\n {\n // iOS optimization to prevent duplicate calls to `getContainerPathAsync`.\n containerPath:\n typeof isExpoGoInstalledAndIfSoContainerPathForIOS === 'string'\n ? isExpoGoInstalledAndIfSoContainerPathForIOS\n : undefined,\n }\n );\n }\n\n if (shouldInstall) {\n // Download the Expo Go app from the Expo servers.\n const binaryPath = await downloadExpoGoAsync(this.platform, { sdkVersion: this.sdkVersion });\n // Install the app on the device.\n const ora = logNewSection(`Installing Expo Go on ${deviceManager.name}`);\n try {\n await deviceManager.installAppAsync(binaryPath);\n } finally {\n ora.stop();\n }\n return true;\n }\n return false;\n }\n}\n"],"names":["ExpoGoInstaller","debug","require","cache","constructor","platform","appId","sdkVersion","isInstalledClientVersionMismatched","installedVersion","expectedExpoGoVersion","semver","eq","getExpectedExpoGoClientVersionAsync","versions","getVersionsAsync","specificVersion","sdkVersions","latestVersion","promptForUninstallExpoGoIfInstalledClientVersionMismatchedAndReturnShouldInstallAsync","deviceManager","containerPath","cacheId","identifier","installedExpoGoVersion","Promise","all","getAppVersionAsync","Log","log","confirm","confirmAsync","initial","message","name","learnMore","uninstallAppAsync","ensureAsync","isExpoGoInstalledAndIfSoContainerPathForIOS","isAppInstalledAndIfSoReturnContainerPathForIOSAsync","shouldInstall","env","EXPO_OFFLINE","warn","CommandError","undefined","binaryPath","downloadExpoGoAsync","ora","logNewSection","installAppAsync","stop"],"mappings":"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"}
@@ -12,6 +12,9 @@ _export(exports, {
12
12
  MetroTerminalReporter: function() {
13
13
  return MetroTerminalReporter;
14
14
  },
15
+ extractCodeFrame: function() {
16
+ return extractCodeFrame;
17
+ },
15
18
  formatUsingNodeStandardLibraryError: function() {
16
19
  return formatUsingNodeStandardLibraryError;
17
20
  },
@@ -36,6 +39,13 @@ function _path() {
36
39
  };
37
40
  return data;
38
41
  }
42
+ function _util() {
43
+ const data = require("util");
44
+ _util = function() {
45
+ return data;
46
+ };
47
+ return data;
48
+ }
39
49
  const _TerminalReporter = require("./TerminalReporter");
40
50
  const _externals = require("./externals");
41
51
  const _env = require("../../../utils/env");
@@ -259,21 +269,32 @@ function isNodeStdLibraryModule(moduleName) {
259
269
  return /^node:/.test(moduleName) || _externals.NODE_STDLIB_MODULES.includes(moduleName);
260
270
  }
261
271
  /** If the code frame can be found then append it to the existing message. */ function maybeAppendCodeFrame(message, rawMessage) {
262
- const codeFrame = stripMetroInfo(rawMessage);
272
+ const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));
263
273
  if (codeFrame) {
264
274
  message += '\n' + codeFrame;
265
275
  }
266
276
  return message;
267
277
  }
278
+ function extractCodeFrame(errorMessage) {
279
+ const codeFrameLine = /^(?:\s*(?:>?\s*\d+\s*\||\s*\|).*\n?)+/;
280
+ let wasPreviousLineCodeFrame = null;
281
+ return errorMessage.split('\n').filter((line)=>{
282
+ if (wasPreviousLineCodeFrame === false) return false;
283
+ const keep = codeFrameLine.test((0, _util().stripVTControlCharacters)(line));
284
+ if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;
285
+ else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;
286
+ return keep;
287
+ }).join('\n');
288
+ }
268
289
  function stripMetroInfo(errorMessage) {
269
290
  // Newer versions of Metro don't include the list.
270
291
  if (!errorMessage.includes('4. Remove the cache')) {
271
- return null;
292
+ return errorMessage;
272
293
  }
273
294
  const lines = errorMessage.split('\n');
274
295
  const index = lines.findIndex((line)=>line.includes('4. Remove the cache'));
275
296
  if (index === -1) {
276
- return null;
297
+ return errorMessage;
277
298
  }
278
299
  return lines.slice(index + 1).join('\n');
279
300
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import type { Terminal } from '@expo/metro/metro-core';\nimport chalk from 'chalk';\nimport path from 'path';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { env } from '../../../utils/env';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatJSErrorStackLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\nimport { attachImportStackToRootMessage, nearestImportStack } from './metroErrorInterface';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n constructor(\n public projectRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n _log(event: TerminalReportableEvent): void {\n switch (event.type) {\n case 'unstable_server_log':\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n break;\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n const { level } = event;\n\n if (!level) {\n break;\n }\n\n const mode = event.mode === 'NOBRIDGE' || event.mode === 'BRIDGE' ? '' : (event.mode ?? '');\n // @ts-expect-error\n if (level === 'warn' || level === 'error') {\n let hasStack = false;\n const parsed = event.data.map((msg) => {\n // Quick check to see if an unsymbolicated stack is being logged.\n if (msg.includes('.bundle//&platform=')) {\n const stack = parseErrorStringToObject(msg);\n if (stack) {\n hasStack = true;\n }\n return stack;\n }\n return msg;\n });\n\n if (hasStack) {\n (async () => {\n const symbolicating = parsed.map((p) => {\n if (typeof p === 'string') return p;\n return maybeSymbolicateAndFormatJSErrorStackLogAsync(this.projectRoot, level, p);\n });\n\n let usefulStackCount = 0;\n const fallbackIndices: number[] = [];\n const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index) => {\n if (s.status === 'rejected') {\n debug('Error formatting stack', parsed[index], s.reason);\n return parsed[index];\n } else if (typeof s.value === 'string') {\n return s.value;\n } else {\n if (!s.value.isFallback) {\n usefulStackCount++;\n } else {\n fallbackIndices.push(index);\n }\n return s.value.stack;\n }\n });\n\n // Using EXPO_DEBUG we can print all stack\n const filtered =\n usefulStackCount && !env.EXPO_DEBUG\n ? symbolicated.filter((_, index) => !fallbackIndices.includes(index))\n : symbolicated;\n\n logLikeMetro(this.terminal.log.bind(this.terminal), level, mode, ...filtered);\n })();\n return;\n }\n }\n\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, mode, ...event.data);\n return;\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n let localPath: string;\n\n if (\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ) {\n // Because we use a generated entry file for DOM components, we need to adjust the logging path so it\n // shows a unique path for each component.\n // Here, we take the relative import path and remove all the starting slashes.\n localPath = progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '');\n } else {\n const inputFile = progress.bundleDetails.entryFile;\n\n localPath = path.isAbsolute(inputFile)\n ? path.relative(this.projectRoot, inputFile)\n : inputFile;\n }\n\n if (!inProgress) {\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: string = '';\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const micro = Number(elapsed) / 1000;\n const converted = Number(elapsed) / 1e6;\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (converted <= 0.5) {\n const tenthFractionOfMicro = ((micro * 10) / 1000).toFixed(0);\n // Format as microseconds to nearest tenth\n time = chalk.cyan.bold(`0.${tenthFractionOfMicro}ms`);\n } else {\n time = chalk.dim(converted.toFixed(0) + 'ms');\n }\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n time +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n this.terminal.log(chalk.dim('Starting Metro Bundler'));\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n _logBundlingError(error: SnippetError): void {\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);\n if (moduleResolutionError) {\n let message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n message += '\\n\\n' + nearestImportStack(error);\n return this.terminal.log(message);\n }\n\n attachImportStackToRootMessage(error);\n return super._logBundlingError(error);\n }\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n projectRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(projectRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = stripMetroInfo(rawMessage);\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\n}\n\n/**\n * Remove the Metro cache clearing steps if they exist.\n * In future versions we won't need this.\n * Returns the remaining code frame logs.\n */\nexport function stripMetroInfo(errorMessage: string): string | null {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return null;\n }\n const lines = errorMessage.split('\\n');\n const index = lines.findIndex((line) => line.includes('4. Remove the cache'));\n if (index === -1) {\n return null;\n }\n return lines.slice(index + 1).join('\\n');\n}\n\n/** @returns if the message matches the initial startup log */\nfunction isAppRegistryStartupMessage(body: any[]): boolean {\n return (\n body.length === 1 &&\n (/^Running application \"main\" with appParams:/.test(body[0]) ||\n /^Running \"main\" with \\{/.test(body[0]))\n );\n}\n\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getPlatformTagForBuildDetails(bundleDetails?: BundleDetails | null): string {\n const platform = bundleDetails?.platform ?? null;\n if (platform) {\n const formatted = { ios: 'iOS', android: 'Android', web: 'Web' }[platform] || platform;\n return `${chalk.bold(formatted)} `;\n }\n\n return '';\n}\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getEnvironmentForBuildDetails(bundleDetails?: BundleDetails | null): string {\n // Expo CLI will pass `customTransformOptions.environment = 'node'` when bundling for the server.\n const env = bundleDetails?.customTransformOptions?.environment ?? null;\n if (env === 'node') {\n return chalk.bold('λ') + ' ';\n } else if (env === 'react-server') {\n return chalk.bold(`RSC(${getPlatformTagForBuildDetails(bundleDetails).trim()})`) + ' ';\n }\n\n if (\n bundleDetails?.customTransformOptions?.dom &&\n typeof bundleDetails?.customTransformOptions?.dom === 'string'\n ) {\n return chalk.bold(`DOM`) + ' ';\n }\n\n return '';\n}\n"],"names":["MetroTerminalReporter","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","constructor","projectRoot","terminal","_log","event","type","data","message","match","env","EXPO_DEBUG","shouldFilterClientLog","level","mode","hasStack","parsed","map","msg","includes","stack","parseErrorStringToObject","symbolicating","p","maybeSymbolicateAndFormatJSErrorStackLogAsync","usefulStackCount","fallbackIndices","symbolicated","Promise","allSettled","s","index","status","reason","value","isFallback","push","filtered","filter","_","logLikeMetro","log","bind","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","bundleDetails","platform","getPlatformTagForBuildDetails","inProgress","localPath","customTransformOptions","dom","path","sep","replace","inputFile","entryFile","isAbsolute","relative","color","chalk","green","red","_bundleTimers","get","buildID","time","elapsed","micro","Number","converted","tenthFractionOfMicro","toFixed","cyan","bold","dim","plural","totalFileCount","reset","filledBar","Math","floor","ratio","_progress","bgGreen","repeat","bgWhite","white","padStart","transformedFileCount","toString","length","dirname","basename","_logInitializing","port","hasReducedPerformance","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","join","_logBundlingError","error","moduleResolutionError","maybeAppendCodeFrame","nearestImportStack","attachImportStackToRootMessage","targetModuleName","originModulePath","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","lines","split","findIndex","line","slice","body","formatted","ios","android","web","environment","trim"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import type { Terminal } from '@expo/metro/metro-core';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { stripVTControlCharacters } from 'util';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { env } from '../../../utils/env';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatJSErrorStackLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\nimport { attachImportStackToRootMessage, nearestImportStack } from './metroErrorInterface';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n constructor(\n public projectRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n _log(event: TerminalReportableEvent): void {\n switch (event.type) {\n case 'unstable_server_log':\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n break;\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n const { level } = event;\n\n if (!level) {\n break;\n }\n\n const mode = event.mode === 'NOBRIDGE' || event.mode === 'BRIDGE' ? '' : (event.mode ?? '');\n // @ts-expect-error\n if (level === 'warn' || level === 'error') {\n let hasStack = false;\n const parsed = event.data.map((msg) => {\n // Quick check to see if an unsymbolicated stack is being logged.\n if (msg.includes('.bundle//&platform=')) {\n const stack = parseErrorStringToObject(msg);\n if (stack) {\n hasStack = true;\n }\n return stack;\n }\n return msg;\n });\n\n if (hasStack) {\n (async () => {\n const symbolicating = parsed.map((p) => {\n if (typeof p === 'string') return p;\n return maybeSymbolicateAndFormatJSErrorStackLogAsync(this.projectRoot, level, p);\n });\n\n let usefulStackCount = 0;\n const fallbackIndices: number[] = [];\n const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index) => {\n if (s.status === 'rejected') {\n debug('Error formatting stack', parsed[index], s.reason);\n return parsed[index];\n } else if (typeof s.value === 'string') {\n return s.value;\n } else {\n if (!s.value.isFallback) {\n usefulStackCount++;\n } else {\n fallbackIndices.push(index);\n }\n return s.value.stack;\n }\n });\n\n // Using EXPO_DEBUG we can print all stack\n const filtered =\n usefulStackCount && !env.EXPO_DEBUG\n ? symbolicated.filter((_, index) => !fallbackIndices.includes(index))\n : symbolicated;\n\n logLikeMetro(this.terminal.log.bind(this.terminal), level, mode, ...filtered);\n })();\n return;\n }\n }\n\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, mode, ...event.data);\n return;\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n let localPath: string;\n\n if (\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ) {\n // Because we use a generated entry file for DOM components, we need to adjust the logging path so it\n // shows a unique path for each component.\n // Here, we take the relative import path and remove all the starting slashes.\n localPath = progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '');\n } else {\n const inputFile = progress.bundleDetails.entryFile;\n\n localPath = path.isAbsolute(inputFile)\n ? path.relative(this.projectRoot, inputFile)\n : inputFile;\n }\n\n if (!inProgress) {\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: string = '';\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const micro = Number(elapsed) / 1000;\n const converted = Number(elapsed) / 1e6;\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (converted <= 0.5) {\n const tenthFractionOfMicro = ((micro * 10) / 1000).toFixed(0);\n // Format as microseconds to nearest tenth\n time = chalk.cyan.bold(`0.${tenthFractionOfMicro}ms`);\n } else {\n time = chalk.dim(converted.toFixed(0) + 'ms');\n }\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n time +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n this.terminal.log(chalk.dim('Starting Metro Bundler'));\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n _logBundlingError(error: SnippetError): void {\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);\n if (moduleResolutionError) {\n let message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n message += '\\n\\n' + nearestImportStack(error);\n return this.terminal.log(message);\n }\n\n attachImportStackToRootMessage(error);\n return super._logBundlingError(error);\n }\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n projectRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(projectRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\n}\n\n/** Extract fist code frame presented in the error message */\nexport function extractCodeFrame(errorMessage: string): string {\n const codeFrameLine = /^(?:\\s*(?:>?\\s*\\d+\\s*\\||\\s*\\|).*\\n?)+/;\n let wasPreviousLineCodeFrame: boolean | null = null;\n return errorMessage\n .split('\\n')\n .filter((line) => {\n if (wasPreviousLineCodeFrame === false) return false;\n const keep = codeFrameLine.test(stripVTControlCharacters(line));\n if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;\n else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;\n return keep;\n })\n .join('\\n');\n}\n\n/**\n * Remove the Metro cache clearing steps if they exist.\n * In future versions we won't need this.\n * Returns the remaining code frame logs.\n */\nexport function stripMetroInfo(errorMessage: string): string {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return errorMessage;\n }\n const lines = errorMessage.split('\\n');\n const index = lines.findIndex((line) => line.includes('4. Remove the cache'));\n if (index === -1) {\n return errorMessage;\n }\n return lines.slice(index + 1).join('\\n');\n}\n\n/** @returns if the message matches the initial startup log */\nfunction isAppRegistryStartupMessage(body: any[]): boolean {\n return (\n body.length === 1 &&\n (/^Running application \"main\" with appParams:/.test(body[0]) ||\n /^Running \"main\" with \\{/.test(body[0]))\n );\n}\n\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getPlatformTagForBuildDetails(bundleDetails?: BundleDetails | null): string {\n const platform = bundleDetails?.platform ?? null;\n if (platform) {\n const formatted = { ios: 'iOS', android: 'Android', web: 'Web' }[platform] || platform;\n return `${chalk.bold(formatted)} `;\n }\n\n return '';\n}\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getEnvironmentForBuildDetails(bundleDetails?: BundleDetails | null): string {\n // Expo CLI will pass `customTransformOptions.environment = 'node'` when bundling for the server.\n const env = bundleDetails?.customTransformOptions?.environment ?? null;\n if (env === 'node') {\n return chalk.bold('λ') + ' ';\n } else if (env === 'react-server') {\n return chalk.bold(`RSC(${getPlatformTagForBuildDetails(bundleDetails).trim()})`) + ' ';\n }\n\n if (\n bundleDetails?.customTransformOptions?.dom &&\n typeof bundleDetails?.customTransformOptions?.dom === 'string'\n ) {\n return chalk.bold(`DOM`) + ' ';\n }\n\n return '';\n}\n"],"names":["MetroTerminalReporter","extractCodeFrame","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","constructor","projectRoot","terminal","_log","event","type","data","message","match","env","EXPO_DEBUG","shouldFilterClientLog","level","mode","hasStack","parsed","map","msg","includes","stack","parseErrorStringToObject","symbolicating","p","maybeSymbolicateAndFormatJSErrorStackLogAsync","usefulStackCount","fallbackIndices","symbolicated","Promise","allSettled","s","index","status","reason","value","isFallback","push","filtered","filter","_","logLikeMetro","log","bind","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","bundleDetails","platform","getPlatformTagForBuildDetails","inProgress","localPath","customTransformOptions","dom","path","sep","replace","inputFile","entryFile","isAbsolute","relative","color","chalk","green","red","_bundleTimers","get","buildID","time","elapsed","micro","Number","converted","tenthFractionOfMicro","toFixed","cyan","bold","dim","plural","totalFileCount","reset","filledBar","Math","floor","ratio","_progress","bgGreen","repeat","bgWhite","white","padStart","transformedFileCount","toString","length","dirname","basename","_logInitializing","port","hasReducedPerformance","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","join","_logBundlingError","error","moduleResolutionError","maybeAppendCodeFrame","nearestImportStack","attachImportStackToRootMessage","targetModuleName","originModulePath","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","codeFrameLine","wasPreviousLineCodeFrame","split","line","keep","stripVTControlCharacters","lines","findIndex","slice","body","formatted","ios","android","web","environment","trim"],"mappings":"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"}
@@ -177,8 +177,14 @@ function createRouteHandlerMiddleware(projectRoot, options) {
177
177
  basedir: options.appDir
178
178
  });
179
179
  try {
180
+ var _middlewareModule_unstable_settings;
180
181
  debug(`Bundling middleware at: ${resolvedFunctionPath}`);
181
- return await options.bundleApiRoute(resolvedFunctionPath);
182
+ const middlewareModule = await options.bundleApiRoute(resolvedFunctionPath);
183
+ if ((_middlewareModule_unstable_settings = middlewareModule.unstable_settings) == null ? void 0 : _middlewareModule_unstable_settings.matcher) {
184
+ var _middlewareModule_unstable_settings1;
185
+ (0, _router.warnInvalidMiddlewareMatcherSettings)((_middlewareModule_unstable_settings1 = middlewareModule.unstable_settings) == null ? void 0 : _middlewareModule_unstable_settings1.matcher);
186
+ }
187
+ return middlewareModule;
182
188
  } catch (error) {
183
189
  return new Response('Failed to load middleware: ' + resolvedFunctionPath + '\n\n' + error.message, {
184
190
  status: 500,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/createServerRouteMiddleware.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 */\n\nimport type { ProjectConfig } from '@expo/config';\nimport resolve from 'resolve';\nimport resolveFrom from 'resolve-from';\nimport { promisify } from 'util';\n\nimport { fetchManifest } from './fetchRouterManifest';\nimport { getErrorOverlayHtmlAsync, logMetroError } from './metroErrorInterface';\nimport { warnInvalidWebOutput, warnInvalidMiddlewareOutput } from './router';\nimport { CommandError } from '../../../utils/errors';\n\nconst debug = require('debug')('expo:start:server:metro') as typeof console.log;\n\nconst resolveAsync = promisify(resolve) as any as (\n id: string,\n opts: resolve.AsyncOpts\n) => Promise<string | null>;\n\nexport function createRouteHandlerMiddleware(\n projectRoot: string,\n options: {\n appDir: string;\n routerRoot: string;\n getStaticPageAsync: (pathname: string) => Promise<{ content: string }>;\n bundleApiRoute: (\n functionFilePath: string\n ) => Promise<null | Record<string, Function> | Response>;\n config: ProjectConfig;\n } & import('expo-router/build/routes-manifest').Options\n) {\n if (!resolveFrom.silent(projectRoot, 'expo-router')) {\n throw new CommandError(\n `static and server rendering requires the expo-router package to be installed in your project. Either install the expo-router package or change 'web.output' to 'static' in your app.json.`\n );\n }\n\n const { createRequestHandler } =\n require('@expo/server/adapter/http') as typeof import('@expo/server/adapter/http');\n\n return createRequestHandler(\n { build: '' },\n {\n async getRoutesManifest() {\n const manifest = await fetchManifest<RegExp>(projectRoot, options);\n debug('manifest', manifest);\n // NOTE: no app dir if null\n // TODO: Redirect to 404 page\n return (\n manifest ?? {\n // Support the onboarding screen if there's no manifest\n htmlRoutes: [\n {\n file: 'index.js',\n page: '/index',\n routeKeys: {},\n namedRegex: /^\\/(?:index)?\\/?$/i,\n },\n ],\n apiRoutes: [],\n notFoundRoutes: [],\n redirects: [],\n rewrites: [],\n }\n );\n },\n async getHtml(request) {\n try {\n const { content } = await options.getStaticPageAsync(request.url);\n return content;\n } catch (error: any) {\n // Forward the Metro server response as-is. It won't be pretty, but at least it will be accurate.\n\n try {\n return new Response(\n await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot,\n }),\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n } catch (staticError: any) {\n debug('Failed to render static error overlay:', staticError);\n // Fallback error for when Expo Router is misconfigured in the project.\n return new Response(\n '<span><h3>Internal Error:</h3><b>Project is not setup correctly for static rendering (check terminal for more info):</b><br/>' +\n error.message +\n '<br/><br/>' +\n staticError.message +\n '</span>',\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n }\n },\n async handleRouteError(error) {\n const { ExpoError } = require('@expo/server') as typeof import('@expo/server');\n\n if (ExpoError.isExpoError(error)) {\n // TODO(@krystofwoldrich): Can we show code snippet of the handler?\n // NOTE(@krystofwoldrich): Removing stack since to avoid confusion. The error is not in the server code.\n delete error.stack;\n }\n\n const htmlServerError = await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot!,\n });\n\n return new Response(htmlServerError, {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n });\n },\n async getApiRoute(route) {\n const { exp } = options.config;\n if (exp.web?.output !== 'server') {\n warnInvalidWebOutput();\n }\n\n const resolvedFunctionPath = await resolveAsync(route.file, {\n extensions: ['.js', '.jsx', '.ts', '.tsx'],\n basedir: options.appDir,\n })!;\n\n try {\n debug(`Bundling API route at: ${resolvedFunctionPath}`);\n return await options.bundleApiRoute(resolvedFunctionPath!);\n } catch (error: any) {\n return new Response(\n 'Failed to load API Route: ' + resolvedFunctionPath + '\\n\\n' + error.message,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n },\n async getMiddleware(route) {\n const { exp } = options.config;\n\n if (!options.unstable_useServerMiddleware) {\n return {\n default: () => {\n throw new CommandError(\n 'Server middleware is not enabled. Add unstable_useServerMiddleware: true to your `expo-router` plugin config.'\n );\n },\n };\n }\n\n if (exp.web?.output !== 'server') {\n warnInvalidMiddlewareOutput();\n return {\n default: () => {\n console.warn(\n 'Server middleware is only supported when web.output is set to \"server\" in your app config'\n );\n },\n };\n }\n\n const resolvedFunctionPath = await resolveAsync(route.file, {\n extensions: ['.js', '.jsx', '.ts', '.tsx'],\n basedir: options.appDir,\n })!;\n\n try {\n debug(`Bundling middleware at: ${resolvedFunctionPath}`);\n return await options.bundleApiRoute(resolvedFunctionPath!);\n } catch (error: any) {\n return new Response(\n 'Failed to load middleware: ' + resolvedFunctionPath + '\\n\\n' + error.message,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n },\n }\n );\n}\n"],"names":["createRouteHandlerMiddleware","debug","require","resolveAsync","promisify","resolve","projectRoot","options","resolveFrom","silent","CommandError","createRequestHandler","build","getRoutesManifest","manifest","fetchManifest","htmlRoutes","file","page","routeKeys","namedRegex","apiRoutes","notFoundRoutes","redirects","rewrites","getHtml","request","content","getStaticPageAsync","url","error","Response","getErrorOverlayHtmlAsync","routerRoot","status","headers","staticError","message","handleRouteError","ExpoError","isExpoError","stack","htmlServerError","getApiRoute","route","exp","config","web","output","warnInvalidWebOutput","resolvedFunctionPath","extensions","basedir","appDir","bundleApiRoute","getMiddleware","unstable_useServerMiddleware","default","warnInvalidMiddlewareOutput","console","warn"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/server/metro/createServerRouteMiddleware.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 */\n\nimport type { ProjectConfig } from '@expo/config';\nimport { MiddlewareModule } from '@expo/server/build/types';\nimport resolve from 'resolve';\nimport resolveFrom from 'resolve-from';\nimport { promisify } from 'util';\n\nimport { fetchManifest } from './fetchRouterManifest';\nimport { getErrorOverlayHtmlAsync, logMetroError } from './metroErrorInterface';\nimport {\n warnInvalidWebOutput,\n warnInvalidMiddlewareOutput,\n warnInvalidMiddlewareMatcherSettings,\n} from './router';\nimport { CommandError } from '../../../utils/errors';\n\nconst debug = require('debug')('expo:start:server:metro') as typeof console.log;\n\nconst resolveAsync = promisify(resolve) as any as (\n id: string,\n opts: resolve.AsyncOpts\n) => Promise<string | null>;\n\nexport function createRouteHandlerMiddleware(\n projectRoot: string,\n options: {\n appDir: string;\n routerRoot: string;\n getStaticPageAsync: (pathname: string) => Promise<{ content: string }>;\n bundleApiRoute: (\n functionFilePath: string\n ) => Promise<null | Record<string, Function> | Response>;\n config: ProjectConfig;\n } & import('expo-router/build/routes-manifest').Options\n) {\n if (!resolveFrom.silent(projectRoot, 'expo-router')) {\n throw new CommandError(\n `static and server rendering requires the expo-router package to be installed in your project. Either install the expo-router package or change 'web.output' to 'static' in your app.json.`\n );\n }\n\n const { createRequestHandler } =\n require('@expo/server/adapter/http') as typeof import('@expo/server/adapter/http');\n\n return createRequestHandler(\n { build: '' },\n {\n async getRoutesManifest() {\n const manifest = await fetchManifest<RegExp>(projectRoot, options);\n debug('manifest', manifest);\n // NOTE: no app dir if null\n // TODO: Redirect to 404 page\n return (\n manifest ?? {\n // Support the onboarding screen if there's no manifest\n htmlRoutes: [\n {\n file: 'index.js',\n page: '/index',\n routeKeys: {},\n namedRegex: /^\\/(?:index)?\\/?$/i,\n },\n ],\n apiRoutes: [],\n notFoundRoutes: [],\n redirects: [],\n rewrites: [],\n }\n );\n },\n async getHtml(request) {\n try {\n const { content } = await options.getStaticPageAsync(request.url);\n return content;\n } catch (error: any) {\n // Forward the Metro server response as-is. It won't be pretty, but at least it will be accurate.\n\n try {\n return new Response(\n await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot,\n }),\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n } catch (staticError: any) {\n debug('Failed to render static error overlay:', staticError);\n // Fallback error for when Expo Router is misconfigured in the project.\n return new Response(\n '<span><h3>Internal Error:</h3><b>Project is not setup correctly for static rendering (check terminal for more info):</b><br/>' +\n error.message +\n '<br/><br/>' +\n staticError.message +\n '</span>',\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n }\n },\n async handleRouteError(error) {\n const { ExpoError } = require('@expo/server') as typeof import('@expo/server');\n\n if (ExpoError.isExpoError(error)) {\n // TODO(@krystofwoldrich): Can we show code snippet of the handler?\n // NOTE(@krystofwoldrich): Removing stack since to avoid confusion. The error is not in the server code.\n delete error.stack;\n }\n\n const htmlServerError = await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot!,\n });\n\n return new Response(htmlServerError, {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n });\n },\n async getApiRoute(route) {\n const { exp } = options.config;\n if (exp.web?.output !== 'server') {\n warnInvalidWebOutput();\n }\n\n const resolvedFunctionPath = await resolveAsync(route.file, {\n extensions: ['.js', '.jsx', '.ts', '.tsx'],\n basedir: options.appDir,\n })!;\n\n try {\n debug(`Bundling API route at: ${resolvedFunctionPath}`);\n return await options.bundleApiRoute(resolvedFunctionPath!);\n } catch (error: any) {\n return new Response(\n 'Failed to load API Route: ' + resolvedFunctionPath + '\\n\\n' + error.message,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n },\n async getMiddleware(route) {\n const { exp } = options.config;\n\n if (!options.unstable_useServerMiddleware) {\n return {\n default: () => {\n throw new CommandError(\n 'Server middleware is not enabled. Add unstable_useServerMiddleware: true to your `expo-router` plugin config.'\n );\n },\n };\n }\n\n if (exp.web?.output !== 'server') {\n warnInvalidMiddlewareOutput();\n return {\n default: () => {\n console.warn(\n 'Server middleware is only supported when web.output is set to \"server\" in your app config'\n );\n },\n };\n }\n\n const resolvedFunctionPath = await resolveAsync(route.file, {\n extensions: ['.js', '.jsx', '.ts', '.tsx'],\n basedir: options.appDir,\n })!;\n\n try {\n debug(`Bundling middleware at: ${resolvedFunctionPath}`);\n const middlewareModule = (await options.bundleApiRoute(\n resolvedFunctionPath!\n )) as unknown as MiddlewareModule;\n\n if (middlewareModule.unstable_settings?.matcher) {\n warnInvalidMiddlewareMatcherSettings(middlewareModule.unstable_settings?.matcher);\n }\n\n return middlewareModule;\n } catch (error: any) {\n return new Response(\n 'Failed to load middleware: ' + resolvedFunctionPath + '\\n\\n' + error.message,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n },\n }\n );\n}\n"],"names":["createRouteHandlerMiddleware","debug","require","resolveAsync","promisify","resolve","projectRoot","options","resolveFrom","silent","CommandError","createRequestHandler","build","getRoutesManifest","manifest","fetchManifest","htmlRoutes","file","page","routeKeys","namedRegex","apiRoutes","notFoundRoutes","redirects","rewrites","getHtml","request","content","getStaticPageAsync","url","error","Response","getErrorOverlayHtmlAsync","routerRoot","status","headers","staticError","message","handleRouteError","ExpoError","isExpoError","stack","htmlServerError","getApiRoute","route","exp","config","web","output","warnInvalidWebOutput","resolvedFunctionPath","extensions","basedir","appDir","bundleApiRoute","getMiddleware","unstable_useServerMiddleware","default","warnInvalidMiddlewareOutput","console","warn","middlewareModule","unstable_settings","matcher","warnInvalidMiddlewareMatcherSettings"],"mappings":"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"}
@@ -72,7 +72,7 @@ const metroOpenStackFrameMiddleware = (req, res, next)=>{
72
72
  };
73
73
  function createMetroStatusMiddleware(metroConfig) {
74
74
  return (_req, res)=>{
75
- res.setHeader('X-React-Native-Project-Root', metroConfig.projectRoot);
75
+ res.setHeader('X-React-Native-Project-Root', encodeURI(metroConfig.projectRoot));
76
76
  res.end('packager-status:running');
77
77
  };
78
78
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/start/server/metro/dev-server/createMetroMiddleware.ts"],"sourcesContent":["import type { MetroConfig } from '@expo/metro/metro';\nimport connect from 'connect';\n\nimport { createEventsSocket } from './createEventSocket';\nimport { createMessagesSocket } from './createMessageSocket';\nimport { Log } from '../../../../log';\nimport { openInEditorAsync } from '../../../../utils/editor';\n\nconst compression = require('compression');\n\nexport function createMetroMiddleware(metroConfig: Pick<MetroConfig, 'projectRoot'>) {\n const messages = createMessagesSocket({ logger: Log });\n const events = createEventsSocket(messages);\n\n const middleware = connect()\n .use(noCacheMiddleware)\n .use(compression())\n // Support opening stack frames from clients directly in the editor\n .use('/open-stack-frame', rawBodyMiddleware)\n .use('/open-stack-frame', metroOpenStackFrameMiddleware)\n // Support the symbolication endpoint of Metro\n // See: https://github.com/facebook/metro/blob/a792d85ffde3c21c3fbf64ac9404ab0afe5ff957/packages/metro/src/Server.js#L1266\n .use('/symbolicate', rawBodyMiddleware)\n // Support status check to detect if the packager needs to be started from the native side\n .use('/status', createMetroStatusMiddleware(metroConfig));\n\n return {\n middleware,\n messagesSocket: messages,\n eventsSocket: events,\n websocketEndpoints: {\n [messages.endpoint]: messages.server,\n [events.endpoint]: events.server,\n },\n };\n}\n\nconst noCacheMiddleware: connect.NextHandleFunction = (req, res, next) => {\n res.setHeader('Surrogate-Control', 'no-store');\n res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');\n res.setHeader('Pragma', 'no-cache');\n res.setHeader('Expires', '0');\n next();\n};\n\nconst rawBodyMiddleware: connect.NextHandleFunction = (req, _res, next) => {\n const reqWithBody = req as typeof req & { rawBody: string };\n reqWithBody.setEncoding('utf8');\n reqWithBody.rawBody = '';\n reqWithBody.on('data', (chunk) => (reqWithBody.rawBody += chunk));\n reqWithBody.on('end', next);\n};\n\nconst metroOpenStackFrameMiddleware: connect.NextHandleFunction = (req, res, next) => {\n // Only accept POST requests\n if (req.method !== 'POST') return next();\n // Only handle requests with a raw body\n if (!('rawBody' in req) || !req.rawBody) {\n res.statusCode = 406;\n return res.end('Open stack frame requires the JSON stack frame as request body');\n }\n\n const frame = JSON.parse(req.rawBody as string);\n openInEditorAsync(frame.file, frame.lineNumber).finally(() => res.end('OK'));\n};\n\nfunction createMetroStatusMiddleware(\n metroConfig: Pick<MetroConfig, 'projectRoot'>\n): connect.NextHandleFunction {\n return (_req, res) => {\n res.setHeader('X-React-Native-Project-Root', metroConfig.projectRoot!);\n res.end('packager-status:running');\n };\n}\n"],"names":["createMetroMiddleware","compression","require","metroConfig","messages","createMessagesSocket","logger","Log","events","createEventsSocket","middleware","connect","use","noCacheMiddleware","rawBodyMiddleware","metroOpenStackFrameMiddleware","createMetroStatusMiddleware","messagesSocket","eventsSocket","websocketEndpoints","endpoint","server","req","res","next","setHeader","_res","reqWithBody","setEncoding","rawBody","on","chunk","method","statusCode","end","frame","JSON","parse","openInEditorAsync","file","lineNumber","finally","_req","projectRoot"],"mappings":";;;;+BAUgBA;;;eAAAA;;;;gEATI;;;;;;mCAEe;qCACE;qBACjB;wBACc;;;;;;AAElC,MAAMC,cAAcC,QAAQ;AAErB,SAASF,sBAAsBG,WAA6C;IACjF,MAAMC,WAAWC,IAAAA,yCAAoB,EAAC;QAAEC,QAAQC,QAAG;IAAC;IACpD,MAAMC,SAASC,IAAAA,qCAAkB,EAACL;IAElC,MAAMM,aAAaC,IAAAA,kBAAO,IACvBC,GAAG,CAACC,mBACJD,GAAG,CAACX,cACL,mEAAmE;KAClEW,GAAG,CAAC,qBAAqBE,mBACzBF,GAAG,CAAC,qBAAqBG,8BAC1B,8CAA8C;IAC9C,0HAA0H;KACzHH,GAAG,CAAC,gBAAgBE,kBACrB,0FAA0F;KACzFF,GAAG,CAAC,WAAWI,4BAA4Bb;IAE9C,OAAO;QACLO;QACAO,gBAAgBb;QAChBc,cAAcV;QACdW,oBAAoB;YAClB,CAACf,SAASgB,QAAQ,CAAC,EAAEhB,SAASiB,MAAM;YACpC,CAACb,OAAOY,QAAQ,CAAC,EAAEZ,OAAOa,MAAM;QAClC;IACF;AACF;AAEA,MAAMR,oBAAgD,CAACS,KAAKC,KAAKC;IAC/DD,IAAIE,SAAS,CAAC,qBAAqB;IACnCF,IAAIE,SAAS,CAAC,iBAAiB;IAC/BF,IAAIE,SAAS,CAAC,UAAU;IACxBF,IAAIE,SAAS,CAAC,WAAW;IACzBD;AACF;AAEA,MAAMV,oBAAgD,CAACQ,KAAKI,MAAMF;IAChE,MAAMG,cAAcL;IACpBK,YAAYC,WAAW,CAAC;IACxBD,YAAYE,OAAO,GAAG;IACtBF,YAAYG,EAAE,CAAC,QAAQ,CAACC,QAAWJ,YAAYE,OAAO,IAAIE;IAC1DJ,YAAYG,EAAE,CAAC,OAAON;AACxB;AAEA,MAAMT,gCAA4D,CAACO,KAAKC,KAAKC;IAC3E,4BAA4B;IAC5B,IAAIF,IAAIU,MAAM,KAAK,QAAQ,OAAOR;IAClC,uCAAuC;IACvC,IAAI,CAAE,CAAA,aAAaF,GAAE,KAAM,CAACA,IAAIO,OAAO,EAAE;QACvCN,IAAIU,UAAU,GAAG;QACjB,OAAOV,IAAIW,GAAG,CAAC;IACjB;IAEA,MAAMC,QAAQC,KAAKC,KAAK,CAACf,IAAIO,OAAO;IACpCS,IAAAA,yBAAiB,EAACH,MAAMI,IAAI,EAAEJ,MAAMK,UAAU,EAAEC,OAAO,CAAC,IAAMlB,IAAIW,GAAG,CAAC;AACxE;AAEA,SAASlB,4BACPb,WAA6C;IAE7C,OAAO,CAACuC,MAAMnB;QACZA,IAAIE,SAAS,CAAC,+BAA+BtB,YAAYwC,WAAW;QACpEpB,IAAIW,GAAG,CAAC;IACV;AACF"}
1
+ {"version":3,"sources":["../../../../../../src/start/server/metro/dev-server/createMetroMiddleware.ts"],"sourcesContent":["import type { MetroConfig } from '@expo/metro/metro';\nimport connect from 'connect';\n\nimport { createEventsSocket } from './createEventSocket';\nimport { createMessagesSocket } from './createMessageSocket';\nimport { Log } from '../../../../log';\nimport { openInEditorAsync } from '../../../../utils/editor';\n\nconst compression = require('compression');\n\nexport function createMetroMiddleware(metroConfig: Pick<MetroConfig, 'projectRoot'>) {\n const messages = createMessagesSocket({ logger: Log });\n const events = createEventsSocket(messages);\n\n const middleware = connect()\n .use(noCacheMiddleware)\n .use(compression())\n // Support opening stack frames from clients directly in the editor\n .use('/open-stack-frame', rawBodyMiddleware)\n .use('/open-stack-frame', metroOpenStackFrameMiddleware)\n // Support the symbolication endpoint of Metro\n // See: https://github.com/facebook/metro/blob/a792d85ffde3c21c3fbf64ac9404ab0afe5ff957/packages/metro/src/Server.js#L1266\n .use('/symbolicate', rawBodyMiddleware)\n // Support status check to detect if the packager needs to be started from the native side\n .use('/status', createMetroStatusMiddleware(metroConfig));\n\n return {\n middleware,\n messagesSocket: messages,\n eventsSocket: events,\n websocketEndpoints: {\n [messages.endpoint]: messages.server,\n [events.endpoint]: events.server,\n },\n };\n}\n\nconst noCacheMiddleware: connect.NextHandleFunction = (req, res, next) => {\n res.setHeader('Surrogate-Control', 'no-store');\n res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');\n res.setHeader('Pragma', 'no-cache');\n res.setHeader('Expires', '0');\n next();\n};\n\nconst rawBodyMiddleware: connect.NextHandleFunction = (req, _res, next) => {\n const reqWithBody = req as typeof req & { rawBody: string };\n reqWithBody.setEncoding('utf8');\n reqWithBody.rawBody = '';\n reqWithBody.on('data', (chunk) => (reqWithBody.rawBody += chunk));\n reqWithBody.on('end', next);\n};\n\nconst metroOpenStackFrameMiddleware: connect.NextHandleFunction = (req, res, next) => {\n // Only accept POST requests\n if (req.method !== 'POST') return next();\n // Only handle requests with a raw body\n if (!('rawBody' in req) || !req.rawBody) {\n res.statusCode = 406;\n return res.end('Open stack frame requires the JSON stack frame as request body');\n }\n\n const frame = JSON.parse(req.rawBody as string);\n openInEditorAsync(frame.file, frame.lineNumber).finally(() => res.end('OK'));\n};\n\nfunction createMetroStatusMiddleware(\n metroConfig: Pick<MetroConfig, 'projectRoot'>\n): connect.NextHandleFunction {\n return (_req, res) => {\n res.setHeader('X-React-Native-Project-Root', encodeURI(metroConfig.projectRoot!));\n res.end('packager-status:running');\n };\n}\n"],"names":["createMetroMiddleware","compression","require","metroConfig","messages","createMessagesSocket","logger","Log","events","createEventsSocket","middleware","connect","use","noCacheMiddleware","rawBodyMiddleware","metroOpenStackFrameMiddleware","createMetroStatusMiddleware","messagesSocket","eventsSocket","websocketEndpoints","endpoint","server","req","res","next","setHeader","_res","reqWithBody","setEncoding","rawBody","on","chunk","method","statusCode","end","frame","JSON","parse","openInEditorAsync","file","lineNumber","finally","_req","encodeURI","projectRoot"],"mappings":";;;;+BAUgBA;;;eAAAA;;;;gEATI;;;;;;mCAEe;qCACE;qBACjB;wBACc;;;;;;AAElC,MAAMC,cAAcC,QAAQ;AAErB,SAASF,sBAAsBG,WAA6C;IACjF,MAAMC,WAAWC,IAAAA,yCAAoB,EAAC;QAAEC,QAAQC,QAAG;IAAC;IACpD,MAAMC,SAASC,IAAAA,qCAAkB,EAACL;IAElC,MAAMM,aAAaC,IAAAA,kBAAO,IACvBC,GAAG,CAACC,mBACJD,GAAG,CAACX,cACL,mEAAmE;KAClEW,GAAG,CAAC,qBAAqBE,mBACzBF,GAAG,CAAC,qBAAqBG,8BAC1B,8CAA8C;IAC9C,0HAA0H;KACzHH,GAAG,CAAC,gBAAgBE,kBACrB,0FAA0F;KACzFF,GAAG,CAAC,WAAWI,4BAA4Bb;IAE9C,OAAO;QACLO;QACAO,gBAAgBb;QAChBc,cAAcV;QACdW,oBAAoB;YAClB,CAACf,SAASgB,QAAQ,CAAC,EAAEhB,SAASiB,MAAM;YACpC,CAACb,OAAOY,QAAQ,CAAC,EAAEZ,OAAOa,MAAM;QAClC;IACF;AACF;AAEA,MAAMR,oBAAgD,CAACS,KAAKC,KAAKC;IAC/DD,IAAIE,SAAS,CAAC,qBAAqB;IACnCF,IAAIE,SAAS,CAAC,iBAAiB;IAC/BF,IAAIE,SAAS,CAAC,UAAU;IACxBF,IAAIE,SAAS,CAAC,WAAW;IACzBD;AACF;AAEA,MAAMV,oBAAgD,CAACQ,KAAKI,MAAMF;IAChE,MAAMG,cAAcL;IACpBK,YAAYC,WAAW,CAAC;IACxBD,YAAYE,OAAO,GAAG;IACtBF,YAAYG,EAAE,CAAC,QAAQ,CAACC,QAAWJ,YAAYE,OAAO,IAAIE;IAC1DJ,YAAYG,EAAE,CAAC,OAAON;AACxB;AAEA,MAAMT,gCAA4D,CAACO,KAAKC,KAAKC;IAC3E,4BAA4B;IAC5B,IAAIF,IAAIU,MAAM,KAAK,QAAQ,OAAOR;IAClC,uCAAuC;IACvC,IAAI,CAAE,CAAA,aAAaF,GAAE,KAAM,CAACA,IAAIO,OAAO,EAAE;QACvCN,IAAIU,UAAU,GAAG;QACjB,OAAOV,IAAIW,GAAG,CAAC;IACjB;IAEA,MAAMC,QAAQC,KAAKC,KAAK,CAACf,IAAIO,OAAO;IACpCS,IAAAA,yBAAiB,EAACH,MAAMI,IAAI,EAAEJ,MAAMK,UAAU,EAAEC,OAAO,CAAC,IAAMlB,IAAIW,GAAG,CAAC;AACxE;AAEA,SAASlB,4BACPb,WAA6C;IAE7C,OAAO,CAACuC,MAAMnB;QACZA,IAAIE,SAAS,CAAC,+BAA+BkB,UAAUxC,YAAYyC,WAAW;QAC9ErB,IAAIW,GAAG,CAAC;IACV;AACF"}
@@ -36,6 +36,9 @@ _export(exports, {
36
36
  isApiRouteConvention: function() {
37
37
  return isApiRouteConvention;
38
38
  },
39
+ warnInvalidMiddlewareMatcherSettings: function() {
40
+ return warnInvalidMiddlewareMatcherSettings;
41
+ },
39
42
  warnInvalidMiddlewareOutput: function() {
40
43
  return warnInvalidMiddlewareOutput;
41
44
  },
@@ -174,5 +177,42 @@ function warnInvalidMiddlewareOutput() {
174
177
  }
175
178
  hasWarnedAboutMiddlewareOutput = true;
176
179
  }
180
+ function warnInvalidMiddlewareMatcherSettings(matcher) {
181
+ const validMethods = [
182
+ 'GET',
183
+ 'POST',
184
+ 'PUT',
185
+ 'PATCH',
186
+ 'DELETE',
187
+ 'OPTIONS',
188
+ 'HEAD'
189
+ ];
190
+ // Ensure methods are valid HTTP methods
191
+ if (matcher.methods) {
192
+ if (!Array.isArray(matcher.methods)) {
193
+ _log.Log.error(_chalk().default.red`Middleware matcher methods must be an array of valid HTTP methods. Supported methods are: ${validMethods.join(', ')}`);
194
+ } else {
195
+ for (const method of matcher.methods){
196
+ if (!validMethods.includes(method)) {
197
+ _log.Log.error(_chalk().default.red`Invalid middleware HTTP method: ${method}. Supported methods are: ${validMethods.join(', ')}`);
198
+ }
199
+ }
200
+ }
201
+ }
202
+ // Ensure patterns are either a string or RegExp
203
+ if (matcher.patterns) {
204
+ const patterns = Array.isArray(matcher.patterns) ? matcher.patterns : [
205
+ matcher.patterns
206
+ ];
207
+ for (const pattern of patterns){
208
+ if (typeof pattern !== 'string' && !(pattern instanceof RegExp)) {
209
+ _log.Log.error(_chalk().default.red`Middleware matcher patterns must be strings or regular expressions. Received: ${String(pattern)}`);
210
+ }
211
+ if (typeof pattern === 'string' && !pattern.startsWith('/')) {
212
+ _log.Log.error(_chalk().default.red`String patterns in middleware matcher must start with '/'. Received: ${pattern}`);
213
+ }
214
+ }
215
+ }
216
+ }
177
217
 
178
218
  //# sourceMappingURL=router.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/router.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport { sync as globSync } from 'glob';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { Log } from '../../../log';\nimport { directoryExistsSync } from '../../../utils/dir';\nimport { toPosixPath } from '../../../utils/filePath';\nimport { learnMore } from '../../../utils/link';\n\nconst debug = require('debug')('expo:start:server:metro:router') as typeof console.log;\n\n/**\n * Get the relative path for requiring the `/app` folder relative to the `expo-router/entry` file.\n * This mechanism does require the server to restart after the `expo-router` package is installed.\n */\nexport function getAppRouterRelativeEntryPath(\n projectRoot: string,\n routerDirectory: string = getRouterDirectory(projectRoot)\n): string | undefined {\n // Auto pick App entry\n const routerEntry =\n resolveFrom.silent(projectRoot, 'expo-router/entry') ?? getFallbackEntryRoot(projectRoot);\n if (!routerEntry) {\n return undefined;\n }\n // It doesn't matter if the app folder exists.\n const appFolder = path.join(projectRoot, routerDirectory);\n const appRoot = path.relative(path.dirname(routerEntry), appFolder);\n debug('expo-router entry', routerEntry, appFolder, appRoot);\n return appRoot;\n}\n\n/** If the `expo-router` package is not installed, then use the `expo` package to determine where the node modules are relative to the project. */\nfunction getFallbackEntryRoot(projectRoot: string): string {\n const expoRoot = resolveFrom.silent(projectRoot, 'expo/package.json');\n if (expoRoot) {\n return path.join(path.dirname(path.dirname(expoRoot)), 'expo-router/entry');\n }\n return path.join(projectRoot, 'node_modules/expo-router/entry');\n}\n\nexport function getRouterDirectoryModuleIdWithManifest(\n projectRoot: string,\n exp: ExpoConfig\n): string {\n return toPosixPath(exp.extra?.router?.root ?? getRouterDirectory(projectRoot));\n}\n\nlet hasWarnedAboutSrcDir = false;\nconst logSrcDir = () => {\n if (hasWarnedAboutSrcDir) return;\n hasWarnedAboutSrcDir = true;\n Log.log(chalk.gray('Using src/app as the root directory for Expo Router.'));\n};\n\nexport function getRouterDirectory(projectRoot: string): string {\n // more specific directories first\n if (directoryExistsSync(path.join(projectRoot, 'src', 'app'))) {\n logSrcDir();\n return path.join('src', 'app');\n }\n\n debug('Using app as the root directory for Expo Router.');\n return 'app';\n}\n\nexport function isApiRouteConvention(name: string): boolean {\n return /\\+api\\.[tj]sx?$/.test(name);\n}\n\nexport function getApiRoutesForDirectory(cwd: string) {\n return globSync('**/*+api.@(ts|tsx|js|jsx)', {\n cwd,\n absolute: true,\n dot: true,\n });\n}\n\n/**\n * Gets the +middleware file for a given directory. In\n * @param cwd\n */\nexport function getMiddlewareForDirectory(cwd: string): string | null {\n const files = globSync('+middleware.@(ts|tsx|js|jsx)', {\n cwd,\n absolute: true,\n dot: true,\n });\n\n if (files.length === 0) return null;\n\n if (files.length > 1) {\n // In development, throw an error if there are multiple root-level middleware files\n if (process.env.NODE_ENV !== 'production') {\n const relativePaths = files.map((f) => './' + path.relative(cwd, f)).sort();\n throw new Error(\n `Only one middleware file is allowed. Keep one of the conflicting files: ${relativePaths.map((p) => `\"${p}\"`).join(' or ')}`\n );\n }\n }\n\n return files[0];\n}\n\n// Used to emulate a context module, but way faster. TODO: May need to adjust the extensions to stay in sync with Metro.\nexport function getRoutePaths(cwd: string) {\n return globSync('**/*.@(ts|tsx|js|jsx)', {\n cwd,\n dot: true,\n }).map((p) => './' + normalizePaths(p));\n}\n\nfunction normalizePaths(p: string) {\n return p.replace(/\\\\/g, '/');\n}\n\nlet hasWarnedAboutApiRouteOutput = false;\nlet hasWarnedAboutMiddlewareOutput = false;\n\nexport function hasWarnedAboutApiRoutes() {\n return hasWarnedAboutApiRouteOutput;\n}\n\nexport function hasWarnedAboutMiddleware() {\n return hasWarnedAboutMiddlewareOutput;\n}\n\nexport function warnInvalidWebOutput() {\n if (!hasWarnedAboutApiRouteOutput) {\n Log.warn(\n chalk.yellow`Using API routes requires the {bold web.output} to be set to {bold \"server\"} in the project {bold app.json}. ${learnMore(\n 'https://docs.expo.dev/router/reference/api-routes/'\n )}`\n );\n }\n\n hasWarnedAboutApiRouteOutput = true;\n}\n\nexport function warnInvalidMiddlewareOutput() {\n if (!hasWarnedAboutMiddlewareOutput) {\n Log.warn(\n chalk.yellow`Using middleware requires the {bold web.output} to be set to {bold \"server\"} in the project {bold app.json}. ${learnMore(\n 'https://docs.expo.dev/router/reference/api-routes/'\n )}`\n );\n }\n\n hasWarnedAboutMiddlewareOutput = true;\n}\n"],"names":["getApiRoutesForDirectory","getAppRouterRelativeEntryPath","getMiddlewareForDirectory","getRoutePaths","getRouterDirectory","getRouterDirectoryModuleIdWithManifest","hasWarnedAboutApiRoutes","hasWarnedAboutMiddleware","isApiRouteConvention","warnInvalidMiddlewareOutput","warnInvalidWebOutput","debug","require","projectRoot","routerDirectory","routerEntry","resolveFrom","silent","getFallbackEntryRoot","undefined","appFolder","path","join","appRoot","relative","dirname","expoRoot","exp","toPosixPath","extra","router","root","hasWarnedAboutSrcDir","logSrcDir","Log","log","chalk","gray","directoryExistsSync","name","test","cwd","globSync","absolute","dot","files","length","process","env","NODE_ENV","relativePaths","map","f","sort","Error","p","normalizePaths","replace","hasWarnedAboutApiRouteOutput","hasWarnedAboutMiddlewareOutput","warn","yellow","learnMore"],"mappings":";;;;;;;;;;;IAwEgBA,wBAAwB;eAAxBA;;IAvDAC,6BAA6B;eAA7BA;;IAmEAC,yBAAyB;eAAzBA;;IAuBAC,aAAa;eAAbA;;IAlDAC,kBAAkB;eAAlBA;;IAdAC,sCAAsC;eAAtCA;;IA8EAC,uBAAuB;eAAvBA;;IAIAC,wBAAwB;eAAxBA;;IAzDAC,oBAAoB;eAApBA;;IAyEAC,2BAA2B;eAA3BA;;IAZAC,oBAAoB;eAApBA;;;;gEAhIE;;;;;;;yBACe;;;;;;;gEAChB;;;;;;;gEACO;;;;;;qBAEJ;qBACgB;0BACR;sBACF;;;;;;AAE1B,MAAMC,QAAQC,QAAQ,SAAS;AAMxB,SAASX,8BACdY,WAAmB,EACnBC,kBAA0BV,mBAAmBS,YAAY;IAEzD,sBAAsB;IACtB,MAAME,cACJC,sBAAW,CAACC,MAAM,CAACJ,aAAa,wBAAwBK,qBAAqBL;IAC/E,IAAI,CAACE,aAAa;QAChB,OAAOI;IACT;IACA,8CAA8C;IAC9C,MAAMC,YAAYC,eAAI,CAACC,IAAI,CAACT,aAAaC;IACzC,MAAMS,UAAUF,eAAI,CAACG,QAAQ,CAACH,eAAI,CAACI,OAAO,CAACV,cAAcK;IACzDT,MAAM,qBAAqBI,aAAaK,WAAWG;IACnD,OAAOA;AACT;AAEA,gJAAgJ,GAChJ,SAASL,qBAAqBL,WAAmB;IAC/C,MAAMa,WAAWV,sBAAW,CAACC,MAAM,CAACJ,aAAa;IACjD,IAAIa,UAAU;QACZ,OAAOL,eAAI,CAACC,IAAI,CAACD,eAAI,CAACI,OAAO,CAACJ,eAAI,CAACI,OAAO,CAACC,YAAY;IACzD;IACA,OAAOL,eAAI,CAACC,IAAI,CAACT,aAAa;AAChC;AAEO,SAASR,uCACdQ,WAAmB,EACnBc,GAAe;QAEIA,mBAAAA;IAAnB,OAAOC,IAAAA,qBAAW,EAACD,EAAAA,aAAAA,IAAIE,KAAK,sBAATF,oBAAAA,WAAWG,MAAM,qBAAjBH,kBAAmBI,IAAI,KAAI3B,mBAAmBS;AACnE;AAEA,IAAImB,uBAAuB;AAC3B,MAAMC,YAAY;IAChB,IAAID,sBAAsB;IAC1BA,uBAAuB;IACvBE,QAAG,CAACC,GAAG,CAACC,gBAAK,CAACC,IAAI,CAAC;AACrB;AAEO,SAASjC,mBAAmBS,WAAmB;IACpD,kCAAkC;IAClC,IAAIyB,IAAAA,wBAAmB,EAACjB,eAAI,CAACC,IAAI,CAACT,aAAa,OAAO,SAAS;QAC7DoB;QACA,OAAOZ,eAAI,CAACC,IAAI,CAAC,OAAO;IAC1B;IAEAX,MAAM;IACN,OAAO;AACT;AAEO,SAASH,qBAAqB+B,IAAY;IAC/C,OAAO,kBAAkBC,IAAI,CAACD;AAChC;AAEO,SAASvC,yBAAyByC,GAAW;IAClD,OAAOC,IAAAA,YAAQ,EAAC,6BAA6B;QAC3CD;QACAE,UAAU;QACVC,KAAK;IACP;AACF;AAMO,SAAS1C,0BAA0BuC,GAAW;IACnD,MAAMI,QAAQH,IAAAA,YAAQ,EAAC,gCAAgC;QACrDD;QACAE,UAAU;QACVC,KAAK;IACP;IAEA,IAAIC,MAAMC,MAAM,KAAK,GAAG,OAAO;IAE/B,IAAID,MAAMC,MAAM,GAAG,GAAG;QACpB,mFAAmF;QACnF,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,MAAMC,gBAAgBL,MAAMM,GAAG,CAAC,CAACC,IAAM,OAAO/B,eAAI,CAACG,QAAQ,CAACiB,KAAKW,IAAIC,IAAI;YACzE,MAAM,IAAIC,MACR,CAAC,wEAAwE,EAAEJ,cAAcC,GAAG,CAAC,CAACI,IAAM,CAAC,CAAC,EAAEA,EAAE,CAAC,CAAC,EAAEjC,IAAI,CAAC,SAAS;QAEhI;IACF;IAEA,OAAOuB,KAAK,CAAC,EAAE;AACjB;AAGO,SAAS1C,cAAcsC,GAAW;IACvC,OAAOC,IAAAA,YAAQ,EAAC,yBAAyB;QACvCD;QACAG,KAAK;IACP,GAAGO,GAAG,CAAC,CAACI,IAAM,OAAOC,eAAeD;AACtC;AAEA,SAASC,eAAeD,CAAS;IAC/B,OAAOA,EAAEE,OAAO,CAAC,OAAO;AAC1B;AAEA,IAAIC,+BAA+B;AACnC,IAAIC,iCAAiC;AAE9B,SAASrD;IACd,OAAOoD;AACT;AAEO,SAASnD;IACd,OAAOoD;AACT;AAEO,SAASjD;IACd,IAAI,CAACgD,8BAA8B;QACjCxB,QAAG,CAAC0B,IAAI,CACNxB,gBAAK,CAACyB,MAAM,CAAC,6GAA6G,EAAEC,IAAAA,eAAS,EACnI,sDACA,CAAC;IAEP;IAEAJ,+BAA+B;AACjC;AAEO,SAASjD;IACd,IAAI,CAACkD,gCAAgC;QACnCzB,QAAG,CAAC0B,IAAI,CACNxB,gBAAK,CAACyB,MAAM,CAAC,6GAA6G,EAAEC,IAAAA,eAAS,EACnI,sDACA,CAAC;IAEP;IAEAH,iCAAiC;AACnC"}
1
+ {"version":3,"sources":["../../../../../src/start/server/metro/router.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport type { MiddlewareMatcher } from '@expo/server/build/types';\nimport chalk from 'chalk';\nimport { sync as globSync } from 'glob';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { Log } from '../../../log';\nimport { directoryExistsSync } from '../../../utils/dir';\nimport { toPosixPath } from '../../../utils/filePath';\nimport { learnMore } from '../../../utils/link';\n\nconst debug = require('debug')('expo:start:server:metro:router') as typeof console.log;\n\n/**\n * Get the relative path for requiring the `/app` folder relative to the `expo-router/entry` file.\n * This mechanism does require the server to restart after the `expo-router` package is installed.\n */\nexport function getAppRouterRelativeEntryPath(\n projectRoot: string,\n routerDirectory: string = getRouterDirectory(projectRoot)\n): string | undefined {\n // Auto pick App entry\n const routerEntry =\n resolveFrom.silent(projectRoot, 'expo-router/entry') ?? getFallbackEntryRoot(projectRoot);\n if (!routerEntry) {\n return undefined;\n }\n // It doesn't matter if the app folder exists.\n const appFolder = path.join(projectRoot, routerDirectory);\n const appRoot = path.relative(path.dirname(routerEntry), appFolder);\n debug('expo-router entry', routerEntry, appFolder, appRoot);\n return appRoot;\n}\n\n/** If the `expo-router` package is not installed, then use the `expo` package to determine where the node modules are relative to the project. */\nfunction getFallbackEntryRoot(projectRoot: string): string {\n const expoRoot = resolveFrom.silent(projectRoot, 'expo/package.json');\n if (expoRoot) {\n return path.join(path.dirname(path.dirname(expoRoot)), 'expo-router/entry');\n }\n return path.join(projectRoot, 'node_modules/expo-router/entry');\n}\n\nexport function getRouterDirectoryModuleIdWithManifest(\n projectRoot: string,\n exp: ExpoConfig\n): string {\n return toPosixPath(exp.extra?.router?.root ?? getRouterDirectory(projectRoot));\n}\n\nlet hasWarnedAboutSrcDir = false;\nconst logSrcDir = () => {\n if (hasWarnedAboutSrcDir) return;\n hasWarnedAboutSrcDir = true;\n Log.log(chalk.gray('Using src/app as the root directory for Expo Router.'));\n};\n\nexport function getRouterDirectory(projectRoot: string): string {\n // more specific directories first\n if (directoryExistsSync(path.join(projectRoot, 'src', 'app'))) {\n logSrcDir();\n return path.join('src', 'app');\n }\n\n debug('Using app as the root directory for Expo Router.');\n return 'app';\n}\n\nexport function isApiRouteConvention(name: string): boolean {\n return /\\+api\\.[tj]sx?$/.test(name);\n}\n\nexport function getApiRoutesForDirectory(cwd: string) {\n return globSync('**/*+api.@(ts|tsx|js|jsx)', {\n cwd,\n absolute: true,\n dot: true,\n });\n}\n\n/**\n * Gets the +middleware file for a given directory. In\n * @param cwd\n */\nexport function getMiddlewareForDirectory(cwd: string): string | null {\n const files = globSync('+middleware.@(ts|tsx|js|jsx)', {\n cwd,\n absolute: true,\n dot: true,\n });\n\n if (files.length === 0) return null;\n\n if (files.length > 1) {\n // In development, throw an error if there are multiple root-level middleware files\n if (process.env.NODE_ENV !== 'production') {\n const relativePaths = files.map((f) => './' + path.relative(cwd, f)).sort();\n throw new Error(\n `Only one middleware file is allowed. Keep one of the conflicting files: ${relativePaths.map((p) => `\"${p}\"`).join(' or ')}`\n );\n }\n }\n\n return files[0];\n}\n\n// Used to emulate a context module, but way faster. TODO: May need to adjust the extensions to stay in sync with Metro.\nexport function getRoutePaths(cwd: string) {\n return globSync('**/*.@(ts|tsx|js|jsx)', {\n cwd,\n dot: true,\n }).map((p) => './' + normalizePaths(p));\n}\n\nfunction normalizePaths(p: string) {\n return p.replace(/\\\\/g, '/');\n}\n\nlet hasWarnedAboutApiRouteOutput = false;\nlet hasWarnedAboutMiddlewareOutput = false;\n\nexport function hasWarnedAboutApiRoutes() {\n return hasWarnedAboutApiRouteOutput;\n}\n\nexport function hasWarnedAboutMiddleware() {\n return hasWarnedAboutMiddlewareOutput;\n}\n\nexport function warnInvalidWebOutput() {\n if (!hasWarnedAboutApiRouteOutput) {\n Log.warn(\n chalk.yellow`Using API routes requires the {bold web.output} to be set to {bold \"server\"} in the project {bold app.json}. ${learnMore(\n 'https://docs.expo.dev/router/reference/api-routes/'\n )}`\n );\n }\n\n hasWarnedAboutApiRouteOutput = true;\n}\n\nexport function warnInvalidMiddlewareOutput() {\n if (!hasWarnedAboutMiddlewareOutput) {\n Log.warn(\n chalk.yellow`Using middleware requires the {bold web.output} to be set to {bold \"server\"} in the project {bold app.json}. ${learnMore(\n 'https://docs.expo.dev/router/reference/api-routes/'\n )}`\n );\n }\n\n hasWarnedAboutMiddlewareOutput = true;\n}\n\nexport function warnInvalidMiddlewareMatcherSettings(matcher: MiddlewareMatcher) {\n const validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];\n\n // Ensure methods are valid HTTP methods\n if (matcher.methods) {\n if (!Array.isArray(matcher.methods)) {\n Log.error(\n chalk.red`Middleware matcher methods must be an array of valid HTTP methods. Supported methods are: ${validMethods.join(', ')}`\n );\n } else {\n for (const method of matcher.methods) {\n if (!validMethods.includes(method)) {\n Log.error(\n chalk.red`Invalid middleware HTTP method: ${method}. Supported methods are: ${validMethods.join(', ')}`\n );\n }\n }\n }\n }\n\n // Ensure patterns are either a string or RegExp\n if (matcher.patterns) {\n const patterns = Array.isArray(matcher.patterns) ? matcher.patterns : [matcher.patterns];\n for (const pattern of patterns) {\n if (typeof pattern !== 'string' && !(pattern instanceof RegExp)) {\n Log.error(\n chalk.red`Middleware matcher patterns must be strings or regular expressions. Received: ${String(\n pattern\n )}`\n );\n }\n\n if (typeof pattern === 'string' && !pattern.startsWith('/')) {\n Log.error(\n chalk.red`String patterns in middleware matcher must start with '/'. Received: ${pattern}`\n );\n }\n }\n }\n}\n"],"names":["getApiRoutesForDirectory","getAppRouterRelativeEntryPath","getMiddlewareForDirectory","getRoutePaths","getRouterDirectory","getRouterDirectoryModuleIdWithManifest","hasWarnedAboutApiRoutes","hasWarnedAboutMiddleware","isApiRouteConvention","warnInvalidMiddlewareMatcherSettings","warnInvalidMiddlewareOutput","warnInvalidWebOutput","debug","require","projectRoot","routerDirectory","routerEntry","resolveFrom","silent","getFallbackEntryRoot","undefined","appFolder","path","join","appRoot","relative","dirname","expoRoot","exp","toPosixPath","extra","router","root","hasWarnedAboutSrcDir","logSrcDir","Log","log","chalk","gray","directoryExistsSync","name","test","cwd","globSync","absolute","dot","files","length","process","env","NODE_ENV","relativePaths","map","f","sort","Error","p","normalizePaths","replace","hasWarnedAboutApiRouteOutput","hasWarnedAboutMiddlewareOutput","warn","yellow","learnMore","matcher","validMethods","methods","Array","isArray","error","red","method","includes","patterns","pattern","RegExp","String","startsWith"],"mappings":";;;;;;;;;;;IAyEgBA,wBAAwB;eAAxBA;;IAvDAC,6BAA6B;eAA7BA;;IAmEAC,yBAAyB;eAAzBA;;IAuBAC,aAAa;eAAbA;;IAlDAC,kBAAkB;eAAlBA;;IAdAC,sCAAsC;eAAtCA;;IA8EAC,uBAAuB;eAAvBA;;IAIAC,wBAAwB;eAAxBA;;IAzDAC,oBAAoB;eAApBA;;IAqFAC,oCAAoC;eAApCA;;IAZAC,2BAA2B;eAA3BA;;IAZAC,oBAAoB;eAApBA;;;;gEAhIE;;;;;;;yBACe;;;;;;;gEAChB;;;;;;;gEACO;;;;;;qBAEJ;qBACgB;0BACR;sBACF;;;;;;AAE1B,MAAMC,QAAQC,QAAQ,SAAS;AAMxB,SAASZ,8BACda,WAAmB,EACnBC,kBAA0BX,mBAAmBU,YAAY;IAEzD,sBAAsB;IACtB,MAAME,cACJC,sBAAW,CAACC,MAAM,CAACJ,aAAa,wBAAwBK,qBAAqBL;IAC/E,IAAI,CAACE,aAAa;QAChB,OAAOI;IACT;IACA,8CAA8C;IAC9C,MAAMC,YAAYC,eAAI,CAACC,IAAI,CAACT,aAAaC;IACzC,MAAMS,UAAUF,eAAI,CAACG,QAAQ,CAACH,eAAI,CAACI,OAAO,CAACV,cAAcK;IACzDT,MAAM,qBAAqBI,aAAaK,WAAWG;IACnD,OAAOA;AACT;AAEA,gJAAgJ,GAChJ,SAASL,qBAAqBL,WAAmB;IAC/C,MAAMa,WAAWV,sBAAW,CAACC,MAAM,CAACJ,aAAa;IACjD,IAAIa,UAAU;QACZ,OAAOL,eAAI,CAACC,IAAI,CAACD,eAAI,CAACI,OAAO,CAACJ,eAAI,CAACI,OAAO,CAACC,YAAY;IACzD;IACA,OAAOL,eAAI,CAACC,IAAI,CAACT,aAAa;AAChC;AAEO,SAAST,uCACdS,WAAmB,EACnBc,GAAe;QAEIA,mBAAAA;IAAnB,OAAOC,IAAAA,qBAAW,EAACD,EAAAA,aAAAA,IAAIE,KAAK,sBAATF,oBAAAA,WAAWG,MAAM,qBAAjBH,kBAAmBI,IAAI,KAAI5B,mBAAmBU;AACnE;AAEA,IAAImB,uBAAuB;AAC3B,MAAMC,YAAY;IAChB,IAAID,sBAAsB;IAC1BA,uBAAuB;IACvBE,QAAG,CAACC,GAAG,CAACC,gBAAK,CAACC,IAAI,CAAC;AACrB;AAEO,SAASlC,mBAAmBU,WAAmB;IACpD,kCAAkC;IAClC,IAAIyB,IAAAA,wBAAmB,EAACjB,eAAI,CAACC,IAAI,CAACT,aAAa,OAAO,SAAS;QAC7DoB;QACA,OAAOZ,eAAI,CAACC,IAAI,CAAC,OAAO;IAC1B;IAEAX,MAAM;IACN,OAAO;AACT;AAEO,SAASJ,qBAAqBgC,IAAY;IAC/C,OAAO,kBAAkBC,IAAI,CAACD;AAChC;AAEO,SAASxC,yBAAyB0C,GAAW;IAClD,OAAOC,IAAAA,YAAQ,EAAC,6BAA6B;QAC3CD;QACAE,UAAU;QACVC,KAAK;IACP;AACF;AAMO,SAAS3C,0BAA0BwC,GAAW;IACnD,MAAMI,QAAQH,IAAAA,YAAQ,EAAC,gCAAgC;QACrDD;QACAE,UAAU;QACVC,KAAK;IACP;IAEA,IAAIC,MAAMC,MAAM,KAAK,GAAG,OAAO;IAE/B,IAAID,MAAMC,MAAM,GAAG,GAAG;QACpB,mFAAmF;QACnF,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,MAAMC,gBAAgBL,MAAMM,GAAG,CAAC,CAACC,IAAM,OAAO/B,eAAI,CAACG,QAAQ,CAACiB,KAAKW,IAAIC,IAAI;YACzE,MAAM,IAAIC,MACR,CAAC,wEAAwE,EAAEJ,cAAcC,GAAG,CAAC,CAACI,IAAM,CAAC,CAAC,EAAEA,EAAE,CAAC,CAAC,EAAEjC,IAAI,CAAC,SAAS;QAEhI;IACF;IAEA,OAAOuB,KAAK,CAAC,EAAE;AACjB;AAGO,SAAS3C,cAAcuC,GAAW;IACvC,OAAOC,IAAAA,YAAQ,EAAC,yBAAyB;QACvCD;QACAG,KAAK;IACP,GAAGO,GAAG,CAAC,CAACI,IAAM,OAAOC,eAAeD;AACtC;AAEA,SAASC,eAAeD,CAAS;IAC/B,OAAOA,EAAEE,OAAO,CAAC,OAAO;AAC1B;AAEA,IAAIC,+BAA+B;AACnC,IAAIC,iCAAiC;AAE9B,SAAStD;IACd,OAAOqD;AACT;AAEO,SAASpD;IACd,OAAOqD;AACT;AAEO,SAASjD;IACd,IAAI,CAACgD,8BAA8B;QACjCxB,QAAG,CAAC0B,IAAI,CACNxB,gBAAK,CAACyB,MAAM,CAAC,6GAA6G,EAAEC,IAAAA,eAAS,EACnI,sDACA,CAAC;IAEP;IAEAJ,+BAA+B;AACjC;AAEO,SAASjD;IACd,IAAI,CAACkD,gCAAgC;QACnCzB,QAAG,CAAC0B,IAAI,CACNxB,gBAAK,CAACyB,MAAM,CAAC,6GAA6G,EAAEC,IAAAA,eAAS,EACnI,sDACA,CAAC;IAEP;IAEAH,iCAAiC;AACnC;AAEO,SAASnD,qCAAqCuD,OAA0B;IAC7E,MAAMC,eAAe;QAAC;QAAO;QAAQ;QAAO;QAAS;QAAU;QAAW;KAAO;IAEjF,wCAAwC;IACxC,IAAID,QAAQE,OAAO,EAAE;QACnB,IAAI,CAACC,MAAMC,OAAO,CAACJ,QAAQE,OAAO,GAAG;YACnC/B,QAAG,CAACkC,KAAK,CACPhC,gBAAK,CAACiC,GAAG,CAAC,0FAA0F,EAAEL,aAAa1C,IAAI,CAAC,MAAM,CAAC;QAEnI,OAAO;YACL,KAAK,MAAMgD,UAAUP,QAAQE,OAAO,CAAE;gBACpC,IAAI,CAACD,aAAaO,QAAQ,CAACD,SAAS;oBAClCpC,QAAG,CAACkC,KAAK,CACPhC,gBAAK,CAACiC,GAAG,CAAC,gCAAgC,EAAEC,OAAO,yBAAyB,EAAEN,aAAa1C,IAAI,CAAC,MAAM,CAAC;gBAE3G;YACF;QACF;IACF;IAEA,gDAAgD;IAChD,IAAIyC,QAAQS,QAAQ,EAAE;QACpB,MAAMA,WAAWN,MAAMC,OAAO,CAACJ,QAAQS,QAAQ,IAAIT,QAAQS,QAAQ,GAAG;YAACT,QAAQS,QAAQ;SAAC;QACxF,KAAK,MAAMC,WAAWD,SAAU;YAC9B,IAAI,OAAOC,YAAY,YAAY,CAAEA,CAAAA,mBAAmBC,MAAK,GAAI;gBAC/DxC,QAAG,CAACkC,KAAK,CACPhC,gBAAK,CAACiC,GAAG,CAAC,8EAA8E,EAAEM,OACxFF,SACA,CAAC;YAEP;YAEA,IAAI,OAAOA,YAAY,YAAY,CAACA,QAAQG,UAAU,CAAC,MAAM;gBAC3D1C,QAAG,CAACkC,KAAK,CACPhC,gBAAK,CAACiC,GAAG,CAAC,qEAAqE,EAAEI,QAAQ,CAAC;YAE9F;QACF;IACF;AACF"}
@@ -33,7 +33,7 @@ class FetchClient {
33
33
  this.headers = {
34
34
  accept: 'application/json',
35
35
  'content-type': 'application/json',
36
- 'user-agent': `expo-cli/${"0.26.7"}`,
36
+ 'user-agent': `expo-cli/${"0.26.9"}`,
37
37
  authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
38
38
  };
39
39
  }
@@ -83,7 +83,7 @@ function createContext() {
83
83
  cpu: summarizeCpuInfo(),
84
84
  app: {
85
85
  name: 'expo/cli',
86
- version: "0.26.7"
86
+ version: "0.26.9"
87
87
  },
88
88
  ci: _ciinfo().isCI ? {
89
89
  name: _ciinfo().name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/cli",
3
- "version": "0.26.7",
3
+ "version": "0.26.9",
4
4
  "description": "The Expo CLI",
5
5
  "main": "build/bin/cli",
6
6
  "bin": {
@@ -49,13 +49,13 @@
49
49
  "@expo/image-utils": "^0.8.6",
50
50
  "@expo/json-file": "^10.0.6",
51
51
  "@expo/metro": "~0.1.1",
52
- "@expo/metro-config": "~0.21.8",
52
+ "@expo/metro-config": "~0.21.11",
53
53
  "@expo/osascript": "^2.3.6",
54
54
  "@expo/package-manager": "^1.9.6",
55
55
  "@expo/plist": "^0.4.6",
56
56
  "@expo/prebuild-config": "^10.0.8",
57
57
  "@expo/schema-utils": "^0.1.6",
58
- "@expo/server": "^0.7.2",
58
+ "@expo/server": "^0.7.3",
59
59
  "@expo/spawn-async": "^1.7.2",
60
60
  "@expo/ws-tunnel": "^1.0.1",
61
61
  "@expo/xcpretty": "^4.3.0",
@@ -167,5 +167,5 @@
167
167
  "tree-kill": "^1.2.2",
168
168
  "tsd": "^0.28.1"
169
169
  },
170
- "gitHead": "d635404a12ea7996b987ce0fb7679a238ebcf31b"
170
+ "gitHead": "d087a2182086089f23bcee65e27434f21db50128"
171
171
  }