eas-cli 3.1.1 → 3.2.1

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.
@@ -1,12 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLatestBuildAsync = exports.listAndSelectBuildsOnAppAsync = exports.listAndSelectBuildOnAppAsync = exports.listAndRenderBuildsOnAppAsync = exports.BUILDS_LIMIT = void 0;
3
+ exports.getLatestBuildAsync = exports.listAndSelectBuildOnAppAsync = exports.listAndRenderBuildsOnAppAsync = exports.BUILDS_LIMIT = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  const generated_1 = require("../graphql/generated");
7
7
  const BuildQuery_1 = require("../graphql/queries/BuildQuery");
8
8
  const log_1 = tslib_1.__importDefault(require("../log"));
9
- const prompts_1 = require("../prompts");
10
9
  const date_1 = require("../utils/date");
11
10
  const json_1 = require("../utils/json");
12
11
  const queries_1 = require("../utils/queries");
@@ -41,13 +40,13 @@ async function listAndRenderBuildsOnAppAsync(graphqlClient, { projectId, project
41
40
  }
42
41
  }
43
42
  exports.listAndRenderBuildsOnAppAsync = listAndRenderBuildsOnAppAsync;
44
- async function listAndSelectBuildOnAppAsync(graphqlClient, { projectId, title, filter, paginatedQueryOptions, }) {
43
+ async function listAndSelectBuildOnAppAsync(graphqlClient, { projectId, title, filter, paginatedQueryOptions, selectPromptDisabledFunction, selectPromptWarningMessage, }) {
45
44
  var _a;
46
45
  if (paginatedQueryOptions.nonInteractive) {
47
46
  throw new Error('Unable to select a build in non-interactive mode.');
48
47
  }
49
48
  else {
50
- return await (0, queries_1.paginatedQueryWithSelectPromptAsync)({
49
+ const selectedBuild = await (0, queries_1.paginatedQueryWithSelectPromptAsync)({
51
50
  limit: (_a = paginatedQueryOptions.limit) !== null && _a !== void 0 ? _a : exports.BUILDS_LIMIT,
52
51
  offset: paginatedQueryOptions.offset,
53
52
  queryToPerform: (limit, offset) => BuildQuery_1.BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
@@ -59,59 +58,35 @@ async function listAndSelectBuildOnAppAsync(graphqlClient, { projectId, title, f
59
58
  promptOptions: {
60
59
  title,
61
60
  getIdentifierForQueryItem: build => build.id,
62
- createDisplayTextForSelectionPromptListItem: formatBuildChoiceTitleAndDescription,
61
+ makePartialChoiceObject: createBuildToPartialChoiceMaker(selectPromptDisabledFunction),
62
+ selectPromptWarningMessage,
63
63
  },
64
64
  });
65
+ return selectedBuild !== null && selectedBuild !== void 0 ? selectedBuild : null;
65
66
  }
66
67
  }
67
68
  exports.listAndSelectBuildOnAppAsync = listAndSelectBuildOnAppAsync;
68
69
  function formatBuildChoiceValue(value) {
69
- return value ? chalk_1.default.bold(value) : chalk_1.default.dim('Unknown');
70
+ return value ? chalk_1.default.bold(value) : 'Unknown';
70
71
  }
71
- function formatBuildChoiceTitleAndDescription(build) {
72
- var _a;
73
- const splitCommitMessage = (_a = build.gitCommitMessage) === null || _a === void 0 ? void 0 : _a.split('\n');
74
- const formattedCommitData = build.gitCommitHash && splitCommitMessage && splitCommitMessage.length > 0
75
- ? `${chalk_1.default.dim(build.gitCommitHash.slice(0, 7))} "${chalk_1.default.bold(splitCommitMessage[0] + (splitCommitMessage.length > 1 ? '…' : ''))}"`
76
- : 'Unknown';
77
- return {
78
- title: `ID: ${chalk_1.default.dim(build.id)} (${chalk_1.default.dim(`${(0, date_1.fromNow)(new Date(build.updatedAt))} ago`)})`,
79
- description: [
80
- `\tVersion: ${formatBuildChoiceValue(build.appVersion)}`,
81
- `\t${build.platform === generated_1.AppPlatform.Ios ? 'Build number' : 'Version code'}: ${formatBuildChoiceValue(build.appBuildVersion)}`,
82
- `\tCommit: ${formattedCommitData}`,
83
- ].join('\n'),
72
+ function createBuildToPartialChoiceMaker(selectPromptDisabledFunction) {
73
+ return (build) => {
74
+ var _a;
75
+ const splitCommitMessage = (_a = build.gitCommitMessage) === null || _a === void 0 ? void 0 : _a.split('\n');
76
+ const formattedCommitData = build.gitCommitHash && splitCommitMessage && splitCommitMessage.length > 0
77
+ ? `${build.gitCommitHash.slice(0, 7)} "${chalk_1.default.bold(splitCommitMessage[0] + (splitCommitMessage.length > 1 ? '…' : ''))}"`
78
+ : 'Unknown';
79
+ return {
80
+ title: `${chalk_1.default.bold(`ID:`)} ${build.id} (${chalk_1.default.bold(`${(0, date_1.fromNow)(new Date(build.completedAt))} ago`)})`,
81
+ description: [
82
+ `\t${chalk_1.default.bold(`Version:`)} ${formatBuildChoiceValue(build.appVersion)}`,
83
+ `\t${chalk_1.default.bold(build.platform === generated_1.AppPlatform.Ios ? 'Build number:' : 'Version code:')} ${formatBuildChoiceValue(build.appBuildVersion)}`,
84
+ `\t${chalk_1.default.bold(`Commit:`)} ${formattedCommitData}`,
85
+ ].join('\n'),
86
+ disabled: selectPromptDisabledFunction === null || selectPromptDisabledFunction === void 0 ? void 0 : selectPromptDisabledFunction(build),
87
+ };
84
88
  };
85
89
  }
86
- async function listAndSelectBuildsOnAppAsync(graphqlClient, selectedPlatform, { projectId, projectDisplayName, filter, queryOptions, selectPromptDisabledFunction, warningMessage, }) {
87
- var _a;
88
- const builds = await BuildQuery_1.BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
89
- appId: projectId,
90
- limit: (_a = queryOptions.limit) !== null && _a !== void 0 ? _a : exports.BUILDS_LIMIT,
91
- offset: queryOptions.offset,
92
- filter,
93
- });
94
- if (builds.length === 0) {
95
- throw new Error('Found no builds matching the provided criteria.');
96
- }
97
- const { selectedSimulatorBuild } = await (0, prompts_1.promptAsync)({
98
- type: 'select',
99
- message: `Select ${selectedPlatform === generated_1.AppPlatform.Ios ? 'iOS' : 'Android'} ${selectedPlatform === generated_1.AppPlatform.Ios ? 'simulator' : 'emulator'} build to run for ${projectDisplayName} app`,
100
- name: 'selectedSimulatorBuild',
101
- choices: builds.map(build => {
102
- const buildChoice = formatBuildChoiceTitleAndDescription(build);
103
- return {
104
- title: buildChoice.title,
105
- description: buildChoice.description,
106
- value: build,
107
- disabled: selectPromptDisabledFunction === null || selectPromptDisabledFunction === void 0 ? void 0 : selectPromptDisabledFunction(build),
108
- };
109
- }),
110
- warn: warningMessage,
111
- });
112
- return selectedSimulatorBuild;
113
- }
114
- exports.listAndSelectBuildsOnAppAsync = listAndSelectBuildsOnAppAsync;
115
90
  async function getLatestBuildAsync(graphqlClient, { projectId, filter, }) {
116
91
  const builds = await BuildQuery_1.BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
117
92
  appId: projectId,
@@ -120,7 +95,7 @@ async function getLatestBuildAsync(graphqlClient, { projectId, filter, }) {
120
95
  filter,
121
96
  });
122
97
  if (builds.length === 0) {
123
- throw new Error('Found no build matching the provided criteria.');
98
+ return null;
124
99
  }
125
100
  return builds[0];
126
101
  }
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.printUserError = exports.printDeprecationWarnings = exports.printBuildResults = exports.printLogsUrls = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const assert_1 = tslib_1.__importDefault(require("assert"));
6
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
6
  const indent_string_1 = tslib_1.__importDefault(require("indent-string"));
8
7
  const qrcode_terminal_1 = tslib_1.__importDefault(require("qrcode-terminal"));
9
8
  const generated_1 = require("../../graphql/generated");
@@ -12,12 +11,12 @@ const platform_1 = require("../../platform");
12
11
  const url_1 = require("./url");
13
12
  function printLogsUrls(builds) {
14
13
  if (builds.length === 1) {
15
- log_1.default.log(`Build details: ${chalk_1.default.underline((0, url_1.getBuildLogsUrl)(builds[0]))}`);
14
+ log_1.default.log(`Build details: ${(0, log_1.link)((0, url_1.getBuildLogsUrl)(builds[0]))}`);
16
15
  }
17
16
  else {
18
17
  builds.forEach(build => {
19
18
  const logsUrl = (0, url_1.getBuildLogsUrl)(build);
20
- log_1.default.log(`${platform_1.appPlatformEmojis[build.platform]} ${platform_1.appPlatformDisplayNames[build.platform]} build details: ${chalk_1.default.underline(logsUrl)}`);
19
+ log_1.default.log(`${platform_1.appPlatformEmojis[build.platform]} ${platform_1.appPlatformDisplayNames[build.platform]} build details: ${(0, log_1.link)(logsUrl)}`);
21
20
  });
22
21
  }
23
22
  }
@@ -56,14 +55,14 @@ function printBuildResult(build) {
56
55
  const qrcodeUrl = build.platform === generated_1.AppPlatform.Ios ? (0, url_1.getInternalDistributionInstallUrl)(build) : logsUrl;
57
56
  qrcode_terminal_1.default.generate(qrcodeUrl, { small: true }, code => log_1.default.log(`${(0, indent_string_1.default)(code, 2)}\n`));
58
57
  log_1.default.log(`${platform_1.appPlatformEmojis[build.platform]} Open this link on your ${platform_1.appPlatformDisplayNames[build.platform]} devices (or scan the QR code) to install the app:`);
59
- log_1.default.log(`${chalk_1.default.underline(logsUrl)}`);
58
+ log_1.default.log(`${(0, log_1.link)(logsUrl)}`);
60
59
  }
61
60
  else {
62
61
  // TODO: it looks like buildUrl could possibly be undefined, based on the code below.
63
62
  // we should account for this case better if it is possible
64
63
  const url = (_b = (_a = build.artifacts) === null || _a === void 0 ? void 0 : _a.buildUrl) !== null && _b !== void 0 ? _b : '';
65
64
  log_1.default.log(`${platform_1.appPlatformEmojis[build.platform]} ${platform_1.appPlatformDisplayNames[build.platform]} app:`);
66
- log_1.default.log(`${chalk_1.default.underline(url)}`);
65
+ log_1.default.log(`${(0, log_1.link)(url)}`);
67
66
  }
68
67
  }
69
68
  function printDeprecationWarnings(deprecationInfo) {
@@ -24,7 +24,7 @@ async function selectChannelOnAppAsync(graphqlClient, { projectId, selectionProm
24
24
  queryToPerform: (limit, offset) => queryChannelsOnAppAsync(graphqlClient, { appId: projectId, limit, offset }),
25
25
  promptOptions: {
26
26
  title: selectionPromptTitle,
27
- createDisplayTextForSelectionPromptListItem: updateChannel => ({ title: updateChannel.name }),
27
+ makePartialChoiceObject: updateChannel => ({ title: updateChannel.name }),
28
28
  getIdentifierForQueryItem: updateChannel => updateChannel.id,
29
29
  },
30
30
  });
@@ -12,6 +12,7 @@ const pagination_1 = require("../../commandUtils/pagination");
12
12
  const generated_1 = require("../../graphql/generated");
13
13
  const BuildQuery_1 = require("../../graphql/queries/BuildQuery");
14
14
  const log_1 = tslib_1.__importDefault(require("../../log"));
15
+ const platform_1 = require("../../platform");
15
16
  const projectUtils_1 = require("../../project/projectUtils");
16
17
  const prompts_1 = require("../../prompts");
17
18
  const run_1 = require("../../run/run");
@@ -103,30 +104,47 @@ async function resolvePlatformAsync(platform) {
103
104
  });
104
105
  return selectedPlatform;
105
106
  }
107
+ function validateChosenBuild(maybeBuild, selectedPlatform) {
108
+ if (!maybeBuild) {
109
+ throw new Error('There are no simulator/emulator builds that can be run for this project.');
110
+ }
111
+ if (selectedPlatform !== maybeBuild.platform) {
112
+ throw new Error(`The selected build is for ${platform_1.appPlatformDisplayNames[maybeBuild.platform]}, but you selected ${platform_1.appPlatformDisplayNames[selectedPlatform]}`);
113
+ }
114
+ if (maybeBuild.status !== generated_1.BuildStatus.Finished) {
115
+ throw new Error('The selected build is not finished.');
116
+ }
117
+ if (!(0, utils_1.isRunnableOnSimulatorOrEmulator)(maybeBuild)) {
118
+ throw new Error('Artifacts for the latest build have expired and are no longer available, or this is not a simulator/emulator build.');
119
+ }
120
+ return maybeBuild;
121
+ }
106
122
  async function maybeGetBuildAsync(graphqlClient, flags, projectId, paginatedQueryOptions) {
107
123
  const distributionType = flags.selectedPlatform === generated_1.AppPlatform.Ios ? generated_1.DistributionType.Simulator : undefined;
108
124
  if (flags.runArchiveFlags.id) {
109
- return BuildQuery_1.BuildQuery.byIdAsync(graphqlClient, flags.runArchiveFlags.id);
125
+ const build = await BuildQuery_1.BuildQuery.byIdAsync(graphqlClient, flags.runArchiveFlags.id);
126
+ return validateChosenBuild(build, flags.selectedPlatform);
110
127
  }
111
128
  else if (!flags.runArchiveFlags.id &&
112
129
  !flags.runArchiveFlags.path &&
113
130
  !flags.runArchiveFlags.url &&
114
131
  !flags.runArchiveFlags.latest) {
115
- return await (0, queries_1.listAndSelectBuildsOnAppAsync)(graphqlClient, flags.selectedPlatform, {
132
+ const build = await (0, queries_1.listAndSelectBuildOnAppAsync)(graphqlClient, {
116
133
  projectId,
117
- projectDisplayName: await (0, projectUtils_1.getDisplayNameForProjectIdAsync)(graphqlClient, projectId),
134
+ title: `Select ${platform_1.appPlatformDisplayNames[flags.selectedPlatform]} ${flags.selectedPlatform === generated_1.AppPlatform.Ios ? 'simulator' : 'emulator'} build to run for ${await (0, projectUtils_1.getDisplayNameForProjectIdAsync)(graphqlClient, projectId)} app`,
118
135
  filter: {
119
136
  platform: flags.selectedPlatform,
120
137
  distribution: distributionType,
121
138
  status: generated_1.BuildStatus.Finished,
122
139
  },
123
- queryOptions: paginatedQueryOptions,
140
+ paginatedQueryOptions,
124
141
  selectPromptDisabledFunction: build => !(0, utils_1.isRunnableOnSimulatorOrEmulator)(build),
125
- warningMessage: 'Artifacts for this build have expired and are no longer available, or this is not a simulator/emulator build.',
142
+ selectPromptWarningMessage: 'Artifacts for this build have expired and are no longer available, or this is not a simulator/emulator build.',
126
143
  });
144
+ return validateChosenBuild(build, flags.selectedPlatform);
127
145
  }
128
146
  else if (flags.runArchiveFlags.latest) {
129
- return await (0, queries_1.getLatestBuildAsync)(graphqlClient, {
147
+ const latestBuild = await (0, queries_1.getLatestBuildAsync)(graphqlClient, {
130
148
  projectId,
131
149
  filter: {
132
150
  platform: flags.selectedPlatform,
@@ -134,6 +152,7 @@ async function maybeGetBuildAsync(graphqlClient, flags, projectId, paginatedQuer
134
152
  status: generated_1.BuildStatus.Finished,
135
153
  },
136
154
  });
155
+ return validateChosenBuild(latestBuild, flags.selectedPlatform);
137
156
  }
138
157
  else {
139
158
  return null;
@@ -6,14 +6,13 @@ const config_1 = require("@expo/config");
6
6
  const core_1 = require("@oclif/core");
7
7
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
8
  const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
9
- const terminal_link_1 = tslib_1.__importDefault(require("terminal-link"));
10
9
  const url_1 = require("../../build/utils/url");
11
10
  const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
12
11
  const getProjectIdAsync_1 = require("../../commandUtils/context/contextUtils/getProjectIdAsync");
13
12
  const generated_1 = require("../../graphql/generated");
14
13
  const AppMutation_1 = require("../../graphql/mutations/AppMutation");
15
14
  const AppQuery_1 = require("../../graphql/queries/AppQuery");
16
- const log_1 = tslib_1.__importDefault(require("../../log"));
15
+ const log_1 = tslib_1.__importStar(require("../../log"));
17
16
  const ora_1 = require("../../ora");
18
17
  const expoConfig_1 = require("../../project/expoConfig");
19
18
  const fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync_1 = require("../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync");
@@ -197,10 +196,7 @@ class ProjectInit extends EasCommand_1.default {
197
196
  throw new Error(`Project ID configuration canceled for ${projectFullName}.`);
198
197
  }
199
198
  const projectDashboardUrl = (0, url_1.getProjectDashboardUrl)(accountName, projectName);
200
- const projectLink = (0, terminal_link_1.default)(projectFullName, projectDashboardUrl, {
201
- // https://github.com/sindresorhus/terminal-link/issues/18#issuecomment-1068020361
202
- fallback: () => `${projectFullName} (${projectDashboardUrl})`,
203
- });
199
+ const projectLink = (0, log_1.link)(projectDashboardUrl, { text: projectFullName });
204
200
  const account = (0, nullthrows_1.default)(allAccounts.find(a => a.name === accountName));
205
201
  const spinner = (0, ora_1.ora)(`Creating ${chalk_1.default.bold(projectFullName)}`).start();
206
202
  let createdProjectId;
@@ -22,6 +22,7 @@ class UpdateConfigure extends EasCommand_1.default {
22
22
  projectDir,
23
23
  platform,
24
24
  });
25
+ await (0, configure_1.ensureEASUpdateIsConfiguredInEasJsonAsync)(projectDir);
25
26
  log_1.default.addNewLineIfNone();
26
27
  log_1.default.log(`🎉 Your app is configured with EAS Update!`);
27
28
  log_1.default.newLine();
@@ -2,6 +2,7 @@ import { Platform } from '@expo/config';
2
2
  import EasCommand from '../../commandUtils/EasCommand';
3
3
  declare type UpdateRepublishRawFlags = {
4
4
  branch?: string;
5
+ channel?: string;
5
6
  group?: string;
6
7
  message?: string;
7
8
  platform: string;
@@ -10,6 +11,7 @@ declare type UpdateRepublishRawFlags = {
10
11
  };
11
12
  declare type UpdateRepublishFlags = {
12
13
  branchName?: string;
14
+ channelName?: string;
13
15
  groupId?: string;
14
16
  updateMessage?: string;
15
17
  platform: Platform[];
@@ -21,6 +23,7 @@ export default class UpdateRepublish extends EasCommand {
21
23
  static flags: {
22
24
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
23
25
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
26
+ channel: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
24
27
  branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
25
28
  group: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
26
29
  message: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
@@ -13,6 +13,7 @@ const log_1 = tslib_1.__importStar(require("../../log"));
13
13
  const ora_1 = require("../../ora");
14
14
  const projectUtils_1 = require("../../project/projectUtils");
15
15
  const prompts_1 = require("../../prompts");
16
+ const getBranchNameFromChannelNameAsync_1 = require("../../update/getBranchNameFromChannelNameAsync");
16
17
  const queries_1 = require("../../update/queries");
17
18
  const utils_1 = require("../../update/utils");
18
19
  const formatFields_1 = tslib_1.__importDefault(require("../../utils/formatFields"));
@@ -107,18 +108,24 @@ class UpdateRepublish extends EasCommand_1.default {
107
108
  sanitizeFlags(rawFlags) {
108
109
  var _b;
109
110
  const branchName = rawFlags.branch;
111
+ const channelName = rawFlags.channel;
110
112
  const groupId = rawFlags.group;
111
- if (!branchName && !groupId) {
112
- throw new Error('Either --branch or --group must be specified');
113
+ const nonInteractive = rawFlags['non-interactive'];
114
+ if (nonInteractive && !groupId) {
115
+ throw new Error('Only --group can be used in non-interactive mode');
116
+ }
117
+ if (!groupId && !(branchName || channelName)) {
118
+ throw new Error(`--channel, --branch, or --group must be specified`);
113
119
  }
114
120
  const platform = rawFlags.platform === 'all' ? defaultRepublishPlatforms : [rawFlags.platform];
115
121
  return {
116
122
  branchName,
123
+ channelName,
117
124
  groupId,
118
125
  platform,
119
126
  updateMessage: rawFlags.message,
120
127
  json: (_b = rawFlags.json) !== null && _b !== void 0 ? _b : false,
121
- nonInteractive: rawFlags['non-interactive'],
128
+ nonInteractive,
122
129
  };
123
130
  }
124
131
  }
@@ -126,13 +133,17 @@ exports.default = UpdateRepublish;
126
133
  _a = UpdateRepublish;
127
134
  UpdateRepublish.description = 'rollback to an existing update';
128
135
  UpdateRepublish.flags = {
136
+ channel: core_1.Flags.string({
137
+ description: 'Channel name to select an update to republish from',
138
+ exclusive: ['branch', 'group'],
139
+ }),
129
140
  branch: core_1.Flags.string({
130
141
  description: 'Branch name to select an update to republish from',
131
- exclusive: ['group'],
142
+ exclusive: ['channel', 'group'],
132
143
  }),
133
144
  group: core_1.Flags.string({
134
145
  description: 'Update group ID to republish',
135
- exclusive: ['branch'],
146
+ exclusive: ['branch', 'channel'],
136
147
  }),
137
148
  message: core_1.Flags.string({
138
149
  description: 'Short message describing the republished update',
@@ -170,7 +181,14 @@ async function getOrAskUpdatesAsync(graphqlClient, projectId, flags) {
170
181
  projectId,
171
182
  });
172
183
  }
173
- throw new Error('Must supply --group or --branch');
184
+ if (flags.channelName) {
185
+ return await askUpdatesFromChannelNameAsync(graphqlClient, {
186
+ ...flags,
187
+ channelName: flags.channelName,
188
+ projectId,
189
+ });
190
+ }
191
+ throw new Error('--channel, --branch, or --group is required');
174
192
  }
175
193
  /** Ask the user which update needs to be republished by branch name, this requires interactive mode */
176
194
  async function askUpdatesFromBranchNameAsync(graphqlClient, { projectId, branchName, json, nonInteractive, }) {
@@ -189,6 +207,19 @@ async function askUpdatesFromBranchNameAsync(graphqlClient, { projectId, branchN
189
207
  branchName: group.branch.name,
190
208
  }));
191
209
  }
210
+ /** Ask the user which update needs to be republished by channel name, this requires interactive mode */
211
+ async function askUpdatesFromChannelNameAsync(graphqlClient, { projectId, channelName, json, nonInteractive, }) {
212
+ if (nonInteractive) {
213
+ throw new Error('Must supply --group when in non-interactive mode');
214
+ }
215
+ const branchName = await (0, getBranchNameFromChannelNameAsync_1.getBranchNameFromChannelNameAsync)(graphqlClient, projectId, channelName);
216
+ return await askUpdatesFromBranchNameAsync(graphqlClient, {
217
+ projectId,
218
+ branchName,
219
+ json,
220
+ nonInteractive,
221
+ });
222
+ }
192
223
  /** Get or ask the user for the update (group) message for the republish */
193
224
  async function getOrAskUpdateMessageAsync(updates, flags) {
194
225
  if (flags.updateMessage) {
@@ -3,6 +3,7 @@ import { WebhookType } from '../../graphql/generated';
3
3
  export default class WebhookList extends EasCommand {
4
4
  static description: string;
5
5
  static flags: {
6
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
7
  event: import("@oclif/core/lib/interfaces").OptionFlag<WebhookType | undefined>;
7
8
  };
8
9
  static contextDefinition: {
@@ -5,15 +5,20 @@ const tslib_1 = require("tslib");
5
5
  const core_1 = require("@oclif/core");
6
6
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
7
  const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
8
+ const flags_1 = require("../../commandUtils/flags");
8
9
  const generated_1 = require("../../graphql/generated");
9
10
  const WebhookQuery_1 = require("../../graphql/queries/WebhookQuery");
10
11
  const log_1 = tslib_1.__importDefault(require("../../log"));
11
12
  const ora_1 = require("../../ora");
12
13
  const projectUtils_1 = require("../../project/projectUtils");
14
+ const json_1 = require("../../utils/json");
13
15
  const formatWebhook_1 = require("../../webhooks/formatWebhook");
14
16
  class WebhookList extends EasCommand_1.default {
15
17
  async runAsync() {
16
- const { flags: { event }, } = await this.parse(WebhookList);
18
+ const { flags: { event, json }, } = await this.parse(WebhookList);
19
+ if (json) {
20
+ (0, json_1.enableJsonOutput)();
21
+ }
17
22
  const { projectConfig: { projectId }, loggedIn: { graphqlClient }, } = await this.getContextAsync(WebhookList, {
18
23
  nonInteractive: true,
19
24
  });
@@ -26,10 +31,15 @@ class WebhookList extends EasCommand_1.default {
26
31
  }
27
32
  else {
28
33
  spinner.succeed(`Found ${webhooks.length} webhooks on project ${projectDisplayName}`);
29
- const list = webhooks
30
- .map(webhook => (0, formatWebhook_1.formatWebhook)(webhook))
31
- .join(`\n\n${chalk_1.default.dim('———')}\n\n`);
32
- log_1.default.log(`\n${list}`);
34
+ if (json) {
35
+ (0, json_1.printJsonOnlyOutput)(webhooks);
36
+ }
37
+ else {
38
+ const list = webhooks
39
+ .map(webhook => (0, formatWebhook_1.formatWebhook)(webhook))
40
+ .join(`\n\n${chalk_1.default.dim('———')}\n\n`);
41
+ log_1.default.log(`\n${list}`);
42
+ }
33
43
  }
34
44
  }
35
45
  catch (err) {
@@ -46,6 +56,7 @@ WebhookList.flags = {
46
56
  description: 'Event type that triggers the webhook',
47
57
  options: [generated_1.WebhookType.Build, generated_1.WebhookType.Submit],
48
58
  }),
59
+ ...flags_1.EasJsonOnlyFlag,
49
60
  };
50
61
  WebhookList.contextDefinition = {
51
62
  ..._a.ContextOptions.ProjectConfig,
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertHTMLToASCII = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
- const terminal_link_1 = tslib_1.__importDefault(require("terminal-link"));
7
6
  // @ts-ignore
8
7
  const turndown_1 = tslib_1.__importDefault(require("turndown"));
9
8
  const wrap_ansi_1 = tslib_1.__importDefault(require("wrap-ansi"));
9
+ const log_1 = require("../../../log");
10
10
  const turndownServices = {};
11
11
  function getService(rootUrl) {
12
12
  if (turndownServices[rootUrl]) {
@@ -46,10 +46,7 @@ function getService(rootUrl) {
46
46
  if (href.startsWith('/')) {
47
47
  href = `${rootUrl}${href}`;
48
48
  }
49
- if (terminal_link_1.default.isSupported) {
50
- return chalk_1.default.cyan((0, terminal_link_1.default)(content, href));
51
- }
52
- return `${chalk_1.default.cyan(content)} (${chalk_1.default.underline(href)})`;
49
+ return chalk_1.default.cyan((0, log_1.link)(href, { text: content }));
53
50
  },
54
51
  });
55
52
  turndownServices[rootUrl] = turndownService;
@@ -29,7 +29,7 @@ async function selectAppleTeamOnAccountAsync(graphqlClient, { accountName, selec
29
29
  }),
30
30
  promptOptions: {
31
31
  title: selectionPromptTitle,
32
- createDisplayTextForSelectionPromptListItem: appleTeam => ({
32
+ makePartialChoiceObject: appleTeam => ({
33
33
  title: appleTeam.appleTeamName
34
34
  ? `${appleTeam.appleTeamName} (ID: ${appleTeam.appleTeamIdentifier})`
35
35
  : appleTeam.appleTeamIdentifier,
@@ -61,7 +61,7 @@ async function selectAppleDeviceOnAppleTeamAsync(graphqlClient, { accountName, a
61
61
  }),
62
62
  promptOptions: {
63
63
  title: selectionPromptTitle,
64
- createDisplayTextForSelectionPromptListItem: appleDevice => ({
64
+ makePartialChoiceObject: appleDevice => ({
65
65
  title: (0, DeviceUtils_1.formatDeviceLabel)(appleDevice),
66
66
  }),
67
67
  getIdentifierForQueryItem: appleTeam => appleTeam.id,
@@ -3693,11 +3693,15 @@ export declare type UserDataInput = {
3693
3693
  export declare type UserInvitation = {
3694
3694
  __typename?: 'UserInvitation';
3695
3695
  accountName: Scalars['String'];
3696
+ /** If the invite is for a personal team, the profile photo of account owner */
3697
+ accountProfilePhoto?: Maybe<Scalars['String']>;
3696
3698
  created: Scalars['DateTime'];
3697
3699
  /** Email to which this invitation was sent */
3698
3700
  email: Scalars['String'];
3699
3701
  expires: Scalars['DateTime'];
3700
3702
  id: Scalars['ID'];
3703
+ /** If the invite is for an organization or a personal team */
3704
+ isForOrganization: Scalars['Boolean'];
3701
3705
  /** Account permissions to be granted upon acceptance of this invitation */
3702
3706
  permissions: Array<Permission>;
3703
3707
  /** Role to be granted upon acceptance of this invitation */
@@ -3752,11 +3756,13 @@ export declare type UserInvitationMutationResendUserInvitationArgs = {
3752
3756
  export declare type UserInvitationPublicData = {
3753
3757
  __typename?: 'UserInvitationPublicData';
3754
3758
  accountName: Scalars['String'];
3759
+ accountProfilePhoto?: Maybe<Scalars['String']>;
3755
3760
  created: Scalars['DateTime'];
3756
3761
  email: Scalars['String'];
3757
3762
  expires: Scalars['DateTime'];
3758
3763
  /** Email to which this invitation was sent */
3759
3764
  id: Scalars['ID'];
3765
+ isForOrganization: Scalars['Boolean'];
3760
3766
  };
3761
3767
  export declare type UserInvitationPublicDataQuery = {
3762
3768
  __typename?: 'UserInvitationPublicDataQuery';
@@ -6770,6 +6776,7 @@ export declare type CreateAndroidBuildMutation = {
6770
6776
  priority: BuildPriority;
6771
6777
  createdAt: any;
6772
6778
  updatedAt: any;
6779
+ completedAt?: any | null;
6773
6780
  error?: {
6774
6781
  __typename?: 'BuildError';
6775
6782
  errorCode: string;
@@ -6850,6 +6857,7 @@ export declare type CreateIosBuildMutation = {
6850
6857
  priority: BuildPriority;
6851
6858
  createdAt: any;
6852
6859
  updatedAt: any;
6860
+ completedAt?: any | null;
6853
6861
  error?: {
6854
6862
  __typename?: 'BuildError';
6855
6863
  errorCode: string;
@@ -6926,6 +6934,7 @@ export declare type RetryIosBuildMutation = {
6926
6934
  priority: BuildPriority;
6927
6935
  createdAt: any;
6928
6936
  updatedAt: any;
6937
+ completedAt?: any | null;
6929
6938
  error?: {
6930
6939
  __typename?: 'BuildError';
6931
6940
  errorCode: string;
@@ -7474,6 +7483,7 @@ export declare type BuildsByIdQuery = {
7474
7483
  priority: BuildPriority;
7475
7484
  createdAt: any;
7476
7485
  updatedAt: any;
7486
+ completedAt?: any | null;
7477
7487
  error?: {
7478
7488
  __typename?: 'BuildError';
7479
7489
  errorCode: string;
@@ -7543,6 +7553,7 @@ export declare type BuildsWithSubmissionsByIdQuery = {
7543
7553
  priority: BuildPriority;
7544
7554
  createdAt: any;
7545
7555
  updatedAt: any;
7556
+ completedAt?: any | null;
7546
7557
  submissions: Array<{
7547
7558
  __typename?: 'Submission';
7548
7559
  id: string;
@@ -7652,6 +7663,7 @@ export declare type ViewBuildsOnAppQuery = {
7652
7663
  priority: BuildPriority;
7653
7664
  createdAt: any;
7654
7665
  updatedAt: any;
7666
+ completedAt?: any | null;
7655
7667
  error?: {
7656
7668
  __typename?: 'BuildError';
7657
7669
  errorCode: string;
@@ -8285,6 +8297,7 @@ export declare type BuildFragment = {
8285
8297
  priority: BuildPriority;
8286
8298
  createdAt: any;
8287
8299
  updatedAt: any;
8300
+ completedAt?: any | null;
8288
8301
  error?: {
8289
8302
  __typename?: 'BuildError';
8290
8303
  errorCode: string;
@@ -8345,6 +8358,7 @@ export declare type BuildWithSubmissionsFragment = {
8345
8358
  priority: BuildPriority;
8346
8359
  createdAt: any;
8347
8360
  updatedAt: any;
8361
+ completedAt?: any | null;
8348
8362
  submissions: Array<{
8349
8363
  __typename?: 'Submission';
8350
8364
  id: string;
@@ -54,6 +54,7 @@ exports.BuildFragmentNode = (0, graphql_tag_1.default) `
54
54
  priority
55
55
  createdAt
56
56
  updatedAt
57
+ completedAt
57
58
  }
58
59
  `;
59
60
  exports.BuildFragmentWithSubmissionsNode = (0, graphql_tag_1.default) `
package/build/log.js CHANGED
@@ -78,14 +78,10 @@ Log.isLastLineNewLine = false;
78
78
  * @example https://expo.dev
79
79
  */
80
80
  function link(url, { text = url, dim = true } = {}) {
81
- let output;
82
81
  // Links can be disabled via env variables https://github.com/jamestalmage/supports-hyperlinks/blob/master/index.js
83
- if (terminal_link_1.default.isSupported) {
84
- output = (0, terminal_link_1.default)(text, url);
85
- }
86
- else {
87
- output = `${text === url ? '' : text + ': '}${chalk_1.default.underline(url)}`;
88
- }
82
+ const output = (0, terminal_link_1.default)(text, url, {
83
+ fallback: () => (text === url ? chalk_1.default.underline(url) : `${text}: ${chalk_1.default.underline(url)}`),
84
+ });
89
85
  return dim ? chalk_1.default.dim(output) : output;
90
86
  }
91
87
  exports.link = link;
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.findProjectIdByAccountNameAndSlugNullableAsync = exports.fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
- const terminal_link_1 = tslib_1.__importDefault(require("terminal-link"));
7
6
  const url_1 = require("../build/utils/url");
8
7
  const generated_1 = require("../graphql/generated");
9
8
  const AppMutation_1 = require("../graphql/mutations/AppMutation");
10
9
  const AppQuery_1 = require("../graphql/queries/AppQuery");
10
+ const log_1 = require("../log");
11
11
  const ora_1 = require("../ora");
12
12
  const prompts_1 = require("../prompts");
13
13
  /**
@@ -51,10 +51,7 @@ async function fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync(graph
51
51
  throw new Error(`EAS project ID configuration canceled for ${projectFullName}. Run 'eas init' to configure.`);
52
52
  }
53
53
  const projectDashboardUrl = (0, url_1.getProjectDashboardUrl)(accountName, projectName);
54
- const projectLink = (0, terminal_link_1.default)(projectFullName, projectDashboardUrl, {
55
- // https://github.com/sindresorhus/terminal-link/issues/18#issuecomment-1068020361
56
- fallback: () => `${projectFullName} (${projectDashboardUrl})`,
57
- });
54
+ const projectLink = (0, log_1.link)(projectDashboardUrl, { text: projectFullName });
58
55
  const spinner = (0, ora_1.ora)(`Creating ${chalk_1.default.bold(projectFullName)} on Expo`).start();
59
56
  try {
60
57
  const id = await AppMutation_1.AppMutation.createAppAsync(graphqlClient, {