eas-cli 12.4.0 → 12.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 +60 -60
- package/build/build/local.js +19 -11
- package/build/commands/submit/internal.d.ts +24 -0
- package/build/commands/submit/internal.js +168 -0
- package/build/commands/worker/alias.js +4 -6
- package/build/commands/worker/deploy.d.ts +51 -1
- package/build/commands/worker/deploy.js +30 -19
- package/build/graphql/generated.d.ts +149 -25
- package/build/graphql/generated.js +1 -0
- package/build/graphql/queries/AppStoreConnectApiKeyQuery.d.ts +8 -0
- package/build/graphql/queries/AppStoreConnectApiKeyQuery.js +32 -0
- package/build/graphql/queries/GoogleServiceAccountKeyQuery.d.ts +6 -0
- package/build/graphql/queries/GoogleServiceAccountKeyQuery.js +25 -0
- package/build/project/android/applicationId.js +3 -3
- package/build/project/expoConfig.js +0 -15
- package/build/project/ios/bundleIdentifier.js +3 -3
- package/build/submit/ArchiveSource.js +15 -1
- package/build/submit/BaseSubmitter.d.ts +1 -0
- package/build/submit/BaseSubmitter.js +5 -2
- package/build/submit/android/AndroidSubmitCommand.d.ts +2 -2
- package/build/submit/android/AndroidSubmitCommand.js +1 -1
- package/build/submit/ios/IosSubmitCommand.d.ts +2 -2
- package/build/submit/ios/IosSubmitCommand.js +1 -1
- package/build/submit/submit.js +2 -1
- package/build/submit/utils/builds.js +22 -10
- package/build/worker/deployment.js +12 -8
- package/oclif.manifest.json +63 -20
- package/package.json +7 -6
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
6
|
+
const eas_json_1 = require("@expo/eas-json");
|
|
7
|
+
const core_1 = require("@oclif/core");
|
|
8
|
+
const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
|
|
9
|
+
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
10
|
+
const generated_1 = require("../../graphql/generated");
|
|
11
|
+
const AppStoreConnectApiKeyQuery_1 = require("../../graphql/queries/AppStoreConnectApiKeyQuery");
|
|
12
|
+
const GoogleServiceAccountKeyQuery_1 = require("../../graphql/queries/GoogleServiceAccountKeyQuery");
|
|
13
|
+
const AndroidSubmitCommand_1 = tslib_1.__importDefault(require("../../submit/android/AndroidSubmitCommand"));
|
|
14
|
+
const context_1 = require("../../submit/context");
|
|
15
|
+
const IosSubmitCommand_1 = tslib_1.__importDefault(require("../../submit/ios/IosSubmitCommand"));
|
|
16
|
+
const json_1 = require("../../utils/json");
|
|
17
|
+
const gitNoCommit_1 = tslib_1.__importDefault(require("../../vcs/clients/gitNoCommit"));
|
|
18
|
+
/**
|
|
19
|
+
* This command will be run on the EAS workers.
|
|
20
|
+
* This command resolves credentials and other
|
|
21
|
+
* configuration, that normally would be included in the
|
|
22
|
+
* job and metadata objects, and prints them to stdout.
|
|
23
|
+
*/
|
|
24
|
+
class SubmitInternal extends EasCommand_1.default {
|
|
25
|
+
async runAsync() {
|
|
26
|
+
const { flags } = await this.parse(_a);
|
|
27
|
+
// This command is always run with implicit --non-interactive and --json options
|
|
28
|
+
(0, json_1.enableJsonOutput)();
|
|
29
|
+
const { loggedIn: { actor, graphqlClient }, privateProjectConfig: { exp, projectId, projectDir }, analytics, vcsClient, } = await this.getContextAsync(_a, {
|
|
30
|
+
nonInteractive: true,
|
|
31
|
+
vcsClientOverride: new gitNoCommit_1.default(),
|
|
32
|
+
});
|
|
33
|
+
const submissionProfile = await eas_json_1.EasJsonUtils.getSubmitProfileAsync(eas_json_1.EasJsonAccessor.fromProjectPath(projectDir), flags.platform, flags.profile);
|
|
34
|
+
const ctx = await (0, context_1.createSubmissionContextAsync)({
|
|
35
|
+
platform: flags.platform,
|
|
36
|
+
projectDir,
|
|
37
|
+
profile: submissionProfile,
|
|
38
|
+
archiveFlags: {
|
|
39
|
+
id: flags.id,
|
|
40
|
+
},
|
|
41
|
+
nonInteractive: true,
|
|
42
|
+
isVerboseFastlaneEnabled: false,
|
|
43
|
+
actor,
|
|
44
|
+
graphqlClient,
|
|
45
|
+
analytics,
|
|
46
|
+
exp,
|
|
47
|
+
projectId,
|
|
48
|
+
vcsClient,
|
|
49
|
+
specifiedProfile: flags.profile,
|
|
50
|
+
});
|
|
51
|
+
let config;
|
|
52
|
+
if (ctx.platform === eas_build_job_1.Platform.IOS) {
|
|
53
|
+
const command = new IosSubmitCommand_1.default(ctx);
|
|
54
|
+
const submitter = await command.runAsync();
|
|
55
|
+
const mutationInput = await submitter.getSubmissionInputAsync();
|
|
56
|
+
const iosConfig = mutationInput.submissionConfig;
|
|
57
|
+
const ascApiKeyJson = await getAppStoreConnectApiKeyJsonAsync({
|
|
58
|
+
iosConfig,
|
|
59
|
+
graphqlClient,
|
|
60
|
+
});
|
|
61
|
+
const configInput = {
|
|
62
|
+
ascAppIdentifier: iosConfig.ascAppIdentifier,
|
|
63
|
+
isVerboseFastlaneEnabled: iosConfig.isVerboseFastlaneEnabled ?? undefined,
|
|
64
|
+
...(ascApiKeyJson
|
|
65
|
+
? { ascApiJsonKey: ascApiKeyJson }
|
|
66
|
+
: {
|
|
67
|
+
appleIdUsername: (0, nullthrows_1.default)(iosConfig.appleIdUsername),
|
|
68
|
+
appleAppSpecificPassword: (0, nullthrows_1.default)(iosConfig.appleAppSpecificPassword),
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
config = eas_build_job_1.SubmissionConfig.Ios.SchemaZ.parse(configInput);
|
|
72
|
+
}
|
|
73
|
+
else if (ctx.platform === eas_build_job_1.Platform.ANDROID) {
|
|
74
|
+
const command = new AndroidSubmitCommand_1.default(ctx);
|
|
75
|
+
const submitter = await command.runAsync();
|
|
76
|
+
const mutationInput = await submitter.getSubmissionInputAsync();
|
|
77
|
+
const androidConfig = mutationInput.submissionConfig;
|
|
78
|
+
const changesNotSentForReview = androidConfig.changesNotSentForReview ?? undefined;
|
|
79
|
+
const releaseStatus = androidConfig.releaseStatus
|
|
80
|
+
? graphQlReleaseStatusToConfigReleaseStatus[androidConfig.releaseStatus]
|
|
81
|
+
: undefined;
|
|
82
|
+
const googleServiceAccountKeyJson = (0, nullthrows_1.default)(await getGoogleServiceAccountKeyJsonAsync({
|
|
83
|
+
androidConfig,
|
|
84
|
+
graphqlClient,
|
|
85
|
+
}));
|
|
86
|
+
const track = graphQlTrackToConfigTrack[androidConfig.track];
|
|
87
|
+
const configInput = {
|
|
88
|
+
changesNotSentForReview,
|
|
89
|
+
googleServiceAccountKeyJson,
|
|
90
|
+
track,
|
|
91
|
+
...(releaseStatus === eas_build_job_1.SubmissionConfig.Android.ReleaseStatus.IN_PROGRESS
|
|
92
|
+
? {
|
|
93
|
+
releaseStatus: eas_build_job_1.SubmissionConfig.Android.ReleaseStatus.IN_PROGRESS,
|
|
94
|
+
rollout: androidConfig.rollout ?? undefined,
|
|
95
|
+
}
|
|
96
|
+
: { releaseStatus }),
|
|
97
|
+
};
|
|
98
|
+
config = eas_build_job_1.SubmissionConfig.Android.SchemaZ.parse(configInput);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
throw new Error(`Unsupported platform: ${ctx.platform}`);
|
|
102
|
+
}
|
|
103
|
+
(0, json_1.printJsonOnlyOutput)({ config });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
_a = SubmitInternal;
|
|
107
|
+
SubmitInternal.hidden = true;
|
|
108
|
+
SubmitInternal.flags = {
|
|
109
|
+
platform: core_1.Flags.enum({
|
|
110
|
+
options: [eas_build_job_1.Platform.ANDROID, eas_build_job_1.Platform.IOS],
|
|
111
|
+
required: true,
|
|
112
|
+
}),
|
|
113
|
+
profile: core_1.Flags.string({
|
|
114
|
+
description: 'Name of the submit profile from eas.json. Defaults to "production" if defined in eas.json.',
|
|
115
|
+
}),
|
|
116
|
+
id: core_1.Flags.string({
|
|
117
|
+
description: 'ID of the build to submit',
|
|
118
|
+
required: true,
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
SubmitInternal.contextDefinition = {
|
|
122
|
+
..._a.ContextOptions.LoggedIn,
|
|
123
|
+
..._a.ContextOptions.ProjectConfig,
|
|
124
|
+
..._a.ContextOptions.ProjectDir,
|
|
125
|
+
..._a.ContextOptions.Analytics,
|
|
126
|
+
..._a.ContextOptions.Vcs,
|
|
127
|
+
};
|
|
128
|
+
exports.default = SubmitInternal;
|
|
129
|
+
async function getGoogleServiceAccountKeyJsonAsync({ androidConfig, graphqlClient, }) {
|
|
130
|
+
if (androidConfig.googleServiceAccountKeyJson) {
|
|
131
|
+
return androidConfig.googleServiceAccountKeyJson;
|
|
132
|
+
}
|
|
133
|
+
else if (androidConfig.googleServiceAccountKeyId) {
|
|
134
|
+
const key = await GoogleServiceAccountKeyQuery_1.GoogleServiceAccountKeyQuery.getByIdAsync(graphqlClient, androidConfig.googleServiceAccountKeyId);
|
|
135
|
+
return key.keyJson;
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
async function getAppStoreConnectApiKeyJsonAsync({ iosConfig, graphqlClient, }) {
|
|
140
|
+
if (iosConfig.ascApiKey) {
|
|
141
|
+
return JSON.stringify({
|
|
142
|
+
key_id: iosConfig.ascApiKey.keyIdentifier,
|
|
143
|
+
issuer_id: iosConfig.ascApiKey.issuerIdentifier,
|
|
144
|
+
key: iosConfig.ascApiKey.keyP8,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else if (iosConfig.ascApiKeyId) {
|
|
148
|
+
const key = await AppStoreConnectApiKeyQuery_1.AppStoreConnectApiKeyQuery.getByIdAsync(graphqlClient, iosConfig.ascApiKeyId);
|
|
149
|
+
return JSON.stringify({
|
|
150
|
+
key_id: key.keyIdentifier,
|
|
151
|
+
issuer_id: key.issuerIdentifier,
|
|
152
|
+
key: key.keyP8,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
const graphQlReleaseStatusToConfigReleaseStatus = {
|
|
158
|
+
[generated_1.SubmissionAndroidReleaseStatus.Draft]: eas_build_job_1.SubmissionConfig.Android.ReleaseStatus.DRAFT,
|
|
159
|
+
[generated_1.SubmissionAndroidReleaseStatus.InProgress]: eas_build_job_1.SubmissionConfig.Android.ReleaseStatus.IN_PROGRESS,
|
|
160
|
+
[generated_1.SubmissionAndroidReleaseStatus.Completed]: eas_build_job_1.SubmissionConfig.Android.ReleaseStatus.COMPLETED,
|
|
161
|
+
[generated_1.SubmissionAndroidReleaseStatus.Halted]: eas_build_job_1.SubmissionConfig.Android.ReleaseStatus.HALTED,
|
|
162
|
+
};
|
|
163
|
+
const graphQlTrackToConfigTrack = {
|
|
164
|
+
[generated_1.SubmissionAndroidTrack.Production]: eas_build_job_1.SubmissionConfig.Android.ReleaseTrack.PRODUCTION,
|
|
165
|
+
[generated_1.SubmissionAndroidTrack.Beta]: eas_build_job_1.SubmissionConfig.Android.ReleaseTrack.BETA,
|
|
166
|
+
[generated_1.SubmissionAndroidTrack.Alpha]: eas_build_job_1.SubmissionConfig.Android.ReleaseTrack.ALPHA,
|
|
167
|
+
[generated_1.SubmissionAndroidTrack.Internal]: eas_build_job_1.SubmissionConfig.Android.ReleaseTrack.INTERNAL,
|
|
168
|
+
};
|
|
@@ -14,14 +14,12 @@ const deployment_1 = require("../../worker/deployment");
|
|
|
14
14
|
const logs_1 = require("../../worker/utils/logs");
|
|
15
15
|
class WorkerAlias extends EasCommand_1.default {
|
|
16
16
|
async runAsync() {
|
|
17
|
-
// NOTE(cedric): `Log.warn` uses `console.log`, which is incorrect when running with `--json`
|
|
18
|
-
// eslint-disable-next-line no-console
|
|
19
|
-
console.warn(chalk_1.default.yellow('EAS Worker Deployments are in beta and subject to breaking changes.'));
|
|
20
17
|
const { flags: rawFlags } = await this.parse(_a);
|
|
21
18
|
const flags = this.sanitizeFlags(rawFlags);
|
|
22
19
|
if (flags.json) {
|
|
23
20
|
(0, json_1.enableJsonOutput)();
|
|
24
21
|
}
|
|
22
|
+
log_1.default.warn('EAS Worker Deployments are in beta and subject to breaking changes.');
|
|
25
23
|
const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, } = await this.getContextAsync(_a, {
|
|
26
24
|
nonInteractive: true,
|
|
27
25
|
});
|
|
@@ -110,16 +108,16 @@ WorkerAlias.state = 'beta';
|
|
|
110
108
|
WorkerAlias.flags = {
|
|
111
109
|
prod: core_1.Flags.boolean({
|
|
112
110
|
aliases: ['production'],
|
|
113
|
-
description: 'Promote an existing deployment to production',
|
|
111
|
+
description: 'Promote an existing deployment to production.',
|
|
114
112
|
default: false,
|
|
115
113
|
}),
|
|
116
114
|
alias: core_1.Flags.string({
|
|
117
|
-
description: 'Custom alias to assign to the existing deployment',
|
|
115
|
+
description: 'Custom alias to assign to the existing deployment.',
|
|
118
116
|
helpValue: 'name',
|
|
119
117
|
required: false,
|
|
120
118
|
}),
|
|
121
119
|
id: core_1.Flags.string({
|
|
122
|
-
description: 'Unique identifier of an existing deployment',
|
|
120
|
+
description: 'Unique identifier of an existing deployment.',
|
|
123
121
|
helpValue: 'xyz123',
|
|
124
122
|
required: false,
|
|
125
123
|
}),
|
|
@@ -7,13 +7,63 @@ export default class WorkerDeploy extends EasCommand {
|
|
|
7
7
|
static hidden: boolean;
|
|
8
8
|
static state: string;
|
|
9
9
|
static flags: {
|
|
10
|
-
environment: import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment | undefined>;
|
|
11
10
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
11
|
'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
12
|
prod: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
13
|
alias: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
15
14
|
id: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
16
15
|
'export-dir': import("@oclif/core/lib/interfaces").OptionFlag<string>;
|
|
16
|
+
environment: {
|
|
17
|
+
description: string;
|
|
18
|
+
name: string;
|
|
19
|
+
char?: import("@oclif/core/lib/interfaces").AlphabetUppercase | import("@oclif/core/lib/interfaces").AlphabetLowercase | undefined;
|
|
20
|
+
summary?: string | undefined;
|
|
21
|
+
helpLabel?: string | undefined;
|
|
22
|
+
helpGroup?: string | undefined;
|
|
23
|
+
env?: string | undefined;
|
|
24
|
+
hidden?: boolean | undefined;
|
|
25
|
+
required?: boolean | undefined;
|
|
26
|
+
dependsOn?: string[] | undefined;
|
|
27
|
+
exclusive?: string[] | undefined;
|
|
28
|
+
exactlyOne?: string[] | undefined;
|
|
29
|
+
relationships?: import("@oclif/core/lib/interfaces/parser").Relationship[] | undefined;
|
|
30
|
+
deprecated?: true | import("@oclif/core/lib/interfaces/parser").Deprecation | undefined;
|
|
31
|
+
aliases?: string[] | undefined;
|
|
32
|
+
deprecateAliases?: boolean | undefined;
|
|
33
|
+
parse: import("@oclif/core/lib/interfaces/parser").FlagParser<EnvironmentVariableEnvironment | undefined, string, any>;
|
|
34
|
+
type: "option";
|
|
35
|
+
helpValue?: string | undefined;
|
|
36
|
+
options?: string[] | undefined;
|
|
37
|
+
multiple: false;
|
|
38
|
+
defaultHelp?: import("@oclif/core/lib/interfaces/parser").DefaultHelp<EnvironmentVariableEnvironment | undefined, Record<string, unknown>>;
|
|
39
|
+
input: string[];
|
|
40
|
+
default?: import("@oclif/core/lib/interfaces").Default<EnvironmentVariableEnvironment | undefined, Record<string, unknown>>;
|
|
41
|
+
} | {
|
|
42
|
+
description: string;
|
|
43
|
+
name: string;
|
|
44
|
+
char?: import("@oclif/core/lib/interfaces").AlphabetUppercase | import("@oclif/core/lib/interfaces").AlphabetLowercase | undefined;
|
|
45
|
+
summary?: string | undefined;
|
|
46
|
+
helpLabel?: string | undefined;
|
|
47
|
+
helpGroup?: string | undefined;
|
|
48
|
+
env?: string | undefined;
|
|
49
|
+
hidden?: boolean | undefined;
|
|
50
|
+
required?: boolean | undefined;
|
|
51
|
+
dependsOn?: string[] | undefined;
|
|
52
|
+
exclusive?: string[] | undefined;
|
|
53
|
+
exactlyOne?: string[] | undefined;
|
|
54
|
+
relationships?: import("@oclif/core/lib/interfaces/parser").Relationship[] | undefined;
|
|
55
|
+
deprecated?: true | import("@oclif/core/lib/interfaces/parser").Deprecation | undefined;
|
|
56
|
+
aliases?: string[] | undefined;
|
|
57
|
+
deprecateAliases?: boolean | undefined;
|
|
58
|
+
parse: import("@oclif/core/lib/interfaces/parser").FlagParser<EnvironmentVariableEnvironment | undefined, string, any>;
|
|
59
|
+
type: "option";
|
|
60
|
+
helpValue?: string | undefined;
|
|
61
|
+
options?: string[] | undefined;
|
|
62
|
+
multiple: true;
|
|
63
|
+
defaultHelp?: import("@oclif/core/lib/interfaces/parser").DefaultHelp<EnvironmentVariableEnvironment | undefined, Record<string, unknown>>;
|
|
64
|
+
input: string[];
|
|
65
|
+
default?: import("@oclif/core/lib/interfaces").Default<(EnvironmentVariableEnvironment | undefined)[] | undefined, Record<string, unknown>>;
|
|
66
|
+
};
|
|
17
67
|
};
|
|
18
68
|
static contextDefinition: {
|
|
19
69
|
loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
|
|
@@ -23,19 +23,15 @@ const isDirectory = (directoryPath) => node_fs_1.default.promises
|
|
|
23
23
|
.catch(() => false);
|
|
24
24
|
class WorkerDeploy extends EasCommand_1.default {
|
|
25
25
|
async runAsync() {
|
|
26
|
-
// NOTE(cedric): `Log.warn` uses `console.log`, which is incorrect when running with `--json`
|
|
27
|
-
// eslint-disable-next-line no-console
|
|
28
|
-
console.warn(chalk_1.default.yellow('EAS Worker Deployments are in beta and subject to breaking changes.'));
|
|
29
26
|
const { flags: rawFlags } = await this.parse(_a);
|
|
30
27
|
const flags = this.sanitizeFlags(rawFlags);
|
|
31
28
|
if (flags.json) {
|
|
32
29
|
(0, json_1.enableJsonOutput)();
|
|
33
30
|
}
|
|
31
|
+
log_1.default.warn('EAS Worker Deployments are in beta and subject to breaking changes.');
|
|
34
32
|
const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, projectDir, } = await this.getContextAsync(_a, flags);
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
resolveExportedProjectAsync(flags, projectDir),
|
|
38
|
-
]);
|
|
33
|
+
const projectDist = await resolveExportedProjectAsync(flags, projectDir);
|
|
34
|
+
const { projectId } = await getDynamicPrivateProjectConfigAsync();
|
|
39
35
|
logExportedProjectInfo(projectDist);
|
|
40
36
|
async function* emitWorkerTarballAsync(params) {
|
|
41
37
|
yield ['assets.json', JSON.stringify(params.assetMap)];
|
|
@@ -243,25 +239,27 @@ WorkerDeploy.state = 'beta';
|
|
|
243
239
|
WorkerDeploy.flags = {
|
|
244
240
|
prod: core_1.Flags.boolean({
|
|
245
241
|
aliases: ['production'],
|
|
246
|
-
description: 'Create a new production deployment',
|
|
242
|
+
description: 'Create a new production deployment.',
|
|
247
243
|
default: false,
|
|
248
244
|
}),
|
|
249
245
|
alias: core_1.Flags.string({
|
|
250
|
-
description: 'Custom alias to assign to the new deployment',
|
|
246
|
+
description: 'Custom alias to assign to the new deployment.',
|
|
251
247
|
helpValue: 'name',
|
|
252
248
|
}),
|
|
253
249
|
id: core_1.Flags.string({
|
|
254
|
-
description: 'Custom unique identifier for the new deployment',
|
|
250
|
+
description: 'Custom unique identifier for the new deployment.',
|
|
255
251
|
helpValue: 'xyz123',
|
|
256
252
|
}),
|
|
257
253
|
'export-dir': core_1.Flags.string({
|
|
258
|
-
description: 'Directory where the Expo project was exported',
|
|
254
|
+
description: 'Directory where the Expo project was exported.',
|
|
259
255
|
helpValue: 'dir',
|
|
260
256
|
default: 'dist',
|
|
261
257
|
}),
|
|
262
|
-
|
|
258
|
+
environment: {
|
|
259
|
+
...flags_1.EASEnvironmentFlag.environment,
|
|
260
|
+
description: 'Deploy with EAS Environment Variables matching the specified environment.',
|
|
261
|
+
},
|
|
263
262
|
...flags_1.EasNonInteractiveAndJsonFlags,
|
|
264
|
-
...flags_1.EASEnvironmentFlag,
|
|
265
263
|
};
|
|
266
264
|
WorkerDeploy.contextDefinition = {
|
|
267
265
|
..._a.ContextOptions.DynamicProjectConfig,
|
|
@@ -273,17 +271,30 @@ async function resolveExportedProjectAsync(flags, projectDir) {
|
|
|
273
271
|
const exportPath = path.join(projectDir, flags.exportDir);
|
|
274
272
|
const serverPath = path.join(exportPath, 'server');
|
|
275
273
|
const clientPath = path.join(exportPath, 'client');
|
|
276
|
-
const [hasServerPath, hasClientPath,
|
|
274
|
+
const [hasServerPath, hasClientPath, exportStat] = await Promise.all([
|
|
277
275
|
isDirectory(serverPath),
|
|
278
276
|
isDirectory(clientPath),
|
|
279
|
-
node_fs_1.default.promises.stat(exportPath).
|
|
277
|
+
node_fs_1.default.promises.stat(exportPath).catch(() => null),
|
|
280
278
|
]);
|
|
279
|
+
if (!exportStat?.isDirectory()) {
|
|
280
|
+
throw new Error(`No "${flags.exportDir}/" folder found. Prepare your project for deployment with "npx expo export --platform web"`);
|
|
281
|
+
}
|
|
281
282
|
if (hasServerPath && hasClientPath) {
|
|
282
|
-
return {
|
|
283
|
+
return {
|
|
284
|
+
type: 'server',
|
|
285
|
+
path: exportPath,
|
|
286
|
+
modifiedAt: exportStat.mtime,
|
|
287
|
+
serverPath,
|
|
288
|
+
clientPath,
|
|
289
|
+
};
|
|
283
290
|
}
|
|
284
|
-
return { type: 'static', path: exportPath, modifiedAt };
|
|
291
|
+
return { type: 'static', path: exportPath, modifiedAt: exportStat.mtime };
|
|
285
292
|
}
|
|
286
293
|
function logExportedProjectInfo(project) {
|
|
287
|
-
|
|
288
|
-
|
|
294
|
+
let modifiedAgo = '';
|
|
295
|
+
// Only show the timestamp for exports older than 1 minute
|
|
296
|
+
if (project.modifiedAt && Date.now() - project.modifiedAt.getTime() > 60000) {
|
|
297
|
+
modifiedAgo = ` - exported ${(0, timeago_js_1.format)(project.modifiedAt)}`;
|
|
298
|
+
}
|
|
299
|
+
log_1.default.log((0, chalk_1.default) `{dim > Project export: ${project.type}${modifiedAgo}}`);
|
|
289
300
|
}
|