eas-cli 0.44.1 → 0.47.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.
Files changed (64) hide show
  1. package/README.md +842 -2
  2. package/build/build/android/graphql.js +1 -0
  3. package/build/build/android/prepareJob.js +3 -0
  4. package/build/build/android/syncProjectConfiguration.js +2 -2
  5. package/build/build/ios/graphql.js +1 -0
  6. package/build/build/ios/prepareJob.js +3 -0
  7. package/build/build/ios/syncProjectConfiguration.js +2 -2
  8. package/build/build/local.js +1 -1
  9. package/build/build/metadata.js +1 -2
  10. package/build/build/runBuildAndSubmit.js +4 -0
  11. package/build/build/utils/updates.d.ts +0 -1
  12. package/build/build/utils/updates.js +1 -7
  13. package/build/commands/analytics.js +1 -1
  14. package/build/commands/branch/create.js +1 -1
  15. package/build/commands/branch/delete.js +1 -1
  16. package/build/commands/branch/list.js +1 -1
  17. package/build/commands/branch/rename.js +1 -1
  18. package/build/commands/branch/view.js +1 -1
  19. package/build/commands/build/cancel.js +1 -1
  20. package/build/commands/build/configure.js +2 -3
  21. package/build/commands/build/index.js +1 -1
  22. package/build/commands/build/inspect.js +1 -1
  23. package/build/commands/channel/create.js +8 -7
  24. package/build/commands/channel/delete.js +2 -2
  25. package/build/commands/channel/edit.js +35 -29
  26. package/build/commands/channel/list.js +1 -1
  27. package/build/commands/channel/rollout.js +47 -38
  28. package/build/commands/channel/view.d.ts +0 -2
  29. package/build/commands/channel/view.js +4 -48
  30. package/build/commands/config.js +9 -3
  31. package/build/commands/credentials.js +1 -1
  32. package/build/commands/device/delete.d.ts +17 -0
  33. package/build/commands/device/delete.js +181 -0
  34. package/build/commands/device/list.js +1 -1
  35. package/build/commands/diagnostics.js +1 -1
  36. package/build/commands/secret/create.js +1 -1
  37. package/build/commands/secret/delete.js +1 -3
  38. package/build/commands/secret/list.js +1 -1
  39. package/build/commands/submit.js +2 -3
  40. package/build/commands/update/configure.js +1 -1
  41. package/build/commands/update/delete.js +3 -3
  42. package/build/commands/update/index.js +15 -1
  43. package/build/commands/update/list.js +1 -1
  44. package/build/commands/update/view.js +1 -1
  45. package/build/commands/webhook/create.js +1 -1
  46. package/build/commands/webhook/delete.js +1 -1
  47. package/build/commands/webhook/list.js +1 -1
  48. package/build/commands/webhook/update.js +1 -1
  49. package/build/commands/webhook/view.js +1 -1
  50. package/build/credentials/ios/actions/DeviceUtils.d.ts +1 -0
  51. package/build/credentials/ios/actions/DeviceUtils.js +16 -1
  52. package/build/credentials/ios/api/graphql/mutations/AppleDeviceMutation.d.ts +1 -0
  53. package/build/credentials/ios/api/graphql/mutations/AppleDeviceMutation.js +16 -0
  54. package/build/graphql/generated.d.ts +5822 -3517
  55. package/build/graphql/generated.js +223 -223
  56. package/build/graphql/queries/BranchQuery.d.ts +7 -0
  57. package/build/graphql/queries/BranchQuery.js +29 -0
  58. package/build/graphql/queries/ChannelQuery.d.ts +4 -0
  59. package/build/graphql/queries/ChannelQuery.js +49 -0
  60. package/build/project/projectUtils.d.ts +5 -5
  61. package/build/project/projectUtils.js +24 -25
  62. package/build/submit/ArchiveSource.js +4 -4
  63. package/oclif.manifest.json +1 -1
  64. package/package.json +51 -49
@@ -1,5 +1,4 @@
1
1
  import EasCommand from '../../commandUtils/EasCommand';
2
- import { GetChannelByNameForAppQuery, GetChannelByNameForAppQueryVariables } from '../../graphql/generated';
3
2
  import { FormatUpdateParameter } from '../../update/utils';
4
3
  export declare type BranchMapping = {
5
4
  version: number;
@@ -21,7 +20,6 @@ export declare function getBranchMapping(branchMappingString?: string): {
21
20
  isRollout: boolean;
22
21
  rolloutPercent?: number;
23
22
  };
24
- export declare function getUpdateChannelByNameForAppAsync({ appId, channelName, }: GetChannelByNameForAppQueryVariables): Promise<GetChannelByNameForAppQuery>;
25
23
  export declare function logChannelDetails(channel: {
26
24
  branchMapping: string;
27
25
  updateBranches: {
@@ -1,15 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.logChannelDetails = exports.getUpdateChannelByNameForAppAsync = exports.getBranchMapping = void 0;
3
+ exports.logChannelDetails = exports.getBranchMapping = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const config_1 = require("@expo/config");
6
6
  const core_1 = require("@oclif/core");
7
7
  const assert_1 = (0, tslib_1.__importDefault)(require("assert"));
8
8
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
9
9
  const cli_table3_1 = (0, tslib_1.__importDefault)(require("cli-table3"));
10
- const graphql_tag_1 = (0, tslib_1.__importDefault)(require("graphql-tag"));
11
10
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
12
- const client_1 = require("../../graphql/client");
11
+ const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
13
12
  const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
14
13
  const projectUtils_1 = require("../../project/projectUtils");
15
14
  const prompts_1 = require("../../prompts");
@@ -65,47 +64,6 @@ function getBranchMapping(branchMappingString) {
65
64
  return { branchMapping, isRollout, rolloutPercent };
66
65
  }
67
66
  exports.getBranchMapping = getBranchMapping;
68
- async function getUpdateChannelByNameForAppAsync({ appId, channelName, }) {
69
- return await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
70
- .query((0, graphql_tag_1.default) `
71
- query GetChannelByNameForApp($appId: String!, $channelName: String!) {
72
- app {
73
- byId(appId: $appId) {
74
- id
75
- updateChannelByName(name: $channelName) {
76
- id
77
- name
78
- createdAt
79
- branchMapping
80
- updateBranches(offset: 0, limit: 1000) {
81
- id
82
- name
83
- updates(offset: 0, limit: 10) {
84
- id
85
- group
86
- message
87
- runtimeVersion
88
- createdAt
89
- platform
90
- actor {
91
- id
92
- ... on User {
93
- username
94
- }
95
- ... on Robot {
96
- firstName
97
- }
98
- }
99
- }
100
- }
101
- }
102
- }
103
- }
104
- }
105
- `, { appId, channelName }, { additionalTypenames: ['UpdateChannel', 'UpdateBranch', 'Update'] })
106
- .toPromise());
107
- }
108
- exports.getUpdateChannelByNameForAppAsync = getUpdateChannelByNameForAppAsync;
109
67
  function logChannelDetails(channel) {
110
68
  var _a, _b, _c;
111
69
  const { branchMapping, isRollout, rolloutPercent } = getBranchMapping(channel.branchMapping);
@@ -146,7 +104,6 @@ function logChannelDetails(channel) {
146
104
  exports.logChannelDetails = logChannelDetails;
147
105
  class ChannelView extends EasCommand_1.default {
148
106
  async runAsync() {
149
- var _a;
150
107
  let { args: { name: channelName }, flags: { json: jsonFlag }, } = await this.parse(ChannelView);
151
108
  if (jsonFlag) {
152
109
  (0, json_1.enableJsonOutput)();
@@ -166,11 +123,10 @@ class ChannelView extends EasCommand_1.default {
166
123
  validate: value => (value ? true : validationMessage),
167
124
  }));
168
125
  }
169
- const getUpdateChannelByNameForAppresult = await getUpdateChannelByNameForAppAsync({
126
+ const channel = await ChannelQuery_1.ChannelQuery.getUpdateChannelByNameForAppAsync({
170
127
  appId: projectId,
171
128
  channelName,
172
129
  });
173
- const channel = (_a = getUpdateChannelByNameForAppresult.app) === null || _a === void 0 ? void 0 : _a.byId.updateChannelByName;
174
130
  if (!channel) {
175
131
  throw new Error(`Could not find a channel with name: ${channelName}`);
176
132
  }
@@ -191,7 +147,7 @@ class ChannelView extends EasCommand_1.default {
191
147
  }
192
148
  }
193
149
  exports.default = ChannelView;
194
- ChannelView.description = 'View a channel on the current project.';
150
+ ChannelView.description = 'view a channel';
195
151
  ChannelView.args = [
196
152
  {
197
153
  name: 'name',
@@ -5,8 +5,11 @@ const config_1 = require("@expo/config");
5
5
  const eas_build_job_1 = require("@expo/eas-build-job");
6
6
  const eas_json_1 = require("@expo/eas-json");
7
7
  const core_1 = require("@oclif/core");
8
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
8
9
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../commandUtils/EasCommand"));
10
+ const AppPlatform_1 = require("../graphql/types/AppPlatform");
9
11
  const log_1 = (0, tslib_1.__importDefault)(require("../log"));
12
+ const platform_1 = require("../platform");
10
13
  const expoConfig_1 = require("../project/expoConfig");
11
14
  const projectUtils_1 = require("../project/projectUtils");
12
15
  const prompts_1 = require("../prompts");
@@ -38,18 +41,21 @@ class Config extends EasCommand_1.default {
38
41
  ]));
39
42
  const profile = await reader.getBuildProfileAsync(platform, profileName);
40
43
  const config = (0, expoConfig_1.getExpoConfig)(projectDir, { env: profile.env, isPublicConfig: true });
41
- log_1.default.log((0, config_1.getProjectConfigDescription)(projectDir));
44
+ log_1.default.addNewLineIfNone();
45
+ log_1.default.log(chalk_1.default.bold((0, config_1.getProjectConfigDescription)(projectDir)));
42
46
  log_1.default.newLine();
43
47
  log_1.default.log(JSON.stringify(config, null, 2));
44
48
  log_1.default.newLine();
45
49
  log_1.default.newLine();
46
- log_1.default.log(`Build profile "${profileName}" from eas.json for platform ${platform}`);
50
+ const appPlatform = (0, AppPlatform_1.toAppPlatform)(platform);
51
+ const platformEmoji = platform_1.appPlatformEmojis[appPlatform];
52
+ log_1.default.log(`${platformEmoji} ${chalk_1.default.bold(`Build profile "${profileName}"`)}`);
47
53
  log_1.default.newLine();
48
54
  log_1.default.log(JSON.stringify(profile, null, 2));
49
55
  }
50
56
  }
51
57
  exports.default = Config;
52
- Config.description = 'show the eas.json config';
58
+ Config.description = 'display project configuration (app.json + eas.json)';
53
59
  Config.flags = {
54
60
  platform: core_1.Flags.enum({ char: 'p', options: ['android', 'ios'] }),
55
61
  profile: core_1.Flags.string(),
@@ -9,4 +9,4 @@ class Credentials extends EasCommand_1.default {
9
9
  }
10
10
  }
11
11
  exports.default = Credentials;
12
- Credentials.description = 'manage your credentials';
12
+ Credentials.description = 'manage credentials';
@@ -0,0 +1,17 @@
1
+ import EasCommand from '../../commandUtils/EasCommand';
2
+ import { AppleDeviceQueryResult, AppleDevicesByTeamIdentifierQueryResult } from '../../credentials/ios/api/graphql/queries/AppleDeviceQuery';
3
+ import { AppleDevice, Maybe } from '../../graphql/generated';
4
+ export default class DeviceDelete extends EasCommand {
5
+ static description: string;
6
+ static flags: {
7
+ 'apple-team-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
8
+ udid: import("@oclif/core/lib/interfaces").OptionFlag<string[]>;
9
+ };
10
+ runAsync(): Promise<void>;
11
+ askAndDisableOnAppleAsync(chosenDevices: (AppleDevice | AppleDeviceQueryResult)[], appleTeamIdentifier: string): Promise<void>;
12
+ askAndRemoveFromExpoAsync(chosenDevices: (AppleDevice | AppleDeviceQueryResult)[]): Promise<boolean>;
13
+ logChosenDevices(chosenDevices: (AppleDevice | AppleDeviceQueryResult)[], appleTeamName: Maybe<string> | undefined, appleTeamIdentifier: string): void;
14
+ chooseDevicesToDeleteAsync(appleDevices: AppleDeviceQueryResult[], udids: string[]): Promise<(AppleDevice | AppleDeviceQueryResult)[]>;
15
+ getDevicesForTeamAsync(accountName: string, appleTeamIdentifier: string): Promise<AppleDevicesByTeamIdentifierQueryResult | undefined>;
16
+ askForAppleTeamAsync(accountName: string): Promise<string | undefined>;
17
+ }
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const apple_utils_1 = require("@expo/apple-utils");
5
+ const config_1 = require("@expo/config");
6
+ const core_1 = require("@oclif/core");
7
+ const assert_1 = (0, tslib_1.__importDefault)(require("assert"));
8
+ const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
9
+ const DeviceUtils_1 = require("../../credentials/ios/actions/DeviceUtils");
10
+ const AppleDeviceMutation_1 = require("../../credentials/ios/api/graphql/mutations/AppleDeviceMutation");
11
+ const AppleDeviceQuery_1 = require("../../credentials/ios/api/graphql/queries/AppleDeviceQuery");
12
+ const AppleTeamQuery_1 = require("../../credentials/ios/api/graphql/queries/AppleTeamQuery");
13
+ const authenticate_1 = require("../../credentials/ios/appstore/authenticate");
14
+ const formatDevice_1 = (0, tslib_1.__importDefault)(require("../../devices/utils/formatDevice"));
15
+ const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
16
+ const ora_1 = require("../../ora");
17
+ const projectUtils_1 = require("../../project/projectUtils");
18
+ const prompts_1 = require("../../prompts");
19
+ class DeviceDelete extends EasCommand_1.default {
20
+ async runAsync() {
21
+ let { flags: { 'apple-team-id': appleTeamIdentifier, udid: udids }, } = await this.parse(DeviceDelete);
22
+ const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
23
+ const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
24
+ const accountName = await (0, projectUtils_1.getProjectAccountNameAsync)(exp);
25
+ if (!appleTeamIdentifier) {
26
+ appleTeamIdentifier = await this.askForAppleTeamAsync(accountName);
27
+ }
28
+ (0, assert_1.default)(appleTeamIdentifier, 'No team identifier is specified');
29
+ const appleDevicesResult = await this.getDevicesForTeamAsync(accountName, appleTeamIdentifier);
30
+ if (!appleDevicesResult) {
31
+ return;
32
+ }
33
+ const { appleTeamName, appleDevices } = appleDevicesResult;
34
+ const chosenDevices = await this.chooseDevicesToDeleteAsync(appleDevices, udids);
35
+ if (chosenDevices.length === 0) {
36
+ log_1.default.newLine();
37
+ log_1.default.warn('No devices were chosen to be removed.');
38
+ return;
39
+ }
40
+ this.logChosenDevices(chosenDevices, appleTeamName, appleTeamIdentifier);
41
+ const hasRemoved = await this.askAndRemoveFromExpoAsync(chosenDevices);
42
+ if (!hasRemoved) {
43
+ return;
44
+ }
45
+ await this.askAndDisableOnAppleAsync(chosenDevices, appleTeamIdentifier);
46
+ }
47
+ async askAndDisableOnAppleAsync(chosenDevices, appleTeamIdentifier) {
48
+ log_1.default.newLine();
49
+ const deleteOnApple = await (0, prompts_1.toggleConfirmAsync)({
50
+ message: 'Do you want to disable these devices on your Apple account as well?',
51
+ });
52
+ if (!deleteOnApple) {
53
+ return;
54
+ }
55
+ const ctx = await (0, authenticate_1.authenticateAsync)({ teamId: appleTeamIdentifier });
56
+ const context = (0, authenticate_1.getRequestContext)(ctx);
57
+ log_1.default.addNewLineIfNone();
58
+ const removeAppleSpinner = (0, ora_1.ora)('Disabling devices on Apple').start();
59
+ try {
60
+ let realDevices = await apple_utils_1.Device.getAllIOSProfileDevicesAsync(context);
61
+ realDevices = realDevices.filter(d => chosenDevices.map(cd => cd.identifier).includes(d.attributes.udid));
62
+ for (const device of realDevices) {
63
+ await device.updateAsync({ status: apple_utils_1.DeviceStatus.DISABLED });
64
+ }
65
+ removeAppleSpinner.succeed('Disabled devices on Apple');
66
+ }
67
+ catch (err) {
68
+ removeAppleSpinner.fail();
69
+ throw err;
70
+ }
71
+ }
72
+ async askAndRemoveFromExpoAsync(chosenDevices) {
73
+ log_1.default.warn(`You are about to remove the Apple device${chosenDevices.length > 1 ? 's' : ''} listed above from your Expo account.`);
74
+ log_1.default.newLine();
75
+ const confirmed = await (0, prompts_1.toggleConfirmAsync)({
76
+ message: 'Are you sure you wish to proceed?',
77
+ });
78
+ if (confirmed) {
79
+ const removalSpinner = (0, ora_1.ora)(`Removing Apple devices on Expo`).start();
80
+ try {
81
+ for (const chosenDevice of chosenDevices) {
82
+ await AppleDeviceMutation_1.AppleDeviceMutation.deleteAppleDeviceAsync(chosenDevice.id);
83
+ }
84
+ removalSpinner.succeed('Removed Apple devices from Expo');
85
+ }
86
+ catch (err) {
87
+ removalSpinner.fail();
88
+ throw err;
89
+ }
90
+ }
91
+ return confirmed;
92
+ }
93
+ logChosenDevices(chosenDevices, appleTeamName, appleTeamIdentifier) {
94
+ log_1.default.addNewLineIfNone();
95
+ chosenDevices.forEach(device => {
96
+ log_1.default.log((0, formatDevice_1.default)(device, {
97
+ appleTeamName,
98
+ appleTeamIdentifier: appleTeamIdentifier,
99
+ }));
100
+ log_1.default.newLine();
101
+ });
102
+ }
103
+ async chooseDevicesToDeleteAsync(appleDevices, udids) {
104
+ let chosenDevices = [];
105
+ log_1.default.newLine();
106
+ if (udids) {
107
+ udids.forEach(udid => {
108
+ const foundDevice = appleDevices.find(device => device.identifier === udid);
109
+ if (foundDevice) {
110
+ chosenDevices.push(foundDevice);
111
+ }
112
+ else {
113
+ log_1.default.warn(`No device found with UDID ${udid}.`);
114
+ }
115
+ });
116
+ }
117
+ if (chosenDevices.length === 0) {
118
+ log_1.default.addNewLineIfNone();
119
+ chosenDevices = await (0, DeviceUtils_1.chooseDevicesToDeleteAsync)(appleDevices);
120
+ log_1.default.newLine();
121
+ }
122
+ return chosenDevices;
123
+ }
124
+ async getDevicesForTeamAsync(accountName, appleTeamIdentifier) {
125
+ const devicesSpinner = (0, ora_1.ora)().start('Fetching the list of devices for the team…');
126
+ try {
127
+ const result = await AppleDeviceQuery_1.AppleDeviceQuery.getAllForAppleTeamAsync(accountName, appleTeamIdentifier);
128
+ if (result === null || result === void 0 ? void 0 : result.appleDevices.length) {
129
+ const { appleTeamName, appleDevices } = result;
130
+ devicesSpinner.succeed(`Found ${appleDevices.length} devices for team ${appleTeamName !== null && appleTeamName !== void 0 ? appleTeamName : appleTeamIdentifier}`);
131
+ return result;
132
+ }
133
+ else {
134
+ devicesSpinner.fail(`Couldn't find any devices for the team ${appleTeamIdentifier}`);
135
+ return;
136
+ }
137
+ }
138
+ catch (e) {
139
+ devicesSpinner.fail(`Something went wrong and we couldn't fetch the device list`);
140
+ throw e;
141
+ }
142
+ }
143
+ async askForAppleTeamAsync(accountName) {
144
+ const teamSpinner = (0, ora_1.ora)().start('Fetching the list of teams for the project…');
145
+ try {
146
+ const teams = await AppleTeamQuery_1.AppleTeamQuery.getAllForAccountAsync(accountName);
147
+ if (teams.length > 0) {
148
+ teamSpinner.succeed('Fetched the list of teams for the project');
149
+ if (teams.length === 1) {
150
+ return teams[0].appleTeamIdentifier;
151
+ }
152
+ const result = await (0, prompts_1.promptAsync)({
153
+ type: 'select',
154
+ name: 'appleTeamIdentifier',
155
+ message: 'What Apple Team would you like to list devices for?',
156
+ choices: teams.map(team => ({
157
+ title: team.appleTeamName
158
+ ? `${team.appleTeamName} (ID: ${team.appleTeamIdentifier})`
159
+ : team.appleTeamIdentifier,
160
+ value: team.appleTeamIdentifier,
161
+ })),
162
+ });
163
+ return result.appleTeamIdentifier;
164
+ }
165
+ else {
166
+ teamSpinner.fail(`Couldn't find any teams for the account ${accountName}`);
167
+ return;
168
+ }
169
+ }
170
+ catch (e) {
171
+ teamSpinner.fail(`Something went wrong and we couldn't fetch the list of teams`);
172
+ throw e;
173
+ }
174
+ }
175
+ }
176
+ exports.default = DeviceDelete;
177
+ DeviceDelete.description = 'remove a registered device from your account';
178
+ DeviceDelete.flags = {
179
+ 'apple-team-id': core_1.Flags.string(),
180
+ udid: core_1.Flags.string({ multiple: true }),
181
+ };
@@ -24,7 +24,7 @@ class BuildList extends EasCommand_1.default {
24
24
  spinner = (0, ora_1.ora)().start('Fetching the list of teams for the project…');
25
25
  try {
26
26
  const teams = await AppleTeamQuery_1.AppleTeamQuery.getAllForAccountAsync(accountName);
27
- if (teams.length) {
27
+ if (teams.length > 0) {
28
28
  spinner.succeed();
29
29
  if (teams.length === 1) {
30
30
  appleTeamIdentifier = teams[0].appleTeamIdentifier;
@@ -53,4 +53,4 @@ class Diagnostics extends EasCommand_1.default {
53
53
  }
54
54
  }
55
55
  exports.default = Diagnostics;
56
- Diagnostics.description = 'log environment info to the console';
56
+ Diagnostics.description = 'display environment info';
@@ -106,7 +106,7 @@ class EnvironmentSecretCreate extends EasCommand_1.default {
106
106
  }
107
107
  }
108
108
  exports.default = EnvironmentSecretCreate;
109
- EnvironmentSecretCreate.description = 'Create an environment secret on the current project or owner account.';
109
+ EnvironmentSecretCreate.description = 'create an environment secret on the current project or owner account';
110
110
  EnvironmentSecretCreate.flags = {
111
111
  scope: core_1.Flags.enum({
112
112
  description: 'Scope for the secret',
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const config_1 = require("@expo/config");
5
5
  const core_1 = require("@oclif/core");
6
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
7
6
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
8
7
  const EnvironmentSecretMutation_1 = require("../../graphql/mutations/EnvironmentSecretMutation");
9
8
  const EnvironmentSecretsQuery_1 = require("../../graphql/queries/EnvironmentSecretsQuery");
@@ -52,8 +51,7 @@ class EnvironmentSecretDelete extends EasCommand_1.default {
52
51
  }
53
52
  }
54
53
  exports.default = EnvironmentSecretDelete;
55
- EnvironmentSecretDelete.description = `Delete an environment secret by ID.
56
- Unsure where to find the secret's ID? Run ${chalk_1.default.bold('eas secret:list')}`;
54
+ EnvironmentSecretDelete.description = 'delete an environment secret by ID';
57
55
  EnvironmentSecretDelete.flags = {
58
56
  id: core_1.Flags.string({
59
57
  description: 'ID of the secret to delete',
@@ -32,4 +32,4 @@ class EnvironmentSecretList extends EasCommand_1.default {
32
32
  }
33
33
  }
34
34
  exports.default = EnvironmentSecretList;
35
- EnvironmentSecretList.description = 'Lists environment secrets available for your current app';
35
+ EnvironmentSecretList.description = 'list environment secrets available for your current app';
@@ -6,7 +6,7 @@ const core_1 = require("@oclif/core");
6
6
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
7
7
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../commandUtils/EasCommand"));
8
8
  const AppPlatform_1 = require("../graphql/types/AppPlatform");
9
- const log_1 = (0, tslib_1.__importStar)(require("../log"));
9
+ const log_1 = (0, tslib_1.__importDefault)(require("../log"));
10
10
  const platform_1 = require("../platform");
11
11
  const projectUtils_1 = require("../project/projectUtils");
12
12
  const context_1 = require("../submit/context");
@@ -73,8 +73,7 @@ class Submit extends EasCommand_1.default {
73
73
  }
74
74
  }
75
75
  exports.default = Submit;
76
- Submit.description = `Submit build archive to App Store Connect
77
- See how to configure submits with eas.json: ${(0, log_1.link)('https://docs.expo.dev/submit/eas-json/')}`;
76
+ Submit.description = 'submit app binary to app store';
78
77
  Submit.aliases = ['build:submit'];
79
78
  Submit.flags = {
80
79
  platform: core_1.Flags.enum({
@@ -72,4 +72,4 @@ class UpdateConfigure extends EasCommand_1.default {
72
72
  }
73
73
  }
74
74
  exports.default = UpdateConfigure;
75
- UpdateConfigure.description = 'Configure the project to support EAS Update.';
75
+ UpdateConfigure.description = 'configure the project to support EAS Update';
@@ -32,8 +32,8 @@ class UpdateDelete extends EasCommand_1.default {
32
32
  const shouldAbort = await (0, prompts_1.confirmAsync)({
33
33
  message: `🚨${chalk_1.default.red('CAUTION')}🚨\n\n` +
34
34
  `${chalk_1.default.yellow(`This will delete all of the updates in group "${group}".`)} ${chalk_1.default.red('This is a permanent operation.')}\n\n` +
35
- `If you want to revert to a previous publish, you should use 'branch:publish --republish' targeted at the last working update group instead.\n\n` +
36
- `An update group should only be deleted in an emergency like an accidental publish of a secret. In this case user 'branch:publish --republish' to revert to the last working update group first and then proceed with the deletion. Deleting an update group when it is the latest publish can lead to inconsistent cacheing behavior by clients.\n\n` +
35
+ `If you want to revert to a previous publish, you should use 'update --republish' targeted at the last working update group instead.\n\n` +
36
+ `An update group should only be deleted in an emergency like an accidental publish of a secret. In this case user 'update --republish' to revert to the last working update group first and then proceed with the deletion. Deleting an update group when it is the latest publish can lead to inconsistent cacheing behavior by clients.\n\n` +
37
37
  `Would you like to abort?`,
38
38
  });
39
39
  if (shouldAbort) {
@@ -51,7 +51,7 @@ class UpdateDelete extends EasCommand_1.default {
51
51
  }
52
52
  }
53
53
  exports.default = UpdateDelete;
54
- UpdateDelete.description = 'Delete all the updates in an update Group.';
54
+ UpdateDelete.description = 'delete all the updates in an update group';
55
55
  UpdateDelete.args = [
56
56
  {
57
57
  name: 'groupId',
@@ -98,6 +98,20 @@ class UpdatePublish extends EasCommand_1.default {
98
98
  skipSDKVersionRequirement: true,
99
99
  isPublicConfig: true,
100
100
  });
101
+ if (!(0, projectUtils_1.isExpoUpdatesInstalledOrAvailable)(projectDir, exp.sdkVersion)) {
102
+ const install = await (0, prompts_1.confirmAsync)({
103
+ message: `You are creating an update which requires ${chalk_1.default.bold('expo-updates')} to be installed in your app.\n Do you want EAS CLI to install it for you?`,
104
+ instructions: 'The command will abort unless you agree.',
105
+ });
106
+ if (install) {
107
+ await (0, projectUtils_1.installExpoUpdatesAsync)(projectDir, { nonInteractive: false });
108
+ }
109
+ else {
110
+ core_1.Errors.error(`Install ${chalk_1.default.bold('expo-updates')} manually and come back later.`, {
111
+ exit: 1,
112
+ });
113
+ }
114
+ }
101
115
  const runtimeVersions = await getRuntimeVersionObjectAsync(exp, platformFlag, projectDir);
102
116
  const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
103
117
  await checkEASUpdateURLIsSetAsync(exp);
@@ -311,7 +325,7 @@ class UpdatePublish extends EasCommand_1.default {
311
325
  }
312
326
  }
313
327
  exports.default = UpdatePublish;
314
- UpdatePublish.description = 'Publish an update group.';
328
+ UpdatePublish.description = 'publish an update group';
315
329
  UpdatePublish.flags = {
316
330
  branch: core_1.Flags.string({
317
331
  description: 'Branch to publish the update group on',
@@ -66,7 +66,7 @@ class BranchView extends EasCommand_1.default {
66
66
  }
67
67
  }
68
68
  exports.default = BranchView;
69
- BranchView.description = 'View the recent updates for a branch';
69
+ BranchView.description = 'view the recent updates for a branch';
70
70
  BranchView.flags = {
71
71
  branch: core_1.Flags.string({
72
72
  description: 'List all updates on this branch',
@@ -73,7 +73,7 @@ class UpdateView extends EasCommand_1.default {
73
73
  }
74
74
  }
75
75
  exports.default = UpdateView;
76
- UpdateView.description = 'Update group details.';
76
+ UpdateView.description = 'update group details';
77
77
  UpdateView.args = [
78
78
  {
79
79
  name: 'groupId',
@@ -28,7 +28,7 @@ class WebhookCreate extends EasCommand_1.default {
28
28
  }
29
29
  }
30
30
  exports.default = WebhookCreate;
31
- WebhookCreate.description = 'Create a webhook on the current project.';
31
+ WebhookCreate.description = 'create a webhook';
32
32
  WebhookCreate.flags = {
33
33
  event: core_1.Flags.enum({
34
34
  description: 'Event type that triggers the webhook',
@@ -61,7 +61,7 @@ class WebhookDelete extends EasCommand_1.default {
61
61
  }
62
62
  }
63
63
  exports.default = WebhookDelete;
64
- WebhookDelete.description = 'Delete a webhook on the current project.';
64
+ WebhookDelete.description = 'delete a webhook';
65
65
  WebhookDelete.args = [
66
66
  {
67
67
  name: 'ID',
@@ -39,7 +39,7 @@ class WebhookList extends EasCommand_1.default {
39
39
  }
40
40
  }
41
41
  exports.default = WebhookList;
42
- WebhookList.description = 'List webhooks on the current project.';
42
+ WebhookList.description = 'list webhooks';
43
43
  WebhookList.flags = {
44
44
  event: core_1.Flags.enum({
45
45
  description: 'Event type that triggers the webhook',
@@ -27,7 +27,7 @@ class WebhookUpdate extends EasCommand_1.default {
27
27
  }
28
28
  }
29
29
  exports.default = WebhookUpdate;
30
- WebhookUpdate.description = 'Create a webhook on the current project.';
30
+ WebhookUpdate.description = 'update a webhook';
31
31
  WebhookUpdate.flags = {
32
32
  id: core_1.Flags.string({
33
33
  description: 'Webhook ID',
@@ -22,7 +22,7 @@ class WebhookView extends EasCommand_1.default {
22
22
  }
23
23
  }
24
24
  exports.default = WebhookView;
25
- WebhookView.description = 'View a webhook on the current project.';
25
+ WebhookView.description = 'view a webhook';
26
26
  WebhookView.args = [
27
27
  {
28
28
  name: 'ID',
@@ -1,3 +1,4 @@
1
1
  import { AppleDevice, AppleDeviceFragment } from '../../../graphql/generated';
2
2
  export declare function chooseDevicesAsync(allDevices: AppleDeviceFragment[], preselectedDeviceIdentifiers?: string[]): Promise<AppleDevice[]>;
3
+ export declare function chooseDevicesToDeleteAsync(allDevices: AppleDeviceFragment[]): Promise<AppleDevice[]>;
3
4
  export declare function formatDeviceLabel(device: AppleDeviceFragment): string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatDeviceLabel = exports.chooseDevicesAsync = void 0;
3
+ exports.formatDeviceLabel = exports.chooseDevicesToDeleteAsync = exports.chooseDevicesAsync = void 0;
4
4
  const AppleDevice_1 = require("../../../graphql/types/credentials/AppleDevice");
5
5
  const prompts_1 = require("../.././../prompts");
6
6
  async function chooseDevicesAsync(allDevices, preselectedDeviceIdentifiers = []) {
@@ -23,6 +23,21 @@ async function chooseDevicesAsync(allDevices, preselectedDeviceIdentifiers = [])
23
23
  return devices;
24
24
  }
25
25
  exports.chooseDevicesAsync = chooseDevicesAsync;
26
+ async function chooseDevicesToDeleteAsync(allDevices) {
27
+ const { devices } = await (0, prompts_1.promptAsync)({
28
+ type: 'multiselect',
29
+ name: 'devices',
30
+ message: 'Which devices do you want to remove?',
31
+ choices: allDevices.map(device => ({
32
+ value: device,
33
+ title: formatDeviceLabel(device),
34
+ selected: false,
35
+ })),
36
+ instructions: false,
37
+ });
38
+ return devices;
39
+ }
40
+ exports.chooseDevicesToDeleteAsync = chooseDevicesToDeleteAsync;
26
41
  function formatDeviceLabel(device) {
27
42
  var _a;
28
43
  const deviceDetails = formatDeviceDetails(device);
@@ -1,4 +1,5 @@
1
1
  import { AppleDeviceFragment, AppleDeviceInput } from '../../../../../graphql/generated';
2
2
  export declare const AppleDeviceMutation: {
3
3
  createAppleDeviceAsync(appleDeviceInput: AppleDeviceInput, accountId: string): Promise<AppleDeviceFragment>;
4
+ deleteAppleDeviceAsync(deviceId: string): Promise<string>;
4
5
  };
@@ -29,4 +29,20 @@ exports.AppleDeviceMutation = {
29
29
  .toPromise());
30
30
  return data.appleDevice.createAppleDevice;
31
31
  },
32
+ async deleteAppleDeviceAsync(deviceId) {
33
+ const data = await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
34
+ .mutation((0, graphql_tag_1.default) `
35
+ mutation DeleteAppleDeviceMutation($deviceId: ID!) {
36
+ appleDevice {
37
+ deleteAppleDevice(id: $deviceId) {
38
+ id
39
+ }
40
+ }
41
+ }
42
+ `, {
43
+ deviceId,
44
+ })
45
+ .toPromise());
46
+ return data.id;
47
+ },
32
48
  };