eas-cli 3.13.2 → 3.14.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 +55 -55
- package/build/api.d.ts +1 -0
- package/build/api.js +14 -1
- package/build/build/build.js +8 -5
- package/build/build/configure.d.ts +1 -0
- package/build/build/configure.js +8 -4
- package/build/build/local.js +1 -1
- package/build/build/runBuildAndSubmit.js +29 -0
- package/build/commandUtils/EasCommand.js +3 -1
- package/build/commandUtils/context/contextUtils/getProjectIdAsync.js +3 -3
- package/build/commands/account/login.d.ts +3 -0
- package/build/commands/account/login.js +12 -1
- package/build/commands/build/configure.js +5 -1
- package/build/commands/project/init.js +1 -1
- package/build/commands/update/configure.js +14 -15
- package/build/commands/update/index.js +40 -3
- package/build/credentials/android/api/GraphqlClient.d.ts +1 -0
- package/build/credentials/android/api/GraphqlClient.js +5 -7
- package/build/credentials/android/api/graphql/mutations/AndroidAppBuildCredentialsMutation.d.ts +1 -0
- package/build/credentials/android/api/graphql/mutations/AndroidAppBuildCredentialsMutation.js +23 -0
- package/build/credentials/ios/appstore/bundleIdCapabilities.js +43 -0
- package/build/credentials/manager/Actions.d.ts +11 -10
- package/build/credentials/manager/Actions.js +11 -10
- package/build/credentials/manager/AndroidActions.js +5 -0
- package/build/credentials/manager/CreateAndroidBuildCredentials.d.ts +8 -0
- package/build/credentials/manager/CreateAndroidBuildCredentials.js +33 -0
- package/build/credentials/manager/ManageAndroid.js +6 -15
- package/build/credentials/manager/SetDefaultAndroidKeystore.d.ts +8 -0
- package/build/credentials/manager/SetDefaultAndroidKeystore.js +41 -0
- package/build/graphql/generated.d.ts +76 -12
- package/build/graphql/generated.js +13 -2
- package/build/graphql/queries/UserQuery.js +2 -5
- package/build/project/expoConfig.d.ts +5 -1
- package/build/project/expoConfig.js +58 -1
- package/build/project/projectUtils.d.ts +2 -0
- package/build/project/projectUtils.js +14 -3
- package/build/project/publish.d.ts +8 -1
- package/build/project/publish.js +19 -5
- package/build/update/android/UpdatesModule.d.ts +3 -0
- package/build/update/android/UpdatesModule.js +11 -0
- package/build/update/configure.js +9 -5
- package/build/user/SessionManager.d.ts +3 -1
- package/build/user/SessionManager.js +16 -2
- package/build/user/User.d.ts +1 -1
- package/build/user/User.js +1 -1
- package/build/user/actions.js +1 -1
- package/build/user/expoSsoLauncher.d.ts +4 -0
- package/build/user/expoSsoLauncher.js +71 -0
- package/build/user/fetchSessionSecretAndSsoUser.d.ts +5 -0
- package/build/user/fetchSessionSecretAndSsoUser.js +20 -0
- package/build/user/fetchSessionSecretAndUser.js +4 -24
- package/build/user/fetchUser.d.ts +6 -0
- package/build/user/fetchUser.js +27 -0
- package/build/utils/expoCli.js +12 -2
- package/build/utils/port.d.ts +2 -0
- package/build/utils/port.js +14 -0
- package/build/vcs/clients/git.js +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +5 -4
|
@@ -39,10 +39,12 @@ export default class SessionManager {
|
|
|
39
39
|
*
|
|
40
40
|
* @deprecated Should not be used outside of context functions, except in the AccountLogin command.
|
|
41
41
|
*/
|
|
42
|
-
showLoginPromptAsync({ nonInteractive, printNewLine, }?: {
|
|
42
|
+
showLoginPromptAsync({ nonInteractive, printNewLine, sso, }?: {
|
|
43
43
|
nonInteractive?: boolean | undefined;
|
|
44
44
|
printNewLine?: boolean | undefined;
|
|
45
|
+
sso?: boolean | undefined;
|
|
45
46
|
}): Promise<void>;
|
|
47
|
+
private ssoLoginAsync;
|
|
46
48
|
private loginAsync;
|
|
47
49
|
/**
|
|
48
50
|
* Prompt for an OTP with the option to cancel the question by answering empty (pressing return key).
|
|
@@ -14,6 +14,7 @@ const UserQuery_1 = require("../graphql/queries/UserQuery");
|
|
|
14
14
|
const log_1 = tslib_1.__importStar(require("../log"));
|
|
15
15
|
const prompts_1 = require("../prompts");
|
|
16
16
|
const paths_1 = require("../utils/paths");
|
|
17
|
+
const fetchSessionSecretAndSsoUser_1 = require("./fetchSessionSecretAndSsoUser");
|
|
17
18
|
const fetchSessionSecretAndUser_1 = require("./fetchSessionSecretAndUser");
|
|
18
19
|
var UserSecondFactorDeviceMethod;
|
|
19
20
|
(function (UserSecondFactorDeviceMethod) {
|
|
@@ -102,14 +103,18 @@ class SessionManager {
|
|
|
102
103
|
*
|
|
103
104
|
* @deprecated Should not be used outside of context functions, except in the AccountLogin command.
|
|
104
105
|
*/
|
|
105
|
-
async showLoginPromptAsync({ nonInteractive = false, printNewLine = false, } = {}) {
|
|
106
|
+
async showLoginPromptAsync({ nonInteractive = false, printNewLine = false, sso = false, } = {}) {
|
|
106
107
|
if (nonInteractive) {
|
|
107
108
|
core_1.Errors.error(`Either log in with ${chalk_1.default.bold('eas login')} or set the ${chalk_1.default.bold('EXPO_TOKEN')} environment variable if you're using EAS CLI on CI (${(0, log_1.learnMore)('https://docs.expo.dev/accounts/programmatic-access/', { dim: false })})`);
|
|
108
109
|
}
|
|
109
110
|
if (printNewLine) {
|
|
110
111
|
log_1.default.newLine();
|
|
111
112
|
}
|
|
112
|
-
|
|
113
|
+
if (sso) {
|
|
114
|
+
await this.ssoLoginAsync();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
log_1.default.log(`Log in to EAS with email or username (exit and run ${chalk_1.default.bold('eas login')} for other options)`);
|
|
113
118
|
const { username, password } = await (0, prompts_1.promptAsync)([
|
|
114
119
|
{
|
|
115
120
|
type: 'text',
|
|
@@ -137,6 +142,15 @@ class SessionManager {
|
|
|
137
142
|
}
|
|
138
143
|
}
|
|
139
144
|
}
|
|
145
|
+
async ssoLoginAsync() {
|
|
146
|
+
const { sessionSecret, id, username } = await (0, fetchSessionSecretAndSsoUser_1.fetchSessionSecretAndSsoUserAsync)();
|
|
147
|
+
await this.setSessionAsync({
|
|
148
|
+
sessionSecret,
|
|
149
|
+
userId: id,
|
|
150
|
+
username,
|
|
151
|
+
currentConnection: 'Browser-Flow-Authentication',
|
|
152
|
+
});
|
|
153
|
+
}
|
|
140
154
|
async loginAsync(input) {
|
|
141
155
|
const { sessionSecret, id, username } = await (0, fetchSessionSecretAndUser_1.fetchSessionSecretAndUserAsync)(input);
|
|
142
156
|
await this.setSessionAsync({
|
package/build/user/User.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CurrentUserQuery, Robot, SsoUser, User } from '../graphql/generated';
|
|
2
2
|
export type Actor = NonNullable<CurrentUserQuery['meActor']>;
|
|
3
3
|
/**
|
|
4
|
-
* Resolve the name of the actor, either normal user or robot user.
|
|
4
|
+
* Resolve the name of the actor, either normal user, sso user or robot user.
|
|
5
5
|
* This should be used whenever the "current user" needs to be displayed.
|
|
6
6
|
* The display name CANNOT be used as project owner.
|
|
7
7
|
*/
|
package/build/user/User.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getActorUsername = exports.getActorDisplayName = void 0;
|
|
4
4
|
/**
|
|
5
|
-
* Resolve the name of the actor, either normal user or robot user.
|
|
5
|
+
* Resolve the name of the actor, either normal user, sso user or robot user.
|
|
6
6
|
* This should be used whenever the "current user" needs to be displayed.
|
|
7
7
|
* The display name CANNOT be used as project owner.
|
|
8
8
|
*/
|
package/build/user/actions.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ensureActorHasPrimaryAccount = void 0;
|
|
4
4
|
function ensureActorHasPrimaryAccount(user) {
|
|
5
|
-
if (user.__typename === 'User') {
|
|
5
|
+
if (user.__typename === 'User' || user.__typename === 'SSOUser') {
|
|
6
6
|
return user.primaryAccount;
|
|
7
7
|
}
|
|
8
8
|
throw new Error('This action is not supported for robot users.');
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSessionUsingBrowserAuthFlowAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const better_opn_1 = tslib_1.__importDefault(require("better-opn"));
|
|
6
|
+
const http_1 = tslib_1.__importDefault(require("http"));
|
|
7
|
+
const querystring_1 = tslib_1.__importDefault(require("querystring"));
|
|
8
|
+
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
9
|
+
async function getSessionUsingBrowserAuthFlowAsync(options) {
|
|
10
|
+
const { expoWebsiteUrl, serverPort } = options;
|
|
11
|
+
if (!expoWebsiteUrl || !serverPort) {
|
|
12
|
+
throw new Error('Expo website URL and local server port are required.');
|
|
13
|
+
}
|
|
14
|
+
const scheme = 'http';
|
|
15
|
+
const hostname = 'localhost';
|
|
16
|
+
const path = '/auth/callback';
|
|
17
|
+
const redirectUri = `${scheme}://${hostname}:${serverPort}${path}`;
|
|
18
|
+
const buildExpoSsoLoginUrl = () => {
|
|
19
|
+
const data = {
|
|
20
|
+
app_redirect_uri: redirectUri,
|
|
21
|
+
};
|
|
22
|
+
const params = querystring_1.default.stringify(data);
|
|
23
|
+
return `${expoWebsiteUrl}/sso-login?${params}`;
|
|
24
|
+
};
|
|
25
|
+
// Start server and begin auth flow
|
|
26
|
+
const executeAuthFlow = () => {
|
|
27
|
+
return new Promise(async (resolve, reject) => {
|
|
28
|
+
const connections = new Set();
|
|
29
|
+
const server = http_1.default.createServer((request, response) => {
|
|
30
|
+
var _a;
|
|
31
|
+
try {
|
|
32
|
+
if (!(request.method === 'GET' && ((_a = request.url) === null || _a === void 0 ? void 0 : _a.includes('/auth/callback')))) {
|
|
33
|
+
throw new Error('Unexpected SSO login response.');
|
|
34
|
+
}
|
|
35
|
+
const url = new URL(request.url, `http:${request.headers.host}`);
|
|
36
|
+
const sessionSecret = url.searchParams.get('session_secret');
|
|
37
|
+
if (!sessionSecret) {
|
|
38
|
+
throw new Error('Request missing session_secret search parameter.');
|
|
39
|
+
}
|
|
40
|
+
resolve(sessionSecret);
|
|
41
|
+
response.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
42
|
+
response.write(`Website login has completed. You can now close this tab.`);
|
|
43
|
+
response.end();
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
reject(error);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
server.close();
|
|
50
|
+
// Ensure that the server shuts down
|
|
51
|
+
for (const connection of connections) {
|
|
52
|
+
connection.destroy();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
server.listen(serverPort, hostname, () => {
|
|
57
|
+
log_1.default.log('Waiting for browser login...');
|
|
58
|
+
});
|
|
59
|
+
server.on('connection', connection => {
|
|
60
|
+
connections.add(connection);
|
|
61
|
+
connection.on('close', () => {
|
|
62
|
+
connections.delete(connection);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
const authorizeUrl = buildExpoSsoLoginUrl();
|
|
66
|
+
(0, better_opn_1.default)(authorizeUrl);
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
return await executeAuthFlow();
|
|
70
|
+
}
|
|
71
|
+
exports.getSessionUsingBrowserAuthFlowAsync = getSessionUsingBrowserAuthFlowAsync;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchSessionSecretAndSsoUserAsync = void 0;
|
|
4
|
+
const api_1 = require("../api");
|
|
5
|
+
const expoSsoLauncher_1 = require("./expoSsoLauncher");
|
|
6
|
+
const fetchUser_1 = require("./fetchUser");
|
|
7
|
+
async function fetchSessionSecretAndSsoUserAsync() {
|
|
8
|
+
const config = {
|
|
9
|
+
expoWebsiteUrl: (0, api_1.getExpoWebsiteBaseUrl)(),
|
|
10
|
+
serverPort: await (0, api_1.getSsoLocalServerPortAsync)(),
|
|
11
|
+
};
|
|
12
|
+
const sessionSecret = await (0, expoSsoLauncher_1.getSessionUsingBrowserAuthFlowAsync)(config);
|
|
13
|
+
const userData = await (0, fetchUser_1.fetchUserAsync)({ sessionSecret });
|
|
14
|
+
return {
|
|
15
|
+
sessionSecret,
|
|
16
|
+
id: userData.id,
|
|
17
|
+
username: userData.username,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
exports.fetchSessionSecretAndSsoUserAsync = fetchSessionSecretAndSsoUserAsync;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fetchSessionSecretAndUserAsync = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
|
|
6
4
|
const api_1 = require("../api");
|
|
7
|
-
const
|
|
5
|
+
const fetchUser_1 = require("./fetchUser");
|
|
8
6
|
async function fetchSessionSecretAndUserAsync({ username, password, otp, }) {
|
|
9
7
|
// this is a logged-out endpoint
|
|
10
8
|
const apiV2Client = new api_1.ApiV2Client({
|
|
@@ -15,29 +13,11 @@ async function fetchSessionSecretAndUserAsync({ username, password, otp, }) {
|
|
|
15
13
|
body: { username, password, otp },
|
|
16
14
|
});
|
|
17
15
|
const { sessionSecret } = body.data;
|
|
18
|
-
const
|
|
19
|
-
const result = await graphqlClient
|
|
20
|
-
.query((0, graphql_tag_1.default) `
|
|
21
|
-
query UserQuery {
|
|
22
|
-
viewer {
|
|
23
|
-
id
|
|
24
|
-
username
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
`, {}, {
|
|
28
|
-
fetchOptions: {
|
|
29
|
-
headers: {
|
|
30
|
-
'expo-session': sessionSecret,
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
additionalTypenames: [] /* UserQuery has immutable fields */,
|
|
34
|
-
})
|
|
35
|
-
.toPromise();
|
|
36
|
-
const { data } = result;
|
|
16
|
+
const userData = await (0, fetchUser_1.fetchUserAsync)({ sessionSecret });
|
|
37
17
|
return {
|
|
38
18
|
sessionSecret,
|
|
39
|
-
id:
|
|
40
|
-
username:
|
|
19
|
+
id: userData.id,
|
|
20
|
+
username: userData.username,
|
|
41
21
|
};
|
|
42
22
|
}
|
|
43
23
|
exports.fetchSessionSecretAndUserAsync = fetchSessionSecretAndUserAsync;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchUserAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
|
|
6
|
+
const createGraphqlClient_1 = require("../commandUtils/context/contextUtils/createGraphqlClient");
|
|
7
|
+
async function fetchUserAsync({ sessionSecret, }) {
|
|
8
|
+
const graphqlClient = (0, createGraphqlClient_1.createGraphqlClient)({ accessToken: null, sessionSecret });
|
|
9
|
+
const result = await graphqlClient
|
|
10
|
+
.query((0, graphql_tag_1.default) `
|
|
11
|
+
query UserQuery {
|
|
12
|
+
meUserActor {
|
|
13
|
+
id
|
|
14
|
+
username
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
`, {}, {
|
|
18
|
+
additionalTypenames: [] /* UserQuery has immutable fields */,
|
|
19
|
+
})
|
|
20
|
+
.toPromise();
|
|
21
|
+
const { data } = result;
|
|
22
|
+
return {
|
|
23
|
+
id: data.meUserActor.id,
|
|
24
|
+
username: data.meUserActor.username,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
exports.fetchUserAsync = fetchUserAsync;
|
package/build/utils/expoCli.js
CHANGED
|
@@ -7,7 +7,7 @@ const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
|
7
7
|
const getenv_1 = require("getenv");
|
|
8
8
|
const resolve_from_1 = tslib_1.__importStar(require("resolve-from"));
|
|
9
9
|
const semver_1 = tslib_1.__importDefault(require("semver"));
|
|
10
|
-
const log_1 = tslib_1.
|
|
10
|
+
const log_1 = tslib_1.__importStar(require("../log"));
|
|
11
11
|
const memoize_1 = require("./expodash/memoize");
|
|
12
12
|
// Aggressively returns `true` (UNVERSIONED, invalid SDK version format) to push users towards the versioned CLI.
|
|
13
13
|
function gteSdkVersion(fromSdkVersion, sdkVersion) {
|
|
@@ -53,7 +53,17 @@ exports.shouldUseVersionedExpoCLIExpensive = shouldUseVersionedExpoCLIExpensive;
|
|
|
53
53
|
exports.shouldUseVersionedExpoCLI = (0, memoize_1.memoize)(shouldUseVersionedExpoCLIExpensive);
|
|
54
54
|
async function expoCommandAsync(projectDir, args, { silent = false } = {}) {
|
|
55
55
|
var _a;
|
|
56
|
-
|
|
56
|
+
let expoCliPath;
|
|
57
|
+
try {
|
|
58
|
+
expoCliPath =
|
|
59
|
+
(_a = (0, resolve_from_1.silent)(projectDir, 'expo/bin/cli')) !== null && _a !== void 0 ? _a : (0, resolve_from_1.default)(projectDir, 'expo/bin/cli.js');
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
if (e.code === 'MODULE_NOT_FOUND') {
|
|
63
|
+
throw new Error(`The \`expo\` package was not found. Follow the installation directions at ${(0, log_1.link)('https://docs.expo.dev/bare/installing-expo-modules/')}`);
|
|
64
|
+
}
|
|
65
|
+
throw e;
|
|
66
|
+
}
|
|
57
67
|
const spawnPromise = (0, spawn_async_1.default)(expoCliPath, args, {
|
|
58
68
|
stdio: ['inherit', 'pipe', 'pipe'], // inherit stdin so user can install a missing expo-cli from inside this command
|
|
59
69
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFreePortAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const freeport_async_1 = tslib_1.__importDefault(require("freeport-async"));
|
|
6
|
+
/** Get a free port or throw an error. */
|
|
7
|
+
async function getFreePortAsync(rangeStart) {
|
|
8
|
+
const port = await (0, freeport_async_1.default)(rangeStart, { hostnames: [null, 'localhost'] });
|
|
9
|
+
if (!port) {
|
|
10
|
+
throw new Error('No available port found');
|
|
11
|
+
}
|
|
12
|
+
return port;
|
|
13
|
+
}
|
|
14
|
+
exports.getFreePortAsync = getFreePortAsync;
|
package/build/vcs/clients/git.js
CHANGED
|
@@ -35,7 +35,7 @@ class GitClient extends vcs_1.Client {
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
log_1.default.warn("It looks like you haven't initialized the git repository yet.");
|
|
38
|
-
log_1.default.warn('EAS
|
|
38
|
+
log_1.default.warn('EAS requires you to use a git repository for your project.');
|
|
39
39
|
const cwd = process.cwd();
|
|
40
40
|
const repoRoot = (_a = PackageManagerUtils.findWorkspaceRoot(cwd)) !== null && _a !== void 0 ? _a : cwd;
|
|
41
41
|
const confirmInit = await (0, prompts_1.confirmAsync)({
|