@expo/cli 0.23.4 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin/cli +1 -1
- package/build/src/prebuild/updatePackageJson.js +19 -9
- package/build/src/prebuild/updatePackageJson.js.map +1 -1
- package/build/src/run/remoteBuildCache.js +51 -18
- package/build/src/run/remoteBuildCache.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +5 -5
package/build/bin/cli
CHANGED
|
@@ -189,35 +189,45 @@ function updatePkgDependencies(projectRoot, { pkg, templatePkg, skipDependencyUp
|
|
|
189
189
|
].filter((depKey)=>!!defaultDependencies[depKey]);
|
|
190
190
|
const symlinkedPackages = [];
|
|
191
191
|
const nonRecommendedPackages = [];
|
|
192
|
-
for (const
|
|
192
|
+
for (const dependencyKey of requiredDependencies){
|
|
193
193
|
var _pkg_dependencies;
|
|
194
194
|
// If the local package.json defined the dependency that we want to overwrite...
|
|
195
|
-
if ((_pkg_dependencies = pkg.dependencies) == null ? void 0 : _pkg_dependencies[
|
|
195
|
+
if ((_pkg_dependencies = pkg.dependencies) == null ? void 0 : _pkg_dependencies[dependencyKey]) {
|
|
196
196
|
// Then ensure it isn't symlinked (i.e. the user has a custom version in their yarn workspace).
|
|
197
197
|
if ((0, _isModuleSymlinked.isModuleSymlinked)(projectRoot, {
|
|
198
|
-
moduleId:
|
|
198
|
+
moduleId: dependencyKey,
|
|
199
199
|
isSilent: true
|
|
200
200
|
})) {
|
|
201
201
|
// If the package is in the project's package.json and it's symlinked, then skip overwriting it.
|
|
202
|
-
symlinkedPackages.push(
|
|
202
|
+
symlinkedPackages.push([
|
|
203
|
+
`${dependencyKey}`,
|
|
204
|
+
`${dependencyKey}@${defaultDependencies[dependencyKey]}`
|
|
205
|
+
]);
|
|
203
206
|
continue;
|
|
204
207
|
}
|
|
205
208
|
// Do not modify manually skipped dependencies
|
|
206
|
-
if (skipDependencyUpdate.includes(
|
|
209
|
+
if (skipDependencyUpdate.includes(dependencyKey)) {
|
|
207
210
|
continue;
|
|
208
211
|
}
|
|
209
212
|
// Warn users for outdated dependencies when prebuilding
|
|
210
|
-
const hasRecommendedVersion = versionRangesIntersect(pkg.dependencies[
|
|
213
|
+
const hasRecommendedVersion = versionRangesIntersect(pkg.dependencies[dependencyKey], String(defaultDependencies[dependencyKey]));
|
|
211
214
|
if (!hasRecommendedVersion) {
|
|
212
|
-
nonRecommendedPackages.push(
|
|
215
|
+
nonRecommendedPackages.push([
|
|
216
|
+
`${dependencyKey}@${pkg.dependencies[dependencyKey]}`,
|
|
217
|
+
`${dependencyKey}@${defaultDependencies[dependencyKey]}`
|
|
218
|
+
]);
|
|
213
219
|
}
|
|
214
220
|
}
|
|
215
221
|
}
|
|
216
222
|
if (symlinkedPackages.length) {
|
|
217
|
-
|
|
223
|
+
symlinkedPackages.forEach(([current, recommended])=>{
|
|
224
|
+
_log.log(`\u203A Using symlinked ${_chalk().default.bold(current)} instead of recommended ${_chalk().default.bold(recommended)}.`);
|
|
225
|
+
});
|
|
218
226
|
}
|
|
219
227
|
if (nonRecommendedPackages.length) {
|
|
220
|
-
|
|
228
|
+
nonRecommendedPackages.forEach(([current, recommended])=>{
|
|
229
|
+
_log.warn(`\u203A Using ${_chalk().default.bold(current)} instead of recommended ${_chalk().default.bold(recommended)}.`);
|
|
230
|
+
});
|
|
221
231
|
}
|
|
222
232
|
// Only change the dependencies if the normalized hash changes, this helps to reduce meaningless changes.
|
|
223
233
|
const hasNewDependencies = hashForDependencyMap(pkg.dependencies) !== hashForDependencyMap(combinedDependencies);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/prebuild/updatePackageJson.ts"],"sourcesContent":["import { getPackageJson, PackageJSONConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { intersects as semverIntersects, Range as SemverRange } from 'semver';\n\nimport * as Log from '../log';\nimport { isModuleSymlinked } from '../utils/isModuleSymlinked';\nimport { logNewSection } from '../utils/ora';\n\nexport type DependenciesMap = { [key: string]: string | number };\n\nexport type DependenciesModificationResults = {\n /** A list of new values were added to the `dependencies` object in the `package.json`. */\n changedDependencies: string[];\n};\n\n/** Modifies the `package.json` with `modifyPackageJson` and format/displays the results. */\nexport async function updatePackageJSONAsync(\n projectRoot: string,\n {\n templateDirectory,\n templatePkg = getPackageJson(templateDirectory),\n pkg,\n skipDependencyUpdate,\n }: {\n templateDirectory: string;\n templatePkg?: PackageJSONConfig;\n pkg: PackageJSONConfig;\n skipDependencyUpdate?: string[];\n }\n): Promise<DependenciesModificationResults> {\n const updatingPackageJsonStep = logNewSection('Updating package.json');\n\n const results = modifyPackageJson(projectRoot, {\n templatePkg,\n pkg,\n skipDependencyUpdate,\n });\n\n const hasChanges = results.changedDependencies.length || results.scriptsChanged;\n\n // NOTE: This is effectively bundler caching and subject to breakage if the inputs don't match the mutations.\n if (hasChanges) {\n await fs.promises.writeFile(\n path.resolve(projectRoot, 'package.json'),\n // Add new line to match the format of running yarn.\n // This prevents the `package.json` from changing when running `prebuild --no-install` multiple times.\n JSON.stringify(pkg, null, 2) + '\\n'\n );\n }\n\n updatingPackageJsonStep.succeed(\n 'Updated package.json' + (hasChanges ? '' : chalk.dim(` | no changes`))\n );\n\n return results;\n}\n\n/**\n * Make required modifications to the `package.json` file as a JSON object.\n *\n * 1. Update `package.json` `scripts`.\n * 2. Update `package.json` `dependencies` (not `devDependencies`).\n * 3. Update `package.json` `main`.\n *\n * @param projectRoot The root directory of the project.\n * @param templatePkg Template project package.json as JSON.\n * @param pkg Current package.json as JSON.\n * @param skipDependencyUpdate Array of dependencies to skip updating.\n * @returns\n */\nfunction modifyPackageJson(\n projectRoot: string,\n {\n templatePkg,\n pkg,\n skipDependencyUpdate,\n }: {\n templatePkg: PackageJSONConfig;\n pkg: PackageJSONConfig;\n /** @deprecated Required packages are not overwritten, only added when missing */\n skipDependencyUpdate?: string[];\n }\n) {\n const scriptsChanged = updatePkgScripts({ pkg });\n\n // TODO: Move to `npx expo-doctor`\n return {\n scriptsChanged,\n ...updatePkgDependencies(projectRoot, {\n pkg,\n templatePkg,\n skipDependencyUpdate,\n }),\n };\n}\n\n/**\n * Update `package.json` dependencies by combining the `dependencies` in the\n * project we are creating with the dependencies in the template project.\n *\n * > Exposed for testing.\n */\nexport function updatePkgDependencies(\n projectRoot: string,\n {\n pkg,\n templatePkg,\n skipDependencyUpdate = [],\n }: {\n pkg: PackageJSONConfig;\n templatePkg: PackageJSONConfig;\n /** @deprecated Required packages are not overwritten, only added when missing */\n skipDependencyUpdate?: string[];\n }\n): DependenciesModificationResults {\n const { dependencies } = templatePkg;\n // The default values come from the bare-minimum template's package.json.\n // Users can change this by using different templates with the `--template` flag.\n // The main reason for allowing the changing of dependencies would be to include\n // dependencies that are required for the native project to build. For example,\n // it does not need to include dependencies that are used in the JS-code only.\n const defaultDependencies = createDependenciesMap(dependencies);\n\n // NOTE: This is a hack to ensure this doesn't trigger an extraneous change in the `package.json`\n // it isn't required for anything in the `ios` and `android` folders.\n delete defaultDependencies['expo-status-bar'];\n // NOTE: Expo splash screen is installed by default in the template but the config plugin also lives in prebuild-config\n // so we can delete it to prevent an extraneous change in the `package.json`.\n delete defaultDependencies['expo-splash-screen'];\n\n const combinedDependencies: DependenciesMap = createDependenciesMap({\n ...defaultDependencies,\n ...pkg.dependencies,\n });\n\n // These dependencies are only added, not overwritten from the project\n const requiredDependencies = [\n // TODO: This is no longer required because it's this same package.\n 'expo',\n // TODO: Drop this somehow.\n 'react-native',\n ].filter((depKey) => !!defaultDependencies[depKey]);\n\n const symlinkedPackages: string[] = [];\n const nonRecommendedPackages: string[] = [];\n\n for (const dependenciesKey of requiredDependencies) {\n // If the local package.json defined the dependency that we want to overwrite...\n if (pkg.dependencies?.[dependenciesKey]) {\n // Then ensure it isn't symlinked (i.e. the user has a custom version in their yarn workspace).\n if (isModuleSymlinked(projectRoot, { moduleId: dependenciesKey, isSilent: true })) {\n // If the package is in the project's package.json and it's symlinked, then skip overwriting it.\n symlinkedPackages.push(dependenciesKey);\n continue;\n }\n\n // Do not modify manually skipped dependencies\n if (skipDependencyUpdate.includes(dependenciesKey)) {\n continue;\n }\n\n // Warn users for outdated dependencies when prebuilding\n const hasRecommendedVersion = versionRangesIntersect(\n pkg.dependencies[dependenciesKey],\n String(defaultDependencies[dependenciesKey])\n );\n if (!hasRecommendedVersion) {\n nonRecommendedPackages.push(`${dependenciesKey}@${defaultDependencies[dependenciesKey]}`);\n }\n }\n }\n\n if (symlinkedPackages.length) {\n Log.log(\n `\\u203A Using symlinked ${symlinkedPackages\n .map((pkg) => chalk.bold(pkg))\n .join(', ')} instead of recommended version(s).`\n );\n }\n\n if (nonRecommendedPackages.length) {\n Log.warn(\n `\\u203A Using current versions instead of recommended ${nonRecommendedPackages\n .map((pkg) => chalk.bold(pkg))\n .join(', ')}.`\n );\n }\n\n // Only change the dependencies if the normalized hash changes, this helps to reduce meaningless changes.\n const hasNewDependencies =\n hashForDependencyMap(pkg.dependencies) !== hashForDependencyMap(combinedDependencies);\n // Save the dependencies\n let changedDependencies: string[] = [];\n if (hasNewDependencies) {\n changedDependencies = diffKeys(combinedDependencies, pkg.dependencies ?? {}).sort();\n // Use Object.assign to preserve the original order of dependencies, this makes it easier to see what changed in the git diff.\n pkg.dependencies = Object.assign(pkg.dependencies ?? {}, combinedDependencies);\n }\n\n return {\n changedDependencies,\n };\n}\n\nfunction diffKeys(a: Record<string, any>, b: Record<string, any>): string[] {\n return Object.keys(a).filter((key) => a[key] !== b[key]);\n}\n\n/**\n * Create an object of type DependenciesMap a dependencies object or throw if not valid.\n *\n * @param dependencies - ideally an object of type {[key]: string} - if not then this will error.\n */\nexport function createDependenciesMap(dependencies: any): DependenciesMap {\n if (typeof dependencies !== 'object') {\n throw new Error(`Dependency map is invalid, expected object but got ${typeof dependencies}`);\n } else if (!dependencies) {\n return {};\n }\n\n const outputMap: DependenciesMap = {};\n\n for (const key of Object.keys(dependencies)) {\n const value = dependencies[key];\n if (typeof value === 'string') {\n outputMap[key] = value;\n } else {\n throw new Error(\n `Dependency for key \\`${key}\\` should be a \\`string\\`, instead got: \\`{ ${key}: ${JSON.stringify(\n value\n )} }\\``\n );\n }\n }\n return outputMap;\n}\n\n/**\n * Updates the package.json scripts for prebuild if the scripts match\n * the default values used in project templates.\n */\nexport function updatePkgScripts({ pkg }: { pkg: PackageJSONConfig }) {\n let hasChanged = false;\n if (!pkg.scripts) {\n pkg.scripts = {};\n }\n if (\n !pkg.scripts.android ||\n pkg.scripts.android === 'expo start --android' ||\n pkg.scripts.android === 'react-native run-android'\n ) {\n pkg.scripts.android = 'expo run:android';\n hasChanged = true;\n }\n if (\n !pkg.scripts.ios ||\n pkg.scripts.ios === 'expo start --ios' ||\n pkg.scripts.ios === 'react-native run-ios'\n ) {\n pkg.scripts.ios = 'expo run:ios';\n hasChanged = true;\n }\n return hasChanged;\n}\n\nfunction normalizeDependencyMap(deps: DependenciesMap): string[] {\n return Object.keys(deps)\n .map((dependency) => `${dependency}@${deps[dependency]}`)\n .sort();\n}\n\nexport function hashForDependencyMap(deps: DependenciesMap = {}): string {\n const depsList = normalizeDependencyMap(deps);\n const depsString = depsList.join('\\n');\n return createFileHash(depsString);\n}\n\nexport function createFileHash(contents: string): string {\n // this doesn't need to be secure, the shorter the better.\n return crypto.createHash('sha1').update(contents).digest('hex');\n}\n\n/**\n * Determine if two semver ranges are overlapping or intersecting.\n * This is a safe version of `semver.intersects` that does not throw.\n */\nfunction versionRangesIntersect(rangeA: string | SemverRange, rangeB: string | SemverRange) {\n try {\n return semverIntersects(rangeA, rangeB);\n } catch {\n return false;\n }\n}\n"],"names":["createDependenciesMap","createFileHash","hashForDependencyMap","updatePackageJSONAsync","updatePkgDependencies","updatePkgScripts","projectRoot","templateDirectory","templatePkg","getPackageJson","pkg","skipDependencyUpdate","updatingPackageJsonStep","logNewSection","results","modifyPackageJson","hasChanges","changedDependencies","length","scriptsChanged","fs","promises","writeFile","path","resolve","JSON","stringify","succeed","chalk","dim","dependencies","defaultDependencies","combinedDependencies","requiredDependencies","filter","depKey","symlinkedPackages","nonRecommendedPackages","dependenciesKey","isModuleSymlinked","moduleId","isSilent","push","includes","hasRecommendedVersion","versionRangesIntersect","String","Log","log","map","bold","join","warn","hasNewDependencies","diffKeys","sort","Object","assign","a","b","keys","key","Error","outputMap","value","hasChanged","scripts","android","ios","normalizeDependencyMap","deps","dependency","depsList","depsString","contents","crypto","createHash","update","digest","rangeA","rangeB","semverIntersects"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/prebuild/updatePackageJson.ts"],"sourcesContent":["import { getPackageJson, PackageJSONConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { intersects as semverIntersects, Range as SemverRange } from 'semver';\n\nimport * as Log from '../log';\nimport { isModuleSymlinked } from '../utils/isModuleSymlinked';\nimport { logNewSection } from '../utils/ora';\n\nexport type DependenciesMap = { [key: string]: string | number };\n\nexport type DependenciesModificationResults = {\n /** A list of new values were added to the `dependencies` object in the `package.json`. */\n changedDependencies: string[];\n};\n\n/** Modifies the `package.json` with `modifyPackageJson` and format/displays the results. */\nexport async function updatePackageJSONAsync(\n projectRoot: string,\n {\n templateDirectory,\n templatePkg = getPackageJson(templateDirectory),\n pkg,\n skipDependencyUpdate,\n }: {\n templateDirectory: string;\n templatePkg?: PackageJSONConfig;\n pkg: PackageJSONConfig;\n skipDependencyUpdate?: string[];\n }\n): Promise<DependenciesModificationResults> {\n const updatingPackageJsonStep = logNewSection('Updating package.json');\n\n const results = modifyPackageJson(projectRoot, {\n templatePkg,\n pkg,\n skipDependencyUpdate,\n });\n\n const hasChanges = results.changedDependencies.length || results.scriptsChanged;\n\n // NOTE: This is effectively bundler caching and subject to breakage if the inputs don't match the mutations.\n if (hasChanges) {\n await fs.promises.writeFile(\n path.resolve(projectRoot, 'package.json'),\n // Add new line to match the format of running yarn.\n // This prevents the `package.json` from changing when running `prebuild --no-install` multiple times.\n JSON.stringify(pkg, null, 2) + '\\n'\n );\n }\n\n updatingPackageJsonStep.succeed(\n 'Updated package.json' + (hasChanges ? '' : chalk.dim(` | no changes`))\n );\n\n return results;\n}\n\n/**\n * Make required modifications to the `package.json` file as a JSON object.\n *\n * 1. Update `package.json` `scripts`.\n * 2. Update `package.json` `dependencies` (not `devDependencies`).\n * 3. Update `package.json` `main`.\n *\n * @param projectRoot The root directory of the project.\n * @param templatePkg Template project package.json as JSON.\n * @param pkg Current package.json as JSON.\n * @param skipDependencyUpdate Array of dependencies to skip updating.\n * @returns\n */\nfunction modifyPackageJson(\n projectRoot: string,\n {\n templatePkg,\n pkg,\n skipDependencyUpdate,\n }: {\n templatePkg: PackageJSONConfig;\n pkg: PackageJSONConfig;\n /** @deprecated Required packages are not overwritten, only added when missing */\n skipDependencyUpdate?: string[];\n }\n) {\n const scriptsChanged = updatePkgScripts({ pkg });\n\n // TODO: Move to `npx expo-doctor`\n return {\n scriptsChanged,\n ...updatePkgDependencies(projectRoot, {\n pkg,\n templatePkg,\n skipDependencyUpdate,\n }),\n };\n}\n\n/**\n * Update `package.json` dependencies by combining the `dependencies` in the\n * project we are creating with the dependencies in the template project.\n *\n * > Exposed for testing.\n */\nexport function updatePkgDependencies(\n projectRoot: string,\n {\n pkg,\n templatePkg,\n skipDependencyUpdate = [],\n }: {\n pkg: PackageJSONConfig;\n templatePkg: PackageJSONConfig;\n /** @deprecated Required packages are not overwritten, only added when missing */\n skipDependencyUpdate?: string[];\n }\n): DependenciesModificationResults {\n const { dependencies } = templatePkg;\n // The default values come from the bare-minimum template's package.json.\n // Users can change this by using different templates with the `--template` flag.\n // The main reason for allowing the changing of dependencies would be to include\n // dependencies that are required for the native project to build. For example,\n // it does not need to include dependencies that are used in the JS-code only.\n const defaultDependencies = createDependenciesMap(dependencies);\n\n // NOTE: This is a hack to ensure this doesn't trigger an extraneous change in the `package.json`\n // it isn't required for anything in the `ios` and `android` folders.\n delete defaultDependencies['expo-status-bar'];\n // NOTE: Expo splash screen is installed by default in the template but the config plugin also lives in prebuild-config\n // so we can delete it to prevent an extraneous change in the `package.json`.\n delete defaultDependencies['expo-splash-screen'];\n\n const combinedDependencies: DependenciesMap = createDependenciesMap({\n ...defaultDependencies,\n ...pkg.dependencies,\n });\n\n // These dependencies are only added, not overwritten from the project\n const requiredDependencies = [\n // TODO: This is no longer required because it's this same package.\n 'expo',\n // TODO: Drop this somehow.\n 'react-native',\n ].filter((depKey) => !!defaultDependencies[depKey]);\n\n const symlinkedPackages: [string, string][] = [];\n const nonRecommendedPackages: [string, string][] = [];\n\n for (const dependencyKey of requiredDependencies) {\n // If the local package.json defined the dependency that we want to overwrite...\n if (pkg.dependencies?.[dependencyKey]) {\n // Then ensure it isn't symlinked (i.e. the user has a custom version in their yarn workspace).\n if (isModuleSymlinked(projectRoot, { moduleId: dependencyKey, isSilent: true })) {\n // If the package is in the project's package.json and it's symlinked, then skip overwriting it.\n symlinkedPackages.push([\n `${dependencyKey}`,\n `${dependencyKey}@${defaultDependencies[dependencyKey]}`,\n ]);\n continue;\n }\n\n // Do not modify manually skipped dependencies\n if (skipDependencyUpdate.includes(dependencyKey)) {\n continue;\n }\n\n // Warn users for outdated dependencies when prebuilding\n const hasRecommendedVersion = versionRangesIntersect(\n pkg.dependencies[dependencyKey],\n String(defaultDependencies[dependencyKey])\n );\n if (!hasRecommendedVersion) {\n nonRecommendedPackages.push([\n `${dependencyKey}@${pkg.dependencies[dependencyKey]}`,\n `${dependencyKey}@${defaultDependencies[dependencyKey]}`,\n ]);\n }\n }\n }\n\n if (symlinkedPackages.length) {\n symlinkedPackages.forEach(([current, recommended]) => {\n Log.log(\n `\\u203A Using symlinked ${chalk.bold(current)} instead of recommended ${chalk.bold(recommended)}.`\n );\n });\n }\n\n if (nonRecommendedPackages.length) {\n nonRecommendedPackages.forEach(([current, recommended]) => {\n Log.warn(\n `\\u203A Using ${chalk.bold(current)} instead of recommended ${chalk.bold(recommended)}.`\n );\n });\n }\n\n // Only change the dependencies if the normalized hash changes, this helps to reduce meaningless changes.\n const hasNewDependencies =\n hashForDependencyMap(pkg.dependencies) !== hashForDependencyMap(combinedDependencies);\n // Save the dependencies\n let changedDependencies: string[] = [];\n if (hasNewDependencies) {\n changedDependencies = diffKeys(combinedDependencies, pkg.dependencies ?? {}).sort();\n // Use Object.assign to preserve the original order of dependencies, this makes it easier to see what changed in the git diff.\n pkg.dependencies = Object.assign(pkg.dependencies ?? {}, combinedDependencies);\n }\n\n return {\n changedDependencies,\n };\n}\n\nfunction diffKeys(a: Record<string, any>, b: Record<string, any>): string[] {\n return Object.keys(a).filter((key) => a[key] !== b[key]);\n}\n\n/**\n * Create an object of type DependenciesMap a dependencies object or throw if not valid.\n *\n * @param dependencies - ideally an object of type {[key]: string} - if not then this will error.\n */\nexport function createDependenciesMap(dependencies: any): DependenciesMap {\n if (typeof dependencies !== 'object') {\n throw new Error(`Dependency map is invalid, expected object but got ${typeof dependencies}`);\n } else if (!dependencies) {\n return {};\n }\n\n const outputMap: DependenciesMap = {};\n\n for (const key of Object.keys(dependencies)) {\n const value = dependencies[key];\n if (typeof value === 'string') {\n outputMap[key] = value;\n } else {\n throw new Error(\n `Dependency for key \\`${key}\\` should be a \\`string\\`, instead got: \\`{ ${key}: ${JSON.stringify(\n value\n )} }\\``\n );\n }\n }\n return outputMap;\n}\n\n/**\n * Updates the package.json scripts for prebuild if the scripts match\n * the default values used in project templates.\n */\nexport function updatePkgScripts({ pkg }: { pkg: PackageJSONConfig }) {\n let hasChanged = false;\n if (!pkg.scripts) {\n pkg.scripts = {};\n }\n if (\n !pkg.scripts.android ||\n pkg.scripts.android === 'expo start --android' ||\n pkg.scripts.android === 'react-native run-android'\n ) {\n pkg.scripts.android = 'expo run:android';\n hasChanged = true;\n }\n if (\n !pkg.scripts.ios ||\n pkg.scripts.ios === 'expo start --ios' ||\n pkg.scripts.ios === 'react-native run-ios'\n ) {\n pkg.scripts.ios = 'expo run:ios';\n hasChanged = true;\n }\n return hasChanged;\n}\n\nfunction normalizeDependencyMap(deps: DependenciesMap): string[] {\n return Object.keys(deps)\n .map((dependency) => `${dependency}@${deps[dependency]}`)\n .sort();\n}\n\nexport function hashForDependencyMap(deps: DependenciesMap = {}): string {\n const depsList = normalizeDependencyMap(deps);\n const depsString = depsList.join('\\n');\n return createFileHash(depsString);\n}\n\nexport function createFileHash(contents: string): string {\n // this doesn't need to be secure, the shorter the better.\n return crypto.createHash('sha1').update(contents).digest('hex');\n}\n\n/**\n * Determine if two semver ranges are overlapping or intersecting.\n * This is a safe version of `semver.intersects` that does not throw.\n */\nfunction versionRangesIntersect(rangeA: string | SemverRange, rangeB: string | SemverRange) {\n try {\n return semverIntersects(rangeA, rangeB);\n } catch {\n return false;\n }\n}\n"],"names":["createDependenciesMap","createFileHash","hashForDependencyMap","updatePackageJSONAsync","updatePkgDependencies","updatePkgScripts","projectRoot","templateDirectory","templatePkg","getPackageJson","pkg","skipDependencyUpdate","updatingPackageJsonStep","logNewSection","results","modifyPackageJson","hasChanges","changedDependencies","length","scriptsChanged","fs","promises","writeFile","path","resolve","JSON","stringify","succeed","chalk","dim","dependencies","defaultDependencies","combinedDependencies","requiredDependencies","filter","depKey","symlinkedPackages","nonRecommendedPackages","dependencyKey","isModuleSymlinked","moduleId","isSilent","push","includes","hasRecommendedVersion","versionRangesIntersect","String","forEach","current","recommended","Log","log","bold","warn","hasNewDependencies","diffKeys","sort","Object","assign","a","b","keys","key","Error","outputMap","value","hasChanged","scripts","android","ios","normalizeDependencyMap","deps","map","dependency","depsList","depsString","join","contents","crypto","createHash","update","digest","rangeA","rangeB","semverIntersects"],"mappings":"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"}
|
|
@@ -23,6 +23,13 @@ function _spawnasync() {
|
|
|
23
23
|
};
|
|
24
24
|
return data;
|
|
25
25
|
}
|
|
26
|
+
function _chalk() {
|
|
27
|
+
const data = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
28
|
+
_chalk = function() {
|
|
29
|
+
return data;
|
|
30
|
+
};
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
26
33
|
function _fs() {
|
|
27
34
|
const data = /*#__PURE__*/ _interop_require_default(require("fs"));
|
|
28
35
|
_fs = function() {
|
|
@@ -38,6 +45,7 @@ function _path() {
|
|
|
38
45
|
return data;
|
|
39
46
|
}
|
|
40
47
|
const _log = require("../log");
|
|
48
|
+
const _xcrun = require("../start/platforms/ios/xcrun");
|
|
41
49
|
function _interop_require_default(obj) {
|
|
42
50
|
return obj && obj.__esModule ? obj : {
|
|
43
51
|
default: obj
|
|
@@ -45,32 +53,27 @@ function _interop_require_default(obj) {
|
|
|
45
53
|
}
|
|
46
54
|
const debug = require('debug')('expo:run:remote-build');
|
|
47
55
|
async function resolveRemoteBuildCache(projectRoot, { platform, provider }) {
|
|
48
|
-
const
|
|
49
|
-
if (!Fingerprint) {
|
|
50
|
-
debug('@expo/fingerprint is not installed in the project, skip checking for remote builds');
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
const fingerprint = await Fingerprint.createFingerprintAsync(projectRoot);
|
|
56
|
+
const fingerprintHash = await calculateFingerprintHashAsync(projectRoot, platform, provider);
|
|
54
57
|
if (provider === 'eas') {
|
|
55
58
|
const easJsonPath = _path().default.join(projectRoot, 'eas.json');
|
|
56
59
|
if (!_fs().default.existsSync(easJsonPath)) {
|
|
57
60
|
debug('eas.json not found, skip checking for remote builds');
|
|
58
61
|
return null;
|
|
59
62
|
}
|
|
60
|
-
_log.Log.log(`Searching builds with matching fingerprint on EAS servers`);
|
|
63
|
+
_log.Log.log((0, _chalk().default)`{whiteBright \u203A} {bold Searching builds with matching fingerprint on EAS servers}`);
|
|
61
64
|
try {
|
|
62
65
|
const results = await (0, _spawnasync().default)('npx', [
|
|
63
66
|
'eas-cli',
|
|
64
67
|
'build:download',
|
|
65
68
|
`--platform=${platform}`,
|
|
66
|
-
`--fingerprint=${
|
|
69
|
+
`--fingerprint=${fingerprintHash}`,
|
|
67
70
|
'--non-interactive',
|
|
68
71
|
'--dev-client',
|
|
69
72
|
'--json'
|
|
70
73
|
], {
|
|
71
74
|
cwd: projectRoot
|
|
72
75
|
});
|
|
73
|
-
_log.Log.log(`Successfully downloaded cached build`);
|
|
76
|
+
_log.Log.log((0, _chalk().default)`{whiteBright \u203A} {bold Successfully downloaded cached build}`);
|
|
74
77
|
// {
|
|
75
78
|
// "path": "/var/folders/03/lppcpcnn61q3mz5ckzmzd8w80000gn/T/eas-cli-nodejs/eas-build-run-cache/c0f9ba9c-0cf1-4c5c-8566-b28b7971050f_22f1bbfa-1c09-4b67-9e4a-721906546b58.app"
|
|
76
79
|
// }
|
|
@@ -78,18 +81,17 @@ async function resolveRemoteBuildCache(projectRoot, { platform, provider }) {
|
|
|
78
81
|
return json == null ? void 0 : json.path;
|
|
79
82
|
} catch (error) {
|
|
80
83
|
debug('eas-cli error:', error);
|
|
84
|
+
// @TODO(2025-04-11): remove this in a future release
|
|
85
|
+
if ((0, _xcrun.isSpawnResultError)(error) && error.stderr.includes('command build:download not found')) {
|
|
86
|
+
_log.Log.warn(`To take advantage of remote build cache, upgrade your eas-cli installation to latest.`);
|
|
87
|
+
}
|
|
81
88
|
return null;
|
|
82
89
|
}
|
|
83
90
|
}
|
|
84
91
|
return null;
|
|
85
92
|
}
|
|
86
93
|
async function uploadRemoteBuildCache(projectRoot, { platform, provider }) {
|
|
87
|
-
const
|
|
88
|
-
if (!Fingerprint) {
|
|
89
|
-
debug('@expo/fingerprint is not installed in the project, skip checking for remote builds');
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
const fingerprint = await Fingerprint.createFingerprintAsync(projectRoot);
|
|
94
|
+
const fingerprintHash = await calculateFingerprintHashAsync(projectRoot, platform, provider);
|
|
93
95
|
if (provider === 'eas') {
|
|
94
96
|
const easJsonPath = _path().default.join(projectRoot, 'eas.json');
|
|
95
97
|
if (!_fs().default.existsSync(easJsonPath)) {
|
|
@@ -97,12 +99,12 @@ async function uploadRemoteBuildCache(projectRoot, { platform, provider }) {
|
|
|
97
99
|
return null;
|
|
98
100
|
}
|
|
99
101
|
try {
|
|
100
|
-
_log.Log.log(
|
|
102
|
+
_log.Log.log((0, _chalk().default)`{whiteBright \u203A} {bold Uploading build to remote cache}`);
|
|
101
103
|
const results = await (0, _spawnasync().default)('npx', [
|
|
102
104
|
'eas-cli',
|
|
103
105
|
'upload',
|
|
104
106
|
`--platform=${platform}`,
|
|
105
|
-
`--fingerprint=${
|
|
107
|
+
`--fingerprint=${fingerprintHash}`,
|
|
106
108
|
'--non-interactive',
|
|
107
109
|
'--json'
|
|
108
110
|
], {
|
|
@@ -112,7 +114,7 @@ async function uploadRemoteBuildCache(projectRoot, { platform, provider }) {
|
|
|
112
114
|
// "url": "/var/folders/03/lppcpcnn61q3mz5ckzmzd8w80000gn/T/eas-cli-nodejs/eas-build-run-cache/c0f9ba9c-0cf1-4c5c-8566-b28b7971050f_22f1bbfa-1c09-4b67-9e4a-721906546b58.app"
|
|
113
115
|
// }
|
|
114
116
|
const json = JSON.parse(results.stdout.trim());
|
|
115
|
-
_log.Log.log(`Build successfully uploaded: ${json == null ? void 0 : json.url}`);
|
|
117
|
+
_log.Log.log((0, _chalk().default)`{whiteBright \u203A} {bold Build successfully uploaded: ${json == null ? void 0 : json.url}}`);
|
|
116
118
|
} catch (error) {
|
|
117
119
|
debug('eas-cli error:', error);
|
|
118
120
|
return null;
|
|
@@ -120,6 +122,37 @@ async function uploadRemoteBuildCache(projectRoot, { platform, provider }) {
|
|
|
120
122
|
}
|
|
121
123
|
return null;
|
|
122
124
|
}
|
|
125
|
+
async function calculateFingerprintHashAsync(projectRoot, platform, provider) {
|
|
126
|
+
if (provider === 'eas') {
|
|
127
|
+
// prefer using `eas fingerprint:generate` because it automatically upload sources
|
|
128
|
+
try {
|
|
129
|
+
const results = await (0, _spawnasync().default)('npx', [
|
|
130
|
+
'eas-cli',
|
|
131
|
+
'fingerprint:generate',
|
|
132
|
+
`--platform=${platform}`,
|
|
133
|
+
'--json',
|
|
134
|
+
'--non-interactive'
|
|
135
|
+
], {
|
|
136
|
+
cwd: projectRoot
|
|
137
|
+
});
|
|
138
|
+
// {
|
|
139
|
+
// "hash": "203f960b965e154b77dc31c6c42e5582e8d77196"
|
|
140
|
+
// }
|
|
141
|
+
const json = JSON.parse(results.stdout.trim());
|
|
142
|
+
return json == null ? void 0 : json.hash;
|
|
143
|
+
} catch (error) {
|
|
144
|
+
// if eas-cli is not installed, fallback to @expo/fingerprint
|
|
145
|
+
debug('eas-cli error:', error);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const Fingerprint = importFingerprintForDev(projectRoot);
|
|
149
|
+
if (!Fingerprint) {
|
|
150
|
+
debug('@expo/fingerprint is not installed in the project, skip checking for remote builds');
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const fingerprint = await Fingerprint.createFingerprintAsync(projectRoot);
|
|
154
|
+
return fingerprint.hash;
|
|
155
|
+
}
|
|
123
156
|
function importFingerprintForDev(projectRoot) {
|
|
124
157
|
try {
|
|
125
158
|
return require(require.resolve('@expo/fingerprint', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/run/remoteBuildCache.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport { ModPlatform } from '@expo/config-plugins';\nimport spawnAsync from '@expo/spawn-async';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { Log } from '../log';\n\nconst debug = require('debug')('expo:run:remote-build') as typeof console.log;\n\nexport async function resolveRemoteBuildCache(\n projectRoot: string,\n {\n platform,\n provider,\n }: {\n platform: ModPlatform;\n provider?: Required<Required<ExpoConfig>['experiments']>['remoteBuildCache']['provider'];\n }\n): Promise<string | null> {\n const
|
|
1
|
+
{"version":3,"sources":["../../../src/run/remoteBuildCache.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport { ModPlatform } from '@expo/config-plugins';\nimport spawnAsync from '@expo/spawn-async';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { Log } from '../log';\nimport { isSpawnResultError } from '../start/platforms/ios/xcrun';\n\nconst debug = require('debug')('expo:run:remote-build') as typeof console.log;\n\nexport async function resolveRemoteBuildCache(\n projectRoot: string,\n {\n platform,\n provider,\n }: {\n platform: ModPlatform;\n provider?: Required<Required<ExpoConfig>['experiments']>['remoteBuildCache']['provider'];\n }\n): Promise<string | null> {\n const fingerprintHash = await calculateFingerprintHashAsync(projectRoot, platform, provider);\n\n if (provider === 'eas') {\n const easJsonPath = path.join(projectRoot, 'eas.json');\n if (!fs.existsSync(easJsonPath)) {\n debug('eas.json not found, skip checking for remote builds');\n return null;\n }\n\n Log.log(\n chalk`{whiteBright \\u203A} {bold Searching builds with matching fingerprint on EAS servers}`\n );\n try {\n const results = await spawnAsync(\n 'npx',\n [\n 'eas-cli',\n 'build:download',\n `--platform=${platform}`,\n `--fingerprint=${fingerprintHash}`,\n '--non-interactive',\n '--dev-client',\n '--json',\n ],\n {\n cwd: projectRoot,\n }\n );\n\n Log.log(chalk`{whiteBright \\u203A} {bold Successfully downloaded cached build}`);\n // {\n // \"path\": \"/var/folders/03/lppcpcnn61q3mz5ckzmzd8w80000gn/T/eas-cli-nodejs/eas-build-run-cache/c0f9ba9c-0cf1-4c5c-8566-b28b7971050f_22f1bbfa-1c09-4b67-9e4a-721906546b58.app\"\n // }\n const json = JSON.parse(results.stdout.trim());\n return json?.path;\n } catch (error) {\n debug('eas-cli error:', error);\n // @TODO(2025-04-11): remove this in a future release\n if (isSpawnResultError(error) && error.stderr.includes('command build:download not found')) {\n Log.warn(\n `To take advantage of remote build cache, upgrade your eas-cli installation to latest.`\n );\n }\n return null;\n }\n }\n\n return null;\n}\n\nexport async function uploadRemoteBuildCache(\n projectRoot: string,\n {\n platform,\n provider,\n }: {\n platform: ModPlatform;\n provider?: Required<Required<ExpoConfig>['experiments']>['remoteBuildCache']['provider'];\n }\n): Promise<string | null> {\n const fingerprintHash = await calculateFingerprintHashAsync(projectRoot, platform, provider);\n\n if (provider === 'eas') {\n const easJsonPath = path.join(projectRoot, 'eas.json');\n if (!fs.existsSync(easJsonPath)) {\n debug('eas.json not found, skip checking for remote builds');\n return null;\n }\n\n try {\n Log.log(chalk`{whiteBright \\u203A} {bold Uploading build to remote cache}`);\n const results = await spawnAsync(\n 'npx',\n [\n 'eas-cli',\n 'upload',\n `--platform=${platform}`,\n `--fingerprint=${fingerprintHash}`,\n '--non-interactive',\n '--json',\n ],\n {\n cwd: projectRoot,\n }\n );\n // {\n // \"url\": \"/var/folders/03/lppcpcnn61q3mz5ckzmzd8w80000gn/T/eas-cli-nodejs/eas-build-run-cache/c0f9ba9c-0cf1-4c5c-8566-b28b7971050f_22f1bbfa-1c09-4b67-9e4a-721906546b58.app\"\n // }\n const json = JSON.parse(results.stdout.trim());\n Log.log(chalk`{whiteBright \\u203A} {bold Build successfully uploaded: ${json?.url}}`);\n } catch (error) {\n debug('eas-cli error:', error);\n return null;\n }\n }\n\n return null;\n}\n\nasync function calculateFingerprintHashAsync(\n projectRoot: string,\n platform: ModPlatform,\n provider?: Required<Required<ExpoConfig>['experiments']>['remoteBuildCache']['provider']\n): Promise<string | null> {\n if (provider === 'eas') {\n // prefer using `eas fingerprint:generate` because it automatically upload sources\n try {\n const results = await spawnAsync(\n 'npx',\n [\n 'eas-cli',\n 'fingerprint:generate',\n `--platform=${platform}`,\n '--json',\n '--non-interactive',\n ],\n {\n cwd: projectRoot,\n }\n );\n // {\n // \"hash\": \"203f960b965e154b77dc31c6c42e5582e8d77196\"\n // }\n const json = JSON.parse(results.stdout.trim());\n return json?.hash;\n } catch (error) {\n // if eas-cli is not installed, fallback to @expo/fingerprint\n debug('eas-cli error:', error);\n }\n }\n\n const Fingerprint = importFingerprintForDev(projectRoot);\n if (!Fingerprint) {\n debug('@expo/fingerprint is not installed in the project, skip checking for remote builds');\n return null;\n }\n const fingerprint = await Fingerprint.createFingerprintAsync(projectRoot);\n\n return fingerprint.hash;\n}\n\nfunction importFingerprintForDev(projectRoot: string): null | typeof import('@expo/fingerprint') {\n try {\n return require(require.resolve('@expo/fingerprint', { paths: [projectRoot] }));\n } catch {\n return null;\n }\n}\n"],"names":["resolveRemoteBuildCache","uploadRemoteBuildCache","debug","require","projectRoot","platform","provider","fingerprintHash","calculateFingerprintHashAsync","easJsonPath","path","join","fs","existsSync","Log","log","chalk","results","spawnAsync","cwd","json","JSON","parse","stdout","trim","error","isSpawnResultError","stderr","includes","warn","url","hash","Fingerprint","importFingerprintForDev","fingerprint","createFingerprintAsync","resolve","paths"],"mappings":";;;;;;;;;;;IAYsBA,uBAAuB;eAAvBA;;IA4DAC,sBAAsB;eAAtBA;;;;gEAtEC;;;;;;;gEACL;;;;;;;gEACH;;;;;;;gEACE;;;;;;qBAEG;uBACe;;;;;;AAEnC,MAAMC,QAAQC,QAAQ,SAAS;AAExB,eAAeH,wBACpBI,WAAmB,EACnB,EACEC,QAAQ,EACRC,QAAQ,EAIT;IAED,MAAMC,kBAAkB,MAAMC,8BAA8BJ,aAAaC,UAAUC;IAEnF,IAAIA,aAAa,OAAO;QACtB,MAAMG,cAAcC,eAAI,CAACC,IAAI,CAACP,aAAa;QAC3C,IAAI,CAACQ,aAAE,CAACC,UAAU,CAACJ,cAAc;YAC/BP,MAAM;YACN,OAAO;QACT;QAEAY,QAAG,CAACC,GAAG,CACLC,IAAAA,gBAAK,CAAA,CAAC,qFAAqF,CAAC;QAE9F,IAAI;YACF,MAAMC,UAAU,MAAMC,IAAAA,qBAAU,EAC9B,OACA;gBACE;gBACA;gBACA,CAAC,WAAW,EAAEb,UAAU;gBACxB,CAAC,cAAc,EAAEE,iBAAiB;gBAClC;gBACA;gBACA;aACD,EACD;gBACEY,KAAKf;YACP;YAGFU,QAAG,CAACC,GAAG,CAACC,IAAAA,gBAAK,CAAA,CAAC,gEAAgE,CAAC;YAC/E,IAAI;YACJ,gLAAgL;YAChL,IAAI;YACJ,MAAMI,OAAOC,KAAKC,KAAK,CAACL,QAAQM,MAAM,CAACC,IAAI;YAC3C,OAAOJ,wBAAAA,KAAMV,IAAI;QACnB,EAAE,OAAOe,OAAO;YACdvB,MAAM,kBAAkBuB;YACxB,qDAAqD;YACrD,IAAIC,IAAAA,yBAAkB,EAACD,UAAUA,MAAME,MAAM,CAACC,QAAQ,CAAC,qCAAqC;gBAC1Fd,QAAG,CAACe,IAAI,CACN,CAAC,qFAAqF,CAAC;YAE3F;YACA,OAAO;QACT;IACF;IAEA,OAAO;AACT;AAEO,eAAe5B,uBACpBG,WAAmB,EACnB,EACEC,QAAQ,EACRC,QAAQ,EAIT;IAED,MAAMC,kBAAkB,MAAMC,8BAA8BJ,aAAaC,UAAUC;IAEnF,IAAIA,aAAa,OAAO;QACtB,MAAMG,cAAcC,eAAI,CAACC,IAAI,CAACP,aAAa;QAC3C,IAAI,CAACQ,aAAE,CAACC,UAAU,CAACJ,cAAc;YAC/BP,MAAM;YACN,OAAO;QACT;QAEA,IAAI;YACFY,QAAG,CAACC,GAAG,CAACC,IAAAA,gBAAK,CAAA,CAAC,2DAA2D,CAAC;YAC1E,MAAMC,UAAU,MAAMC,IAAAA,qBAAU,EAC9B,OACA;gBACE;gBACA;gBACA,CAAC,WAAW,EAAEb,UAAU;gBACxB,CAAC,cAAc,EAAEE,iBAAiB;gBAClC;gBACA;aACD,EACD;gBACEY,KAAKf;YACP;YAEF,IAAI;YACJ,+KAA+K;YAC/K,IAAI;YACJ,MAAMgB,OAAOC,KAAKC,KAAK,CAACL,QAAQM,MAAM,CAACC,IAAI;YAC3CV,QAAG,CAACC,GAAG,CAACC,IAAAA,gBAAK,CAAA,CAAC,wDAAwD,EAAEI,wBAAAA,KAAMU,GAAG,CAAC,CAAC,CAAC;QACtF,EAAE,OAAOL,OAAO;YACdvB,MAAM,kBAAkBuB;YACxB,OAAO;QACT;IACF;IAEA,OAAO;AACT;AAEA,eAAejB,8BACbJ,WAAmB,EACnBC,QAAqB,EACrBC,QAAwF;IAExF,IAAIA,aAAa,OAAO;QACtB,kFAAkF;QAClF,IAAI;YACF,MAAMW,UAAU,MAAMC,IAAAA,qBAAU,EAC9B,OACA;gBACE;gBACA;gBACA,CAAC,WAAW,EAAEb,UAAU;gBACxB;gBACA;aACD,EACD;gBACEc,KAAKf;YACP;YAEF,IAAI;YACJ,uDAAuD;YACvD,IAAI;YACJ,MAAMgB,OAAOC,KAAKC,KAAK,CAACL,QAAQM,MAAM,CAACC,IAAI;YAC3C,OAAOJ,wBAAAA,KAAMW,IAAI;QACnB,EAAE,OAAON,OAAO;YACd,6DAA6D;YAC7DvB,MAAM,kBAAkBuB;QAC1B;IACF;IAEA,MAAMO,cAAcC,wBAAwB7B;IAC5C,IAAI,CAAC4B,aAAa;QAChB9B,MAAM;QACN,OAAO;IACT;IACA,MAAMgC,cAAc,MAAMF,YAAYG,sBAAsB,CAAC/B;IAE7D,OAAO8B,YAAYH,IAAI;AACzB;AAEA,SAASE,wBAAwB7B,WAAmB;IAClD,IAAI;QACF,OAAOD,QAAQA,QAAQiC,OAAO,CAAC,qBAAqB;YAAEC,OAAO;gBAACjC;aAAY;QAAC;IAC7E,EAAE,OAAM;QACN,OAAO;IACT;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.
|
|
36
|
+
'user-agent': `expo-cli/${"0.24.0"}`,
|
|
37
37
|
authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
|
|
38
38
|
};
|
|
39
39
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "The Expo CLI",
|
|
5
5
|
"main": "build/bin/cli",
|
|
6
6
|
"bin": {
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"@0no-co/graphql.web": "^1.0.8",
|
|
43
43
|
"@babel/runtime": "^7.20.0",
|
|
44
44
|
"@expo/code-signing-certificates": "^0.0.5",
|
|
45
|
-
"@expo/config": "~11.0.
|
|
46
|
-
"@expo/config-plugins": "~9.1.
|
|
45
|
+
"@expo/config": "~11.0.2",
|
|
46
|
+
"@expo/config-plugins": "~9.1.3",
|
|
47
47
|
"@expo/devcert": "^1.1.2",
|
|
48
48
|
"@expo/env": "~1.0.2",
|
|
49
49
|
"@expo/image-utils": "^0.7.1",
|
|
50
50
|
"@expo/json-file": "^9.1.1",
|
|
51
|
-
"@expo/metro-config": "~0.20.
|
|
51
|
+
"@expo/metro-config": "~0.20.3",
|
|
52
52
|
"@expo/osascript": "^2.2.1",
|
|
53
53
|
"@expo/package-manager": "^1.8.1",
|
|
54
54
|
"@expo/plist": "^0.3.1",
|
|
@@ -152,5 +152,5 @@
|
|
|
152
152
|
"tree-kill": "^1.2.2",
|
|
153
153
|
"tsd": "^0.28.1"
|
|
154
154
|
},
|
|
155
|
-
"gitHead": "
|
|
155
|
+
"gitHead": "dd2c7150fd75c56505aa6d3f805c14e255649c5d"
|
|
156
156
|
}
|