eas-cli 18.4.0 → 18.6.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 +92 -90
- package/build/build/android/prepareJob.js +2 -2
- package/build/build/ios/prepareJob.js +2 -2
- package/build/build/metadata.js +2 -1
- package/build/commandUtils/EasCommand.js +23 -2
- package/build/commandUtils/context/contextUtils/getProjectIdAsync.js +2 -0
- package/build/commandUtils/pagination.d.ts +2 -1
- package/build/commandUtils/pagination.js +3 -2
- package/build/commandUtils/workflow/fetchLogs.js +11 -2
- package/build/commandUtils/workflow/types.d.ts +5 -1
- package/build/commandUtils/workflow/utils.js +22 -16
- package/build/commands/deploy/index.js +18 -2
- package/build/commands/metadata/pull.d.ts +1 -0
- package/build/commands/metadata/pull.js +9 -4
- package/build/commands/metadata/push.d.ts +1 -0
- package/build/commands/metadata/push.js +9 -4
- package/build/commands/observe/events.d.ts +27 -0
- package/build/commands/observe/events.js +140 -0
- package/build/commands/observe/metrics.d.ts +21 -0
- package/build/commands/observe/metrics.js +111 -0
- package/build/commands/observe/versions.d.ts +19 -0
- package/build/commands/observe/versions.js +69 -0
- package/build/commands/project/onboarding.js +3 -0
- package/build/commands/workflow/logs.js +12 -12
- package/build/credentials/ios/IosCredentialsProvider.js +8 -4
- package/build/credentials/ios/utils/provisioningProfile.d.ts +1 -0
- package/build/credentials/ios/utils/provisioningProfile.js +15 -1
- package/build/graphql/generated.d.ts +1273 -73
- package/build/graphql/generated.js +59 -19
- package/build/graphql/queries/ObserveQuery.d.ts +35 -0
- package/build/graphql/queries/ObserveQuery.js +109 -0
- package/build/graphql/queries/UserQuery.js +3 -0
- package/build/graphql/types/Observe.d.ts +3 -0
- package/build/graphql/types/Observe.js +84 -0
- package/build/graphql/types/Update.js +3 -0
- package/build/metadata/apple/config/reader.d.ts +13 -1
- package/build/metadata/apple/config/reader.js +33 -0
- package/build/metadata/apple/config/writer.d.ts +11 -1
- package/build/metadata/apple/config/writer.js +57 -0
- package/build/metadata/apple/data.d.ts +7 -2
- package/build/metadata/apple/rules/infoRestrictedWords.js +6 -1
- package/build/metadata/apple/tasks/age-rating.d.ts +1 -1
- package/build/metadata/apple/tasks/age-rating.js +19 -3
- package/build/metadata/apple/tasks/app-clip.d.ts +37 -0
- package/build/metadata/apple/tasks/app-clip.js +404 -0
- package/build/metadata/apple/tasks/app-review-detail.js +7 -2
- package/build/metadata/apple/tasks/index.js +6 -0
- package/build/metadata/apple/tasks/previews.d.ts +18 -0
- package/build/metadata/apple/tasks/previews.js +212 -0
- package/build/metadata/apple/tasks/screenshots.d.ts +18 -0
- package/build/metadata/apple/tasks/screenshots.js +235 -0
- package/build/metadata/apple/types.d.ts +61 -1
- package/build/metadata/auth.d.ts +11 -1
- package/build/metadata/auth.js +96 -2
- package/build/metadata/download.d.ts +5 -1
- package/build/metadata/download.js +16 -8
- package/build/metadata/upload.d.ts +5 -1
- package/build/metadata/upload.js +11 -4
- package/build/observe/fetchEvents.d.ts +27 -0
- package/build/observe/fetchEvents.js +83 -0
- package/build/observe/fetchMetrics.d.ts +11 -0
- package/build/observe/fetchMetrics.js +78 -0
- package/build/observe/fetchVersions.d.ts +7 -0
- package/build/observe/fetchVersions.js +31 -0
- package/build/observe/formatEvents.d.ts +31 -0
- package/build/observe/formatEvents.js +99 -0
- package/build/observe/formatMetrics.d.ts +38 -0
- package/build/observe/formatMetrics.js +206 -0
- package/build/observe/formatVersions.d.ts +32 -0
- package/build/observe/formatVersions.js +92 -0
- package/build/observe/metricNames.d.ts +4 -0
- package/build/observe/metricNames.js +33 -0
- package/build/observe/startAndEndTime.d.ts +18 -0
- package/build/observe/startAndEndTime.js +36 -0
- package/build/project/projectUtils.d.ts +0 -2
- package/build/project/projectUtils.js +0 -12
- package/build/project/workflow.js +1 -1
- package/build/sentry.d.ts +2 -0
- package/build/sentry.js +22 -0
- package/build/update/utils.d.ts +2 -2
- package/build/update/utils.js +1 -0
- package/build/user/SessionManager.js +11 -0
- package/build/user/User.d.ts +2 -2
- package/build/user/User.js +3 -0
- package/build/user/expoBrowserAuthFlowLauncher.js +70 -13
- package/build/worker/upload.js +15 -5
- package/oclif.manifest.json +1794 -1306
- package/package.json +15 -11
- package/schema/metadata-0.json +213 -0
|
@@ -4,20 +4,65 @@ exports.getSessionUsingBrowserAuthFlowAsync = getSessionUsingBrowserAuthFlowAsyn
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
6
|
const better_opn_1 = tslib_1.__importDefault(require("better-opn"));
|
|
7
|
+
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
7
8
|
const http_1 = tslib_1.__importDefault(require("http"));
|
|
8
|
-
const querystring_1 = tslib_1.__importDefault(require("querystring"));
|
|
9
9
|
const api_1 = require("../api");
|
|
10
|
+
const fetch_1 = tslib_1.__importDefault(require("../fetch"));
|
|
10
11
|
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
12
|
+
const CLIENT_ID = 'eas-cli';
|
|
13
|
+
function generateCodeVerifier() {
|
|
14
|
+
return crypto_1.default.randomBytes(32).toString('base64url');
|
|
15
|
+
}
|
|
16
|
+
function generateCodeChallenge(codeVerifier) {
|
|
17
|
+
return crypto_1.default.createHash('sha256').update(codeVerifier).digest('base64url');
|
|
18
|
+
}
|
|
19
|
+
function generateState() {
|
|
20
|
+
return crypto_1.default.randomBytes(32).toString('base64url');
|
|
21
|
+
}
|
|
22
|
+
async function exchangeCodeForSessionSecretAsync({ code, codeVerifier, redirectUri, }) {
|
|
23
|
+
const tokenUrl = `${(0, api_1.getExpoApiBaseUrl)()}/v2/auth/token`;
|
|
24
|
+
const response = await (0, fetch_1.default)(tokenUrl, {
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers: {
|
|
27
|
+
'Content-Type': 'application/json',
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
grant_type: 'authorization_code',
|
|
31
|
+
code,
|
|
32
|
+
redirect_uri: redirectUri,
|
|
33
|
+
code_verifier: codeVerifier,
|
|
34
|
+
client_id: CLIENT_ID,
|
|
35
|
+
}),
|
|
36
|
+
});
|
|
37
|
+
const result = await response.json();
|
|
38
|
+
const sessionSecret = result?.data?.session_secret;
|
|
39
|
+
if (!sessionSecret) {
|
|
40
|
+
throw new Error('Failed to obtain session secret from token exchange.');
|
|
41
|
+
}
|
|
42
|
+
return sessionSecret;
|
|
43
|
+
}
|
|
11
44
|
async function getSessionUsingBrowserAuthFlowAsync({ sso = false }) {
|
|
12
45
|
const scheme = 'http';
|
|
13
46
|
const hostname = 'localhost';
|
|
14
|
-
const
|
|
47
|
+
const callbackPath = '/auth/callback';
|
|
15
48
|
const expoWebsiteUrl = (0, api_1.getExpoWebsiteBaseUrl)();
|
|
49
|
+
const codeVerifier = generateCodeVerifier();
|
|
50
|
+
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
51
|
+
const state = generateState();
|
|
52
|
+
const buildRedirectUri = (port) => `${scheme}://${hostname}:${port}${callbackPath}`;
|
|
16
53
|
const buildExpoLoginUrl = (port, sso) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
54
|
+
// Note: we avoid URLSearchParams here because better-opn calls encodeURI()
|
|
55
|
+
// on the URL before passing it to AppleScript, which would double-encode
|
|
56
|
+
// the percent-encoded values from URLSearchParams.toString().
|
|
57
|
+
const params = [
|
|
58
|
+
`client_id=${CLIENT_ID}`,
|
|
59
|
+
`redirect_uri=${buildRedirectUri(port)}`,
|
|
60
|
+
`response_type=code`,
|
|
61
|
+
`code_challenge=${codeChallenge}`,
|
|
62
|
+
`code_challenge_method=S256`,
|
|
63
|
+
`state=${state}`,
|
|
64
|
+
`confirm_account=true`,
|
|
65
|
+
].join('&');
|
|
21
66
|
return `${expoWebsiteUrl}${sso ? '/sso-login' : '/login'}?${params}`;
|
|
22
67
|
};
|
|
23
68
|
// Start server and begin auth flow
|
|
@@ -34,22 +79,34 @@ async function getSessionUsingBrowserAuthFlowAsync({ sso = false }) {
|
|
|
34
79
|
connection.destroy();
|
|
35
80
|
}
|
|
36
81
|
};
|
|
37
|
-
|
|
82
|
+
const handleRequestAsync = async () => {
|
|
38
83
|
if (!(request.method === 'GET' && request.url?.includes('/auth/callback'))) {
|
|
39
84
|
throw new Error('Unexpected login response.');
|
|
40
85
|
}
|
|
41
86
|
const url = new URL(request.url, `http:${request.headers.host}`);
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
87
|
+
const code = url.searchParams.get('code');
|
|
88
|
+
const returnedState = url.searchParams.get('state');
|
|
89
|
+
if (!code) {
|
|
90
|
+
throw new Error('Request missing code search parameter.');
|
|
91
|
+
}
|
|
92
|
+
if (returnedState !== state) {
|
|
93
|
+
throw new Error('State mismatch. Possible CSRF attack.');
|
|
45
94
|
}
|
|
95
|
+
const address = server.address();
|
|
96
|
+
(0, assert_1.default)(address !== null && typeof address === 'object');
|
|
97
|
+
const redirectUri = buildRedirectUri(address.port);
|
|
98
|
+
const sessionSecret = await exchangeCodeForSessionSecretAsync({
|
|
99
|
+
code,
|
|
100
|
+
codeVerifier,
|
|
101
|
+
redirectUri,
|
|
102
|
+
});
|
|
46
103
|
resolve(sessionSecret);
|
|
47
104
|
redirectAndCleanup('success');
|
|
48
|
-
}
|
|
49
|
-
catch
|
|
105
|
+
};
|
|
106
|
+
handleRequestAsync().catch(error => {
|
|
50
107
|
redirectAndCleanup('error');
|
|
51
108
|
reject(error);
|
|
52
|
-
}
|
|
109
|
+
});
|
|
53
110
|
});
|
|
54
111
|
server.listen(0, hostname, () => {
|
|
55
112
|
log_1.default.log('Waiting for browser login...');
|
package/build/worker/upload.js
CHANGED
|
@@ -166,6 +166,7 @@ async function* batchUploadAsync(init, payloads, onProgressUpdate) {
|
|
|
166
166
|
(() => {
|
|
167
167
|
onProgressUpdate(getProgressValue());
|
|
168
168
|
});
|
|
169
|
+
let firstError = null;
|
|
169
170
|
try {
|
|
170
171
|
let index = 0;
|
|
171
172
|
while (index < payloads.length || queue.size > 0) {
|
|
@@ -177,27 +178,36 @@ async function* batchUploadAsync(init, payloads, onProgressUpdate) {
|
|
|
177
178
|
progressTracker[currentIndex] = progress;
|
|
178
179
|
sendProgressUpdate();
|
|
179
180
|
});
|
|
180
|
-
const uploadPromise = uploadAsync(initWithSignal, payload, onChildProgressUpdate).
|
|
181
|
+
const uploadPromise = uploadAsync(initWithSignal, payload, onChildProgressUpdate).then(result => {
|
|
181
182
|
queue.delete(uploadPromise);
|
|
182
183
|
progressTracker[currentIndex] = 1;
|
|
184
|
+
return result;
|
|
185
|
+
}, error => {
|
|
186
|
+
queue.delete(uploadPromise);
|
|
187
|
+
firstError ??= error;
|
|
188
|
+
controller.abort();
|
|
189
|
+
throw error;
|
|
183
190
|
});
|
|
184
191
|
queue.add(uploadPromise);
|
|
185
192
|
yield { payload, progress: getProgressValue() };
|
|
186
193
|
}
|
|
194
|
+
if (firstError) {
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
187
197
|
yield {
|
|
188
198
|
...(await Promise.race(queue)),
|
|
189
199
|
progress: getProgressValue(),
|
|
190
200
|
};
|
|
191
201
|
}
|
|
192
|
-
if (queue.size > 0) {
|
|
193
|
-
controller.abort();
|
|
194
|
-
}
|
|
195
202
|
}
|
|
196
203
|
catch (error) {
|
|
197
204
|
if (error.name !== 'AbortError') {
|
|
198
|
-
|
|
205
|
+
firstError ??= error;
|
|
199
206
|
}
|
|
200
207
|
}
|
|
208
|
+
if (firstError) {
|
|
209
|
+
throw firstError;
|
|
210
|
+
}
|
|
201
211
|
}
|
|
202
212
|
function createProgressBar(label = 'Uploading assets') {
|
|
203
213
|
const queueProgressBar = new cli_progress_1.default.SingleBar({ format: `|{bar}| {percentage}% ${label}` }, cli_progress_1.default.Presets.rect);
|