eas-cli 14.4.0 → 14.5.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/README.md +93 -91
- package/build/build/android/version.js +1 -1
- package/build/build/build.js +4 -3
- package/build/build/evaluateConfigWithEnvVarsAsync.js +10 -16
- package/build/build/ios/version.js +1 -1
- package/build/build/local.js +1 -1
- package/build/commands/build/list.d.ts +1 -0
- package/build/commands/build/list.js +4 -0
- package/build/commands/{worker → deploy}/alias.js +4 -4
- package/build/commands/{worker/deploy.js → deploy/index.js} +5 -5
- package/build/commands/env/exec.d.ts +1 -1
- package/build/commands/env/exec.js +18 -11
- package/build/commands/fingerprint/compare.js +14 -0
- package/build/commands/update/index.js +3 -6
- package/build/commands/update/roll-back-to-embedded.js +2 -2
- package/build/credentials/ios/appstore/resolveCredentials.js +6 -1
- package/build/graphql/generated.d.ts +188 -5
- package/build/graphql/generated.js +9 -1
- package/build/graphql/mutations/FingerprintMutation.d.ts +9 -0
- package/build/graphql/mutations/FingerprintMutation.js +29 -0
- package/build/project/publish.d.ts +4 -4
- package/build/project/publish.js +9 -8
- package/build/project/resolveRuntimeVersionAsync.d.ts +4 -4
- package/build/project/resolveRuntimeVersionAsync.js +4 -4
- package/build/worker/upload.js +19 -3
- package/oclif.manifest.json +158 -152
- package/package.json +5 -5
- /package/build/commands/{worker → deploy}/alias.d.ts +0 -0
- /package/build/commands/{worker/deploy.d.ts → deploy/index.d.ts} +0 -0
|
@@ -126,7 +126,7 @@ async function resolveRemoteVersionCodeAsync(graphqlClient, { projectDir, projec
|
|
|
126
126
|
}
|
|
127
127
|
else {
|
|
128
128
|
if (localVersions.appBuildVersion) {
|
|
129
|
-
log_1.default.
|
|
129
|
+
log_1.default.log(chalk_1.default.green('No remote versions are configured for this project, versionCode will be initialized based on the value from the local project.'));
|
|
130
130
|
currentBuildVersion = localVersions.appBuildVersion;
|
|
131
131
|
}
|
|
132
132
|
else {
|
package/build/build/build.js
CHANGED
|
@@ -464,21 +464,22 @@ async function computeAndMaybeUploadFingerprintFromExpoUpdatesAsync(ctx) {
|
|
|
464
464
|
* It's ok for fingerprintSources or runtimeVersion to be empty
|
|
465
465
|
* fingerprintSources only exist if the project is using runtimeVersion.policy: fingerprint
|
|
466
466
|
*/
|
|
467
|
-
if (!resolvedRuntimeVersion.
|
|
467
|
+
if (!resolvedRuntimeVersion.expoUpdatesRuntimeFingerprint ||
|
|
468
|
+
!resolvedRuntimeVersion.runtimeVersion) {
|
|
468
469
|
return {
|
|
469
470
|
runtimeVersion: resolvedRuntimeVersion.runtimeVersion ?? undefined,
|
|
470
471
|
};
|
|
471
472
|
}
|
|
472
473
|
const uploadedFingerprint = await (0, maybeUploadFingerprintAsync_1.maybeUploadFingerprintAsync)({
|
|
473
474
|
hash: resolvedRuntimeVersion.runtimeVersion,
|
|
474
|
-
fingerprint: resolvedRuntimeVersion.
|
|
475
|
+
fingerprint: resolvedRuntimeVersion.expoUpdatesRuntimeFingerprint,
|
|
475
476
|
graphqlClient: ctx.graphqlClient,
|
|
476
477
|
localBuildMode: ctx.localBuildOptions.localBuildMode,
|
|
477
478
|
});
|
|
478
479
|
return {
|
|
479
480
|
runtimeVersion: uploadedFingerprint.hash,
|
|
480
481
|
fingerprintSource: uploadedFingerprint.fingerprintSource,
|
|
481
|
-
fingerprintHash: resolvedRuntimeVersion.
|
|
482
|
+
fingerprintHash: resolvedRuntimeVersion.expoUpdatesRuntimeFingerprintHash ?? undefined,
|
|
482
483
|
};
|
|
483
484
|
}
|
|
484
485
|
async function computeAndMaybeUploadFingerprintWithoutExpoUpdatesAsync(ctx, { debug } = {}) {
|
|
@@ -43,10 +43,10 @@ async function resolveEnvVarsAsync({ buildProfile, buildProfileName, graphqlClie
|
|
|
43
43
|
.filter(({ name, value }) => name && value)
|
|
44
44
|
.map(({ name, value }) => [name, value]));
|
|
45
45
|
if (Object.keys(serverEnvVars).length > 0) {
|
|
46
|
-
log_1.default.log(`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS
|
|
46
|
+
log_1.default.log(`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS: ${Object.keys(serverEnvVars).join(', ')}.`);
|
|
47
47
|
}
|
|
48
48
|
else {
|
|
49
|
-
log_1.default.log(`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS
|
|
49
|
+
log_1.default.log(`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS.`);
|
|
50
50
|
}
|
|
51
51
|
if (buildProfile.env && Object.keys(buildProfile.env).length > 0) {
|
|
52
52
|
log_1.default.log(`Environment variables loaded from the "${buildProfileName}" build profile "env" configuration: ${buildProfile.env && Object.keys(buildProfile.env).join(', ')}.`);
|
|
@@ -56,7 +56,7 @@ async function resolveEnvVarsAsync({ buildProfile, buildProfileName, graphqlClie
|
|
|
56
56
|
Object.keys(serverEnvVars).length > 0) {
|
|
57
57
|
const overlappingKeys = Object.keys(serverEnvVars).filter(key => buildProfile.env && Object.keys(buildProfile.env).includes(key));
|
|
58
58
|
if (overlappingKeys.length > 0) {
|
|
59
|
-
log_1.default.warn(`The following environment variables are defined in both the "${buildProfileName}" build profile "env" configuration and the "${environment.toLowerCase()}" environment on EAS
|
|
59
|
+
log_1.default.warn(`The following environment variables are defined in both the "${buildProfileName}" build profile "env" configuration and the "${environment.toLowerCase()}" environment on EAS: ${overlappingKeys.join(', ')}. The values from the build profile configuration will be used.`);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
log_1.default.newLine();
|
|
@@ -70,17 +70,11 @@ async function resolveEnvVarsAsync({ buildProfile, buildProfileName, graphqlClie
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
function resolveSuggestedEnvironmentForBuildProfileConfiguration(buildProfile) {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
log_1.default.log(`We detected that you are building the development client. Resolving the environment for environment variables used during the build to "development". ${setEnvironmentMessage}`);
|
|
81
|
-
return generated_1.EnvironmentVariableEnvironment.Development;
|
|
82
|
-
}
|
|
83
|
-
log_1.default.log(`We detected that you are building for the "internal" distribution. Resolving the environment for environment variables used during the build to "preview". ${setEnvironmentMessage}`);
|
|
84
|
-
return generated_1.EnvironmentVariableEnvironment.Preview;
|
|
85
|
-
}
|
|
73
|
+
const environment = buildProfile.distribution === 'store'
|
|
74
|
+
? generated_1.EnvironmentVariableEnvironment.Production
|
|
75
|
+
: buildProfile.developmentClient
|
|
76
|
+
? generated_1.EnvironmentVariableEnvironment.Development
|
|
77
|
+
: generated_1.EnvironmentVariableEnvironment.Preview;
|
|
78
|
+
log_1.default.log(`Resolved "${environment.toLowerCase()}" environment for the build. ${(0, log_1.learnMore)('https://docs.expo.dev/eas/environment-variables/#setting-the-environment-for-your-builds')}`);
|
|
79
|
+
return environment;
|
|
86
80
|
}
|
|
@@ -214,7 +214,7 @@ async function resolveRemoteBuildNumberAsync(graphqlClient, { projectDir, projec
|
|
|
214
214
|
}
|
|
215
215
|
else {
|
|
216
216
|
if (localBuildNumber) {
|
|
217
|
-
log_1.default.
|
|
217
|
+
log_1.default.log(chalk_1.default.green('No remote versions are configured for this project, buildNumber will be initialized based on the value from the local project.'));
|
|
218
218
|
currentBuildVersion = localBuildNumber;
|
|
219
219
|
}
|
|
220
220
|
else {
|
package/build/build/local.js
CHANGED
|
@@ -7,7 +7,7 @@ const semver_1 = tslib_1.__importDefault(require("semver"));
|
|
|
7
7
|
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
8
8
|
const ora_1 = require("../ora");
|
|
9
9
|
const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
|
|
10
|
-
const PLUGIN_PACKAGE_VERSION = '1.0.
|
|
10
|
+
const PLUGIN_PACKAGE_VERSION = '1.0.163';
|
|
11
11
|
var LocalBuildMode;
|
|
12
12
|
(function (LocalBuildMode) {
|
|
13
13
|
/**
|
|
@@ -20,6 +20,7 @@ export default class BuildList extends EasCommand {
|
|
|
20
20
|
'app-identifier': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
21
21
|
'build-profile': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
22
22
|
'git-commit-hash': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
23
|
+
'fingerprint-hash': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
23
24
|
};
|
|
24
25
|
static contextDefinition: {
|
|
25
26
|
vcsClient: import("../../commandUtils/context/VcsClientContextField").default;
|
|
@@ -58,6 +58,9 @@ class BuildList extends EasCommand_1.default {
|
|
|
58
58
|
aliases: ['gitCommitHash'],
|
|
59
59
|
description: 'Filter only builds created with the specified git commit hash',
|
|
60
60
|
}),
|
|
61
|
+
'fingerprint-hash': core_1.Flags.string({
|
|
62
|
+
description: 'Filter only builds with the specified fingerprint hash',
|
|
63
|
+
}),
|
|
61
64
|
...pagination_1.EasPaginatedQueryFlags,
|
|
62
65
|
limit: (0, pagination_1.getLimitFlagWithCustomValues)({ defaultTo: 10, limit: queries_1.BUILDS_LIMIT }),
|
|
63
66
|
...flags_1.EasNonInteractiveAndJsonFlags,
|
|
@@ -107,6 +110,7 @@ class BuildList extends EasCommand_1.default {
|
|
|
107
110
|
buildProfile: flags['build-profile'],
|
|
108
111
|
gitCommitHash: flags['git-commit-hash'],
|
|
109
112
|
simulator: flags.simulator,
|
|
113
|
+
fingerprintHash: flags['fingerprint-hash'],
|
|
110
114
|
},
|
|
111
115
|
paginatedQueryOptions,
|
|
112
116
|
});
|
|
@@ -12,9 +12,9 @@ const json_1 = require("../../utils/json");
|
|
|
12
12
|
const deployment_1 = require("../../worker/deployment");
|
|
13
13
|
const logs_1 = require("../../worker/utils/logs");
|
|
14
14
|
class WorkerAlias extends EasCommand_1.default {
|
|
15
|
-
static description = 'Assign deployment aliases';
|
|
16
|
-
static aliases = ['
|
|
17
|
-
static state = '
|
|
15
|
+
static description = 'Assign deployment aliases.';
|
|
16
|
+
static aliases = ['worker:alias', 'deploy:promote'];
|
|
17
|
+
static state = 'preview';
|
|
18
18
|
static flags = {
|
|
19
19
|
prod: core_1.Flags.boolean({
|
|
20
20
|
aliases: ['production'],
|
|
@@ -44,7 +44,7 @@ class WorkerAlias extends EasCommand_1.default {
|
|
|
44
44
|
if (flags.json) {
|
|
45
45
|
(0, json_1.enableJsonOutput)();
|
|
46
46
|
}
|
|
47
|
-
log_1.default.warn('EAS Hosting is still in
|
|
47
|
+
log_1.default.warn('EAS Hosting is still in preview and subject to changes.');
|
|
48
48
|
const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, } = await this.getContextAsync(WorkerAlias, {
|
|
49
49
|
nonInteractive: true,
|
|
50
50
|
withServerSideEnvironment: null,
|
|
@@ -21,10 +21,10 @@ const isDirectory = (directoryPath) => node_fs_1.default.promises
|
|
|
21
21
|
.then(stat => stat.isDirectory())
|
|
22
22
|
.catch(() => false);
|
|
23
23
|
class WorkerDeploy extends EasCommand_1.default {
|
|
24
|
-
static description = 'Deploy your Expo web build';
|
|
25
|
-
static aliases = ['deploy'];
|
|
24
|
+
static description = 'Deploy your Expo Router web build and API Routes.';
|
|
25
|
+
static aliases = ['worker:deploy'];
|
|
26
26
|
static usage = [(0, chalk_1.default) `deploy {dim [options]}`, `deploy --prod`];
|
|
27
|
-
static state = '
|
|
27
|
+
static state = 'preview';
|
|
28
28
|
static flags = {
|
|
29
29
|
prod: core_1.Flags.boolean({
|
|
30
30
|
aliases: ['production'],
|
|
@@ -62,7 +62,7 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
62
62
|
if (flags.json) {
|
|
63
63
|
(0, json_1.enableJsonOutput)();
|
|
64
64
|
}
|
|
65
|
-
log_1.default.warn('EAS Hosting is still in
|
|
65
|
+
log_1.default.warn('EAS Hosting is still in preview and subject to changes.');
|
|
66
66
|
const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, projectDir, } = await this.getContextAsync(WorkerDeploy, { ...flags, withServerSideEnvironment: null });
|
|
67
67
|
const projectDist = await resolveExportedProjectAsync(flags, projectDir);
|
|
68
68
|
const { projectId } = await getDynamicPrivateProjectConfigAsync();
|
|
@@ -331,7 +331,7 @@ function logExportedProjectInfo(project) {
|
|
|
331
331
|
// Only show the timestamp for exports older than 1 minute
|
|
332
332
|
if (project.modifiedAt && Date.now() - project.modifiedAt.getTime() > 60000) {
|
|
333
333
|
modifiedAgo = ` - exported ${(0, timeago_js_1.format)(project.modifiedAt)}`;
|
|
334
|
-
log_1.default.warn(`> Project export: ${project.type}${modifiedAgo}
|
|
334
|
+
log_1.default.warn(`> Project export: ${project.type}${modifiedAgo}`);
|
|
335
335
|
}
|
|
336
336
|
else {
|
|
337
337
|
log_1.default.log((0, chalk_1.default) `{dim > Project export: ${project.type}}`);
|
|
@@ -16,8 +16,8 @@ export default class EnvExec extends EasCommand {
|
|
|
16
16
|
private isNonInteractive;
|
|
17
17
|
runAsync(): Promise<void>;
|
|
18
18
|
private sanitizeFlagsAndArgs;
|
|
19
|
-
private runCommandNonInteractiveWithEnvVarsAsync;
|
|
20
19
|
protected catch(err: Error): Promise<any>;
|
|
20
|
+
private runCommandNonInteractiveWithEnvVarsAsync;
|
|
21
21
|
private runCommandWithEnvVarsAsync;
|
|
22
22
|
private loadEnvironmentVariablesAsync;
|
|
23
23
|
}
|
|
@@ -67,21 +67,17 @@ class EnvExec extends EasCommand_1.default {
|
|
|
67
67
|
if (!(0, variableUtils_1.isEnvironment)(environment)) {
|
|
68
68
|
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
|
|
69
69
|
}
|
|
70
|
+
const firstChar = bash_command[0];
|
|
71
|
+
const lastChar = bash_command[bash_command.length - 1];
|
|
72
|
+
const cleanCommand = (firstChar === '"' && lastChar === '"') || (firstChar === "'" && lastChar === "'")
|
|
73
|
+
? bash_command.slice(1, -1)
|
|
74
|
+
: bash_command;
|
|
70
75
|
return {
|
|
71
76
|
nonInteractive: rawFlags['non-interactive'],
|
|
72
77
|
environment,
|
|
73
|
-
command:
|
|
78
|
+
command: cleanCommand,
|
|
74
79
|
};
|
|
75
80
|
}
|
|
76
|
-
async runCommandNonInteractiveWithEnvVarsAsync({ command, environmentVariables, }) {
|
|
77
|
-
await (0, spawn_async_1.default)('bash', ['-c', command], {
|
|
78
|
-
stdio: 'inherit',
|
|
79
|
-
env: {
|
|
80
|
-
...process.env,
|
|
81
|
-
...environmentVariables,
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
81
|
// eslint-disable-next-line async-protect/async-suffix
|
|
86
82
|
async catch(err) {
|
|
87
83
|
// when in non-interactive, make the behavior of this command a pure passthrough, outputting only the subprocess' stdout and stderr and exiting with the
|
|
@@ -93,9 +89,20 @@ class EnvExec extends EasCommand_1.default {
|
|
|
93
89
|
await super.catch(err);
|
|
94
90
|
}
|
|
95
91
|
}
|
|
92
|
+
async runCommandNonInteractiveWithEnvVarsAsync({ command, environmentVariables, }) {
|
|
93
|
+
await (0, spawn_async_1.default)(command, [], {
|
|
94
|
+
shell: true,
|
|
95
|
+
stdio: 'inherit',
|
|
96
|
+
env: {
|
|
97
|
+
...process.env,
|
|
98
|
+
...environmentVariables,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
96
102
|
async runCommandWithEnvVarsAsync({ command, environmentVariables, }) {
|
|
97
103
|
log_1.default.log(`Running command: ${chalk_1.default.bold(command)}`);
|
|
98
|
-
const spawnPromise = (0, spawn_async_1.default)(
|
|
104
|
+
const spawnPromise = (0, spawn_async_1.default)(command, [], {
|
|
105
|
+
shell: true,
|
|
99
106
|
stdio: ['inherit', 'pipe', 'pipe'],
|
|
100
107
|
env: {
|
|
101
108
|
...process.env,
|
|
@@ -9,9 +9,11 @@ const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasComm
|
|
|
9
9
|
const builds_1 = require("../../commandUtils/builds");
|
|
10
10
|
const flags_1 = require("../../commandUtils/flags");
|
|
11
11
|
const generated_1 = require("../../graphql/generated");
|
|
12
|
+
const FingerprintMutation_1 = require("../../graphql/mutations/FingerprintMutation");
|
|
12
13
|
const BuildQuery_1 = require("../../graphql/queries/BuildQuery");
|
|
13
14
|
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
14
15
|
const ora_1 = require("../../ora");
|
|
16
|
+
const maybeUploadFingerprintAsync_1 = require("../../project/maybeUploadFingerprintAsync");
|
|
15
17
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
16
18
|
const workflow_1 = require("../../project/workflow");
|
|
17
19
|
const prompts_1 = require("../../prompts");
|
|
@@ -80,6 +82,18 @@ class FingerprintCompare extends EasCommand_1.default {
|
|
|
80
82
|
log_1.default.error('Project fingerprints can only be computed for projects with SDK 52 or higher');
|
|
81
83
|
return;
|
|
82
84
|
}
|
|
85
|
+
const uploadedFingerprint = await (0, maybeUploadFingerprintAsync_1.maybeUploadFingerprintAsync)({
|
|
86
|
+
hash: fingerprint.hash,
|
|
87
|
+
fingerprint: {
|
|
88
|
+
fingerprintSources: fingerprint.sources,
|
|
89
|
+
isDebugFingerprintSource: log_1.default.isDebug,
|
|
90
|
+
},
|
|
91
|
+
graphqlClient,
|
|
92
|
+
});
|
|
93
|
+
await FingerprintMutation_1.FingerprintMutation.createFingerprintAsync(graphqlClient, projectId, {
|
|
94
|
+
hash: uploadedFingerprint.hash,
|
|
95
|
+
source: uploadedFingerprint.fingerprintSource,
|
|
96
|
+
});
|
|
83
97
|
if (fingerprint.hash === projectFingerprint.hash) {
|
|
84
98
|
log_1.default.log(`✅ Project fingerprint matches build`);
|
|
85
99
|
return;
|
|
@@ -269,10 +269,10 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
269
269
|
const runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMappingFromExpoUpdates = await Promise.all(runtimeToPlatformsAndFingerprintInfoMapping.map(async (info) => {
|
|
270
270
|
return {
|
|
271
271
|
...info,
|
|
272
|
-
|
|
272
|
+
expoUpdatesRuntimeFingerprintSource: info.expoUpdatesRuntimeFingerprint
|
|
273
273
|
? (await (0, maybeUploadFingerprintAsync_1.maybeUploadFingerprintAsync)({
|
|
274
274
|
hash: info.runtimeVersion,
|
|
275
|
-
fingerprint: info.
|
|
275
|
+
fingerprint: info.expoUpdatesRuntimeFingerprint,
|
|
276
276
|
graphqlClient,
|
|
277
277
|
})).fingerprintSource ?? null
|
|
278
278
|
: null,
|
|
@@ -296,7 +296,7 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
296
296
|
const gitCommitHash = await vcsClient.getCommitHashAsync();
|
|
297
297
|
const isGitWorkingTreeDirty = await vcsClient.hasUncommittedChangesAsync();
|
|
298
298
|
// Sort the updates into different groups based on their platform specific runtime versions
|
|
299
|
-
const updateGroups = runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.map(({ runtimeVersion, platforms,
|
|
299
|
+
const updateGroups = runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.map(({ runtimeVersion, platforms, fingerprintInfoGroup }) => {
|
|
300
300
|
const localUpdateInfoGroup = Object.fromEntries(platforms.map(platform => [
|
|
301
301
|
platform,
|
|
302
302
|
unsortedUpdateInfoGroups[platform],
|
|
@@ -323,9 +323,6 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
323
323
|
branchId: branch.id,
|
|
324
324
|
updateInfoGroup: localUpdateInfoGroup,
|
|
325
325
|
rolloutInfoGroup: localRolloutInfoGroup,
|
|
326
|
-
runtimeFingerprintSource: fingerprintSource
|
|
327
|
-
? (0, graphql_1.transformFingerprintSource)(fingerprintSource)
|
|
328
|
-
: null,
|
|
329
326
|
fingerprintInfoGroup: transformedFingerprintInfoGroup,
|
|
330
327
|
runtimeVersion,
|
|
331
328
|
message: updateMessage,
|
|
@@ -123,8 +123,8 @@ class UpdateRollBackToEmbedded extends EasCommand_1.default {
|
|
|
123
123
|
platform,
|
|
124
124
|
runtimeVersionInfo: {
|
|
125
125
|
runtimeVersion: selectedRuntime,
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
expoUpdatesRuntimeFingerprint: null,
|
|
127
|
+
expoUpdatesRuntimeFingerprintHash: null,
|
|
128
128
|
},
|
|
129
129
|
})));
|
|
130
130
|
let newUpdates;
|
|
@@ -162,13 +162,18 @@ async function promptUsernameAsync() {
|
|
|
162
162
|
// Get the email address that was last used and set it as
|
|
163
163
|
// the default value for quicker authentication.
|
|
164
164
|
const lastAppleId = await getCachedUsernameAsync();
|
|
165
|
-
|
|
165
|
+
let { username } = await (0, prompts_1.promptAsync)({
|
|
166
166
|
type: 'text',
|
|
167
167
|
name: 'username',
|
|
168
168
|
message: `Apple ID:`,
|
|
169
169
|
validate: (val) => val !== '',
|
|
170
170
|
initial: lastAppleId ?? undefined,
|
|
171
171
|
});
|
|
172
|
+
// https://github.com/expo/eas-cli/issues/2254
|
|
173
|
+
// user got an invalid unprintable character in their username, which was saved to cache and used to prefill the prompt
|
|
174
|
+
// which made them accept the prefilled value not knowing it contains the character and fail to log in
|
|
175
|
+
// this replace makes sure no such characters are used or cached
|
|
176
|
+
username = username.replace(/[\x00-\x1F]/gi, '');
|
|
172
177
|
if (username && username !== lastAppleId) {
|
|
173
178
|
await cacheUsernameAsync(username);
|
|
174
179
|
}
|