eas-cli 12.6.2 → 13.0.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.
Files changed (58) hide show
  1. package/README.md +63 -63
  2. package/build/build/local.js +1 -1
  3. package/build/commandUtils/context/DynamicProjectConfigContextField.js +4 -4
  4. package/build/commandUtils/context/OptionalPrivateProjectConfigContextField.js +2 -2
  5. package/build/commandUtils/context/PrivateProjectConfigContextField.js +2 -2
  6. package/build/commandUtils/context/ProjectIdContextField.js +1 -1
  7. package/build/commandUtils/context/ServerSideEnvironmentVariablesContextField.js +1 -1
  8. package/build/commandUtils/context/contextUtils/getProjectIdAsync.js +1 -1
  9. package/build/commandUtils/context/contextUtils/loadServerSideEnvironmentVariablesAsync.js +1 -1
  10. package/build/commandUtils/flags.d.ts +3 -0
  11. package/build/commandUtils/flags.js +11 -1
  12. package/build/commands/env/create.d.ts +5 -0
  13. package/build/commands/env/create.js +22 -7
  14. package/build/commands/env/delete.d.ts +6 -1
  15. package/build/commands/env/delete.js +17 -3
  16. package/build/commands/env/exec.d.ts +1 -3
  17. package/build/commands/env/exec.js +23 -17
  18. package/build/commands/env/get.d.ts +6 -1
  19. package/build/commands/env/get.js +24 -4
  20. package/build/commands/env/link.d.ts +6 -0
  21. package/build/commands/env/link.js +31 -1
  22. package/build/commands/env/list.d.ts +7 -1
  23. package/build/commands/env/list.js +25 -2
  24. package/build/commands/env/pull.d.ts +6 -1
  25. package/build/commands/env/pull.js +14 -2
  26. package/build/commands/env/push.d.ts +12 -0
  27. package/build/commands/env/push.js +21 -1
  28. package/build/commands/env/unlink.d.ts +6 -0
  29. package/build/commands/env/unlink.js +27 -1
  30. package/build/commands/env/update.d.ts +5 -0
  31. package/build/commands/env/update.js +20 -3
  32. package/build/commands/project/init.js +3 -3
  33. package/build/commands/project/onboarding.js +2 -2
  34. package/build/commands/update/configure.d.ts +3 -1
  35. package/build/commands/update/configure.js +6 -5
  36. package/build/commands/update/index.d.ts +4 -2
  37. package/build/commands/update/index.js +5 -25
  38. package/build/credentials/android/actions/BuildCredentialsUtils.js +4 -4
  39. package/build/credentials/android/actions/CreateKeystore.js +1 -1
  40. package/build/credentials/context.d.ts +3 -3
  41. package/build/credentials/context.js +6 -6
  42. package/build/credentials/ios/actions/BuildCredentialsUtils.js +3 -3
  43. package/build/credentials/manager/ManageIos.js +5 -4
  44. package/build/credentials/manager/SetUpIosBuildCredentials.js +1 -1
  45. package/build/metadata/apple/config/reader.js +6 -4
  46. package/build/metadata/apple/config/writer.d.ts +1 -1
  47. package/build/metadata/apple/config/writer.js +7 -4
  48. package/build/metadata/apple/types.d.ts +1 -1
  49. package/build/project/expoConfig.d.ts +2 -2
  50. package/build/project/expoConfig.js +45 -13
  51. package/build/project/ios/entitlements.js +30 -7
  52. package/build/project/projectUtils.d.ts +1 -0
  53. package/build/project/projectUtils.js +6 -1
  54. package/build/utils/variableUtils.d.ts +1 -0
  55. package/build/utils/variableUtils.js +5 -1
  56. package/oclif.manifest.json +105 -42
  57. package/package.json +15 -15
  58. package/schema/metadata-0.json +53 -18
@@ -16,7 +16,8 @@ const prompts_2 = require("../../utils/prompts");
16
16
  const variableUtils_1 = require("../../utils/variableUtils");
17
17
  class EnvironmentVariableUnlink extends EasCommand_1.default {
18
18
  async runAsync() {
19
- let { flags: { 'variable-name': name, 'non-interactive': nonInteractive, environment: unlinkEnvironments, }, } = await this.parse(_a);
19
+ const { args, flags } = await this.parse(_a);
20
+ let { 'variable-name': name, 'non-interactive': nonInteractive, environment: unlinkEnvironments, } = this.validateInputs(flags, args);
20
21
  const { projectId, loggedIn: { graphqlClient }, } = await this.getContextAsync(_a, {
21
22
  nonInteractive,
22
23
  });
@@ -74,6 +75,24 @@ class EnvironmentVariableUnlink extends EasCommand_1.default {
74
75
  }
75
76
  }
76
77
  }
78
+ validateInputs(flags, { environment }) {
79
+ if (flags['non-interactive']) {
80
+ if (!flags['variable-name']) {
81
+ throw new Error('Current name is required in non-interactive mode. Run the command with --variable-name flag.');
82
+ }
83
+ }
84
+ if (environment) {
85
+ environment = environment.toUpperCase();
86
+ if (!(0, variableUtils_1.isEnvironment)(environment)) {
87
+ throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
88
+ }
89
+ return {
90
+ environment: [environment],
91
+ ...flags,
92
+ };
93
+ }
94
+ return flags;
95
+ }
77
96
  }
78
97
  _a = EnvironmentVariableUnlink;
79
98
  EnvironmentVariableUnlink.description = 'unlink a shared environment variable to the current project';
@@ -89,4 +108,11 @@ EnvironmentVariableUnlink.contextDefinition = {
89
108
  ..._a.ContextOptions.ProjectId,
90
109
  ..._a.ContextOptions.LoggedIn,
91
110
  };
111
+ EnvironmentVariableUnlink.args = [
112
+ {
113
+ name: 'environment',
114
+ description: "Environment to unlink the variable from. One of 'production', 'preview', or 'development'.",
115
+ required: false,
116
+ },
117
+ ];
92
118
  exports.default = EnvironmentVariableUnlink;
@@ -14,6 +14,11 @@ export default class EnvironmentVariableUpdate extends EasCommand {
14
14
  value: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
15
15
  type: import("@oclif/core/lib/interfaces").OptionFlag<"string" | "file" | undefined>;
16
16
  };
17
+ static args: {
18
+ name: string;
19
+ description: string;
20
+ required: boolean;
21
+ }[];
17
22
  static contextDefinition: {
18
23
  loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
19
24
  analytics: import("../../commandUtils/context/AnalyticsContextField").default;
@@ -19,8 +19,8 @@ const prompts_2 = require("../../utils/prompts");
19
19
  const variableUtils_1 = require("../../utils/variableUtils");
20
20
  class EnvironmentVariableUpdate extends EasCommand_1.default {
21
21
  async runAsync() {
22
- const { flags } = await this.parse(_a);
23
- const { name, value: rawValue, scope, 'variable-name': currentName, 'variable-environment': currentEnvironment, 'non-interactive': nonInteractive, environment: environments, type, visibility, } = this.validateFlags(flags);
22
+ const { args, flags } = await this.parse(_a);
23
+ const { name, value: rawValue, scope, 'variable-name': currentName, 'variable-environment': currentEnvironment, 'non-interactive': nonInteractive, environment: environments, type, visibility, } = this.validateFlags(flags, args);
24
24
  const { projectId, loggedIn: { graphqlClient }, } = await this.getContextAsync(_a, {
25
25
  nonInteractive,
26
26
  });
@@ -82,7 +82,7 @@ class EnvironmentVariableUpdate extends EasCommand_1.default {
82
82
  }
83
83
  log_1.default.withTick(`Updated variable ${chalk_1.default.bold(selectedVariable.name)} ${suffix}.`);
84
84
  }
85
- validateFlags(flags) {
85
+ validateFlags(flags, { environment }) {
86
86
  if (flags['non-interactive']) {
87
87
  if (!flags['variable-name']) {
88
88
  throw new Error('Current name is required in non-interactive mode. Run the command with --variable-name flag.');
@@ -91,6 +91,16 @@ class EnvironmentVariableUpdate extends EasCommand_1.default {
91
91
  throw new Error('Value is required when type is set. Run the command with --value flag.');
92
92
  }
93
93
  }
94
+ if (environment) {
95
+ environment = environment.toUpperCase();
96
+ if (!(0, variableUtils_1.isEnvironment)(environment)) {
97
+ throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
98
+ }
99
+ return {
100
+ 'variable-environment': environment,
101
+ ...flags,
102
+ };
103
+ }
94
104
  return flags;
95
105
  }
96
106
  async promptForMissingFlagsAsync(selectedVariable, { name, value, environment: environments, visibility, 'non-interactive': nonInteractive, type, ...rest }) {
@@ -197,6 +207,13 @@ EnvironmentVariableUpdate.flags = {
197
207
  ...flags_1.EASMultiEnvironmentFlag,
198
208
  ...flags_1.EASNonInteractiveFlag,
199
209
  };
210
+ EnvironmentVariableUpdate.args = [
211
+ {
212
+ name: 'environment',
213
+ description: "Current environment of the variable to update. One of 'production', 'preview', or 'development'.",
214
+ required: false,
215
+ },
216
+ ];
200
217
  EnvironmentVariableUpdate.contextDefinition = {
201
218
  ..._a.ContextOptions.ProjectId,
202
219
  ..._a.ContextOptions.Analytics,
@@ -59,7 +59,7 @@ class ProjectInit extends EasCommand_1.default {
59
59
  }
60
60
  }
61
61
  static async ensureOwnerSlugConsistencyAsync(graphqlClient, projectId, projectDir, { force, nonInteractive }) {
62
- const exp = (0, expoConfig_1.getPrivateExpoConfig)(projectDir);
62
+ const exp = await (0, expoConfig_1.getPrivateExpoConfigAsync)(projectDir);
63
63
  const appForProjectId = await AppQuery_1.AppQuery.byIdAsync(graphqlClient, projectId);
64
64
  const correctOwner = appForProjectId.ownerAccount.name;
65
65
  const correctSlug = appForProjectId.slug;
@@ -107,7 +107,7 @@ class ProjectInit extends EasCommand_1.default {
107
107
  }
108
108
  }
109
109
  static async setExplicitIDAsync(projectId, projectDir, { force, nonInteractive }) {
110
- const exp = (0, expoConfig_1.getPrivateExpoConfig)(projectDir);
110
+ const exp = await (0, expoConfig_1.getPrivateExpoConfigAsync)(projectDir);
111
111
  const existingProjectId = exp.extra?.eas?.projectId;
112
112
  if (projectId === existingProjectId) {
113
113
  log_1.default.succeed(`Project already linked (ID: ${chalk_1.default.bold(existingProjectId)})`);
@@ -141,7 +141,7 @@ class ProjectInit extends EasCommand_1.default {
141
141
  });
142
142
  }
143
143
  static async initializeWithoutExplicitIDAsync(graphqlClient, actor, projectDir, { force, nonInteractive }) {
144
- const exp = (0, expoConfig_1.getPrivateExpoConfig)(projectDir);
144
+ const exp = await (0, expoConfig_1.getPrivateExpoConfigAsync)(projectDir);
145
145
  const existingProjectId = exp.extra?.eas?.projectId;
146
146
  if (existingProjectId) {
147
147
  log_1.default.succeed(`Project already linked (ID: ${chalk_1.default.bold(existingProjectId)}). To re-configure, remove the "extra.eas.projectId" field from your app config.`);
@@ -236,7 +236,7 @@ Onboarding.contextDefinition = {
236
236
  exports.default = Onboarding;
237
237
  // we can't get this automated by using command context because when we run a command the project directory doesn't exist yet
238
238
  async function getPrivateExpoConfigWithProjectIdAsync({ projectDir, graphqlClient, actor, options, }) {
239
- const expBefore = (0, expoConfig_1.getPrivateExpoConfig)(projectDir, options);
239
+ const expBefore = await (0, expoConfig_1.getPrivateExpoConfigAsync)(projectDir, options);
240
240
  const projectId = await (0, getProjectIdAsync_1.validateOrSetProjectIdAsync)({
241
241
  exp: expBefore,
242
242
  graphqlClient,
@@ -246,7 +246,7 @@ async function getPrivateExpoConfigWithProjectIdAsync({ projectDir, graphqlClien
246
246
  },
247
247
  cwd: projectDir,
248
248
  });
249
- const exp = (0, expoConfig_1.getPrivateExpoConfig)(projectDir, options);
249
+ const exp = await (0, expoConfig_1.getPrivateExpoConfigAsync)(projectDir, options);
250
250
  return {
251
251
  exp,
252
252
  projectId,
@@ -1,9 +1,11 @@
1
1
  import EasCommand from '../../commandUtils/EasCommand';
2
+ import { RequestedPlatform } from '../../platform';
2
3
  export default class UpdateConfigure extends EasCommand {
3
4
  static description: string;
4
5
  static flags: {
5
6
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
- platform: import("@oclif/core/lib/interfaces").OptionFlag<string>;
7
+ 'with-eas-environment-variables-set': import("@oclif/core/lib/interfaces").OptionFlag<import("../../graphql/generated").EnvironmentVariableEnvironment | null>;
8
+ platform: import("@oclif/core/lib/interfaces").OptionFlag<RequestedPlatform>;
7
9
  };
8
10
  static contextDefinition: {
9
11
  vcsClient: import("../../commandUtils/context/VcsClientContextField").default;
@@ -8,14 +8,14 @@ const configure_1 = require("../../build/configure");
8
8
  const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
9
9
  const flags_1 = require("../../commandUtils/flags");
10
10
  const log_1 = tslib_1.__importStar(require("../../log"));
11
+ const platform_1 = require("../../platform");
11
12
  const configure_2 = require("../../update/configure");
12
13
  class UpdateConfigure extends EasCommand_1.default {
13
14
  async runAsync() {
14
15
  const { flags } = await this.parse(_a);
15
- const platform = flags.platform;
16
16
  const { privateProjectConfig: { projectId, exp, projectDir }, vcsClient, } = await this.getContextAsync(_a, {
17
17
  nonInteractive: flags['non-interactive'],
18
- withServerSideEnvironment: null,
18
+ withServerSideEnvironment: flags['with-eas-environment-variables-set'],
19
19
  });
20
20
  log_1.default.log('💡 The following process will configure your project to use EAS Update. These changes only apply to your local project files and you can safely revert them at any time.');
21
21
  await vcsClient.ensureRepoExistsAsync();
@@ -23,7 +23,7 @@ class UpdateConfigure extends EasCommand_1.default {
23
23
  exp,
24
24
  projectId,
25
25
  projectDir,
26
- platform,
26
+ platform: flags['platform'],
27
27
  vcsClient,
28
28
  env: undefined,
29
29
  });
@@ -46,9 +46,10 @@ UpdateConfigure.flags = {
46
46
  platform: core_1.Flags.enum({
47
47
  description: 'Platform to configure',
48
48
  char: 'p',
49
- options: ['android', 'ios', 'all'],
50
- default: 'all',
49
+ options: Object.values(platform_1.RequestedPlatform),
50
+ default: platform_1.RequestedPlatform.All,
51
51
  }),
52
+ ...flags_1.WithEasEnvironmentVariablesSetFlag,
52
53
  ...flags_1.EASNonInteractiveFlag,
53
54
  };
54
55
  UpdateConfigure.contextDefinition = {
@@ -1,9 +1,12 @@
1
1
  import EasCommand from '../../commandUtils/EasCommand';
2
+ import { EnvironmentVariableEnvironment } from '../../graphql/generated';
3
+ import { RequestedPlatform } from '../../platform';
2
4
  export default class UpdatePublish extends EasCommand {
3
5
  static description: string;
4
6
  static flags: {
5
7
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
8
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ 'with-eas-environment-variables-set': import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment | null>;
7
10
  branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
8
11
  channel: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
9
12
  message: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
@@ -12,10 +15,9 @@ export default class UpdatePublish extends EasCommand {
12
15
  'clear-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
16
  'emit-metadata': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
14
17
  'rollout-percentage': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined>;
15
- platform: import("@oclif/core/lib/interfaces").OptionFlag<string>;
18
+ platform: import("@oclif/core/lib/interfaces").OptionFlag<RequestedPlatform>;
16
19
  auto: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
17
20
  'private-key-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
18
- 'with-eas-environment-variables-set': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
19
21
  };
20
22
  static contextDefinition: {
21
23
  getServerSideEnvironmentVariablesAsync: import("../../commandUtils/context/ServerSideEnvironmentVariablesContextField").ServerSideEnvironmentVariablesContextField;
@@ -18,6 +18,7 @@ const generated_1 = require("../../graphql/generated");
18
18
  const PublishMutation_1 = require("../../graphql/mutations/PublishMutation");
19
19
  const log_1 = tslib_1.__importStar(require("../../log"));
20
20
  const ora_1 = require("../../ora");
21
+ const platform_1 = require("../../platform");
21
22
  const maybeUploadFingerprintAsync_1 = require("../../project/maybeUploadFingerprintAsync");
22
23
  const projectUtils_1 = require("../../project/projectUtils");
23
24
  const publish_1 = require("../../project/publish");
@@ -37,7 +38,7 @@ class UpdatePublish extends EasCommand_1.default {
37
38
  const { auto: autoFlag, platform: requestedPlatform, channelName: channelNameArg, updateMessage: updateMessageArg, inputDir, skipBundler, clearCache, privateKeyPath, json: jsonFlag, nonInteractive, branchName: branchNameArg, emitMetadata, rolloutPercentage, withEasEnvironmentVariablesSet, } = this.sanitizeFlags(rawFlags);
38
39
  const { getDynamicPublicProjectConfigAsync, getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, vcsClient, getServerSideEnvironmentVariablesAsync, } = await this.getContextAsync(_a, {
39
40
  nonInteractive,
40
- withServerSideEnvironment: withEasEnvironmentVariablesSet ?? null,
41
+ withServerSideEnvironment: withEasEnvironmentVariablesSet,
41
42
  });
42
43
  if (jsonFlag) {
43
44
  (0, json_1.enableJsonOutput)();
@@ -379,12 +380,6 @@ class UpdatePublish extends EasCommand_1.default {
379
380
  emitMetadata = false;
380
381
  log_1.default.warn('ignoring flag --emit-metadata as metadata cannot be generated when skipping bundle generation');
381
382
  }
382
- if (flags['with-eas-environment-variables-set'] &&
383
- !Object.values(generated_1.EnvironmentVariableEnvironment).includes(flags['with-eas-environment-variables-set'])) {
384
- core_1.Errors.error(`--with-eas-environment-variables-set must be one of ${Object.values(generated_1.EnvironmentVariableEnvironment)
385
- .map(env => `"${env.toLocaleLowerCase()}"`)
386
- .join(', ')}`, { exit: 1 });
387
- }
388
383
  return {
389
384
  auto,
390
385
  branchName,
@@ -444,12 +439,8 @@ UpdatePublish.flags = {
444
439
  }),
445
440
  platform: core_1.Flags.enum({
446
441
  char: 'p',
447
- options: [
448
- // TODO: Add web when it's fully supported
449
- ...publish_1.defaultPublishPlatforms,
450
- 'all',
451
- ],
452
- default: 'all',
442
+ options: Object.values(platform_1.RequestedPlatform), // TODO: Add web when it's fully supported
443
+ default: platform_1.RequestedPlatform.All,
453
444
  required: false,
454
445
  }),
455
446
  auto: core_1.Flags.boolean({
@@ -460,18 +451,7 @@ UpdatePublish.flags = {
460
451
  description: `File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named "private-key.pem" in the certificate's directory. Only relevant if you are using code signing: https://docs.expo.dev/eas-update/code-signing/`,
461
452
  required: false,
462
453
  }),
463
- 'with-eas-environment-variables-set': core_1.Flags.enum({
464
- description: 'Environment to use for EAS environment variables',
465
- options: [
466
- generated_1.EnvironmentVariableEnvironment.Development,
467
- generated_1.EnvironmentVariableEnvironment.Preview,
468
- generated_1.EnvironmentVariableEnvironment.Production,
469
- ].map(env => env.toLowerCase()),
470
- // eslint-disable-next-line async-protect/async-suffix
471
- parse: async (input) => input.toUpperCase(),
472
- required: false,
473
- hidden: true,
474
- }),
454
+ ...flags_1.WithEasEnvironmentVariablesSetFlag,
475
455
  ...flags_1.EasNonInteractiveAndJsonFlags,
476
456
  };
477
457
  UpdatePublish.contextDefinition = {
@@ -61,11 +61,11 @@ async function promptUserAndCopyLegacyCredentialsAsync(ctx, app) {
61
61
  }
62
62
  exports.promptUserAndCopyLegacyCredentialsAsync = promptUserAndCopyLegacyCredentialsAsync;
63
63
  async function getAppLookupParamsFromContextAsync(ctx, gradleContext) {
64
- ctx.ensureProjectContext();
65
- const projectName = ctx.exp.slug;
66
- const projectId = ctx.projectId;
64
+ const exp = await ctx.getExpoConfigAsync();
65
+ const projectName = exp.slug;
66
+ const projectId = await ctx.getProjectIdAsync();
67
67
  const account = await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(ctx.graphqlClient, projectId);
68
- const androidApplicationIdentifier = await (0, applicationId_1.getApplicationIdAsync)(ctx.projectDir, ctx.exp, ctx.vcsClient, gradleContext);
68
+ const androidApplicationIdentifier = await (0, applicationId_1.getApplicationIdAsync)(ctx.projectDir, exp, ctx.vcsClient, gradleContext);
69
69
  if (!androidApplicationIdentifier) {
70
70
  throw new errors_1.AndroidPackageNotDefinedError(`android.package needs to be defined in your ${(0, projectUtils_1.getProjectConfigDescription)(ctx.projectDir)} file`);
71
71
  }
@@ -15,7 +15,7 @@ class CreateKeystore {
15
15
  if (ctx.nonInteractive) {
16
16
  throw new Error(`New keystore cannot be created in non-interactive mode.`);
17
17
  }
18
- const projectId = ctx.projectId;
18
+ const projectId = await ctx.getProjectIdAsync();
19
19
  const keystore = await this.provideOrGenerateAsync(ctx.graphqlClient, ctx.analytics, projectId);
20
20
  const keystoreFragment = await ctx.android.createKeystoreAsync(ctx.graphqlClient, this.account, keystore);
21
21
  log_1.default.succeed('Created keystore');
@@ -40,8 +40,8 @@ export declare class CredentialsContext {
40
40
  env?: Env;
41
41
  });
42
42
  get hasProjectContext(): boolean;
43
- get exp(): ExpoConfig;
44
- get projectId(): string;
45
- ensureProjectContext(): void;
43
+ getExpoConfigAsync(): Promise<ExpoConfig>;
44
+ getProjectIdAsync(): Promise<string>;
45
+ ensureProjectContextAsync(): Promise<void>;
46
46
  bestEffortAppStoreAuthenticateAsync(): Promise<void>;
47
47
  }
@@ -31,20 +31,20 @@ class CredentialsContext {
31
31
  get hasProjectContext() {
32
32
  return !!this.projectInfo;
33
33
  }
34
- get exp() {
35
- this.ensureProjectContext();
34
+ async getExpoConfigAsync() {
35
+ await this.ensureProjectContextAsync();
36
36
  return this.projectInfo.exp;
37
37
  }
38
- get projectId() {
39
- this.ensureProjectContext();
38
+ async getProjectIdAsync() {
39
+ await this.ensureProjectContextAsync();
40
40
  return this.projectInfo.projectId;
41
41
  }
42
- ensureProjectContext() {
42
+ async ensureProjectContextAsync() {
43
43
  if (this.hasProjectContext) {
44
44
  return;
45
45
  }
46
46
  // trigger getConfig error
47
- (0, expoConfig_1.getPrivateExpoConfig)(this.options.projectDir);
47
+ await (0, expoConfig_1.getPrivateExpoConfigAsync)(this.options.projectDir);
48
48
  }
49
49
  async bestEffortAppStoreAuthenticateAsync() {
50
50
  if (!!this.appStore.authCtx || !this.shouldAskAuthenticateAppStore) {
@@ -47,9 +47,9 @@ async function assignBuildCredentialsAsync(ctx, app, iosDistributionType, distCe
47
47
  }
48
48
  exports.assignBuildCredentialsAsync = assignBuildCredentialsAsync;
49
49
  async function getAppFromContextAsync(ctx) {
50
- ctx.ensureProjectContext();
51
- const projectName = ctx.exp.slug;
52
- const projectId = ctx.projectId;
50
+ const exp = await ctx.getExpoConfigAsync();
51
+ const projectName = exp.slug;
52
+ const projectId = await ctx.getProjectIdAsync();
53
53
  const account = await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(ctx.graphqlClient, projectId);
54
54
  return {
55
55
  account,
@@ -73,7 +73,7 @@ class ManageIos {
73
73
  return await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(ctx.graphqlClient, projectId);
74
74
  };
75
75
  const account = ctx.hasProjectContext
76
- ? await getAccountForProjectAsync(ctx.projectId)
76
+ ? await getAccountForProjectAsync(await ctx.getProjectIdAsync())
77
77
  : (0, actions_1.ensureActorHasPrimaryAccount)(ctx.user);
78
78
  let app = null;
79
79
  let targets = null;
@@ -160,15 +160,16 @@ class ManageIos {
160
160
  }
161
161
  async createProjectContextAsync(ctx, account, buildProfile) {
162
162
  (0, assert_1.default)(ctx.hasProjectContext, 'createProjectContextAsync: must have project context.');
163
- const app = { account, projectName: ctx.exp.slug };
163
+ const exp = await ctx.getExpoConfigAsync();
164
+ const app = { account, projectName: exp.slug };
164
165
  const xcodeBuildContext = await (0, scheme_1.resolveXcodeBuildContextAsync)({
165
166
  projectDir: ctx.projectDir,
166
167
  nonInteractive: ctx.nonInteractive,
167
- exp: ctx.exp,
168
+ exp,
168
169
  vcsClient: ctx.vcsClient,
169
170
  }, buildProfile);
170
171
  const targets = await (0, target_1.resolveTargetsAsync)({
171
- exp: ctx.exp,
172
+ exp,
172
173
  projectDir: ctx.projectDir,
173
174
  xcodeBuildContext,
174
175
  env: buildProfile.env,
@@ -42,7 +42,7 @@ class SetUpIosBuildCredentials extends ManageIos_1.ManageIos {
42
42
  return await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(ctx.graphqlClient, projectId);
43
43
  };
44
44
  const account = ctx.hasProjectContext
45
- ? await getAccountForProjectAsync(ctx.projectId)
45
+ ? await getAccountForProjectAsync(await ctx.getProjectIdAsync())
46
46
  : (0, actions_1.ensureActorHasPrimaryAccount)(ctx.user);
47
47
  let app = null;
48
48
  let targets = null;
@@ -21,22 +21,24 @@ class AppleConfigReader {
21
21
  return null;
22
22
  }
23
23
  return {
24
+ ageRatingOverride: attributes.ageRatingOverride ?? apple_utils_1.RatingOverride.NONE,
24
25
  alcoholTobaccoOrDrugUseOrReferences: attributes.alcoholTobaccoOrDrugUseOrReferences ?? apple_utils_1.Rating.NONE,
25
26
  contests: attributes.contests ?? apple_utils_1.Rating.NONE,
27
+ gambling: attributes.gambling ?? false,
26
28
  gamblingSimulated: attributes.gamblingSimulated ?? apple_utils_1.Rating.NONE,
27
29
  horrorOrFearThemes: attributes.horrorOrFearThemes ?? apple_utils_1.Rating.NONE,
30
+ kidsAgeBand: attributes.kidsAgeBand ?? null,
31
+ koreaAgeRatingOverride: attributes.koreaAgeRatingOverride ?? apple_utils_1.KoreaRatingOverride.NONE,
32
+ lootBox: attributes.lootBox ?? false,
28
33
  matureOrSuggestiveThemes: attributes.matureOrSuggestiveThemes ?? apple_utils_1.Rating.NONE,
29
34
  medicalOrTreatmentInformation: attributes.medicalOrTreatmentInformation ?? apple_utils_1.Rating.NONE,
30
35
  profanityOrCrudeHumor: attributes.profanityOrCrudeHumor ?? apple_utils_1.Rating.NONE,
31
36
  sexualContentGraphicAndNudity: attributes.sexualContentGraphicAndNudity ?? apple_utils_1.Rating.NONE,
32
37
  sexualContentOrNudity: attributes.sexualContentOrNudity ?? apple_utils_1.Rating.NONE,
38
+ unrestrictedWebAccess: attributes.unrestrictedWebAccess ?? false,
33
39
  violenceCartoonOrFantasy: attributes.violenceCartoonOrFantasy ?? apple_utils_1.Rating.NONE,
34
40
  violenceRealistic: attributes.violenceRealistic ?? apple_utils_1.Rating.NONE,
35
41
  violenceRealisticProlongedGraphicOrSadistic: attributes.violenceRealisticProlongedGraphicOrSadistic ?? apple_utils_1.Rating.NONE,
36
- gambling: attributes.gambling ?? false,
37
- unrestrictedWebAccess: attributes.unrestrictedWebAccess ?? false,
38
- kidsAgeBand: attributes.kidsAgeBand ?? null,
39
- seventeenPlus: attributes.seventeenPlus ?? false,
40
42
  };
41
43
  }
42
44
  getLocales() {
@@ -14,7 +14,7 @@ export declare class AppleConfigWriter {
14
14
  configVersion: number;
15
15
  apple: Partial<AppleMetadata>;
16
16
  };
17
- setAgeRating(attributes: AttributesOf<AgeRatingDeclaration>): void;
17
+ setAgeRating(attributes: Omit<AttributesOf<AgeRatingDeclaration>, 'seventeenPlus' | 'gamblingAndContests'>): void;
18
18
  setInfoLocale(attributes: AttributesOf<AppInfoLocalization>): void;
19
19
  setCategories(attributes: Pick<AttributesOf<AppInfo>, 'primaryCategory' | 'primarySubcategoryOne' | 'primarySubcategoryTwo' | 'secondaryCategory' | 'secondarySubcategoryOne' | 'secondarySubcategoryTwo'>): void;
20
20
  setVersion(attributes: Omit<AttributesOf<AppStoreVersion>, 'releaseType' | 'earliestReleaseDate'>): void;
@@ -17,24 +17,27 @@ class AppleConfigWriter {
17
17
  apple: this.schema,
18
18
  };
19
19
  }
20
+ // Note, both `seventeenPlus` and `gamlingAndContests` are deprecated
20
21
  setAgeRating(attributes) {
21
22
  this.schema.advisory = {
23
+ ageRatingOverride: attributes.ageRatingOverride ?? apple_utils_1.RatingOverride.NONE,
22
24
  alcoholTobaccoOrDrugUseOrReferences: attributes.alcoholTobaccoOrDrugUseOrReferences ?? apple_utils_1.Rating.NONE,
23
25
  contests: attributes.contests ?? apple_utils_1.Rating.NONE,
26
+ gambling: attributes.gambling ?? false,
24
27
  gamblingSimulated: attributes.gamblingSimulated ?? apple_utils_1.Rating.NONE,
25
28
  horrorOrFearThemes: attributes.horrorOrFearThemes ?? apple_utils_1.Rating.NONE,
29
+ kidsAgeBand: attributes.kidsAgeBand ?? null,
30
+ koreaAgeRatingOverride: attributes.koreaAgeRatingOverride ?? apple_utils_1.KoreaRatingOverride.NONE,
31
+ lootBox: attributes.lootBox ?? false,
26
32
  matureOrSuggestiveThemes: attributes.matureOrSuggestiveThemes ?? apple_utils_1.Rating.NONE,
27
33
  medicalOrTreatmentInformation: attributes.medicalOrTreatmentInformation ?? apple_utils_1.Rating.NONE,
28
34
  profanityOrCrudeHumor: attributes.profanityOrCrudeHumor ?? apple_utils_1.Rating.NONE,
29
35
  sexualContentGraphicAndNudity: attributes.sexualContentGraphicAndNudity ?? apple_utils_1.Rating.NONE,
30
36
  sexualContentOrNudity: attributes.sexualContentOrNudity ?? apple_utils_1.Rating.NONE,
37
+ unrestrictedWebAccess: attributes.unrestrictedWebAccess ?? false,
31
38
  violenceCartoonOrFantasy: attributes.violenceCartoonOrFantasy ?? apple_utils_1.Rating.NONE,
32
39
  violenceRealistic: attributes.violenceRealistic ?? apple_utils_1.Rating.NONE,
33
40
  violenceRealisticProlongedGraphicOrSadistic: attributes.violenceRealisticProlongedGraphicOrSadistic ?? apple_utils_1.Rating.NONE,
34
- gambling: attributes.gambling ?? false,
35
- unrestrictedWebAccess: attributes.unrestrictedWebAccess ?? false,
36
- kidsAgeBand: attributes.kidsAgeBand ?? null,
37
- seventeenPlus: attributes.seventeenPlus ?? false,
38
41
  };
39
42
  }
40
43
  setInfoLocale(attributes) {
@@ -11,7 +11,7 @@ export interface AppleMetadata {
11
11
  preview?: Record<string, string[]>;
12
12
  review?: AppleReview;
13
13
  }
14
- export type AppleAdvisory = Partial<AgeRatingDeclarationProps>;
14
+ export type AppleAdvisory = Omit<Partial<AgeRatingDeclarationProps>, 'seventeenPlus' | 'gamblingAndContests'>;
15
15
  /** Apps can define up to two categories, or categories with up to two subcategories */
16
16
  export type AppleCategory = (string | string[])[];
17
17
  export interface AppleRelease {
@@ -13,7 +13,7 @@ export interface ExpoConfigOptions {
13
13
  export declare function createOrModifyExpoConfigAsync(projectDir: string, exp: Partial<ExpoConfig>, readOptions?: {
14
14
  skipSDKVersionRequirement?: boolean;
15
15
  }): ReturnType<typeof modifyConfigAsync>;
16
- export declare function getPrivateExpoConfig(projectDir: string, opts?: ExpoConfigOptions): ExpoConfig;
16
+ export declare function getPrivateExpoConfigAsync(projectDir: string, opts?: ExpoConfigOptions): Promise<ExpoConfig>;
17
17
  export declare function ensureExpoConfigExists(projectDir: string): void;
18
18
  export declare function isUsingStaticExpoConfig(projectDir: string): boolean;
19
- export declare function getPublicExpoConfig(projectDir: string, opts?: ExpoConfigOptions): PublicExpoConfig;
19
+ export declare function getPublicExpoConfigAsync(projectDir: string, opts?: ExpoConfigOptions): Promise<PublicExpoConfig>;
@@ -1,11 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPublicExpoConfig = exports.isUsingStaticExpoConfig = exports.ensureExpoConfigExists = exports.getPrivateExpoConfig = exports.createOrModifyExpoConfigAsync = void 0;
3
+ exports.getPublicExpoConfigAsync = exports.isUsingStaticExpoConfig = exports.ensureExpoConfigExists = exports.getPrivateExpoConfigAsync = exports.createOrModifyExpoConfigAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const config_1 = require("@expo/config");
6
+ const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
6
7
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
7
8
  const joi_1 = tslib_1.__importDefault(require("joi"));
8
9
  const path_1 = tslib_1.__importDefault(require("path"));
10
+ const projectUtils_1 = require("./projectUtils");
11
+ const log_1 = tslib_1.__importDefault(require("../log"));
9
12
  async function createOrModifyExpoConfigAsync(projectDir, exp, readOptions) {
10
13
  ensureExpoConfigExists(projectDir);
11
14
  if (readOptions) {
@@ -16,18 +19,47 @@ async function createOrModifyExpoConfigAsync(projectDir, exp, readOptions) {
16
19
  }
17
20
  }
18
21
  exports.createOrModifyExpoConfigAsync = createOrModifyExpoConfigAsync;
19
- function getExpoConfigInternal(projectDir, opts = {}) {
22
+ let wasExpoConfigWarnPrinted = false;
23
+ async function getExpoConfigInternalAsync(projectDir, opts = {}) {
20
24
  const originalProcessEnv = process.env;
21
25
  try {
22
26
  process.env = {
23
27
  ...process.env,
24
28
  ...opts.env,
25
29
  };
26
- const { exp } = (0, config_1.getConfig)(projectDir, {
27
- skipSDKVersionRequirement: true,
28
- ...(opts.isPublicConfig ? { isPublicConfig: true } : {}),
29
- ...(opts.skipPlugins ? { skipPlugins: true } : {}),
30
- });
30
+ let exp;
31
+ if ((0, projectUtils_1.isExpoInstalled)(projectDir)) {
32
+ try {
33
+ const { stdout } = await (0, spawn_async_1.default)('npx', ['expo', 'config', '--json', ...(opts.isPublicConfig ? ['--type', 'public'] : [])], {
34
+ cwd: projectDir,
35
+ env: {
36
+ ...process.env,
37
+ ...opts.env,
38
+ EXPO_NO_DOTENV: '1',
39
+ },
40
+ });
41
+ exp = JSON.parse(stdout);
42
+ }
43
+ catch (err) {
44
+ if (!wasExpoConfigWarnPrinted) {
45
+ log_1.default.warn(`Failed to read the app config from the project using "npx expo config" command: ${err.message}.`);
46
+ log_1.default.warn('Falling back to the version of "@expo/config" shipped with the EAS CLI.');
47
+ wasExpoConfigWarnPrinted = true;
48
+ }
49
+ exp = (0, config_1.getConfig)(projectDir, {
50
+ skipSDKVersionRequirement: true,
51
+ ...(opts.isPublicConfig ? { isPublicConfig: true } : {}),
52
+ ...(opts.skipPlugins ? { skipPlugins: true } : {}),
53
+ }).exp;
54
+ }
55
+ }
56
+ else {
57
+ exp = (0, config_1.getConfig)(projectDir, {
58
+ skipSDKVersionRequirement: true,
59
+ ...(opts.isPublicConfig ? { isPublicConfig: true } : {}),
60
+ ...(opts.skipPlugins ? { skipPlugins: true } : {}),
61
+ }).exp;
62
+ }
31
63
  const { error } = MinimalAppConfigSchema.validate(exp, {
32
64
  allowUnknown: true,
33
65
  abortEarly: true,
@@ -52,11 +84,11 @@ const MinimalAppConfigSchema = joi_1.default.object({
52
84
  buildNumber: joi_1.default.string(),
53
85
  }),
54
86
  });
55
- function getPrivateExpoConfig(projectDir, opts = {}) {
87
+ async function getPrivateExpoConfigAsync(projectDir, opts = {}) {
56
88
  ensureExpoConfigExists(projectDir);
57
- return getExpoConfigInternal(projectDir, { ...opts, isPublicConfig: false });
89
+ return await getExpoConfigInternalAsync(projectDir, { ...opts, isPublicConfig: false });
58
90
  }
59
- exports.getPrivateExpoConfig = getPrivateExpoConfig;
91
+ exports.getPrivateExpoConfigAsync = getPrivateExpoConfigAsync;
60
92
  function ensureExpoConfigExists(projectDir) {
61
93
  const paths = (0, config_1.getConfigFilePaths)(projectDir);
62
94
  if (!paths?.staticConfigPath && !paths?.dynamicConfigPath) {
@@ -70,8 +102,8 @@ function isUsingStaticExpoConfig(projectDir) {
70
102
  return !!(paths.staticConfigPath?.endsWith('app.json') && !paths.dynamicConfigPath);
71
103
  }
72
104
  exports.isUsingStaticExpoConfig = isUsingStaticExpoConfig;
73
- function getPublicExpoConfig(projectDir, opts = {}) {
105
+ async function getPublicExpoConfigAsync(projectDir, opts = {}) {
74
106
  ensureExpoConfigExists(projectDir);
75
- return getExpoConfigInternal(projectDir, { ...opts, isPublicConfig: true });
107
+ return await getExpoConfigInternalAsync(projectDir, { ...opts, isPublicConfig: true });
76
108
  }
77
- exports.getPublicExpoConfig = getPublicExpoConfig;
109
+ exports.getPublicExpoConfigAsync = getPublicExpoConfigAsync;