@expo/cli 0.21.0 → 0.21.2

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
@@ -121,7 +121,7 @@ const args = (0, _arg().default)({
121
121
  });
122
122
  if (args["--version"]) {
123
123
  // Version is added in the build script.
124
- console.log("0.21.0");
124
+ console.log("0.21.2");
125
125
  process.exit(0);
126
126
  }
127
127
  if (args["--non-interactive"]) {
@@ -11,8 +11,7 @@ function _export(target, all) {
11
11
  _export(exports, {
12
12
  validateDependenciesVersionsAsync: ()=>validateDependenciesVersionsAsync,
13
13
  logIncorrectDependencies: ()=>logIncorrectDependencies,
14
- getVersionedDependenciesAsync: ()=>getVersionedDependenciesAsync,
15
- isDependencyVersionIncorrect: ()=>isDependencyVersionIncorrect
14
+ getVersionedDependenciesAsync: ()=>getVersionedDependenciesAsync
16
15
  });
17
16
  function _assert() {
18
17
  const data = /*#__PURE__*/ _interopRequireDefault(require("assert"));
@@ -233,19 +232,8 @@ function isDependencyVersionIncorrect(packageName, actualVersion, expectedVersio
233
232
  if (packageName === "expo") {
234
233
  return _semver().default.ltr(actualVersion, expectedVersionOrRange);
235
234
  }
236
- const actualPrerelease = _semver().default.prerelease(actualVersion);
237
- const expectedPrerelease = _semver().default.prerelease(expectedVersionOrRange);
238
- // If both are prereleases or both are not prereleases, use satisfies
239
- if (actualPrerelease && expectedPrerelease || !actualPrerelease && !expectedPrerelease) {
240
- return !_semver().default.satisfies(actualVersion, expectedVersionOrRange);
241
- }
242
- // If actual is prerelease but expected is not
243
- if (actualPrerelease && !expectedPrerelease) {
244
- const cleanedActualVersion = `${_semver().default.major(actualVersion)}.${_semver().default.minor(actualVersion)}.${_semver().default.patch(actualVersion)}`;
245
- return !_semver().default.satisfies(cleanedActualVersion, expectedVersionOrRange);
246
- }
247
- // If expected is prerelease but actual is not, consider it incorrect
248
- return true;
235
+ // all other packages: version range is based on Expo SDK version, so we always want to match range
236
+ return !_semver().default.intersects(expectedVersionOrRange, actualVersion);
249
237
  }
250
238
  function findDependencyType(pkg, packageName) {
251
239
  if (pkg.devDependencies && packageName in pkg.devDependencies) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/doctor/dependencies/validateDependenciesVersions.ts"],"sourcesContent":["import { ExpoConfig, PackageJSONConfig } from '@expo/config';\nimport assert from 'assert';\nimport chalk from 'chalk';\nimport npmPackageArg from 'npm-package-arg';\nimport semver from 'semver';\nimport semverRangeSubset from 'semver/ranges/subset';\n\nimport { BundledNativeModules } from './bundledNativeModules';\nimport { getCombinedKnownVersionsAsync } from './getVersionedPackages';\nimport { resolveAllPackageVersionsAsync } from './resolvePackages';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\n\nconst debug = require('debug')('expo:doctor:dependencies:validate') as typeof console.log;\n\ntype IncorrectDependency = {\n packageName: string;\n packageType: 'dependencies' | 'devDependencies';\n expectedVersionOrRange: string;\n actualVersion: string;\n};\n\ntype DependenciesToCheck = { known: string[]; unknown: string[] };\n\n/**\n * Print a list of incorrect dependency versions.\n * This only checks dependencies when not running in offline mode.\n *\n * @param projectRoot Expo project root.\n * @param exp Expo project config.\n * @param pkg Project's `package.json`.\n * @param packagesToCheck A list of packages to check, if undefined or empty, all will be checked.\n * @returns `true` if there are no incorrect dependencies.\n */\nexport async function validateDependenciesVersionsAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'sdkVersion'>,\n pkg: PackageJSONConfig,\n packagesToCheck?: string[]\n): Promise<boolean | null> {\n if (env.EXPO_OFFLINE) {\n Log.warn('Skipping dependency validation in offline mode');\n return null;\n }\n\n const incorrectDeps = await getVersionedDependenciesAsync(projectRoot, exp, pkg, packagesToCheck);\n return logIncorrectDependencies(incorrectDeps);\n}\n\nfunction logInvalidDependency({\n packageName,\n expectedVersionOrRange,\n actualVersion,\n}: IncorrectDependency) {\n Log.warn(\n chalk` {bold ${packageName}}{cyan @}{red ${actualVersion}} - expected version: {green ${expectedVersionOrRange}}`\n );\n}\n\nexport function logIncorrectDependencies(incorrectDeps: IncorrectDependency[]) {\n if (!incorrectDeps.length) {\n return true;\n }\n\n Log.warn(\n chalk`The following packages should be updated for best compatibility with the installed {bold expo} version:`\n );\n incorrectDeps.forEach((dep) => logInvalidDependency(dep));\n\n Log.warn(\n 'Your project may not work correctly until you install the expected versions of the packages.'\n );\n\n return false;\n}\n\n/**\n * Return a list of versioned dependencies for the project SDK version.\n *\n * @param projectRoot Expo project root.\n * @param exp Expo project config.\n * @param pkg Project's `package.json`.\n * @param packagesToCheck A list of packages to check, if undefined or empty, all will be checked.\n * @returns A list of incorrect dependencies.\n */\nexport async function getVersionedDependenciesAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'sdkVersion'>,\n pkg: PackageJSONConfig,\n packagesToCheck?: string[]\n): Promise<IncorrectDependency[]> {\n // This should never happen under normal circumstances since\n // the CLI is versioned in the `expo` package.\n assert(exp.sdkVersion, 'SDK Version is missing');\n\n // Get from both endpoints and combine the known package versions.\n const combinedKnownPackages = await getCombinedKnownVersionsAsync({\n projectRoot,\n sdkVersion: exp.sdkVersion,\n });\n // debug(`Known dependencies: %O`, combinedKnownPackages);\n\n const resolvedDependencies = packagesToCheck?.length\n ? // Diff the provided packages to ensure we only check against installed packages.\n getFilteredObject(packagesToCheck, { ...pkg.dependencies, ...pkg.devDependencies })\n : // If no packages are provided, check against the `package.json` `dependencies` + `devDependencies` object.\n { ...pkg.dependencies, ...pkg.devDependencies };\n debug(`Checking dependencies for ${exp.sdkVersion}: %O`, resolvedDependencies);\n\n // intersection of packages from package.json and bundled native modules\n const { known: resolvedPackagesToCheck, unknown } = getPackagesToCheck(\n combinedKnownPackages,\n resolvedDependencies\n );\n debug(`Comparing known versions: %O`, resolvedPackagesToCheck);\n debug(`Skipping packages that cannot be versioned automatically: %O`, unknown);\n // read package versions from the file system (node_modules)\n const packageVersions = await resolveAllPackageVersionsAsync(\n projectRoot,\n resolvedPackagesToCheck\n );\n debug(`Package versions: %O`, packageVersions);\n // find incorrect dependencies by comparing the actual package versions with the bundled native module version ranges\n let incorrectDeps = findIncorrectDependencies(pkg, packageVersions, combinedKnownPackages);\n debug(`Incorrect dependencies: %O`, incorrectDeps);\n\n if (pkg?.expo?.install?.exclude) {\n const packagesToExclude = pkg.expo.install.exclude;\n\n // Parse the exclude list to ensure we can factor in any specified version ranges\n const parsedPackagesToExclude = packagesToExclude.reduce(\n (acc: Record<string, npmPackageArg.Result>, packageName: string) => {\n const npaResult = npmPackageArg(packageName);\n if (typeof npaResult.name === 'string') {\n acc[npaResult.name] = npaResult;\n } else {\n acc[packageName] = npaResult;\n }\n return acc;\n },\n {}\n );\n\n const incorrectAndExcludedDeps = incorrectDeps\n .filter((dep) => {\n if (parsedPackagesToExclude[dep.packageName]) {\n const { name, raw, rawSpec, type } = parsedPackagesToExclude[dep.packageName];\n const suggestedRange = combinedKnownPackages[name];\n\n // If only the package name itself is specified, then we keep it in the exclude list\n if (name === raw) {\n return true;\n } else if (type === 'version') {\n return suggestedRange === rawSpec;\n } else if (type === 'range') {\n // Fall through exclusions if the suggested range is invalid\n if (!semver.validRange(suggestedRange)) {\n debug(\n `Invalid semver range in combined known packages for package ${name} in expo.install.exclude: %O`,\n suggestedRange\n );\n return false;\n }\n\n return semverRangeSubset(suggestedRange, rawSpec);\n } else {\n debug(\n `Unsupported npm package argument type for package ${name} in expo.install.exclude: %O`,\n type\n );\n }\n }\n\n return false;\n })\n .map((dep) => dep.packageName);\n\n debug(\n `Incorrect dependency warnings filtered out by expo.install.exclude: %O`,\n incorrectAndExcludedDeps\n );\n incorrectDeps = incorrectDeps.filter(\n (dep) => !incorrectAndExcludedDeps.includes(dep.packageName)\n );\n }\n\n return incorrectDeps;\n}\n\nfunction getFilteredObject(keys: string[], object: Record<string, string>) {\n return keys.reduce<Record<string, string>>((acc, key) => {\n acc[key] = object[key];\n return acc;\n }, {});\n}\n\nfunction getPackagesToCheck(\n bundledNativeModules: BundledNativeModules,\n dependencies?: Record<string, string> | null\n): DependenciesToCheck {\n const dependencyNames = Object.keys(dependencies ?? {});\n const known: string[] = [];\n const unknown: string[] = [];\n for (const dependencyName of dependencyNames) {\n if (dependencyName in bundledNativeModules) {\n known.push(dependencyName);\n } else {\n unknown.push(dependencyName);\n }\n }\n return { known, unknown };\n}\n\nfunction findIncorrectDependencies(\n pkg: PackageJSONConfig,\n packageVersions: Record<string, string>,\n bundledNativeModules: BundledNativeModules\n): IncorrectDependency[] {\n const packages = Object.keys(packageVersions);\n const incorrectDeps: IncorrectDependency[] = [];\n\n for (const packageName of packages) {\n const expectedVersionOrRange = bundledNativeModules[packageName];\n const actualVersion = packageVersions[packageName];\n if (isDependencyVersionIncorrect(packageName, actualVersion, expectedVersionOrRange)) {\n incorrectDeps.push({\n packageName,\n packageType: findDependencyType(pkg, packageName),\n expectedVersionOrRange,\n actualVersion,\n });\n }\n }\n return incorrectDeps;\n}\n\nexport function isDependencyVersionIncorrect(\n packageName: string,\n actualVersion: string,\n expectedVersionOrRange?: string\n) {\n if (!expectedVersionOrRange) {\n return false;\n }\n\n // we never want to go backwards with the expo patch version\n if (packageName === 'expo') {\n return semver.ltr(actualVersion, expectedVersionOrRange);\n }\n\n const actualPrerelease = semver.prerelease(actualVersion);\n const expectedPrerelease = semver.prerelease(expectedVersionOrRange);\n\n // If both are prereleases or both are not prereleases, use satisfies\n if ((actualPrerelease && expectedPrerelease) || (!actualPrerelease && !expectedPrerelease)) {\n return !semver.satisfies(actualVersion, expectedVersionOrRange);\n }\n\n // If actual is prerelease but expected is not\n if (actualPrerelease && !expectedPrerelease) {\n const cleanedActualVersion = `${semver.major(actualVersion)}.${semver.minor(actualVersion)}.${semver.patch(actualVersion)}`;\n return !semver.satisfies(cleanedActualVersion, expectedVersionOrRange);\n }\n\n // If expected is prerelease but actual is not, consider it incorrect\n return true;\n}\n\nfunction findDependencyType(\n pkg: PackageJSONConfig,\n packageName: string\n): IncorrectDependency['packageType'] {\n if (pkg.devDependencies && packageName in pkg.devDependencies) {\n return 'devDependencies';\n }\n\n return 'dependencies';\n}\n"],"names":["validateDependenciesVersionsAsync","logIncorrectDependencies","getVersionedDependenciesAsync","isDependencyVersionIncorrect","debug","require","projectRoot","exp","pkg","packagesToCheck","env","EXPO_OFFLINE","Log","warn","incorrectDeps","logInvalidDependency","packageName","expectedVersionOrRange","actualVersion","chalk","length","forEach","dep","assert","sdkVersion","combinedKnownPackages","getCombinedKnownVersionsAsync","resolvedDependencies","getFilteredObject","dependencies","devDependencies","known","resolvedPackagesToCheck","unknown","getPackagesToCheck","packageVersions","resolveAllPackageVersionsAsync","findIncorrectDependencies","expo","install","exclude","packagesToExclude","parsedPackagesToExclude","reduce","acc","npaResult","npmPackageArg","name","incorrectAndExcludedDeps","filter","raw","rawSpec","type","suggestedRange","semver","validRange","semverRangeSubset","map","includes","keys","object","key","bundledNativeModules","dependencyNames","Object","dependencyName","push","packages","packageType","findDependencyType","ltr","actualPrerelease","prerelease","expectedPrerelease","satisfies","cleanedActualVersion","major","minor","patch"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/doctor/dependencies/validateDependenciesVersions.ts"],"sourcesContent":["import { ExpoConfig, PackageJSONConfig } from '@expo/config';\nimport assert from 'assert';\nimport chalk from 'chalk';\nimport npmPackageArg from 'npm-package-arg';\nimport semver from 'semver';\nimport semverRangeSubset from 'semver/ranges/subset';\n\nimport { BundledNativeModules } from './bundledNativeModules';\nimport { getCombinedKnownVersionsAsync } from './getVersionedPackages';\nimport { resolveAllPackageVersionsAsync } from './resolvePackages';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\n\nconst debug = require('debug')('expo:doctor:dependencies:validate') as typeof console.log;\n\ntype IncorrectDependency = {\n packageName: string;\n packageType: 'dependencies' | 'devDependencies';\n expectedVersionOrRange: string;\n actualVersion: string;\n};\n\ntype DependenciesToCheck = { known: string[]; unknown: string[] };\n\n/**\n * Print a list of incorrect dependency versions.\n * This only checks dependencies when not running in offline mode.\n *\n * @param projectRoot Expo project root.\n * @param exp Expo project config.\n * @param pkg Project's `package.json`.\n * @param packagesToCheck A list of packages to check, if undefined or empty, all will be checked.\n * @returns `true` if there are no incorrect dependencies.\n */\nexport async function validateDependenciesVersionsAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'sdkVersion'>,\n pkg: PackageJSONConfig,\n packagesToCheck?: string[]\n): Promise<boolean | null> {\n if (env.EXPO_OFFLINE) {\n Log.warn('Skipping dependency validation in offline mode');\n return null;\n }\n\n const incorrectDeps = await getVersionedDependenciesAsync(projectRoot, exp, pkg, packagesToCheck);\n return logIncorrectDependencies(incorrectDeps);\n}\n\nfunction logInvalidDependency({\n packageName,\n expectedVersionOrRange,\n actualVersion,\n}: IncorrectDependency) {\n Log.warn(\n chalk` {bold ${packageName}}{cyan @}{red ${actualVersion}} - expected version: {green ${expectedVersionOrRange}}`\n );\n}\n\nexport function logIncorrectDependencies(incorrectDeps: IncorrectDependency[]) {\n if (!incorrectDeps.length) {\n return true;\n }\n\n Log.warn(\n chalk`The following packages should be updated for best compatibility with the installed {bold expo} version:`\n );\n incorrectDeps.forEach((dep) => logInvalidDependency(dep));\n\n Log.warn(\n 'Your project may not work correctly until you install the expected versions of the packages.'\n );\n\n return false;\n}\n\n/**\n * Return a list of versioned dependencies for the project SDK version.\n *\n * @param projectRoot Expo project root.\n * @param exp Expo project config.\n * @param pkg Project's `package.json`.\n * @param packagesToCheck A list of packages to check, if undefined or empty, all will be checked.\n * @returns A list of incorrect dependencies.\n */\nexport async function getVersionedDependenciesAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'sdkVersion'>,\n pkg: PackageJSONConfig,\n packagesToCheck?: string[]\n): Promise<IncorrectDependency[]> {\n // This should never happen under normal circumstances since\n // the CLI is versioned in the `expo` package.\n assert(exp.sdkVersion, 'SDK Version is missing');\n\n // Get from both endpoints and combine the known package versions.\n const combinedKnownPackages = await getCombinedKnownVersionsAsync({\n projectRoot,\n sdkVersion: exp.sdkVersion,\n });\n // debug(`Known dependencies: %O`, combinedKnownPackages);\n\n const resolvedDependencies = packagesToCheck?.length\n ? // Diff the provided packages to ensure we only check against installed packages.\n getFilteredObject(packagesToCheck, { ...pkg.dependencies, ...pkg.devDependencies })\n : // If no packages are provided, check against the `package.json` `dependencies` + `devDependencies` object.\n { ...pkg.dependencies, ...pkg.devDependencies };\n debug(`Checking dependencies for ${exp.sdkVersion}: %O`, resolvedDependencies);\n\n // intersection of packages from package.json and bundled native modules\n const { known: resolvedPackagesToCheck, unknown } = getPackagesToCheck(\n combinedKnownPackages,\n resolvedDependencies\n );\n debug(`Comparing known versions: %O`, resolvedPackagesToCheck);\n debug(`Skipping packages that cannot be versioned automatically: %O`, unknown);\n // read package versions from the file system (node_modules)\n const packageVersions = await resolveAllPackageVersionsAsync(\n projectRoot,\n resolvedPackagesToCheck\n );\n debug(`Package versions: %O`, packageVersions);\n // find incorrect dependencies by comparing the actual package versions with the bundled native module version ranges\n let incorrectDeps = findIncorrectDependencies(pkg, packageVersions, combinedKnownPackages);\n debug(`Incorrect dependencies: %O`, incorrectDeps);\n\n if (pkg?.expo?.install?.exclude) {\n const packagesToExclude = pkg.expo.install.exclude;\n\n // Parse the exclude list to ensure we can factor in any specified version ranges\n const parsedPackagesToExclude = packagesToExclude.reduce(\n (acc: Record<string, npmPackageArg.Result>, packageName: string) => {\n const npaResult = npmPackageArg(packageName);\n if (typeof npaResult.name === 'string') {\n acc[npaResult.name] = npaResult;\n } else {\n acc[packageName] = npaResult;\n }\n return acc;\n },\n {}\n );\n\n const incorrectAndExcludedDeps = incorrectDeps\n .filter((dep) => {\n if (parsedPackagesToExclude[dep.packageName]) {\n const { name, raw, rawSpec, type } = parsedPackagesToExclude[dep.packageName];\n const suggestedRange = combinedKnownPackages[name];\n\n // If only the package name itself is specified, then we keep it in the exclude list\n if (name === raw) {\n return true;\n } else if (type === 'version') {\n return suggestedRange === rawSpec;\n } else if (type === 'range') {\n // Fall through exclusions if the suggested range is invalid\n if (!semver.validRange(suggestedRange)) {\n debug(\n `Invalid semver range in combined known packages for package ${name} in expo.install.exclude: %O`,\n suggestedRange\n );\n return false;\n }\n\n return semverRangeSubset(suggestedRange, rawSpec);\n } else {\n debug(\n `Unsupported npm package argument type for package ${name} in expo.install.exclude: %O`,\n type\n );\n }\n }\n\n return false;\n })\n .map((dep) => dep.packageName);\n\n debug(\n `Incorrect dependency warnings filtered out by expo.install.exclude: %O`,\n incorrectAndExcludedDeps\n );\n incorrectDeps = incorrectDeps.filter(\n (dep) => !incorrectAndExcludedDeps.includes(dep.packageName)\n );\n }\n\n return incorrectDeps;\n}\n\nfunction getFilteredObject(keys: string[], object: Record<string, string>) {\n return keys.reduce<Record<string, string>>((acc, key) => {\n acc[key] = object[key];\n return acc;\n }, {});\n}\n\nfunction getPackagesToCheck(\n bundledNativeModules: BundledNativeModules,\n dependencies?: Record<string, string> | null\n): DependenciesToCheck {\n const dependencyNames = Object.keys(dependencies ?? {});\n const known: string[] = [];\n const unknown: string[] = [];\n for (const dependencyName of dependencyNames) {\n if (dependencyName in bundledNativeModules) {\n known.push(dependencyName);\n } else {\n unknown.push(dependencyName);\n }\n }\n return { known, unknown };\n}\n\nfunction findIncorrectDependencies(\n pkg: PackageJSONConfig,\n packageVersions: Record<string, string>,\n bundledNativeModules: BundledNativeModules\n): IncorrectDependency[] {\n const packages = Object.keys(packageVersions);\n const incorrectDeps: IncorrectDependency[] = [];\n for (const packageName of packages) {\n const expectedVersionOrRange = bundledNativeModules[packageName];\n const actualVersion = packageVersions[packageName];\n if (isDependencyVersionIncorrect(packageName, actualVersion, expectedVersionOrRange)) {\n incorrectDeps.push({\n packageName,\n packageType: findDependencyType(pkg, packageName),\n expectedVersionOrRange,\n actualVersion,\n });\n }\n }\n return incorrectDeps;\n}\n\nfunction isDependencyVersionIncorrect(\n packageName: string,\n actualVersion: string,\n expectedVersionOrRange?: string\n) {\n if (!expectedVersionOrRange) {\n return false;\n }\n\n // we never want to go backwards with the expo patch version\n if (packageName === 'expo') {\n return semver.ltr(actualVersion, expectedVersionOrRange);\n }\n\n // all other packages: version range is based on Expo SDK version, so we always want to match range\n return !semver.intersects(expectedVersionOrRange, actualVersion);\n}\n\nfunction findDependencyType(\n pkg: PackageJSONConfig,\n packageName: string\n): IncorrectDependency['packageType'] {\n if (pkg.devDependencies && packageName in pkg.devDependencies) {\n return 'devDependencies';\n }\n\n return 'dependencies';\n}\n"],"names":["validateDependenciesVersionsAsync","logIncorrectDependencies","getVersionedDependenciesAsync","debug","require","projectRoot","exp","pkg","packagesToCheck","env","EXPO_OFFLINE","Log","warn","incorrectDeps","logInvalidDependency","packageName","expectedVersionOrRange","actualVersion","chalk","length","forEach","dep","assert","sdkVersion","combinedKnownPackages","getCombinedKnownVersionsAsync","resolvedDependencies","getFilteredObject","dependencies","devDependencies","known","resolvedPackagesToCheck","unknown","getPackagesToCheck","packageVersions","resolveAllPackageVersionsAsync","findIncorrectDependencies","expo","install","exclude","packagesToExclude","parsedPackagesToExclude","reduce","acc","npaResult","npmPackageArg","name","incorrectAndExcludedDeps","filter","raw","rawSpec","type","suggestedRange","semver","validRange","semverRangeSubset","map","includes","keys","object","key","bundledNativeModules","dependencyNames","Object","dependencyName","push","packages","isDependencyVersionIncorrect","packageType","findDependencyType","ltr","intersects"],"mappings":"AAAA;;;;;;;;;;;IAkCsBA,iCAAiC,MAAjCA,iCAAiC;IAyBvCC,wBAAwB,MAAxBA,wBAAwB;IA0BlBC,6BAA6B,MAA7BA,6BAA6B;;;8DApFhC,QAAQ;;;;;;;8DACT,OAAO;;;;;;;8DACC,iBAAiB;;;;;;;8DACxB,QAAQ;;;;;;;8DACG,sBAAsB;;;;;;sCAGN,wBAAwB;iCACvB,mBAAmB;2DAC7C,cAAc;qBACf,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAExC,MAAMC,KAAK,GAAGC,OAAO,CAAC,OAAO,CAAC,CAAC,mCAAmC,CAAC,AAAsB,AAAC;AAqBnF,eAAeJ,iCAAiC,CACrDK,WAAmB,EACnBC,GAAmC,EACnCC,GAAsB,EACtBC,eAA0B,EACD;IACzB,IAAIC,IAAG,IAAA,CAACC,YAAY,EAAE;QACpBC,IAAG,CAACC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAMC,aAAa,GAAG,MAAMX,6BAA6B,CAACG,WAAW,EAAEC,GAAG,EAAEC,GAAG,EAAEC,eAAe,CAAC,AAAC;IAClG,OAAOP,wBAAwB,CAACY,aAAa,CAAC,CAAC;AACjD,CAAC;AAED,SAASC,oBAAoB,CAAC,EAC5BC,WAAW,CAAA,EACXC,sBAAsB,CAAA,EACtBC,aAAa,CAAA,EACO,EAAE;IACtBN,IAAG,CAACC,IAAI,CACNM,IAAAA,MAAK,EAAA,QAAA,CAAA,CAAC,QAAQ,EAAEH,WAAW,CAAC,cAAc,EAAEE,aAAa,CAAC,6BAA6B,EAAED,sBAAsB,CAAC,CAAC,CAAC,CACnH,CAAC;AACJ,CAAC;AAEM,SAASf,wBAAwB,CAACY,aAAoC,EAAE;IAC7E,IAAI,CAACA,aAAa,CAACM,MAAM,EAAE;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAEDR,IAAG,CAACC,IAAI,CACNM,IAAAA,MAAK,EAAA,QAAA,CAAA,CAAC,uGAAuG,CAAC,CAC/G,CAAC;IACFL,aAAa,CAACO,OAAO,CAAC,CAACC,GAAG,GAAKP,oBAAoB,CAACO,GAAG,CAAC,CAAC,CAAC;IAE1DV,IAAG,CAACC,IAAI,CACN,8FAA8F,CAC/F,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC;AAWM,eAAeV,6BAA6B,CACjDG,WAAmB,EACnBC,GAAmC,EACnCC,GAAsB,EACtBC,eAA0B,EACM;QAoC5BD,GAAS;IAnCb,4DAA4D;IAC5D,8CAA8C;IAC9Ce,IAAAA,OAAM,EAAA,QAAA,EAAChB,GAAG,CAACiB,UAAU,EAAE,wBAAwB,CAAC,CAAC;IAEjD,kEAAkE;IAClE,MAAMC,qBAAqB,GAAG,MAAMC,IAAAA,qBAA6B,8BAAA,EAAC;QAChEpB,WAAW;QACXkB,UAAU,EAAEjB,GAAG,CAACiB,UAAU;KAC3B,CAAC,AAAC;IACH,0DAA0D;IAE1D,MAAMG,oBAAoB,GAAGlB,CAAAA,eAAe,QAAQ,GAAvBA,KAAAA,CAAuB,GAAvBA,eAAe,CAAEW,MAAM,CAAA,GAEhDQ,iBAAiB,CAACnB,eAAe,EAAE;QAAE,GAAGD,GAAG,CAACqB,YAAY;QAAE,GAAGrB,GAAG,CAACsB,eAAe;KAAE,CAAC,GAEnF;QAAE,GAAGtB,GAAG,CAACqB,YAAY;QAAE,GAAGrB,GAAG,CAACsB,eAAe;KAAE,AAAC;IACpD1B,KAAK,CAAC,CAAC,0BAA0B,EAAEG,GAAG,CAACiB,UAAU,CAAC,IAAI,CAAC,EAAEG,oBAAoB,CAAC,CAAC;IAE/E,wEAAwE;IACxE,MAAM,EAAEI,KAAK,EAAEC,uBAAuB,CAAA,EAAEC,OAAO,CAAA,EAAE,GAAGC,kBAAkB,CACpET,qBAAqB,EACrBE,oBAAoB,CACrB,AAAC;IACFvB,KAAK,CAAC,CAAC,4BAA4B,CAAC,EAAE4B,uBAAuB,CAAC,CAAC;IAC/D5B,KAAK,CAAC,CAAC,4DAA4D,CAAC,EAAE6B,OAAO,CAAC,CAAC;IAC/E,4DAA4D;IAC5D,MAAME,eAAe,GAAG,MAAMC,IAAAA,gBAA8B,+BAAA,EAC1D9B,WAAW,EACX0B,uBAAuB,CACxB,AAAC;IACF5B,KAAK,CAAC,CAAC,oBAAoB,CAAC,EAAE+B,eAAe,CAAC,CAAC;IAC/C,qHAAqH;IACrH,IAAIrB,aAAa,GAAGuB,yBAAyB,CAAC7B,GAAG,EAAE2B,eAAe,EAAEV,qBAAqB,CAAC,AAAC;IAC3FrB,KAAK,CAAC,CAAC,0BAA0B,CAAC,EAAEU,aAAa,CAAC,CAAC;IAEnD,IAAIN,GAAG,QAAM,GAATA,KAAAA,CAAS,GAATA,CAAAA,GAAS,GAATA,GAAG,CAAE8B,IAAI,SAAA,GAAT9B,KAAAA,CAAS,GAATA,QAAAA,GAAS,CAAE+B,OAAO,SAAT,GAAT/B,KAAAA,CAAS,QAAWgC,OAAO,AAAlB,EAAoB;QAC/B,MAAMC,iBAAiB,GAAGjC,GAAG,CAAC8B,IAAI,CAACC,OAAO,CAACC,OAAO,AAAC;QAEnD,iFAAiF;QACjF,MAAME,uBAAuB,GAAGD,iBAAiB,CAACE,MAAM,CACtD,CAACC,GAAyC,EAAE5B,WAAmB,GAAK;YAClE,MAAM6B,SAAS,GAAGC,IAAAA,cAAa,EAAA,QAAA,EAAC9B,WAAW,CAAC,AAAC;YAC7C,IAAI,OAAO6B,SAAS,CAACE,IAAI,KAAK,QAAQ,EAAE;gBACtCH,GAAG,CAACC,SAAS,CAACE,IAAI,CAAC,GAAGF,SAAS,CAAC;YAClC,OAAO;gBACLD,GAAG,CAAC5B,WAAW,CAAC,GAAG6B,SAAS,CAAC;YAC/B,CAAC;YACD,OAAOD,GAAG,CAAC;QACb,CAAC,EACD,EAAE,CACH,AAAC;QAEF,MAAMI,wBAAwB,GAAGlC,aAAa,CAC3CmC,MAAM,CAAC,CAAC3B,GAAG,GAAK;YACf,IAAIoB,uBAAuB,CAACpB,GAAG,CAACN,WAAW,CAAC,EAAE;gBAC5C,MAAM,EAAE+B,IAAI,CAAA,EAAEG,GAAG,CAAA,EAAEC,OAAO,CAAA,EAAEC,IAAI,CAAA,EAAE,GAAGV,uBAAuB,CAACpB,GAAG,CAACN,WAAW,CAAC,AAAC;gBAC9E,MAAMqC,cAAc,GAAG5B,qBAAqB,CAACsB,IAAI,CAAC,AAAC;gBAEnD,oFAAoF;gBACpF,IAAIA,IAAI,KAAKG,GAAG,EAAE;oBAChB,OAAO,IAAI,CAAC;gBACd,OAAO,IAAIE,IAAI,KAAK,SAAS,EAAE;oBAC7B,OAAOC,cAAc,KAAKF,OAAO,CAAC;gBACpC,OAAO,IAAIC,IAAI,KAAK,OAAO,EAAE;oBAC3B,4DAA4D;oBAC5D,IAAI,CAACE,OAAM,EAAA,QAAA,CAACC,UAAU,CAACF,cAAc,CAAC,EAAE;wBACtCjD,KAAK,CACH,CAAC,4DAA4D,EAAE2C,IAAI,CAAC,4BAA4B,CAAC,EACjGM,cAAc,CACf,CAAC;wBACF,OAAO,KAAK,CAAC;oBACf,CAAC;oBAED,OAAOG,IAAAA,OAAiB,EAAA,QAAA,EAACH,cAAc,EAAEF,OAAO,CAAC,CAAC;gBACpD,OAAO;oBACL/C,KAAK,CACH,CAAC,kDAAkD,EAAE2C,IAAI,CAAC,4BAA4B,CAAC,EACvFK,IAAI,CACL,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CACDK,GAAG,CAAC,CAACnC,GAAG,GAAKA,GAAG,CAACN,WAAW,CAAC,AAAC;QAEjCZ,KAAK,CACH,CAAC,sEAAsE,CAAC,EACxE4C,wBAAwB,CACzB,CAAC;QACFlC,aAAa,GAAGA,aAAa,CAACmC,MAAM,CAClC,CAAC3B,GAAG,GAAK,CAAC0B,wBAAwB,CAACU,QAAQ,CAACpC,GAAG,CAACN,WAAW,CAAC,CAC7D,CAAC;IACJ,CAAC;IAED,OAAOF,aAAa,CAAC;AACvB,CAAC;AAED,SAASc,iBAAiB,CAAC+B,IAAc,EAAEC,MAA8B,EAAE;IACzE,OAAOD,IAAI,CAAChB,MAAM,CAAyB,CAACC,GAAG,EAAEiB,GAAG,GAAK;QACvDjB,GAAG,CAACiB,GAAG,CAAC,GAAGD,MAAM,CAACC,GAAG,CAAC,CAAC;QACvB,OAAOjB,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED,SAASV,kBAAkB,CACzB4B,oBAA0C,EAC1CjC,YAA4C,EACvB;IACrB,MAAMkC,eAAe,GAAGC,MAAM,CAACL,IAAI,CAAC9B,YAAY,IAAI,EAAE,CAAC,AAAC;IACxD,MAAME,KAAK,GAAa,EAAE,AAAC;IAC3B,MAAME,OAAO,GAAa,EAAE,AAAC;IAC7B,KAAK,MAAMgC,cAAc,IAAIF,eAAe,CAAE;QAC5C,IAAIE,cAAc,IAAIH,oBAAoB,EAAE;YAC1C/B,KAAK,CAACmC,IAAI,CAACD,cAAc,CAAC,CAAC;QAC7B,OAAO;YACLhC,OAAO,CAACiC,IAAI,CAACD,cAAc,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,OAAO;QAAElC,KAAK;QAAEE,OAAO;KAAE,CAAC;AAC5B,CAAC;AAED,SAASI,yBAAyB,CAChC7B,GAAsB,EACtB2B,eAAuC,EACvC2B,oBAA0C,EACnB;IACvB,MAAMK,QAAQ,GAAGH,MAAM,CAACL,IAAI,CAACxB,eAAe,CAAC,AAAC;IAC9C,MAAMrB,aAAa,GAA0B,EAAE,AAAC;IAChD,KAAK,MAAME,WAAW,IAAImD,QAAQ,CAAE;QAClC,MAAMlD,sBAAsB,GAAG6C,oBAAoB,CAAC9C,WAAW,CAAC,AAAC;QACjE,MAAME,aAAa,GAAGiB,eAAe,CAACnB,WAAW,CAAC,AAAC;QACnD,IAAIoD,4BAA4B,CAACpD,WAAW,EAAEE,aAAa,EAAED,sBAAsB,CAAC,EAAE;YACpFH,aAAa,CAACoD,IAAI,CAAC;gBACjBlD,WAAW;gBACXqD,WAAW,EAAEC,kBAAkB,CAAC9D,GAAG,EAAEQ,WAAW,CAAC;gBACjDC,sBAAsB;gBACtBC,aAAa;aACd,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAOJ,aAAa,CAAC;AACvB,CAAC;AAED,SAASsD,4BAA4B,CACnCpD,WAAmB,EACnBE,aAAqB,EACrBD,sBAA+B,EAC/B;IACA,IAAI,CAACA,sBAAsB,EAAE;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4DAA4D;IAC5D,IAAID,WAAW,KAAK,MAAM,EAAE;QAC1B,OAAOsC,OAAM,EAAA,QAAA,CAACiB,GAAG,CAACrD,aAAa,EAAED,sBAAsB,CAAC,CAAC;IAC3D,CAAC;IAED,mGAAmG;IACnG,OAAO,CAACqC,OAAM,EAAA,QAAA,CAACkB,UAAU,CAACvD,sBAAsB,EAAEC,aAAa,CAAC,CAAC;AACnE,CAAC;AAED,SAASoD,kBAAkB,CACzB9D,GAAsB,EACtBQ,WAAmB,EACiB;IACpC,IAAIR,GAAG,CAACsB,eAAe,IAAId,WAAW,IAAIR,GAAG,CAACsB,eAAe,EAAE;QAC7D,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -262,10 +262,11 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
262
262
  }
263
263
  return manifest;
264
264
  }
265
- async getServerManifestAsync({ environment } = {}) {
265
+ async getServerManifestAsync() {
266
266
  // NOTE: This could probably be folded back into `renderStaticContent` when expo-asset and font support RSC.
267
267
  const { getBuildTimeServerManifestAsync } = await this.ssrLoadModule("expo-router/build/static/getServerManifest.js", {
268
- environment: environment ?? (this.isReactServerComponentsEnabled ? "react-server" : "node")
268
+ // Only use react-server environment when the routes are using react-server rendering by default.
269
+ environment: this.isReactServerRoutesEnabled ? "react-server" : "node"
269
270
  });
270
271
  return {
271
272
  serverManifest: await getBuildTimeServerManifestAsync()
@@ -548,11 +549,13 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
548
549
  // When we export the server actions that were imported from the client, we may need to re-bundle the client with the new client boundaries.
549
550
  const { clientBoundaries: nestedClientBoundaries } = await this.rscRenderer.exportServerActionsAsync({
550
551
  platform: options.platform,
552
+ domRoot: options.domRoot,
551
553
  entryPoints: [
552
554
  ...serverActionReferencesInServer,
553
555
  ...reactServerReferences
554
556
  ]
555
557
  }, files);
558
+ // TODO: Check against all modules in the initial client bundles.
556
559
  const hasUniqueClientBoundaries = nestedClientBoundaries.some((boundary)=>!clientBoundaries.includes(boundary));
557
560
  if (hasUniqueClientBoundaries) {
558
561
  debug("Re-bundling client with nested client boundaries:", nestedClientBoundaries);
@@ -563,10 +566,7 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
563
566
  // Run metro bundler and create the JS bundles/source maps.
564
567
  bundle = await this.legacySinglePageExportBundleAsync({
565
568
  ...options,
566
- clientBoundaries: [
567
- ...clientBoundaries,
568
- ...nestedClientBoundaries
569
- ]
569
+ clientBoundaries
570
570
  }, extraOptions);
571
571
  }
572
572
  // Inject the global CSS that was imported during the server render.
@@ -586,7 +586,6 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
586
586
  if (Object.keys(moduleIdToSplitBundle).length) {
587
587
  clientBoundariesAsOpaqueIds.forEach((boundary)=>{
588
588
  if (boundary in moduleIdToSplitBundle) {
589
- // Account for nullish values (bundle is in main chunk).
590
589
  ssrManifest.set(boundary, moduleIdToSplitBundle[boundary]);
591
590
  } else {
592
591
  throw new Error(`Could not find boundary "${boundary}" in the SSR manifest. Available: ${Object.keys(moduleIdToSplitBundle).join(", ")}`);
@@ -669,7 +668,7 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
669
668
  }
670
669
  rscRenderer = null;
671
670
  async startImplementationAsync(options) {
672
- var ref, ref1, ref2, ref3, ref4, ref5, ref6;
671
+ var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7;
673
672
  options.port = await this.resolvePortAsync(options);
674
673
  this.urlCreator = this.getUrlCreator(options);
675
674
  const config = (0, _config().getConfig)(this.projectRoot, {
@@ -677,18 +676,19 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
677
676
  });
678
677
  const { exp } = config;
679
678
  // NOTE: This will change in the future when it's less experimental, we enable React 19, and turn on more RSC flags by default.
680
- const isReactServerComponentsEnabled = !!((ref = exp.experiments) == null ? void 0 : ref.reactServerComponents) || !!((ref1 = exp.experiments) == null ? void 0 : ref1.reactServerActions);
681
- const isReactServerActionsOnlyEnabled = !((ref2 = exp.experiments) == null ? void 0 : ref2.reactServerComponents) && !!((ref3 = exp.experiments) == null ? void 0 : ref3.reactServerActions);
679
+ const isReactServerComponentsEnabled = !!((ref = exp.experiments) == null ? void 0 : ref.reactServerComponentRoutes) || !!((ref1 = exp.experiments) == null ? void 0 : ref1.reactServerFunctions);
680
+ const isReactServerActionsOnlyEnabled = !((ref2 = exp.experiments) == null ? void 0 : ref2.reactServerComponentRoutes) && !!((ref3 = exp.experiments) == null ? void 0 : ref3.reactServerFunctions);
682
681
  this.isReactServerComponentsEnabled = isReactServerComponentsEnabled;
682
+ this.isReactServerRoutesEnabled = !!((ref4 = exp.experiments) == null ? void 0 : ref4.reactServerComponentRoutes);
683
683
  const useServerRendering = [
684
684
  "static",
685
685
  "server"
686
- ].includes(((ref4 = exp.web) == null ? void 0 : ref4.output) ?? "");
687
- const hasApiRoutes = isReactServerComponentsEnabled || ((ref5 = exp.web) == null ? void 0 : ref5.output) === "server";
686
+ ].includes(((ref5 = exp.web) == null ? void 0 : ref5.output) ?? "");
687
+ const hasApiRoutes = isReactServerComponentsEnabled || ((ref6 = exp.web) == null ? void 0 : ref6.output) === "server";
688
688
  const baseUrl = (0, _metroOptions.getBaseUrlFromExpoConfig)(exp);
689
689
  const asyncRoutes = (0, _metroOptions.getAsyncRoutesFromExpoConfig)(exp, options.mode ?? "development", "web");
690
690
  const routerRoot = (0, _router.getRouterDirectoryModuleIdWithManifest)(this.projectRoot, exp);
691
- const reactCompiler = !!((ref6 = exp.experiments) == null ? void 0 : ref6.reactCompiler);
691
+ const reactCompiler = !!((ref7 = exp.experiments) == null ? void 0 : ref7.reactCompiler);
692
692
  const appDir = _path().default.join(this.projectRoot, routerRoot);
693
693
  const mode = options.mode ?? "development";
694
694
  if (isReactServerComponentsEnabled && useServerRendering) {
@@ -795,7 +795,8 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
795
795
  rscPath: "/_flight",
796
796
  ssrLoadModule: this.ssrLoadModule.bind(this),
797
797
  ssrLoadModuleArtifacts: this.metroImportAsArtifactsAsync.bind(this),
798
- useClientRouter: isReactServerActionsOnlyEnabled
798
+ useClientRouter: isReactServerActionsOnlyEnabled,
799
+ createModuleId: metro._createModuleId.bind(metro)
799
800
  });
800
801
  this.rscRenderer = rscMiddleware;
801
802
  middleware.use(rscMiddleware.middleware);
@@ -807,12 +808,12 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
807
808
  // This MUST run last since it's the fallback.
808
809
  middleware.use(new _historyFallbackMiddleware.HistoryFallbackMiddleware(manifestMiddleware.getHandler().internal).getHandler());
809
810
  } else {
810
- var ref7;
811
+ var ref8;
811
812
  middleware.use((0, _createServerRouteMiddleware.createRouteHandlerMiddleware)(this.projectRoot, {
812
813
  appDir,
813
814
  routerRoot,
814
815
  config,
815
- ...(ref7 = config.exp.extra) == null ? void 0 : ref7.router,
816
+ ...(ref8 = config.exp.extra) == null ? void 0 : ref8.router,
816
817
  bundleApiRoute: (functionFilePath)=>this.ssrImportApiRoute(functionFilePath, {
817
818
  platform: "web"
818
819
  }),
@@ -831,7 +832,8 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
831
832
  rscPath: "/_flight",
832
833
  ssrLoadModule: this.ssrLoadModule.bind(this),
833
834
  ssrLoadModuleArtifacts: this.metroImportAsArtifactsAsync.bind(this),
834
- useClientRouter: isReactServerActionsOnlyEnabled
835
+ useClientRouter: isReactServerActionsOnlyEnabled,
836
+ createModuleId: metro._createModuleId.bind(metro)
835
837
  });
836
838
  this.rscRenderer = rscMiddleware1;
837
839
  }
@@ -885,6 +887,9 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
885
887
  const hasUpdate = added.length || modified.length || deleted.length;
886
888
  // NOTE: We throw away the updates and instead simply send a trigger to the client to re-fetch the server route.
887
889
  if (!isInitialUpdate && hasUpdate) {
890
+ // Clear all SSR modules before sending the reload event. This ensures that the next event will rebuild the in-memory state from scratch.
891
+ // @ts-expect-error: __c is not on global but is injected by Metro.
892
+ if (typeof globalThis.__c === "function") globalThis.__c();
888
893
  onReload();
889
894
  }
890
895
  }