eas-cli 0.42.4 → 0.45.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 (67) hide show
  1. package/README.md +120 -50
  2. package/bin/dev +17 -0
  3. package/bin/dev.cmd +3 -0
  4. package/bin/run +4 -3
  5. package/build/build/android/UpdatesModule.d.ts +0 -1
  6. package/build/build/android/UpdatesModule.js +4 -37
  7. package/build/build/android/build.js +3 -3
  8. package/build/build/android/{configure.d.ts → syncProjectConfiguration.d.ts} +2 -3
  9. package/build/build/android/{configure.js → syncProjectConfiguration.js} +22 -23
  10. package/build/build/build.d.ts +1 -1
  11. package/build/build/build.js +6 -8
  12. package/build/build/configure.d.ts +12 -7
  13. package/build/build/configure.js +25 -99
  14. package/build/build/context.d.ts +0 -12
  15. package/build/build/createContext.d.ts +1 -2
  16. package/build/build/createContext.js +1 -2
  17. package/build/build/ios/UpdatesModule.d.ts +0 -1
  18. package/build/build/ios/UpdatesModule.js +8 -39
  19. package/build/build/ios/build.js +3 -3
  20. package/build/build/ios/{configure.d.ts → syncProjectConfiguration.d.ts} +1 -3
  21. package/build/build/ios/{configure.js → syncProjectConfiguration.js} +3 -18
  22. package/build/build/local.d.ts +1 -0
  23. package/build/build/local.js +2 -1
  24. package/build/build/runBuildAndSubmit.d.ts +0 -1
  25. package/build/build/runBuildAndSubmit.js +4 -2
  26. package/build/commands/branch/create.js +8 -3
  27. package/build/commands/branch/delete.js +8 -2
  28. package/build/commands/branch/list.js +5 -1
  29. package/build/commands/branch/rename.js +8 -3
  30. package/build/commands/branch/view.d.ts +0 -2
  31. package/build/commands/branch/view.js +32 -71
  32. package/build/commands/build/configure.js +43 -25
  33. package/build/commands/build/index.d.ts +1 -0
  34. package/build/commands/build/index.js +12 -2
  35. package/build/commands/build/inspect.d.ts +1 -0
  36. package/build/commands/build/inspect.js +23 -17
  37. package/build/commands/channel/create.js +21 -16
  38. package/build/commands/channel/delete.d.ts +15 -0
  39. package/build/commands/channel/delete.js +124 -0
  40. package/build/commands/channel/edit.js +10 -5
  41. package/build/commands/channel/list.js +14 -9
  42. package/build/commands/channel/rollout.js +8 -3
  43. package/build/commands/channel/view.js +16 -11
  44. package/build/commands/device/delete.d.ts +17 -0
  45. package/build/commands/device/delete.js +181 -0
  46. package/build/commands/device/list.js +1 -1
  47. package/build/commands/update/configure.js +1 -1
  48. package/build/commands/update/delete.js +9 -4
  49. package/build/commands/update/index.js +7 -3
  50. package/build/commands/update/list.d.ts +10 -0
  51. package/build/commands/update/list.js +114 -0
  52. package/build/commands/update/view.js +22 -17
  53. package/build/commands/webhook/update.js +1 -1
  54. package/build/credentials/ios/actions/DeviceUtils.d.ts +1 -0
  55. package/build/credentials/ios/actions/DeviceUtils.js +16 -1
  56. package/build/credentials/ios/api/graphql/mutations/AppleDeviceMutation.d.ts +1 -0
  57. package/build/credentials/ios/api/graphql/mutations/AppleDeviceMutation.js +16 -0
  58. package/build/credentials/ios/appstore/bundleIdCapabilities.js +0 -2
  59. package/build/credentials/ios/appstore/ensureAppExists.js +3 -1
  60. package/build/graphql/generated.d.ts +5848 -3500
  61. package/build/graphql/generated.js +223 -223
  62. package/build/graphql/queries/UpdateQuery.d.ts +7 -0
  63. package/build/graphql/queries/UpdateQuery.js +85 -0
  64. package/build/submit/ArchiveSource.js +0 -1
  65. package/build/vcs/local.js +5 -1
  66. package/oclif.manifest.json +1 -1
  67. package/package.json +43 -42
@@ -11,6 +11,7 @@ const client_1 = require("../../graphql/client");
11
11
  const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
12
12
  const projectUtils_1 = require("../../project/projectUtils");
13
13
  const prompts_1 = require("../../prompts");
14
+ const json_1 = require("../../utils/json");
14
15
  async function getChannelByNameForAppAsync({ appId, channelName, }) {
15
16
  var _a;
16
17
  const data = await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
@@ -62,6 +63,9 @@ exports.updateChannelBranchMappingAsync = updateChannelBranchMappingAsync;
62
63
  class ChannelEdit extends EasCommand_1.default {
63
64
  async runAsync() {
64
65
  let { args: { name: channelName }, flags: { branch: branchName, json: jsonFlag }, } = await this.parse(ChannelEdit);
66
+ if (jsonFlag) {
67
+ (0, json_1.enableJsonOutput)();
68
+ }
65
69
  const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
66
70
  const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
67
71
  const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
@@ -103,12 +107,13 @@ class ChannelEdit extends EasCommand_1.default {
103
107
  }),
104
108
  });
105
109
  if (jsonFlag) {
106
- log_1.default.log(JSON.stringify(channel));
107
- return;
110
+ (0, json_1.printJsonOnlyOutput)(channel);
111
+ }
112
+ else {
113
+ log_1.default.withTick((0, chalk_1.default) `Channel {bold ${channel.name}} is now set to branch {bold ${branch.name}}.\n`);
114
+ log_1.default.addNewLineIfNone();
115
+ log_1.default.log((0, chalk_1.default) `Users with builds on channel {bold ${channel.name}} will now receive the active update on {bold ${branch.name}}.`);
108
116
  }
109
- log_1.default.withTick((0, chalk_1.default) `Channel {bold ${channel.name}} is now set to branch {bold ${branch.name}}.\n`);
110
- log_1.default.addNewLineIfNone();
111
- log_1.default.log((0, chalk_1.default) `Users with builds on channel {bold ${channel.name}} will now receive the active update on {bold ${branch.name}}.`);
112
117
  }
113
118
  }
114
119
  exports.default = ChannelEdit;
@@ -9,6 +9,7 @@ const client_1 = require("../../graphql/client");
9
9
  const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
10
10
  const projectUtils_1 = require("../../project/projectUtils");
11
11
  const formatFields_1 = (0, tslib_1.__importDefault)(require("../../utils/formatFields"));
12
+ const json_1 = require("../../utils/json");
12
13
  const view_1 = require("./view");
13
14
  const CHANNEL_LIMIT = 10000;
14
15
  async function getAllUpdateChannelForAppAsync({ appId, }) {
@@ -54,6 +55,9 @@ class ChannelList extends EasCommand_1.default {
54
55
  async runAsync() {
55
56
  var _a;
56
57
  const { flags: { json: jsonFlag }, } = await this.parse(ChannelList);
58
+ if (jsonFlag) {
59
+ (0, json_1.enableJsonOutput)();
60
+ }
57
61
  const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
58
62
  const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
59
63
  const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
@@ -65,16 +69,17 @@ class ChannelList extends EasCommand_1.default {
65
69
  throw new Error(`Could not find channels on project with id ${projectId}`);
66
70
  }
67
71
  if (jsonFlag) {
68
- log_1.default.log(JSON.stringify(channels));
69
- return;
72
+ (0, json_1.printJsonOnlyOutput)(channels);
70
73
  }
71
- for (const channel of channels) {
72
- log_1.default.addNewLineIfNone();
73
- log_1.default.log((0, formatFields_1.default)([
74
- { label: 'Name', value: channel.name },
75
- { label: 'ID', value: channel.id },
76
- ]));
77
- (0, view_1.logChannelDetails)(channel);
74
+ else {
75
+ for (const channel of channels) {
76
+ log_1.default.addNewLineIfNone();
77
+ log_1.default.log((0, formatFields_1.default)([
78
+ { label: 'Name', value: channel.name },
79
+ { label: 'ID', value: channel.id },
80
+ ]));
81
+ (0, view_1.logChannelDetails)(channel);
82
+ }
78
83
  }
79
84
  }
80
85
  }
@@ -8,6 +8,7 @@ const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/Ea
8
8
  const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
9
9
  const projectUtils_1 = require("../../project/projectUtils");
10
10
  const prompts_1 = require("../../prompts");
11
+ const json_1 = require("../../utils/json");
11
12
  const edit_1 = require("./edit");
12
13
  const view_1 = require("./view");
13
14
  async function promptForRolloutPercentAsync({ promptMessage, }) {
@@ -166,6 +167,9 @@ class ChannelRollout extends EasCommand_1.default {
166
167
  async runAsync() {
167
168
  var _a, _b;
168
169
  const { args: { channel: channelName }, flags: { json: jsonFlag, end: endFlag, branch: branchName, percent }, } = await this.parse(ChannelRollout);
170
+ if (jsonFlag) {
171
+ (0, json_1.enableJsonOutput)();
172
+ }
169
173
  const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
170
174
  const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
171
175
  const fullName = await (0, projectUtils_1.getProjectFullNameAsync)(exp);
@@ -228,10 +232,11 @@ class ChannelRollout extends EasCommand_1.default {
228
232
  }
229
233
  const { newChannelInfo, logMessage } = rolloutMutationResult;
230
234
  if (jsonFlag) {
231
- log_1.default.log(JSON.stringify(newChannelInfo));
232
- return;
235
+ (0, json_1.printJsonOnlyOutput)(newChannelInfo);
236
+ }
237
+ else {
238
+ log_1.default.withTick(logMessage);
233
239
  }
234
- log_1.default.withTick(logMessage);
235
240
  }
236
241
  }
237
242
  exports.default = ChannelRollout;
@@ -15,6 +15,7 @@ const projectUtils_1 = require("../../project/projectUtils");
15
15
  const prompts_1 = require("../../prompts");
16
16
  const utils_1 = require("../../update/utils");
17
17
  const formatFields_1 = (0, tslib_1.__importDefault)(require("../../utils/formatFields"));
18
+ const json_1 = require("../../utils/json");
18
19
  /**
19
20
  * Get the branch mapping and determine whether it is a rollout.
20
21
  * Ensure that the branch mapping is properly formatted.
@@ -147,6 +148,9 @@ class ChannelView extends EasCommand_1.default {
147
148
  async runAsync() {
148
149
  var _a;
149
150
  let { args: { name: channelName }, flags: { json: jsonFlag }, } = await this.parse(ChannelView);
151
+ if (jsonFlag) {
152
+ (0, json_1.enableJsonOutput)();
153
+ }
150
154
  const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
151
155
  const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
152
156
  const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
@@ -171,18 +175,19 @@ class ChannelView extends EasCommand_1.default {
171
175
  throw new Error(`Could not find a channel with name: ${channelName}`);
172
176
  }
173
177
  if (jsonFlag) {
174
- log_1.default.log(JSON.stringify(channel));
175
- return;
178
+ (0, json_1.printJsonOnlyOutput)(channel);
179
+ }
180
+ else {
181
+ log_1.default.addNewLineIfNone();
182
+ log_1.default.log(chalk_1.default.bold('Channel:'));
183
+ log_1.default.log((0, formatFields_1.default)([
184
+ { label: 'Name', value: channel.name },
185
+ { label: 'ID', value: channel.id },
186
+ ]));
187
+ log_1.default.addNewLineIfNone();
188
+ log_1.default.log((0, chalk_1.default) `{bold Branches pointed at this channel and their most recent update group:}`);
189
+ logChannelDetails(channel);
176
190
  }
177
- log_1.default.addNewLineIfNone();
178
- log_1.default.log(chalk_1.default.bold('Channel:'));
179
- log_1.default.log((0, formatFields_1.default)([
180
- { label: 'Name', value: channel.name },
181
- { label: 'ID', value: channel.id },
182
- ]));
183
- log_1.default.addNewLineIfNone();
184
- log_1.default.log((0, chalk_1.default) `{bold Branches pointed at this channel and their most recent update group:}`);
185
- logChannelDetails(channel);
186
191
  }
187
192
  }
188
193
  exports.default = ChannelView;
@@ -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;
@@ -41,7 +41,7 @@ async function configureProjectForEASUpdateAsync(projectDir, exp, isBare) {
41
41
  log_1.default.addNewLineIfNone();
42
42
  log_1.default.warn(`It looks like you are using a dynamic configuration! ${(0, log_1.learnMore)('https://docs.expo.dev/workflow/configuration/#dynamic-configuration-with-appconfigjs)')}`);
43
43
  log_1.default.warn(`In order to finish configuring your project for EAS Update, you are going to need manually add the following to your app.config.js:\n${(0, log_1.learnMore)('https://expo.fyi/eas-update-config.md')}\n`);
44
- log_1.default.log(chalk_1.default.bold(`{\n updates": {\n "url": "${easUpdateURL}"\n },\n "runtimeVersion": {\n "policy": "sdkVersion"\n }\n}`));
44
+ log_1.default.log(chalk_1.default.bold(`{\n "updates": {\n "url": "${easUpdateURL}"\n },\n "runtimeVersion": {\n "policy": "sdkVersion"\n }\n}`));
45
45
  log_1.default.addNewLineIfNone();
46
46
  throw new Error(result.message);
47
47
  }
@@ -8,6 +8,7 @@ const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/Ea
8
8
  const client_1 = require("../../graphql/client");
9
9
  const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
10
10
  const prompts_1 = require("../../prompts");
11
+ const json_1 = require("../../utils/json");
11
12
  async function deleteUpdateGroupAsync({ group, }) {
12
13
  return await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
13
14
  .mutation((0, graphql_tag_1.default) `
@@ -24,7 +25,10 @@ async function deleteUpdateGroupAsync({ group, }) {
24
25
  class UpdateDelete extends EasCommand_1.default {
25
26
  async runAsync() {
26
27
  const { args: { groupId: group }, flags: { json: jsonFlag }, } = await this.parse(UpdateDelete);
27
- if (!jsonFlag) {
28
+ if (jsonFlag) {
29
+ (0, json_1.enableJsonOutput)();
30
+ }
31
+ else {
28
32
  const shouldAbort = await (0, prompts_1.confirmAsync)({
29
33
  message: `🚨${chalk_1.default.red('CAUTION')}🚨\n\n` +
30
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` +
@@ -39,10 +43,11 @@ class UpdateDelete extends EasCommand_1.default {
39
43
  }
40
44
  await deleteUpdateGroupAsync({ group });
41
45
  if (jsonFlag) {
42
- log_1.default.log(JSON.stringify({ group }));
43
- return;
46
+ (0, json_1.printJsonOnlyOutput)({ group });
47
+ }
48
+ else {
49
+ log_1.default.withTick(`Deleted update group ${group}`);
44
50
  }
45
- log_1.default.withTick(`Deleted update group ${group}`);
46
51
  }
47
52
  }
48
53
  exports.default = UpdateDelete;
@@ -14,6 +14,7 @@ const api_1 = require("../../api");
14
14
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
15
15
  const client_1 = require("../../graphql/client");
16
16
  const PublishMutation_1 = require("../../graphql/mutations/PublishMutation");
17
+ const UpdateQuery_1 = require("../../graphql/queries/UpdateQuery");
17
18
  const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
18
19
  const ora_1 = require("../../ora");
19
20
  const projectUtils_1 = require("../../project/projectUtils");
@@ -23,10 +24,10 @@ const prompts_1 = require("../../prompts");
23
24
  const utils_1 = require("../../update/utils");
24
25
  const uniqBy_1 = (0, tslib_1.__importDefault)(require("../../utils/expodash/uniqBy"));
25
26
  const formatFields_1 = (0, tslib_1.__importDefault)(require("../../utils/formatFields"));
27
+ const json_1 = require("../../utils/json");
26
28
  const vcs_1 = require("../../vcs");
27
29
  const create_1 = require("../branch/create");
28
30
  const list_1 = require("../branch/list");
29
- const view_1 = require("../branch/view");
30
31
  const create_2 = require("../channel/create");
31
32
  exports.defaultPublishPlatforms = ['android', 'ios'];
32
33
  async function getUpdateGroupAsync({ group, }) {
@@ -67,7 +68,7 @@ async function ensureChannelExistsAsync({ appId, branchId, channelName, }) {
67
68
  }
68
69
  }
69
70
  async function ensureBranchExistsAsync({ appId, name: branchName, }) {
70
- const { app } = await (0, view_1.viewUpdateBranchAsync)({
71
+ const { app } = await UpdateQuery_1.UpdateQuery.viewBranchAsync({
71
72
  appId,
72
73
  name: branchName,
73
74
  });
@@ -86,6 +87,9 @@ class UpdatePublish extends EasCommand_1.default {
86
87
  async runAsync() {
87
88
  var _a, _b, _c;
88
89
  let { flags: { branch: branchName, json: jsonFlag, auto: autoFlag, message, republish, group, 'input-dir': inputDir, 'skip-bundler': skipBundler, platform, }, } = await this.parse(UpdatePublish);
90
+ if (jsonFlag) {
91
+ (0, json_1.enableJsonOutput)();
92
+ }
89
93
  const platformFlag = platform;
90
94
  // If a group was specified, that means we are republishing it.
91
95
  republish = group ? true : republish;
@@ -278,7 +282,7 @@ class UpdatePublish extends EasCommand_1.default {
278
282
  throw e;
279
283
  }
280
284
  if (jsonFlag) {
281
- log_1.default.log(JSON.stringify(newUpdates));
285
+ (0, json_1.printJsonOnlyOutput)(newUpdates);
282
286
  }
283
287
  else {
284
288
  if (new Set(newUpdates.map(update => update.group)).size > 1) {
@@ -0,0 +1,10 @@
1
+ import EasCommand from '../../commandUtils/EasCommand';
2
+ export default class BranchView extends EasCommand {
3
+ static description: string;
4
+ static flags: {
5
+ branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
6
+ all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
7
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ runAsync(): Promise<void>;
10
+ }
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const config_1 = require("@expo/config");
5
+ const core_1 = require("@oclif/core");
6
+ const assert_1 = (0, tslib_1.__importDefault)(require("assert"));
7
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
8
+ const cli_table3_1 = (0, tslib_1.__importDefault)(require("cli-table3"));
9
+ const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
10
+ const UpdateQuery_1 = require("../../graphql/queries/UpdateQuery");
11
+ const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
12
+ const projectUtils_1 = require("../../project/projectUtils");
13
+ const prompts_1 = require("../../prompts");
14
+ const utils_1 = require("../../update/utils");
15
+ const groupBy_1 = (0, tslib_1.__importDefault)(require("../../utils/expodash/groupBy"));
16
+ const json_1 = require("../../utils/json");
17
+ const vcs_1 = require("../../vcs");
18
+ class BranchView extends EasCommand_1.default {
19
+ async runAsync() {
20
+ var _a, _b;
21
+ const { flags: { branch: branchFlag, all, json: jsonFlag }, } = await this.parse(BranchView);
22
+ if (jsonFlag) {
23
+ (0, json_1.enableJsonOutput)();
24
+ }
25
+ const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
26
+ const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
27
+ const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
28
+ let updateGroupDescriptions;
29
+ if (all) {
30
+ const branchesAndUpdates = await UpdateQuery_1.UpdateQuery.viewAllAsync({ appId: projectId });
31
+ updateGroupDescriptions = getUpdateGroupDescriptions(branchesAndUpdates.app.byId.updateBranches);
32
+ }
33
+ else {
34
+ let branchInteractive;
35
+ if (!branchFlag) {
36
+ const validationMessage = 'Branch name may not be empty.';
37
+ if (jsonFlag) {
38
+ throw new Error(validationMessage);
39
+ }
40
+ ({ name: branchInteractive } = await (0, prompts_1.promptAsync)({
41
+ type: 'text',
42
+ name: 'name',
43
+ message: 'Please enter the name of the branch whose updates you wish to view:',
44
+ initial: (_a = (await (0, vcs_1.getVcsClient)().getBranchNameAsync())) !== null && _a !== void 0 ? _a : undefined,
45
+ validate: (value) => (value ? true : validationMessage),
46
+ }));
47
+ }
48
+ const branch = branchFlag !== null && branchFlag !== void 0 ? branchFlag : branchInteractive;
49
+ (0, assert_1.default)(branch, 'Branch name may not be empty.');
50
+ const branchesAndUpdates = await UpdateQuery_1.UpdateQuery.viewBranchAsync({
51
+ appId: projectId,
52
+ name: branch,
53
+ });
54
+ const UpdateBranch = (_b = branchesAndUpdates.app) === null || _b === void 0 ? void 0 : _b.byId.updateBranchByName;
55
+ if (!UpdateBranch) {
56
+ throw new Error(`Could not find branch "${branch}"`);
57
+ }
58
+ updateGroupDescriptions = getUpdateGroupDescriptions([UpdateBranch]);
59
+ }
60
+ if (jsonFlag) {
61
+ (0, json_1.printJsonOnlyOutput)(updateGroupDescriptions);
62
+ }
63
+ else {
64
+ logAsTable(updateGroupDescriptions);
65
+ }
66
+ }
67
+ }
68
+ exports.default = BranchView;
69
+ BranchView.description = 'View the recent updates for a branch';
70
+ BranchView.flags = {
71
+ branch: core_1.Flags.string({
72
+ description: 'List all updates on this branch',
73
+ exclusive: ['all'],
74
+ }),
75
+ all: core_1.Flags.boolean({
76
+ description: 'List all updates associated with this project',
77
+ exclusive: ['branch'],
78
+ default: false,
79
+ }),
80
+ json: core_1.Flags.boolean({
81
+ description: `Return a json with all of the recent update groups.`,
82
+ default: false,
83
+ }),
84
+ };
85
+ function getUpdateGroupDescriptions(branchesAndUpdates) {
86
+ const flattenedBranchesAndUpdates = branchesAndUpdates.flatMap(branch => branch.updates.map(update => {
87
+ return { branch: branch.name, ...update };
88
+ }));
89
+ const updateGroupDescriptions = Object.values((0, groupBy_1.default)(flattenedBranchesAndUpdates, update => update.group)).map(updateGroup => {
90
+ const platforms = updateGroup
91
+ .map(update => update.platform)
92
+ .sort()
93
+ .join(', ');
94
+ return { ...updateGroup[0], platforms };
95
+ });
96
+ updateGroupDescriptions.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
97
+ return updateGroupDescriptions;
98
+ }
99
+ function logAsTable(updateGroupDescriptions) {
100
+ const table = new cli_table3_1.default({
101
+ head: ['Branch', ...utils_1.UPDATE_COLUMNS],
102
+ wordWrap: true,
103
+ });
104
+ table.push(...updateGroupDescriptions.map(updateGroupDescription => [
105
+ updateGroupDescription.branch,
106
+ (0, utils_1.formatUpdate)(updateGroupDescription),
107
+ updateGroupDescription.runtimeVersion,
108
+ updateGroupDescription.group,
109
+ updateGroupDescription.platforms,
110
+ ]));
111
+ log_1.default.addNewLineIfNone();
112
+ log_1.default.log(chalk_1.default.bold('Recently published update groups:'));
113
+ log_1.default.log(table.toString());
114
+ }
@@ -9,6 +9,7 @@ const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/Ea
9
9
  const client_1 = require("../../graphql/client");
10
10
  const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
11
11
  const utils_1 = require("../../update/utils");
12
+ const json_1 = require("../../utils/json");
12
13
  async function viewUpdateAsync({ groupId, }) {
13
14
  const data = await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
14
15
  .query((0, graphql_tag_1.default) `
@@ -45,26 +46,30 @@ class UpdateView extends EasCommand_1.default {
45
46
  async runAsync() {
46
47
  var _a;
47
48
  const { args: { groupId }, flags: { json: jsonFlag }, } = await this.parse(UpdateView);
49
+ if (jsonFlag) {
50
+ (0, json_1.enableJsonOutput)();
51
+ }
48
52
  const { updatesByGroup } = await viewUpdateAsync({ groupId });
49
53
  if (jsonFlag) {
50
- log_1.default.log(JSON.stringify(updatesByGroup));
51
- return;
54
+ (0, json_1.printJsonOnlyOutput)(updatesByGroup);
55
+ }
56
+ else {
57
+ const groupTable = new cli_table3_1.default({
58
+ head: [...utils_1.UPDATE_COLUMNS],
59
+ wordWrap: true,
60
+ });
61
+ const representativeUpdate = updatesByGroup[0];
62
+ groupTable.push([
63
+ (0, utils_1.formatUpdate)(representativeUpdate),
64
+ representativeUpdate.runtimeVersion,
65
+ representativeUpdate.group,
66
+ (0, utils_1.getPlatformsForGroup)({
67
+ updates: updatesByGroup,
68
+ group: (_a = updatesByGroup[0]) === null || _a === void 0 ? void 0 : _a.group,
69
+ }),
70
+ ]);
71
+ log_1.default.log(groupTable.toString());
52
72
  }
53
- const groupTable = new cli_table3_1.default({
54
- head: [...utils_1.UPDATE_COLUMNS],
55
- wordWrap: true,
56
- });
57
- const representativeUpdate = updatesByGroup[0];
58
- groupTable.push([
59
- (0, utils_1.formatUpdate)(representativeUpdate),
60
- representativeUpdate.runtimeVersion,
61
- representativeUpdate.group,
62
- (0, utils_1.getPlatformsForGroup)({
63
- updates: updatesByGroup,
64
- group: (_a = updatesByGroup[0]) === null || _a === void 0 ? void 0 : _a.group,
65
- }),
66
- ]);
67
- log_1.default.log(groupTable.toString());
68
73
  }
69
74
  }
70
75
  exports.default = UpdateView;
@@ -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 on the current project.';
31
31
  WebhookUpdate.flags = {
32
32
  id: core_1.Flags.string({
33
33
  description: 'Webhook ID',