@expo/build-tools 20.4.0 → 20.5.1
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/dist/common/projectSources.js +1 -1
- package/dist/context.d.ts +2 -2
- package/dist/ios/fastlane.d.ts +1 -1
- package/dist/steps/functions/createSubmissionEntity.js +25 -1
- package/dist/steps/functions/downloadArtifact.js +13 -3
- package/dist/steps/functions/repack.js +12 -7
- package/dist/steps/functions/restoreCache.js +2 -1
- package/dist/steps/functions/saveCache.js +3 -2
- package/dist/steps/functions/startIosSimulator.js +19 -0
- package/dist/utils/IosSimulatorUtils.d.ts +4 -0
- package/dist/utils/IosSimulatorUtils.js +40 -0
- package/dist/utils/expoUpdates.js +6 -1
- package/package.json +4 -4
|
@@ -169,7 +169,7 @@ async function uploadProjectMetadataAsync(ctx, { projectDirectory }) {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
`), {
|
|
172
|
-
buildId: ctx.env.EAS_BUILD_ID,
|
|
172
|
+
buildId: (0, nullthrows_1.default)(ctx.env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set'),
|
|
173
173
|
projectMetadataFile: {
|
|
174
174
|
type: 'GCS',
|
|
175
175
|
bucketKey: uploadSession.bucketKey,
|
package/dist/context.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export interface BuildContextOptions {
|
|
|
43
43
|
}>;
|
|
44
44
|
reportError?: (msg: string, err?: Error, options?: {
|
|
45
45
|
tags?: Record<string, string>;
|
|
46
|
-
extras?: Record<string, string>;
|
|
46
|
+
extras?: Record<string, string | undefined>;
|
|
47
47
|
}) => void;
|
|
48
48
|
skipNativeBuild?: boolean;
|
|
49
49
|
metadata?: Metadata;
|
|
@@ -58,7 +58,7 @@ export declare class BuildContext<TJob extends Job = Job> {
|
|
|
58
58
|
readonly cacheManager?: CacheManager;
|
|
59
59
|
readonly reportError?: (msg: string, err?: Error, options?: {
|
|
60
60
|
tags?: Record<string, string>;
|
|
61
|
-
extras?: Record<string, string>;
|
|
61
|
+
extras?: Record<string, string | undefined>;
|
|
62
62
|
}) => void;
|
|
63
63
|
readonly skipNativeBuild?: boolean;
|
|
64
64
|
readonly expoApiV2BaseUrl?: string;
|
package/dist/ios/fastlane.d.ts
CHANGED
|
@@ -19,6 +19,6 @@ export declare function runFastlaneResign<TJob extends Ios.Job>(ctx: BuildContex
|
|
|
19
19
|
}): Promise<void>;
|
|
20
20
|
export declare function runFastlane(fastlaneArgs: string[], { logger, env, cwd, }?: {
|
|
21
21
|
logger?: bunyan;
|
|
22
|
-
env?:
|
|
22
|
+
env?: Env;
|
|
23
23
|
cwd?: string;
|
|
24
24
|
}): Promise<SpawnResult>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createSubmissionEntityFunction = createSubmissionEntityFunction;
|
|
4
4
|
const results_1 = require("@expo/results");
|
|
5
5
|
const steps_1 = require("@expo/steps");
|
|
6
|
+
const sentry_1 = require("../../sentry");
|
|
6
7
|
const retryOnDNSFailure_1 = require("../../utils/retryOnDNSFailure");
|
|
7
8
|
function createSubmissionEntityFunction() {
|
|
8
9
|
return new steps_1.BuildFunction({
|
|
@@ -53,16 +54,39 @@ function createSubmissionEntityFunction() {
|
|
|
53
54
|
const robotAccessToken = stepsCtx.global.staticContext.job.secrets?.robotAccessToken;
|
|
54
55
|
if (!robotAccessToken) {
|
|
55
56
|
stepsCtx.logger.error('Failed to create submission entity: no robot access token found');
|
|
57
|
+
sentry_1.Sentry.capture('Failed to create submission entity: missing robot access token');
|
|
56
58
|
return;
|
|
57
59
|
}
|
|
58
60
|
const buildId = inputs.build_id.value;
|
|
59
61
|
if (!buildId) {
|
|
60
62
|
stepsCtx.logger.error('Failed to create submission entity: no build ID provided');
|
|
63
|
+
sentry_1.Sentry.capture('Failed to create submission entity: missing build ID', {
|
|
64
|
+
extras: {
|
|
65
|
+
buildId,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
61
68
|
return;
|
|
62
69
|
}
|
|
63
70
|
const workflowJobId = stepsCtx.global.env.__WORKFLOW_JOB_ID;
|
|
64
71
|
if (!workflowJobId) {
|
|
65
72
|
stepsCtx.logger.error('Failed to create submission entity: no workflow job ID found');
|
|
73
|
+
sentry_1.Sentry.capture('Failed to create submission entity: missing workflow job ID', {
|
|
74
|
+
extras: {
|
|
75
|
+
buildId,
|
|
76
|
+
workflowJobId,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const expoApiServerURL = stepsCtx.global.staticContext.expoApiServerURL;
|
|
82
|
+
if (!expoApiServerURL) {
|
|
83
|
+
stepsCtx.logger.error('Failed to create submission entity: no Expo API server URL found');
|
|
84
|
+
sentry_1.Sentry.capture('Failed to create submission entity: missing Expo API server URL', {
|
|
85
|
+
extras: {
|
|
86
|
+
buildId,
|
|
87
|
+
workflowJobId,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
66
90
|
return;
|
|
67
91
|
}
|
|
68
92
|
// This is supposed to provide fallback for `''` -> `undefined`.
|
|
@@ -76,7 +100,7 @@ function createSubmissionEntityFunction() {
|
|
|
76
100
|
const ascAppIdentifier = inputs.asc_app_identifier.value || undefined;
|
|
77
101
|
/* eslint-enable @typescript-eslint/prefer-nullish-coalescing */
|
|
78
102
|
try {
|
|
79
|
-
const response = await (0, retryOnDNSFailure_1.retryOnDNSFailure)(fetch)(new URL('/v2/app-store-submissions/',
|
|
103
|
+
const response = await (0, retryOnDNSFailure_1.retryOnDNSFailure)(fetch)(new URL('/v2/app-store-submissions/', expoApiServerURL), {
|
|
80
104
|
method: 'POST',
|
|
81
105
|
headers: {
|
|
82
106
|
Authorization: `Bearer ${robotAccessToken}`,
|
|
@@ -52,11 +52,21 @@ function createDownloadArtifactFunction() {
|
|
|
52
52
|
});
|
|
53
53
|
const interpolationContext = stepsCtx.global.getInterpolationContext();
|
|
54
54
|
if (!('workflow' in interpolationContext)) {
|
|
55
|
-
throw new eas_build_job_1.
|
|
55
|
+
throw new eas_build_job_1.SystemError('No workflow found in the interpolation context.', {
|
|
56
|
+
trackingCode: 'EAS_DOWNLOAD_ARTIFACT_NO_WORKFLOW',
|
|
57
|
+
});
|
|
56
58
|
}
|
|
57
59
|
const robotAccessToken = stepsCtx.global.staticContext.job.secrets?.robotAccessToken;
|
|
58
60
|
if (!robotAccessToken) {
|
|
59
|
-
throw new eas_build_job_1.
|
|
61
|
+
throw new eas_build_job_1.SystemError('No robot access token found in the job secrets.', {
|
|
62
|
+
trackingCode: 'EAS_DOWNLOAD_ARTIFACT_NO_ROBOT_ACCESS_TOKEN',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const expoApiServerURL = stepsCtx.global.staticContext.expoApiServerURL;
|
|
66
|
+
if (!expoApiServerURL) {
|
|
67
|
+
throw new eas_build_job_1.SystemError('Missing Expo API server URL.', {
|
|
68
|
+
trackingCode: 'EAS_DOWNLOAD_ARTIFACT_NO_EXPO_API_SERVER_URL',
|
|
69
|
+
});
|
|
60
70
|
}
|
|
61
71
|
const workflowRunId = interpolationContext.workflow.id;
|
|
62
72
|
const { logger } = stepsCtx;
|
|
@@ -69,7 +79,7 @@ function createDownloadArtifactFunction() {
|
|
|
69
79
|
const { artifactPath } = await downloadArtifactAsync({
|
|
70
80
|
logger,
|
|
71
81
|
workflowRunId,
|
|
72
|
-
expoApiServerURL
|
|
82
|
+
expoApiServerURL,
|
|
73
83
|
robotAccessToken,
|
|
74
84
|
params,
|
|
75
85
|
});
|
|
@@ -33,11 +33,6 @@ function createRepackBuildFunction() {
|
|
|
33
33
|
required: false,
|
|
34
34
|
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
35
35
|
}),
|
|
36
|
-
steps_1.BuildStepInput.createProvider({
|
|
37
|
-
id: 'output_path',
|
|
38
|
-
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
39
|
-
required: false,
|
|
40
|
-
}),
|
|
41
36
|
steps_1.BuildStepInput.createProvider({
|
|
42
37
|
id: 'embed_bundle_assets',
|
|
43
38
|
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.BOOLEAN,
|
|
@@ -93,8 +88,10 @@ function createRepackBuildFunction() {
|
|
|
93
88
|
await node_fs_1.default.promises.mkdir(workingDirectory);
|
|
94
89
|
stepsCtx.logger.info(`Created temporary working directory: ${workingDirectory}`);
|
|
95
90
|
const sourceAppPath = inputs.source_app_path.value;
|
|
96
|
-
const outputPath =
|
|
97
|
-
|
|
91
|
+
const outputPath = createOutputPath({
|
|
92
|
+
sourceAppPath,
|
|
93
|
+
tmpDir,
|
|
94
|
+
});
|
|
98
95
|
const exportEmbedOptions = inputs.embed_bundle_assets.value
|
|
99
96
|
? {
|
|
100
97
|
sourcemapOutput: undefined,
|
|
@@ -174,6 +171,14 @@ function createRepackBuildFunction() {
|
|
|
174
171
|
},
|
|
175
172
|
});
|
|
176
173
|
}
|
|
174
|
+
function createOutputPath({ sourceAppPath, tmpDir, }) {
|
|
175
|
+
const outputPath = node_path_1.default.join(tmpDir, `repacked-${(0, node_crypto_1.randomUUID)()}${node_path_1.default.extname(sourceAppPath)}`);
|
|
176
|
+
const extension = node_path_1.default.extname(outputPath);
|
|
177
|
+
if (extension.toLowerCase() !== '.aab') {
|
|
178
|
+
return outputPath;
|
|
179
|
+
}
|
|
180
|
+
return `${outputPath.slice(0, -extension.length)}.apk`;
|
|
181
|
+
}
|
|
177
182
|
/**
|
|
178
183
|
* Install `@expo/repack-app` in a sandbox directory and import it.
|
|
179
184
|
*/
|
|
@@ -99,11 +99,12 @@ function createRestoreCacheFunction() {
|
|
|
99
99
|
.parse((inputs.restore_keys.value ?? '').split(/[\r\n]+/))
|
|
100
100
|
.filter(key => key !== '');
|
|
101
101
|
const jobId = (0, nullthrows_1.default)(env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set');
|
|
102
|
+
const expoApiServerURL = (0, nullthrows_1.default)(stepsCtx.global.staticContext.expoApiServerURL, 'expoApiServerURL is not set');
|
|
102
103
|
const robotAccessToken = (0, nullthrows_1.default)(stepsCtx.global.staticContext.job.secrets?.robotAccessToken, 'robotAccessToken is not set');
|
|
103
104
|
const { archivePath, matchedKey } = await downloadCacheAsync({
|
|
104
105
|
logger,
|
|
105
106
|
jobId,
|
|
106
|
-
expoApiServerURL
|
|
107
|
+
expoApiServerURL,
|
|
107
108
|
robotAccessToken,
|
|
108
109
|
paths,
|
|
109
110
|
key,
|
|
@@ -80,6 +80,7 @@ function createSaveCacheFunction() {
|
|
|
80
80
|
.filter(path => path.length > 0);
|
|
81
81
|
const key = zod_1.default.string().parse(inputs.key.value);
|
|
82
82
|
const jobId = (0, nullthrows_1.default)(env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set');
|
|
83
|
+
const expoApiServerURL = (0, nullthrows_1.default)(stepsCtx.global.staticContext.expoApiServerURL, 'expoApiServerURL is not set');
|
|
83
84
|
const robotAccessToken = (0, nullthrows_1.default)(stepsCtx.global.staticContext.job.secrets?.robotAccessToken, 'robotAccessToken is not set');
|
|
84
85
|
const { archivePath } = await compressCacheAsync({
|
|
85
86
|
paths,
|
|
@@ -92,7 +93,7 @@ function createSaveCacheFunction() {
|
|
|
92
93
|
await uploadPublicCacheAsync({
|
|
93
94
|
logger,
|
|
94
95
|
jobId,
|
|
95
|
-
expoApiServerURL
|
|
96
|
+
expoApiServerURL,
|
|
96
97
|
robotAccessToken,
|
|
97
98
|
archivePath,
|
|
98
99
|
key,
|
|
@@ -105,7 +106,7 @@ function createSaveCacheFunction() {
|
|
|
105
106
|
await uploadCacheAsync({
|
|
106
107
|
logger,
|
|
107
108
|
jobId,
|
|
108
|
-
expoApiServerURL
|
|
109
|
+
expoApiServerURL,
|
|
109
110
|
robotAccessToken,
|
|
110
111
|
archivePath,
|
|
111
112
|
key,
|
|
@@ -26,6 +26,12 @@ function createStartIosSimulatorBuildFunction() {
|
|
|
26
26
|
defaultValue: 1,
|
|
27
27
|
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.NUMBER,
|
|
28
28
|
}),
|
|
29
|
+
steps_1.BuildStepInput.createProvider({
|
|
30
|
+
id: 'enable_accessibility_settings',
|
|
31
|
+
required: false,
|
|
32
|
+
defaultValue: false,
|
|
33
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.BOOLEAN,
|
|
34
|
+
}),
|
|
29
35
|
],
|
|
30
36
|
fn: async ({ logger }, { inputs, env }) => {
|
|
31
37
|
try {
|
|
@@ -45,9 +51,16 @@ function createStartIosSimulatorBuildFunction() {
|
|
|
45
51
|
}
|
|
46
52
|
const deviceIdentifierInput = inputs.device_identifier.value?.toString();
|
|
47
53
|
const originalDeviceIdentifier = deviceIdentifierInput ?? (await findMostGenericIphoneUuidAsync({ env }));
|
|
54
|
+
const enableAccessibilitySettings = Boolean(inputs.enable_accessibility_settings.value);
|
|
48
55
|
if (!originalDeviceIdentifier) {
|
|
49
56
|
throw new Error('Could not find an iPhone among available simulator devices.');
|
|
50
57
|
}
|
|
58
|
+
if (enableAccessibilitySettings) {
|
|
59
|
+
await IosSimulatorUtils_1.IosSimulatorUtils.enableAccessibilitySettingsAsync({
|
|
60
|
+
deviceIdentifier: originalDeviceIdentifier,
|
|
61
|
+
env,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
51
64
|
const { udid } = await IosSimulatorUtils_1.IosSimulatorUtils.startAsync({
|
|
52
65
|
deviceIdentifier: originalDeviceIdentifier,
|
|
53
66
|
env,
|
|
@@ -78,6 +91,12 @@ function createStartIosSimulatorBuildFunction() {
|
|
|
78
91
|
destinationDeviceName: cloneDeviceName,
|
|
79
92
|
env,
|
|
80
93
|
});
|
|
94
|
+
if (enableAccessibilitySettings) {
|
|
95
|
+
await IosSimulatorUtils_1.IosSimulatorUtils.enableAccessibilitySettingsAsync({
|
|
96
|
+
deviceIdentifier: cloneDeviceName,
|
|
97
|
+
env,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
81
100
|
const { udid: cloneUdid } = await IosSimulatorUtils_1.IosSimulatorUtils.startAsync({
|
|
82
101
|
deviceIdentifier: cloneDeviceName,
|
|
83
102
|
env,
|
|
@@ -39,6 +39,10 @@ export declare namespace IosSimulatorUtils {
|
|
|
39
39
|
destinationDeviceName: IosSimulatorName;
|
|
40
40
|
env: NodeJS.ProcessEnv;
|
|
41
41
|
}): Promise<void>;
|
|
42
|
+
export function enableAccessibilitySettingsAsync({ deviceIdentifier, env, }: {
|
|
43
|
+
deviceIdentifier: IosSimulatorUuid | IosSimulatorName;
|
|
44
|
+
env: NodeJS.ProcessEnv;
|
|
45
|
+
}): Promise<void>;
|
|
42
46
|
export function startAsync({ deviceIdentifier, env, }: {
|
|
43
47
|
deviceIdentifier: IosSimulatorUuid | IosSimulatorName;
|
|
44
48
|
env: NodeJS.ProcessEnv;
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.IosSimulatorUtils = void 0;
|
|
7
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
7
8
|
const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
|
|
8
9
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
10
|
const node_os_1 = __importDefault(require("node:os"));
|
|
@@ -37,6 +38,45 @@ var IosSimulatorUtils;
|
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
IosSimulatorUtils.cloneAsync = cloneAsync;
|
|
41
|
+
async function enableAccessibilitySettingsAsync({ deviceIdentifier, env, }) {
|
|
42
|
+
try {
|
|
43
|
+
const devices = await getAvailableDevicesAsync({ env, filter: 'available' });
|
|
44
|
+
const device = devices.find(device => device.isAvailable &&
|
|
45
|
+
(device.udid === deviceIdentifier || device.name === deviceIdentifier));
|
|
46
|
+
if (!device) {
|
|
47
|
+
throw new eas_build_job_1.UserError('EAS_IOS_SIMULATOR_NOT_FOUND', `Failed to find available iOS Simulator "${deviceIdentifier}" to update accessibility settings.`);
|
|
48
|
+
}
|
|
49
|
+
if (device.state !== 'Shutdown') {
|
|
50
|
+
throw new eas_build_job_1.UserError('EAS_IOS_SIMULATOR_NOT_SHUTDOWN', `Expected iOS Simulator "${deviceIdentifier}" to be shutdown before updating accessibility settings, but it is ${device.state}.`);
|
|
51
|
+
}
|
|
52
|
+
const plistPath = node_path_1.default.join(device.dataPath, 'Library', 'Preferences', 'com.apple.Accessibility.plist');
|
|
53
|
+
await node_fs_1.default.promises.mkdir(node_path_1.default.dirname(plistPath), { recursive: true });
|
|
54
|
+
const plistExists = await node_fs_1.default.promises
|
|
55
|
+
.access(plistPath)
|
|
56
|
+
.then(() => true)
|
|
57
|
+
.catch(() => false);
|
|
58
|
+
if (!plistExists) {
|
|
59
|
+
await (0, turtle_spawn_1.default)('plutil', ['-create', 'binary1', plistPath], { env });
|
|
60
|
+
}
|
|
61
|
+
for (const key of [
|
|
62
|
+
'AutomationEnabled',
|
|
63
|
+
'IgnoreAXServerEntitlements',
|
|
64
|
+
'AccessibilityEnabled',
|
|
65
|
+
'ApplicationAccessibilityEnabled',
|
|
66
|
+
]) {
|
|
67
|
+
await (0, turtle_spawn_1.default)('plutil', ['-replace', key, '-bool', 'true', plistPath], { env });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
if (err instanceof eas_build_job_1.ExpoError) {
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
throw new eas_build_job_1.SystemError('Failed to update iOS Simulator accessibility settings.', {
|
|
75
|
+
cause: err,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
IosSimulatorUtils.enableAccessibilitySettingsAsync = enableAccessibilitySettingsAsync;
|
|
40
80
|
async function startAsync({ deviceIdentifier, env, }) {
|
|
41
81
|
const bootstatusResult = await (0, turtle_spawn_1.default)('xcrun', ['simctl', 'bootstatus', deviceIdentifier, '-b'], {
|
|
42
82
|
env,
|
|
@@ -173,6 +173,11 @@ async function isEASUpdateConfigured(ctx) {
|
|
|
173
173
|
}
|
|
174
174
|
async function logDiffFingerprints({ resolvedRuntime, ctx, }) {
|
|
175
175
|
const { resolvedRuntimeVersion, resolvedFingerprintSources } = resolvedRuntime;
|
|
176
|
+
const buildId = ctx.env.EAS_BUILD_ID;
|
|
177
|
+
if (!buildId) {
|
|
178
|
+
ctx.logger.warn('Skipping fingerprint diff because EAS_BUILD_ID is not set');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
176
181
|
const fingerprintInfo = await ctx.graphqlClient
|
|
177
182
|
.query((0, gql_tada_1.graphql)(`
|
|
178
183
|
query GetFingerprintUrl($id: ID!) {
|
|
@@ -184,7 +189,7 @@ async function logDiffFingerprints({ resolvedRuntime, ctx, }) {
|
|
|
184
189
|
}
|
|
185
190
|
}
|
|
186
191
|
}
|
|
187
|
-
`), { id:
|
|
192
|
+
`), { id: buildId })
|
|
188
193
|
.toPromise();
|
|
189
194
|
if (fingerprintInfo.error) {
|
|
190
195
|
ctx.logger.warn('Failed to fetch current fingerprint info', fingerprintInfo.error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/build-tools",
|
|
3
|
-
"version": "20.
|
|
3
|
+
"version": "20.5.1",
|
|
4
4
|
"bugs": "https://github.com/expo/eas-cli/issues",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Expo <support@expo.io>",
|
|
@@ -38,14 +38,14 @@
|
|
|
38
38
|
"@expo/config": "55.0.10",
|
|
39
39
|
"@expo/config-plugins": "55.0.7",
|
|
40
40
|
"@expo/downloader": "20.0.0",
|
|
41
|
-
"@expo/eas-build-job": "20.1
|
|
41
|
+
"@expo/eas-build-job": "20.5.1",
|
|
42
42
|
"@expo/env": "^0.4.0",
|
|
43
43
|
"@expo/logger": "20.0.0",
|
|
44
44
|
"@expo/package-manager": "1.9.10",
|
|
45
45
|
"@expo/plist": "^0.2.0",
|
|
46
46
|
"@expo/results": "^1.0.0",
|
|
47
47
|
"@expo/spawn-async": "1.7.2",
|
|
48
|
-
"@expo/steps": "20.1
|
|
48
|
+
"@expo/steps": "20.5.1",
|
|
49
49
|
"@expo/template-file": "20.0.0",
|
|
50
50
|
"@expo/turtle-spawn": "20.0.0",
|
|
51
51
|
"@expo/xcpretty": "^4.3.1",
|
|
@@ -100,5 +100,5 @@
|
|
|
100
100
|
"typescript": "^5.5.4",
|
|
101
101
|
"uuid": "^9.0.1"
|
|
102
102
|
},
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "cd47185f29446299b7682d52cd917eb9a01038e7"
|
|
104
104
|
}
|