eas-cli 0.31.1 → 0.32.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 (34) hide show
  1. package/README.md +26 -26
  2. package/build/commands/submit.js +1 -3
  3. package/build/credentials/context.d.ts +1 -1
  4. package/build/credentials/context.js +5 -5
  5. package/build/credentials/errors.d.ts +3 -0
  6. package/build/credentials/errors.js +7 -1
  7. package/build/credentials/ios/actions/AscApiKeyUtils.d.ts +5 -0
  8. package/build/credentials/ios/actions/AscApiKeyUtils.js +63 -0
  9. package/build/credentials/ios/actions/DistributionCertificateUtils.js +5 -5
  10. package/build/credentials/ios/appstore/AppStoreApi.d.ts +7 -1
  11. package/build/credentials/ios/appstore/AppStoreApi.js +17 -0
  12. package/build/credentials/ios/appstore/Credentials.js +3 -3
  13. package/build/credentials/ios/appstore/Credentials.types.d.ts +13 -0
  14. package/build/credentials/ios/appstore/ascApiKey.d.ts +9 -0
  15. package/build/credentials/ios/appstore/ascApiKey.js +99 -0
  16. package/build/credentials/ios/credentials.d.ts +17 -0
  17. package/build/credentials/ios/credentials.js +16 -1
  18. package/build/graphql/generated.d.ts +24 -1
  19. package/build/graphql/generated.js +2 -0
  20. package/build/log.d.ts +11 -1
  21. package/build/log.js +21 -10
  22. package/build/submit/ArchiveSource.d.ts +7 -2
  23. package/build/submit/ArchiveSource.js +91 -8
  24. package/build/submit/ios/AscApiKeySource.d.ts +28 -0
  25. package/build/submit/ios/AscApiKeySource.js +51 -0
  26. package/build/submit/ios/IosSubmitCommand.d.ts +2 -0
  27. package/build/submit/ios/IosSubmitCommand.js +51 -3
  28. package/build/submit/ios/IosSubmitter.d.ts +3 -1
  29. package/build/submit/ios/IosSubmitter.js +48 -4
  30. package/build/submit/submit.js +1 -1
  31. package/build/submit/utils/builds.d.ts +3 -1
  32. package/build/submit/utils/builds.js +6 -6
  33. package/oclif.manifest.json +1 -1
  34. package/package.json +3 -3
package/README.md CHANGED
@@ -73,7 +73,7 @@ ALIASES
73
73
  $ eas login
74
74
  ```
75
75
 
76
- _See code: [src/commands/account/login.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/account/login.js)_
76
+ _See code: [src/commands/account/login.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/account/login.js)_
77
77
 
78
78
  ## `eas account:logout`
79
79
 
@@ -87,7 +87,7 @@ ALIASES
87
87
  $ eas logout
88
88
  ```
89
89
 
90
- _See code: [src/commands/account/logout.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/account/logout.js)_
90
+ _See code: [src/commands/account/logout.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/account/logout.js)_
91
91
 
92
92
  ## `eas account:view`
93
93
 
@@ -101,7 +101,7 @@ ALIASES
101
101
  $ eas whoami
102
102
  ```
103
103
 
104
- _See code: [src/commands/account/view.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/account/view.js)_
104
+ _See code: [src/commands/account/view.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/account/view.js)_
105
105
 
106
106
  ## `eas analytics [STATUS]`
107
107
 
@@ -112,7 +112,7 @@ USAGE
112
112
  $ eas analytics [STATUS]
113
113
  ```
114
114
 
115
- _See code: [src/commands/analytics.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/analytics.js)_
115
+ _See code: [src/commands/analytics.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/analytics.js)_
116
116
 
117
117
  ## `eas build`
118
118
 
@@ -145,7 +145,7 @@ OPTIONS
145
145
  --[no-]wait Wait for build(s) to complete
146
146
  ```
147
147
 
148
- _See code: [src/commands/build/index.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/build/index.js)_
148
+ _See code: [src/commands/build/index.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/build/index.js)_
149
149
 
150
150
  ## `eas build:cancel [BUILD_ID]`
151
151
 
@@ -156,7 +156,7 @@ USAGE
156
156
  $ eas build:cancel [BUILD_ID]
157
157
  ```
158
158
 
159
- _See code: [src/commands/build/cancel.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/build/cancel.js)_
159
+ _See code: [src/commands/build/cancel.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/build/cancel.js)_
160
160
 
161
161
  ## `eas build:configure`
162
162
 
@@ -170,7 +170,7 @@ OPTIONS
170
170
  -p, --platform=(android|ios|all) Platform to configure
171
171
  ```
172
172
 
173
- _See code: [src/commands/build/configure.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/build/configure.js)_
173
+ _See code: [src/commands/build/configure.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/build/configure.js)_
174
174
 
175
175
  ## `eas build:list`
176
176
 
@@ -203,7 +203,7 @@ OPTIONS
203
203
  --status=(new|in-queue|in-progress|errored|finished|canceled)
204
204
  ```
205
205
 
206
- _See code: [src/commands/build/list.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/build/list.js)_
206
+ _See code: [src/commands/build/list.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/build/list.js)_
207
207
 
208
208
  ## `eas build:view [BUILD_ID]`
209
209
 
@@ -217,7 +217,7 @@ OPTIONS
217
217
  --json Enable JSON output, non-JSON messages will be printed to stderr
218
218
  ```
219
219
 
220
- _See code: [src/commands/build/view.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/build/view.js)_
220
+ _See code: [src/commands/build/view.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/build/view.js)_
221
221
 
222
222
  ## `eas config`
223
223
 
@@ -232,7 +232,7 @@ OPTIONS
232
232
  --profile=profile
233
233
  ```
234
234
 
235
- _See code: [src/commands/config.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/config.js)_
235
+ _See code: [src/commands/config.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/config.js)_
236
236
 
237
237
  ## `eas credentials`
238
238
 
@@ -243,7 +243,7 @@ USAGE
243
243
  $ eas credentials
244
244
  ```
245
245
 
246
- _See code: [src/commands/credentials.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/credentials.js)_
246
+ _See code: [src/commands/credentials.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/credentials.js)_
247
247
 
248
248
  ## `eas device:create`
249
249
 
@@ -254,7 +254,7 @@ USAGE
254
254
  $ eas device:create
255
255
  ```
256
256
 
257
- _See code: [src/commands/device/create.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/device/create.js)_
257
+ _See code: [src/commands/device/create.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/device/create.js)_
258
258
 
259
259
  ## `eas device:list`
260
260
 
@@ -268,7 +268,7 @@ OPTIONS
268
268
  --apple-team-id=apple-team-id
269
269
  ```
270
270
 
271
- _See code: [src/commands/device/list.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/device/list.js)_
271
+ _See code: [src/commands/device/list.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/device/list.js)_
272
272
 
273
273
  ## `eas device:view [UDID]`
274
274
 
@@ -279,7 +279,7 @@ USAGE
279
279
  $ eas device:view [UDID]
280
280
  ```
281
281
 
282
- _See code: [src/commands/device/view.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/device/view.js)_
282
+ _See code: [src/commands/device/view.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/device/view.js)_
283
283
 
284
284
  ## `eas diagnostics`
285
285
 
@@ -290,7 +290,7 @@ USAGE
290
290
  $ eas diagnostics
291
291
  ```
292
292
 
293
- _See code: [src/commands/diagnostics.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/diagnostics.js)_
293
+ _See code: [src/commands/diagnostics.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/diagnostics.js)_
294
294
 
295
295
  ## `eas help [COMMAND]`
296
296
 
@@ -318,7 +318,7 @@ USAGE
318
318
  $ eas project:info
319
319
  ```
320
320
 
321
- _See code: [src/commands/project/info.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/project/info.js)_
321
+ _See code: [src/commands/project/info.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/project/info.js)_
322
322
 
323
323
  ## `eas project:init`
324
324
 
@@ -332,7 +332,7 @@ ALIASES
332
332
  $ eas init
333
333
  ```
334
334
 
335
- _See code: [src/commands/project/init.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/project/init.js)_
335
+ _See code: [src/commands/project/init.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/project/init.js)_
336
336
 
337
337
  ## `eas secret:create`
338
338
 
@@ -349,7 +349,7 @@ OPTIONS
349
349
  --value=value Value of the secret
350
350
  ```
351
351
 
352
- _See code: [src/commands/secret/create.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/secret/create.js)_
352
+ _See code: [src/commands/secret/create.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/secret/create.js)_
353
353
 
354
354
  ## `eas secret:delete`
355
355
 
@@ -366,7 +366,7 @@ DESCRIPTION
366
366
  Unsure where to find the secret's ID? Run eas secrets:list
367
367
  ```
368
368
 
369
- _See code: [src/commands/secret/delete.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/secret/delete.js)_
369
+ _See code: [src/commands/secret/delete.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/secret/delete.js)_
370
370
 
371
371
  ## `eas secret:list`
372
372
 
@@ -377,7 +377,7 @@ USAGE
377
377
  $ eas secret:list
378
378
  ```
379
379
 
380
- _See code: [src/commands/secret/list.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/secret/list.js)_
380
+ _See code: [src/commands/secret/list.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/secret/list.js)_
381
381
 
382
382
  ## `eas submit`
383
383
 
@@ -410,7 +410,7 @@ ALIASES
410
410
  $ eas build:submit
411
411
  ```
412
412
 
413
- _See code: [src/commands/submit.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/submit.js)_
413
+ _See code: [src/commands/submit.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/submit.js)_
414
414
 
415
415
  ## `eas webhook:create`
416
416
 
@@ -429,7 +429,7 @@ OPTIONS
429
429
  --url=url Webhook URL
430
430
  ```
431
431
 
432
- _See code: [src/commands/webhook/create.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/webhook/create.js)_
432
+ _See code: [src/commands/webhook/create.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/webhook/create.js)_
433
433
 
434
434
  ## `eas webhook:delete [ID]`
435
435
 
@@ -443,7 +443,7 @@ ARGUMENTS
443
443
  ID ID of the webhook to delete
444
444
  ```
445
445
 
446
- _See code: [src/commands/webhook/delete.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/webhook/delete.js)_
446
+ _See code: [src/commands/webhook/delete.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/webhook/delete.js)_
447
447
 
448
448
  ## `eas webhook:list`
449
449
 
@@ -457,7 +457,7 @@ OPTIONS
457
457
  --event=(BUILD) Event type that triggers the webhook
458
458
  ```
459
459
 
460
- _See code: [src/commands/webhook/list.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/webhook/list.js)_
460
+ _See code: [src/commands/webhook/list.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/webhook/list.js)_
461
461
 
462
462
  ## `eas webhook:update`
463
463
 
@@ -477,7 +477,7 @@ OPTIONS
477
477
  --url=url Webhook URL
478
478
  ```
479
479
 
480
- _See code: [src/commands/webhook/update.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/webhook/update.js)_
480
+ _See code: [src/commands/webhook/update.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/webhook/update.js)_
481
481
 
482
482
  ## `eas webhook:view ID`
483
483
 
@@ -491,5 +491,5 @@ ARGUMENTS
491
491
  ID ID of the webhook to view
492
492
  ```
493
493
 
494
- _See code: [src/commands/webhook/view.js](https://github.com/expo/eas-cli/blob/v0.31.1/packages/eas-cli/src/commands/webhook/view.js)_
494
+ _See code: [src/commands/webhook/view.js](https://github.com/expo/eas-cli/blob/v0.32.0/packages/eas-cli/src/commands/webhook/view.js)_
495
495
  <!-- commandsstop -->
@@ -77,9 +77,7 @@ class Submit extends EasCommand_1.default {
77
77
  }
78
78
  exports.default = Submit;
79
79
  Submit.description = `submit build archive to app store
80
- See how to configure submits with eas.json: ${(0, log_1.learnMore)('https://docs.expo.dev/submit/eas-json/', {
81
- learnMoreMessage: '',
82
- })}`;
80
+ See how to configure submits with eas.json: ${(0, log_1.link)('https://docs.expo.dev/submit/eas-json/')}`;
83
81
  Submit.aliases = ['build:submit'];
84
82
  Submit.flags = {
85
83
  platform: command_1.flags.enum({
@@ -12,7 +12,7 @@ export declare class CredentialsContext {
12
12
  readonly projectDir: string;
13
13
  readonly user: Actor;
14
14
  private shouldAskAuthenticateAppStore;
15
- private _exp?;
15
+ private resolvedExp?;
16
16
  constructor(options: {
17
17
  exp?: ExpoConfig;
18
18
  nonInteractive?: boolean;
@@ -23,10 +23,10 @@ class CredentialsContext {
23
23
  this.projectDir = options.projectDir;
24
24
  this.user = options.user;
25
25
  this.nonInteractive = (_a = options.nonInteractive) !== null && _a !== void 0 ? _a : false;
26
- this._exp = options.exp;
27
- if (!this._exp) {
26
+ this.resolvedExp = options.exp;
27
+ if (!this.resolvedExp) {
28
28
  try {
29
- this._exp = (0, expoConfig_1.getExpoConfig)(options.projectDir);
29
+ this.resolvedExp = (0, expoConfig_1.getExpoConfig)(options.projectDir);
30
30
  }
31
31
  catch (error) {
32
32
  // ignore error, context might be created outside of expo project
@@ -34,11 +34,11 @@ class CredentialsContext {
34
34
  }
35
35
  }
36
36
  get hasProjectContext() {
37
- return !!this._exp;
37
+ return !!this.resolvedExp;
38
38
  }
39
39
  get exp() {
40
40
  this.ensureProjectContext();
41
- return this._exp;
41
+ return this.resolvedExp;
42
42
  }
43
43
  ensureProjectContext() {
44
44
  if (this.hasProjectContext) {
@@ -1,3 +1,6 @@
1
1
  export declare class MissingCredentialsNonInteractiveError extends Error {
2
2
  constructor(message?: string);
3
3
  }
4
+ export declare class MissingCredentialsError extends Error {
5
+ constructor(message?: string);
6
+ }
@@ -1,9 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MissingCredentialsNonInteractiveError = void 0;
3
+ exports.MissingCredentialsError = exports.MissingCredentialsNonInteractiveError = void 0;
4
4
  class MissingCredentialsNonInteractiveError extends Error {
5
5
  constructor(message) {
6
6
  super(message !== null && message !== void 0 ? message : 'Credentials are not set up. Please run this command again in interactive mode.');
7
7
  }
8
8
  }
9
9
  exports.MissingCredentialsNonInteractiveError = MissingCredentialsNonInteractiveError;
10
+ class MissingCredentialsError extends Error {
11
+ constructor(message) {
12
+ super(message !== null && message !== void 0 ? message : 'Credentials are not set up.');
13
+ }
14
+ }
15
+ exports.MissingCredentialsError = MissingCredentialsError;
@@ -0,0 +1,5 @@
1
+ import { AscApiKey } from '../appstore/Credentials.types';
2
+ import { AscApiKeyPath, MinimalAscApiKey } from '../credentials';
3
+ export declare function promptForAscApiKeyAsync(): Promise<AscApiKeyPath>;
4
+ export declare function promptForIssuerIdAsync(): Promise<string>;
5
+ export declare function getMinimalAscApiKeyAsync(ascApiKey: AscApiKey): Promise<MinimalAscApiKey>;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMinimalAscApiKeyAsync = exports.promptForIssuerIdAsync = exports.promptForAscApiKeyAsync = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
6
+ const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
7
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
8
+ const uuid = (0, tslib_1.__importStar)(require("uuid"));
9
+ const log_1 = (0, tslib_1.__importStar)(require("../../../log"));
10
+ const prompts_1 = require("../../../prompts");
11
+ const promptForCredentials_1 = require("../../utils/promptForCredentials");
12
+ const credentials_1 = require("../credentials");
13
+ async function promptForAscApiKeyAsync() {
14
+ var _a, _b;
15
+ log_1.default.log(chalk_1.default.bold('An App Store Connect Api key is required to upload your app to the Apple App Store'));
16
+ log_1.default.log(`If you're not sure what this is or how to create one, ${(0, log_1.learnMore)('https://expo.fyi/creating-asc-api-key')}`);
17
+ const { keyP8Path } = await (0, prompts_1.promptAsync)({
18
+ type: 'text',
19
+ name: 'keyP8Path',
20
+ message: 'Path to App Store Connect Api Key:',
21
+ initial: 'AuthKey_ABCD.p8',
22
+ // eslint-disable-next-line async-protect/async-suffix
23
+ validate: async (filePath) => {
24
+ try {
25
+ const stats = await fs_extra_1.default.stat(filePath);
26
+ if (stats.isFile()) {
27
+ return true;
28
+ }
29
+ return 'Input is not a file.';
30
+ }
31
+ catch {
32
+ return 'File does not exist.';
33
+ }
34
+ },
35
+ });
36
+ const regex = /^AuthKey_(?<keyId>\w+)\.p8$/; // Common ASC Api file name downloaded from Apple
37
+ const bestEffortKeyId = (_b = (_a = path_1.default.basename(keyP8Path).match(regex)) === null || _a === void 0 ? void 0 : _a.groups) === null || _b === void 0 ? void 0 : _b.keyId;
38
+ const ascApiKeyMetadata = await (0, promptForCredentials_1.getCredentialsFromUserAsync)(credentials_1.ascApiKeyMetadataSchema, {
39
+ keyId: bestEffortKeyId,
40
+ });
41
+ return { ...ascApiKeyMetadata, keyP8Path };
42
+ }
43
+ exports.promptForAscApiKeyAsync = promptForAscApiKeyAsync;
44
+ async function promptForIssuerIdAsync() {
45
+ log_1.default.log(chalk_1.default.bold('An App Store Connect Issuer ID is required'));
46
+ log_1.default.log(`If you're not sure what this is or how to find yours, ${(0, log_1.learnMore)('https://expo.fyi/asc-issuer-id')}`);
47
+ const { issuerId } = await (0, prompts_1.promptAsync)({
48
+ type: 'text',
49
+ name: 'issuerId',
50
+ message: 'App Store Connect Issuer ID:',
51
+ validate: (input) => uuid.validate(input),
52
+ });
53
+ return issuerId;
54
+ }
55
+ exports.promptForIssuerIdAsync = promptForIssuerIdAsync;
56
+ async function getMinimalAscApiKeyAsync(ascApiKey) {
57
+ var _a;
58
+ return {
59
+ ...ascApiKey,
60
+ issuerId: (_a = ascApiKey.issuerId) !== null && _a !== void 0 ? _a : (await promptForIssuerIdAsync()),
61
+ };
62
+ }
63
+ exports.getMinimalAscApiKeyAsync = getMinimalAscApiKeyAsync;
@@ -37,7 +37,7 @@ function formatDistributionCertificate(distributionCertificate, validSerialNumbe
37
37
  return line;
38
38
  }
39
39
  exports.formatDistributionCertificate = formatDistributionCertificate;
40
- async function _selectDistributionCertificateAsync(distCerts, validDistributionCertificates) {
40
+ async function selectDistributionCertificateAsync(distCerts, validDistributionCertificates) {
41
41
  const validDistCertSerialNumbers = validDistributionCertificates === null || validDistributionCertificates === void 0 ? void 0 : validDistributionCertificates.map(distCert => distCert.serialNumber);
42
42
  const { chosenDistCert } = await (0, prompts_1.promptAsync)({
43
43
  type: 'select',
@@ -60,12 +60,12 @@ async function selectDistributionCertificateWithDependenciesAsync(ctx, account)
60
60
  return null;
61
61
  }
62
62
  if (!ctx.appStore.authCtx) {
63
- return _selectDistributionCertificateAsync(distCertsForAccount);
63
+ return selectDistributionCertificateAsync(distCertsForAccount);
64
64
  }
65
65
  // get valid certs on the developer portal
66
66
  const certInfoFromApple = await ctx.appStore.listDistributionCertificatesAsync();
67
67
  const validDistCerts = await (0, CredentialsUtils_1.filterRevokedDistributionCertsFromEasServers)(distCertsForAccount, certInfoFromApple);
68
- return _selectDistributionCertificateAsync(distCertsForAccount, validDistCerts);
68
+ return selectDistributionCertificateAsync(distCertsForAccount, validDistCerts);
69
69
  }
70
70
  exports.selectDistributionCertificateWithDependenciesAsync = selectDistributionCertificateWithDependenciesAsync;
71
71
  /**
@@ -79,7 +79,7 @@ async function selectValidDistributionCertificateAsync(ctx, appLookupParams) {
79
79
  return null;
80
80
  }
81
81
  if (!ctx.appStore.authCtx) {
82
- return _selectDistributionCertificateAsync(distCertsForAccount);
82
+ return selectDistributionCertificateAsync(distCertsForAccount);
83
83
  }
84
84
  // filter by apple team
85
85
  (0, assert_1.default)(ctx.appStore.authCtx, 'authentication to the Apple App Store is required');
@@ -91,7 +91,7 @@ async function selectValidDistributionCertificateAsync(ctx, appLookupParams) {
91
91
  const certInfoFromApple = await ctx.appStore.listDistributionCertificatesAsync();
92
92
  const validDistCerts = (0, CredentialsUtils_1.filterRevokedDistributionCertsFromEasServers)(distCertsForAppleTeam, certInfoFromApple);
93
93
  log_1.default.log(`${validDistCerts.length}/${distCertsForAccount.length} Distribution Certificates are currently valid for Apple Team ${(_a = ctx.appStore.authCtx) === null || _a === void 0 ? void 0 : _a.team.id}.`);
94
- return _selectDistributionCertificateAsync(validDistCerts);
94
+ return selectDistributionCertificateAsync(validDistCerts);
95
95
  }
96
96
  exports.selectValidDistributionCertificateAsync = selectValidDistributionCertificateAsync;
97
97
  const APPLE_DIST_CERTS_TOO_MANY_GENERATED_ERROR = `
@@ -1,4 +1,4 @@
1
- import { DistributionCertificate, DistributionCertificateStoreInfo, ProvisioningProfile, ProvisioningProfileStoreInfo, PushKey, PushKeyStoreInfo } from './Credentials.types';
1
+ import { AscApiKey, AscApiKeyInfo, DistributionCertificate, DistributionCertificateStoreInfo, ProvisioningProfile, ProvisioningProfileStoreInfo, PushKey, PushKeyStoreInfo } from './Credentials.types';
2
2
  import { AuthCtx, Options as AuthenticateOptions } from './authenticate';
3
3
  import { AppLookupParams, IosCapabilitiesOptions } from './ensureAppExists';
4
4
  import { ProfileClass } from './provisioningProfile';
@@ -17,4 +17,10 @@ export default class AppStoreApi {
17
17
  createProvisioningProfileAsync(bundleIdentifier: string, distCert: DistributionCertificate, profileName: string, profileClass?: ProfileClass): Promise<ProvisioningProfile>;
18
18
  revokeProvisioningProfileAsync(bundleIdentifier: string, profileClass?: ProfileClass): Promise<void>;
19
19
  createOrReuseAdhocProvisioningProfileAsync(udids: string[], bundleIdentifier: string, distCertSerialNumber: string): Promise<ProvisioningProfile>;
20
+ listAscApiKeysAsync(): Promise<AscApiKeyInfo[]>;
21
+ getAscApiKeyAsync(keyId: string): Promise<AscApiKeyInfo>;
22
+ createAscApiKeyAsync({ nickname }: {
23
+ nickname: string;
24
+ }): Promise<AscApiKey>;
25
+ revokeAscApiKeyAsync(keyId: string): Promise<AscApiKeyInfo>;
20
26
  }
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ascApiKey_1 = require("./ascApiKey");
3
4
  const authenticate_1 = require("./authenticate");
4
5
  const distributionCertificate_1 = require("./distributionCertificate");
5
6
  const ensureAppExists_1 = require("./ensureAppExists");
@@ -61,5 +62,21 @@ class AppStoreApi {
61
62
  const ctx = await this.ensureAuthenticatedAsync();
62
63
  return await (0, provisioningProfileAdhoc_1.createOrReuseAdhocProvisioningProfileAsync)(ctx, udids, bundleIdentifier, distCertSerialNumber);
63
64
  }
65
+ async listAscApiKeysAsync() {
66
+ const ctx = await this.ensureAuthenticatedAsync();
67
+ return await (0, ascApiKey_1.listAscApiKeysAsync)(ctx);
68
+ }
69
+ async getAscApiKeyAsync(keyId) {
70
+ const ctx = await this.ensureAuthenticatedAsync();
71
+ return await (0, ascApiKey_1.getAscApiKeyAsync)(ctx, keyId);
72
+ }
73
+ async createAscApiKeyAsync({ nickname }) {
74
+ const ctx = await this.ensureAuthenticatedAsync();
75
+ return await (0, ascApiKey_1.createAscApiKeyAsync)(ctx, { nickname });
76
+ }
77
+ async revokeAscApiKeyAsync(keyId) {
78
+ const ctx = await this.ensureAuthenticatedAsync();
79
+ return await (0, ascApiKey_1.revokeAscApiKeyAsync)(ctx, keyId);
80
+ }
64
81
  }
65
82
  exports.default = AppStoreApi;
@@ -4,8 +4,8 @@ exports.isPushKey = exports.formatPushKey = exports.isDistributionCertificate =
4
4
  const tslib_1 = require("tslib");
5
5
  const dateformat_1 = (0, tslib_1.__importDefault)(require("dateformat"));
6
6
  function formatDistributionCertificate({ name, id, status, expires, created, ownerName, }) {
7
- const expiresDate = _formatTimestamp(expires);
8
- const createdDate = _formatTimestamp(created);
7
+ const expiresDate = formatTimestamp(expires);
8
+ const createdDate = formatTimestamp(created);
9
9
  return `${name} (${status}) - ID: ${id} - expires: ${expiresDate} (created: ${createdDate}) - owner: ${ownerName}`;
10
10
  }
11
11
  exports.formatDistributionCertificate = formatDistributionCertificate;
@@ -31,6 +31,6 @@ function isPushKey(obj) {
31
31
  typeof obj.teamId === 'string');
32
32
  }
33
33
  exports.isPushKey = isPushKey;
34
- function _formatTimestamp(timestamp) {
34
+ function formatTimestamp(timestamp) {
35
35
  return (0, dateformat_1.default)(new Date(timestamp * 1000));
36
36
  }
@@ -1,3 +1,5 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import { UserRole } from '@expo/apple-utils';
1
3
  export interface Device {
2
4
  id: string;
3
5
  teamId: string;
@@ -59,3 +61,14 @@ export interface PushKey {
59
61
  teamId: string;
60
62
  teamName?: string;
61
63
  }
64
+ export declare type AscApiKeyInfo = {
65
+ keyId: string;
66
+ issuerId?: string;
67
+ teamId: string;
68
+ name: string;
69
+ teamName?: string;
70
+ roles: UserRole[];
71
+ };
72
+ export declare type AscApiKey = AscApiKeyInfo & {
73
+ keyP8: string;
74
+ };
@@ -0,0 +1,9 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import { ApiKey, ApiKeyProps } from '@expo/apple-utils';
3
+ import { AscApiKey, AscApiKeyInfo } from './Credentials.types';
4
+ import { AuthCtx } from './authenticate';
5
+ export declare function listAscApiKeysAsync(authCtx: AuthCtx): Promise<AscApiKeyInfo[]>;
6
+ export declare function getAscApiKeyAsync(authCtx: AuthCtx, keyId: string): Promise<AscApiKeyInfo>;
7
+ export declare function createAscApiKeyAsync(authCtx: AuthCtx, { nickname, allAppsVisible, roles, keyType, }: Partial<Pick<ApiKeyProps, 'nickname' | 'roles' | 'allAppsVisible' | 'keyType'>>): Promise<AscApiKey>;
8
+ export declare function revokeAscApiKeyAsync(authCtx: AuthCtx, keyId: string): Promise<AscApiKeyInfo>;
9
+ export declare function getAscApiKeyInfo(apiKey: ApiKey, authCtx: AuthCtx): AscApiKeyInfo;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAscApiKeyInfo = exports.revokeAscApiKeyAsync = exports.createAscApiKeyAsync = exports.getAscApiKeyAsync = exports.listAscApiKeysAsync = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const apple_utils_1 = require("@expo/apple-utils");
6
+ const log_1 = (0, tslib_1.__importDefault)(require("../../../log"));
7
+ const ora_1 = require("../../../ora");
8
+ const authenticate_1 = require("./authenticate");
9
+ async function listAscApiKeysAsync(authCtx) {
10
+ const spinner = (0, ora_1.ora)(`Fetching App Store Connect API Keys.`).start();
11
+ try {
12
+ const context = (0, authenticate_1.getRequestContext)(authCtx);
13
+ const keys = await apple_utils_1.ApiKey.getAsync(context);
14
+ spinner.succeed(`Fetched App Store Connect API Keys.`);
15
+ return keys.map(key => getAscApiKeyInfo(key, authCtx));
16
+ }
17
+ catch (error) {
18
+ spinner.fail(`Failed to fetch App Store Connect API Keys.`);
19
+ throw error;
20
+ }
21
+ }
22
+ exports.listAscApiKeysAsync = listAscApiKeysAsync;
23
+ async function getAscApiKeyAsync(authCtx, keyId) {
24
+ const spinner = (0, ora_1.ora)(`Fetching App Store Connect API Key.`).start();
25
+ try {
26
+ const context = (0, authenticate_1.getRequestContext)(authCtx);
27
+ const apiKey = await apple_utils_1.ApiKey.infoAsync(context, { id: keyId });
28
+ spinner.succeed(`Fetched App Store Connect API Key (ID: ${keyId}).`);
29
+ return getAscApiKeyInfo(apiKey, authCtx);
30
+ }
31
+ catch (error) {
32
+ log_1.default.error(error);
33
+ spinner.fail(`Failed to fetch App Store Connect API Key.`);
34
+ throw error;
35
+ }
36
+ }
37
+ exports.getAscApiKeyAsync = getAscApiKeyAsync;
38
+ async function createAscApiKeyAsync(authCtx, { nickname, allAppsVisible, roles, keyType, }) {
39
+ const spinner = (0, ora_1.ora)(`Creating App Store Connect API Key.`).start();
40
+ try {
41
+ const context = (0, authenticate_1.getRequestContext)(authCtx);
42
+ const key = await apple_utils_1.ApiKey.createAsync(context, {
43
+ nickname: nickname !== null && nickname !== void 0 ? nickname : `[expo] ${new Date().getTime()}`,
44
+ allAppsVisible: allAppsVisible !== null && allAppsVisible !== void 0 ? allAppsVisible : true,
45
+ roles: roles !== null && roles !== void 0 ? roles : [apple_utils_1.UserRole.ADMIN],
46
+ keyType: keyType !== null && keyType !== void 0 ? keyType : apple_utils_1.ApiKeyType.PUBLIC_API,
47
+ });
48
+ const keyP8 = await key.downloadAsync();
49
+ if (!keyP8) {
50
+ const { nickname, roles } = key.attributes;
51
+ const humanReadableKey = `App Store Connect Key '${nickname}' (${key.id}) with roles {${roles.join(',')}}`;
52
+ if (!key.attributes.canDownload) {
53
+ // this case would be unexpected because we just created the key
54
+ throw new Error(`${humanReadableKey} is not available for download from Apple.`);
55
+ }
56
+ else if (!key.attributes.isActive) {
57
+ throw new Error(`${humanReadableKey} is inactive and could not be downloaded.`);
58
+ }
59
+ throw new Error(`Failed to download .p8 file of ${humanReadableKey}.`);
60
+ }
61
+ return {
62
+ ...getAscApiKeyInfo(key, authCtx),
63
+ keyP8,
64
+ };
65
+ }
66
+ catch (err) {
67
+ spinner.fail('Failed to create App Store Connect API Key.');
68
+ throw err;
69
+ }
70
+ }
71
+ exports.createAscApiKeyAsync = createAscApiKeyAsync;
72
+ async function revokeAscApiKeyAsync(authCtx, keyId) {
73
+ const spinner = (0, ora_1.ora)(`Revoking App Store Connect API Key.`).start();
74
+ try {
75
+ const context = (0, authenticate_1.getRequestContext)(authCtx);
76
+ const apiKey = await apple_utils_1.ApiKey.infoAsync(context, { id: keyId });
77
+ const revokedKey = await apiKey.revokeAsync();
78
+ spinner.succeed(`Revoked App Store Connect API Key.`);
79
+ return getAscApiKeyInfo(revokedKey, authCtx);
80
+ }
81
+ catch (error) {
82
+ log_1.default.error(error);
83
+ spinner.fail(`Failed to revoke App Store Connect API Key.`);
84
+ throw error;
85
+ }
86
+ }
87
+ exports.revokeAscApiKeyAsync = revokeAscApiKeyAsync;
88
+ function getAscApiKeyInfo(apiKey, authCtx) {
89
+ var _a;
90
+ return {
91
+ name: apiKey.attributes.nickname,
92
+ keyId: apiKey.id,
93
+ issuerId: (_a = apiKey.attributes.provider) === null || _a === void 0 ? void 0 : _a.id,
94
+ teamId: authCtx.team.id,
95
+ teamName: authCtx.team.name,
96
+ roles: apiKey.attributes.roles,
97
+ };
98
+ }
99
+ exports.getAscApiKeyInfo = getAscApiKeyInfo;
@@ -1,3 +1,5 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import { UserRole } from '@expo/apple-utils';
1
3
  import { AppleDevice } from '../../graphql/generated';
2
4
  import { CredentialSchema } from '../utils/promptForCredentials';
3
5
  import { DistributionCertificate, ProvisioningProfile, PushKey } from './appstore/Credentials.types';
@@ -36,5 +38,20 @@ export interface IosDistCredentials extends DistributionCertificate {
36
38
  type: 'dist-cert';
37
39
  }
38
40
  export declare const distributionCertificateSchema: CredentialSchema<DistributionCertificate>;
41
+ export declare type MinimalAscApiKey = {
42
+ keyP8: string;
43
+ keyId: string;
44
+ issuerId: string;
45
+ teamId?: string;
46
+ teamName?: string;
47
+ roles?: UserRole[];
48
+ name?: string;
49
+ };
50
+ export interface AscApiKeyPath {
51
+ keyP8Path: string;
52
+ keyId: string;
53
+ issuerId: string;
54
+ }
55
+ export declare const ascApiKeyMetadataSchema: CredentialSchema<Omit<MinimalAscApiKey, 'keyP8'>>;
39
56
  export declare const pushKeySchema: CredentialSchema<PushKey>;
40
57
  export declare const provisioningProfileSchema: CredentialSchema<ProvisioningProfile>;