eas-cli 16.22.0 → 16.23.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 (47) hide show
  1. package/README.md +208 -207
  2. package/build/build/android/graphql.js +1 -2
  3. package/build/build/evaluateConfigWithEnvVarsAsync.js +5 -11
  4. package/build/build/ios/graphql.js +1 -2
  5. package/build/build/utils/environment.d.ts +1 -4
  6. package/build/build/utils/environment.js +7 -24
  7. package/build/commandUtils/EasCommand.d.ts +1 -2
  8. package/build/commandUtils/context/ContextField.d.ts +1 -2
  9. package/build/commandUtils/context/contextUtils/loadServerSideEnvironmentVariablesAsync.d.ts +1 -2
  10. package/build/commandUtils/context/contextUtils/loadServerSideEnvironmentVariablesAsync.js +3 -8
  11. package/build/commandUtils/flags.d.ts +3 -5
  12. package/build/commandUtils/flags.js +8 -22
  13. package/build/commands/build/resign.d.ts +2 -3
  14. package/build/commands/deploy/index.d.ts +1 -2
  15. package/build/commands/env/create.d.ts +1 -2
  16. package/build/commands/env/create.js +12 -14
  17. package/build/commands/env/delete.d.ts +1 -2
  18. package/build/commands/env/delete.js +2 -6
  19. package/build/commands/env/exec.js +6 -7
  20. package/build/commands/env/get.d.ts +1 -2
  21. package/build/commands/env/get.js +4 -6
  22. package/build/commands/env/list.d.ts +1 -2
  23. package/build/commands/env/list.js +8 -6
  24. package/build/commands/env/pull.d.ts +1 -1
  25. package/build/commands/env/pull.js +8 -8
  26. package/build/commands/env/push.d.ts +6 -4
  27. package/build/commands/env/push.js +42 -30
  28. package/build/commands/env/update.d.ts +2 -3
  29. package/build/commands/env/update.js +7 -8
  30. package/build/commands/fingerprint/compare.d.ts +1 -2
  31. package/build/commands/fingerprint/compare.js +1 -1
  32. package/build/commands/fingerprint/generate.d.ts +1 -2
  33. package/build/commands/fingerprint/generate.js +1 -1
  34. package/build/commands/update/configure.d.ts +1 -1
  35. package/build/commands/update/configure.js +1 -1
  36. package/build/commands/update/index.d.ts +1 -2
  37. package/build/commands/update/index.js +1 -1
  38. package/build/graphql/generated.d.ts +14 -0
  39. package/build/graphql/queries/EnvironmentVariablesQuery.d.ts +6 -6
  40. package/build/graphql/queries/EnvironmentVariablesQuery.js +15 -0
  41. package/build/utils/prompts.d.ts +8 -5
  42. package/build/utils/prompts.js +69 -10
  43. package/build/utils/variableUtils.d.ts +1 -3
  44. package/build/utils/variableUtils.js +1 -6
  45. package/build/worker/assets.d.ts +1 -2
  46. package/oclif.manifest.json +36 -110
  47. package/package.json +4 -4
@@ -1,4 +1,3 @@
1
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  export default class EnvPush extends EasCommand {
4
3
  static description: string;
@@ -8,7 +7,8 @@ export default class EnvPush extends EasCommand {
8
7
  };
9
8
  static flags: {
10
9
  path: import("@oclif/core/lib/interfaces").OptionFlag<string>;
11
- environment: import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment[] | undefined>;
10
+ force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined>;
12
12
  };
13
13
  static args: {
14
14
  name: string;
@@ -18,10 +18,12 @@ export default class EnvPush extends EasCommand {
18
18
  runAsync(): Promise<void>;
19
19
  parseFlagsAndArgs(flags: {
20
20
  path: string;
21
- environment: EnvironmentVariableEnvironment[] | undefined;
21
+ environment: string[] | undefined;
22
+ force: boolean;
22
23
  }, { environment }: Record<string, string>): {
23
- environment?: EnvironmentVariableEnvironment[];
24
+ environment?: string[];
24
25
  path: string;
26
+ force: boolean;
25
27
  };
26
28
  private parseEnvFileAsync;
27
29
  }
@@ -13,7 +13,6 @@ const EnvironmentVariablesQuery_1 = require("../../graphql/queries/EnvironmentVa
13
13
  const log_1 = tslib_1.__importDefault(require("../../log"));
14
14
  const prompts_1 = require("../../prompts");
15
15
  const prompts_2 = require("../../utils/prompts");
16
- const variableUtils_1 = require("../../utils/variableUtils");
17
16
  class EnvPush extends EasCommand_1.default {
18
17
  static description = 'push environment variables from .env file to the selected environment';
19
18
  static contextDefinition = {
@@ -26,17 +25,21 @@ class EnvPush extends EasCommand_1.default {
26
25
  description: 'Path to the input `.env` file',
27
26
  default: '.env.local',
28
27
  }),
28
+ force: core_1.Flags.boolean({
29
+ description: 'Skip confirmation and automatically override existing variables',
30
+ default: false,
31
+ }),
29
32
  };
30
33
  static args = [
31
34
  {
32
35
  name: 'environment',
33
- description: "Environment to push variables to. One of 'production', 'preview', or 'development'.",
36
+ description: "Environment to push variables to. Default environments are 'production', 'preview', and 'development'.",
34
37
  required: false,
35
38
  },
36
39
  ];
37
40
  async runAsync() {
38
41
  const { args, flags } = await this.parse(EnvPush);
39
- let { environment: environments, path: envPath } = this.parseFlagsAndArgs(flags, args);
42
+ let { environment: environments, path: envPath, force } = this.parseFlagsAndArgs(flags, args);
40
43
  const { projectId, loggedIn: { graphqlClient }, } = await this.getContextAsync(EnvPush, {
41
44
  nonInteractive: false,
42
45
  });
@@ -44,6 +47,9 @@ class EnvPush extends EasCommand_1.default {
44
47
  environments = await (0, prompts_2.promptVariableEnvironmentAsync)({
45
48
  nonInteractive: false,
46
49
  multiple: true,
50
+ canEnterCustomEnvironment: true,
51
+ graphqlClient,
52
+ projectId,
47
53
  });
48
54
  }
49
55
  const updateVariables = await this.parseEnvFileAsync(envPath, environments);
@@ -82,32 +88,39 @@ class EnvPush extends EasCommand_1.default {
82
88
  if (existingDifferentVariables.length > 0) {
83
89
  log_1.default.warn(`Some variables already exist in the ${displayedEnvironment} environment.`);
84
90
  const variableNames = existingDifferentVariables.map(variable => variable.name);
85
- const confirmationMessage = variableNames.length > 1
86
- ? `The ${variableNames.join(', ')} environment variables already exist in ${displayedEnvironment} environment. Do you want to override them all?`
87
- : `The ${variableNames[0]} environment variable already exists in ${displayedEnvironment} environment. Do you want to override it?`;
88
- const confirm = await (0, prompts_1.confirmAsync)({
89
- message: confirmationMessage,
90
- });
91
91
  let variablesToOverwrite = [];
92
- if (!confirm && existingDifferentVariables.length === 0) {
93
- throw new Error('No new variables to push.');
94
- }
95
- if (confirm) {
92
+ if (force) {
93
+ // When --force is used, automatically override all existing variables
94
+ log_1.default.log('Using --force flag: automatically overriding existing variables.');
96
95
  variablesToOverwrite = existingDifferentVariables.map(variable => variable.name);
97
96
  }
98
97
  else {
99
- const promptResult = await (0, prompts_1.promptAsync)({
100
- type: 'multiselect',
101
- name: 'variablesToOverwrite',
102
- message: 'Select variables to overwrite:',
103
- // @ts-expect-error property missing from `@types/prompts`
104
- optionsPerPage: 20,
105
- choices: existingDifferentVariables.map(variable => ({
106
- title: `${variable.name}: ${updateVariables[variable.name].value} (was ${variable.value ?? '(secret)'})`,
107
- value: variable.name,
108
- })),
98
+ const confirmationMessage = variableNames.length > 1
99
+ ? `The ${variableNames.join(', ')} environment variables already exist in ${displayedEnvironment} environment. Do you want to override them all?`
100
+ : `The ${variableNames[0]} environment variable already exists in ${displayedEnvironment} environment. Do you want to override it?`;
101
+ const confirm = await (0, prompts_1.confirmAsync)({
102
+ message: confirmationMessage,
109
103
  });
110
- variablesToOverwrite = promptResult.variablesToOverwrite;
104
+ if (!confirm && existingDifferentVariables.length === 0) {
105
+ throw new Error('No new variables to push.');
106
+ }
107
+ if (confirm) {
108
+ variablesToOverwrite = existingDifferentVariables.map(variable => variable.name);
109
+ }
110
+ else {
111
+ const promptResult = await (0, prompts_1.promptAsync)({
112
+ type: 'multiselect',
113
+ name: 'variablesToOverwrite',
114
+ message: 'Select variables to overwrite:',
115
+ // @ts-expect-error property missing from `@types/prompts`
116
+ optionsPerPage: 20,
117
+ choices: existingDifferentVariables.map(variable => ({
118
+ title: `${variable.name}: ${updateVariables[variable.name].value} (was ${variable.value ?? '(secret)'})`,
119
+ value: variable.name,
120
+ })),
121
+ });
122
+ variablesToOverwrite = promptResult.variablesToOverwrite;
123
+ }
111
124
  }
112
125
  for (const existingVariable of existingVariables) {
113
126
  const name = existingVariable.name;
@@ -121,7 +134,7 @@ class EnvPush extends EasCommand_1.default {
121
134
  }
122
135
  // Check if any of the sensitive variables already exist in the environment. Prompt the user to overwrite them.
123
136
  const existingSensitiveVariables = existingVariables.filter(variable => variable.visibility !== generated_1.EnvironmentVariableVisibility.Public);
124
- if (existingSensitiveVariables.length > 0) {
137
+ if (existingSensitiveVariables.length > 0 && !force) {
125
138
  const existingSensitiveVariablesNames = existingSensitiveVariables.map(variable => `- ${variable.name}`);
126
139
  const confirm = await (0, prompts_1.confirmAsync)({
127
140
  message: `You are about to overwrite sensitive variables.\n${existingSensitiveVariablesNames.join('\n')}\n Do you want to continue?`,
@@ -130,6 +143,9 @@ class EnvPush extends EasCommand_1.default {
130
143
  throw new Error('Aborting...');
131
144
  }
132
145
  }
146
+ else if (existingSensitiveVariables.length > 0 && force) {
147
+ log_1.default.log('Using --force flag: automatically overriding sensitive variables.');
148
+ }
133
149
  }
134
150
  const variablesToPush = Object.values(updateVariables);
135
151
  if (variablesToPush.length === 0) {
@@ -140,11 +156,7 @@ class EnvPush extends EasCommand_1.default {
140
156
  log_1.default.log(`Uploaded env file to ${environments.join(', ').toLocaleLowerCase()}.`);
141
157
  }
142
158
  parseFlagsAndArgs(flags, { environment }) {
143
- if (environment && !(0, variableUtils_1.isEnvironment)(environment.toLowerCase())) {
144
- throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
145
- }
146
- const environments = flags.environment ??
147
- (environment ? [environment.toLowerCase()] : undefined);
159
+ const environments = flags.environment ?? (environment ? [environment] : undefined);
148
160
  return {
149
161
  ...flags,
150
162
  environment: environments,
@@ -1,15 +1,14 @@
1
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  import { EASEnvironmentVariableScopeFlagValue } from '../../commandUtils/flags';
4
3
  export default class EnvUpdate extends EasCommand {
5
4
  static description: string;
6
5
  static flags: {
7
6
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
- environment: import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment[] | undefined>;
7
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined>;
9
8
  scope: import("@oclif/core/lib/interfaces").OptionFlag<EASEnvironmentVariableScopeFlagValue>;
10
9
  visibility: import("@oclif/core/lib/interfaces").OptionFlag<"plaintext" | "sensitive" | "secret" | undefined>;
11
10
  'variable-name': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
12
- 'variable-environment': import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment | undefined>;
11
+ 'variable-environment': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
13
12
  name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
14
13
  value: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
15
14
  type: import("@oclif/core/lib/interfaces").OptionFlag<"string" | "file" | undefined>;
@@ -22,7 +22,7 @@ class EnvUpdate extends EasCommand_1.default {
22
22
  'variable-name': core_1.Flags.string({
23
23
  description: 'Current name of the variable',
24
24
  }),
25
- 'variable-environment': core_1.Flags.enum({
25
+ 'variable-environment': core_1.Flags.string({
26
26
  ...flags_1.EasEnvironmentFlagParameters,
27
27
  description: 'Current environment of the variable to update',
28
28
  }),
@@ -44,7 +44,7 @@ class EnvUpdate extends EasCommand_1.default {
44
44
  static args = [
45
45
  {
46
46
  name: 'environment',
47
- description: "Current environment of the variable to update. One of 'production', 'preview', or 'development'.",
47
+ description: "Current environment of the variable to update. Default environments are 'production', 'preview', and 'development'.",
48
48
  required: false,
49
49
  },
50
50
  ];
@@ -103,7 +103,7 @@ class EnvUpdate extends EasCommand_1.default {
103
103
  'non-interactive': nonInteractive,
104
104
  type,
105
105
  scope,
106
- });
106
+ }, { graphqlClient, projectId });
107
107
  const variable = await EnvironmentVariableMutation_1.EnvironmentVariableMutation.updateAsync(graphqlClient, {
108
108
  id: selectedVariable.id,
109
109
  name: newName,
@@ -131,10 +131,6 @@ class EnvUpdate extends EasCommand_1.default {
131
131
  ? generated_1.EnvironmentVariableScope.Shared
132
132
  : generated_1.EnvironmentVariableScope.Project;
133
133
  if (environment) {
134
- environment = environment.toLowerCase();
135
- if (!(0, variableUtils_1.isEnvironment)(environment)) {
136
- throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
137
- }
138
134
  return {
139
135
  ...flags,
140
136
  'variable-environment': environment,
@@ -143,7 +139,7 @@ class EnvUpdate extends EasCommand_1.default {
143
139
  }
144
140
  return { ...flags, scope };
145
141
  }
146
- async promptForMissingFlagsAsync(selectedVariable, { name, value, environment: environments, visibility, 'non-interactive': nonInteractive, type, ...rest }) {
142
+ async promptForMissingFlagsAsync(selectedVariable, { name, value, environment: environments, visibility, 'non-interactive': nonInteractive, type, ...rest }, { graphqlClient, projectId }) {
147
143
  let newType;
148
144
  let newVisibility;
149
145
  let fileName;
@@ -190,7 +186,10 @@ class EnvUpdate extends EasCommand_1.default {
190
186
  environments = await (0, prompts_2.promptVariableEnvironmentAsync)({
191
187
  nonInteractive,
192
188
  multiple: true,
189
+ canEnterCustomEnvironment: true,
193
190
  selectedEnvironments: selectedVariable.environments ?? [],
191
+ graphqlClient,
192
+ projectId,
194
193
  });
195
194
  if (!environments ||
196
195
  environments.length === 0 ||
@@ -1,4 +1,3 @@
1
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  export default class FingerprintCompare extends EasCommand {
4
3
  static description: string;
@@ -15,7 +14,7 @@ export default class FingerprintCompare extends EasCommand {
15
14
  'build-id': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined>;
16
15
  'update-id': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined>;
17
16
  open: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
- environment: import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment | undefined>;
17
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
19
18
  };
20
19
  static contextDefinition: {
21
20
  getServerSideEnvironmentVariablesAsync: import("../../commandUtils/context/ServerSideEnvironmentVariablesContextField").ServerSideEnvironmentVariablesContextField;
@@ -69,7 +69,7 @@ class FingerprintCompare extends EasCommand_1.default {
69
69
  open: core_1.Flags.boolean({
70
70
  description: 'Open the fingerprint comparison in the browser',
71
71
  }),
72
- environment: core_1.Flags.enum({
72
+ environment: core_1.Flags.string({
73
73
  ...flags_1.EasEnvironmentFlagParameters,
74
74
  description: 'If generating a fingerprint from the local directory, use the specified environment.',
75
75
  }),
@@ -1,4 +1,3 @@
1
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  export default class FingerprintGenerate extends EasCommand {
4
3
  static description: string;
@@ -7,7 +6,7 @@ export default class FingerprintGenerate extends EasCommand {
7
6
  static flags: {
8
7
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
8
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
- environment: import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment | undefined>;
9
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
11
10
  'build-profile': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
12
11
  platform: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
13
12
  };
@@ -29,7 +29,7 @@ class FingerprintGenerate extends EasCommand_1.default {
29
29
  options: ['android', 'ios'],
30
30
  }),
31
31
  ...flags_1.EASEnvironmentFlag,
32
- environment: core_1.Flags.enum({
32
+ environment: core_1.Flags.string({
33
33
  ...flags_1.EasEnvironmentFlagParameters,
34
34
  exclusive: ['build-profile'],
35
35
  }),
@@ -4,7 +4,7 @@ export default class UpdateConfigure extends EasCommand {
4
4
  static description: string;
5
5
  static flags: {
6
6
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
7
- environment: import("@oclif/core/lib/interfaces").OptionFlag<import("../../build/utils/environment").EnvironmentVariableEnvironment | null>;
7
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
8
8
  platform: import("@oclif/core/lib/interfaces").OptionFlag<RequestedPlatform>;
9
9
  };
10
10
  static contextDefinition: {
@@ -31,7 +31,7 @@ class UpdateConfigure extends EasCommand_1.default {
31
31
  const { flags } = await this.parse(UpdateConfigure);
32
32
  const { privateProjectConfig: { projectId, exp, projectDir }, vcsClient, } = await this.getContextAsync(UpdateConfigure, {
33
33
  nonInteractive: flags['non-interactive'],
34
- withServerSideEnvironment: flags['environment'],
34
+ withServerSideEnvironment: flags['environment'] ?? null,
35
35
  });
36
36
  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.');
37
37
  await vcsClient.ensureRepoExistsAsync();
@@ -1,4 +1,3 @@
1
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  import { RequestedPlatform } from '../../platform';
4
3
  export default class UpdatePublish extends EasCommand {
@@ -6,7 +5,7 @@ export default class UpdatePublish extends EasCommand {
6
5
  static flags: {
7
6
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
7
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
- environment: import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment | null>;
8
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
10
9
  branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
11
10
  channel: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
12
11
  message: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
@@ -101,7 +101,7 @@ class UpdatePublish extends EasCommand_1.default {
101
101
  const { auto: autoFlag, platform: requestedPlatform, channelName: channelNameArg, updateMessage: updateMessageArg, inputDir, skipBundler, clearCache, privateKeyPath, json: jsonFlag, nonInteractive, branchName: branchNameArg, emitMetadata, rolloutPercentage, environment, } = this.sanitizeFlags(rawFlags);
102
102
  const { getDynamicPublicProjectConfigAsync, getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, vcsClient, getServerSideEnvironmentVariablesAsync, } = await this.getContextAsync(UpdatePublish, {
103
103
  nonInteractive,
104
- withServerSideEnvironment: environment,
104
+ withServerSideEnvironment: environment ?? null,
105
105
  });
106
106
  if (jsonFlag) {
107
107
  (0, json_1.enableJsonOutput)();
@@ -13765,6 +13765,20 @@ export type EnvironmentSecretsByAppIdQuery = {
13765
13765
  };
13766
13766
  };
13767
13767
  };
13768
+ export type AppEnvironmentVariableEnvironmentsQueryVariables = Exact<{
13769
+ appId: Scalars['String']['input'];
13770
+ }>;
13771
+ export type AppEnvironmentVariableEnvironmentsQuery = {
13772
+ __typename?: 'RootQuery';
13773
+ app: {
13774
+ __typename?: 'AppQuery';
13775
+ byId: {
13776
+ __typename?: 'App';
13777
+ id: string;
13778
+ environmentVariableEnvironments: Array<any>;
13779
+ };
13780
+ };
13781
+ };
13768
13782
  export type EnvironmentVariablesIncludingSensitiveByAppIdQueryVariables = Exact<{
13769
13783
  appId: Scalars['String']['input'];
13770
13784
  filterNames?: InputMaybe<Array<Scalars['String']['input']> | Scalars['String']['input']>;
@@ -1,35 +1,35 @@
1
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
2
1
  import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
3
2
  import { EnvironmentVariableFragment } from '../generated';
4
3
  type EnvironmentVariableWithLinkedEnvironments = EnvironmentVariableFragment & {
5
- linkedEnvironments?: EnvironmentVariableEnvironment[] | null;
4
+ linkedEnvironments?: string[] | null;
6
5
  };
7
6
  export type EnvironmentVariableWithFileContent = EnvironmentVariableFragment & {
8
7
  valueWithFileContent?: string | null | undefined;
9
8
  };
10
9
  export declare const EnvironmentVariablesQuery: {
10
+ environmentVariableEnvironmentsAsync(graphqlClient: ExpoGraphqlClient, appId: string): Promise<string[]>;
11
11
  byAppIdWithSensitiveAsync(graphqlClient: ExpoGraphqlClient, { appId, environment, filterNames, includeFileContent, }: {
12
12
  appId: string;
13
- environment?: EnvironmentVariableEnvironment | undefined;
13
+ environment?: string | undefined;
14
14
  filterNames?: string[] | undefined;
15
15
  includeFileContent?: boolean | undefined;
16
16
  }): Promise<EnvironmentVariableWithFileContent[]>;
17
17
  byAppIdAsync(graphqlClient: ExpoGraphqlClient, { appId, environment, filterNames, includeFileContent, }: {
18
18
  appId: string;
19
- environment?: EnvironmentVariableEnvironment | undefined;
19
+ environment?: string | undefined;
20
20
  filterNames?: string[] | undefined;
21
21
  includeFileContent?: boolean | undefined;
22
22
  }): Promise<(EnvironmentVariableWithFileContent & EnvironmentVariableWithLinkedEnvironments)[]>;
23
23
  sharedAsync(graphqlClient: ExpoGraphqlClient, { appId, filterNames, environment, includeFileContent, }: {
24
24
  appId: string;
25
25
  filterNames?: string[] | undefined;
26
- environment?: EnvironmentVariableEnvironment | undefined;
26
+ environment?: string | undefined;
27
27
  includeFileContent?: boolean | undefined;
28
28
  }): Promise<(EnvironmentVariableWithFileContent & EnvironmentVariableWithLinkedEnvironments)[]>;
29
29
  sharedWithSensitiveAsync(graphqlClient: ExpoGraphqlClient, { appId, filterNames, environment, includeFileContent, }: {
30
30
  appId: string;
31
31
  filterNames?: string[] | undefined;
32
- environment?: EnvironmentVariableEnvironment | undefined;
32
+ environment?: string | undefined;
33
33
  includeFileContent?: boolean | undefined;
34
34
  }): Promise<EnvironmentVariableWithFileContent[]>;
35
35
  };
@@ -8,6 +8,21 @@ const client_1 = require("../client");
8
8
  const EnvironmentVariable_1 = require("../types/EnvironmentVariable");
9
9
  const EnvironmentVariableWithSecret_1 = require("../types/EnvironmentVariableWithSecret");
10
10
  exports.EnvironmentVariablesQuery = {
11
+ async environmentVariableEnvironmentsAsync(graphqlClient, appId) {
12
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
13
+ .query((0, graphql_tag_1.default) `
14
+ query AppEnvironmentVariableEnvironments($appId: String!) {
15
+ app {
16
+ byId(appId: $appId) {
17
+ id
18
+ environmentVariableEnvironments
19
+ }
20
+ }
21
+ }
22
+ `, { appId }, { additionalTypenames: ['App'] })
23
+ .toPromise());
24
+ return data.app?.byId.environmentVariableEnvironments ?? [];
25
+ },
11
26
  async byAppIdWithSensitiveAsync(graphqlClient, { appId, environment, filterNames, includeFileContent = false, }) {
12
27
  const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
13
28
  .query((0, graphql_tag_1.default) `
@@ -1,20 +1,23 @@
1
- import { EnvironmentVariableEnvironment } from '../build/utils/environment';
1
+ import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
2
2
  import { EnvironmentSecretType, EnvironmentVariableVisibility } from '../graphql/generated';
3
3
  import { RequestedPlatform } from '../platform';
4
+ export declare function getProjectEnvironmentVariableEnvironmentsAsync(graphqlClient: ExpoGraphqlClient, projectId: string): Promise<string[]>;
4
5
  export declare function promptVariableTypeAsync(nonInteractive: boolean, initialType?: EnvironmentSecretType): Promise<EnvironmentSecretType>;
5
6
  export declare function parseVisibility(stringVisibility: 'plaintext' | 'sensitive' | 'secret'): EnvironmentVariableVisibility;
6
7
  export declare function promptVariableVisibilityAsync(nonInteractive: boolean, selectedVisibility?: EnvironmentVariableVisibility | null): Promise<EnvironmentVariableVisibility>;
7
8
  type EnvironmentPromptArgs = {
8
9
  nonInteractive: boolean;
9
- selectedEnvironments?: EnvironmentVariableEnvironment[];
10
- availableEnvironments?: EnvironmentVariableEnvironment[];
10
+ selectedEnvironments?: string[];
11
+ graphqlClient?: ExpoGraphqlClient;
12
+ projectId?: string;
13
+ canEnterCustomEnvironment?: boolean;
11
14
  };
12
15
  export declare function promptVariableEnvironmentAsync(input: EnvironmentPromptArgs & {
13
16
  multiple: true;
14
- }): Promise<EnvironmentVariableEnvironment[]>;
17
+ }): Promise<string[]>;
15
18
  export declare function promptVariableEnvironmentAsync(input: EnvironmentPromptArgs & {
16
19
  multiple?: false;
17
- }): Promise<EnvironmentVariableEnvironment>;
20
+ }): Promise<string>;
18
21
  export declare function promptVariableValueAsync({ nonInteractive, required, hidden, filePath, initial, }: {
19
22
  nonInteractive: boolean;
20
23
  required?: boolean;
@@ -1,12 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.promptPlatformAsync = exports.promptVariableNameAsync = exports.promptVariableValueAsync = exports.promptVariableEnvironmentAsync = exports.promptVariableVisibilityAsync = exports.parseVisibility = exports.promptVariableTypeAsync = void 0;
3
+ exports.promptPlatformAsync = exports.promptVariableNameAsync = exports.promptVariableValueAsync = exports.promptVariableEnvironmentAsync = exports.promptVariableVisibilityAsync = exports.parseVisibility = exports.promptVariableTypeAsync = exports.getProjectEnvironmentVariableEnvironmentsAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  const environment_1 = require("../build/utils/environment");
7
7
  const generated_1 = require("../graphql/generated");
8
+ const EnvironmentVariablesQuery_1 = require("../graphql/queries/EnvironmentVariablesQuery");
8
9
  const platform_1 = require("../platform");
9
10
  const prompts_1 = require("../prompts");
11
+ const DEFAULT_ENVIRONMENTS = Object.values(environment_1.DefaultEnvironment);
12
+ async function getProjectEnvironmentVariableEnvironmentsAsync(graphqlClient, projectId) {
13
+ try {
14
+ const environments = await EnvironmentVariablesQuery_1.EnvironmentVariablesQuery.environmentVariableEnvironmentsAsync(graphqlClient, projectId);
15
+ return environments;
16
+ }
17
+ catch {
18
+ throw new Error('Failed to fetch available environments');
19
+ }
20
+ }
21
+ exports.getProjectEnvironmentVariableEnvironmentsAsync = getProjectEnvironmentVariableEnvironmentsAsync;
22
+ const CUSTOM_ENVIRONMENT_VALUE = '~~CUSTOM~~';
10
23
  async function promptVariableTypeAsync(nonInteractive, initialType) {
11
24
  if (nonInteractive) {
12
25
  throw new Error('The `--type` flag must be set when running in `--non-interactive` mode.');
@@ -39,6 +52,23 @@ function parseVisibility(stringVisibility) {
39
52
  }
40
53
  }
41
54
  exports.parseVisibility = parseVisibility;
55
+ async function promptCustomEnvironmentAsync() {
56
+ const { customEnvironment } = await (0, prompts_1.promptAsync)({
57
+ type: 'text',
58
+ name: 'customEnvironment',
59
+ message: 'Enter custom environment name:',
60
+ validate: (value) => {
61
+ if (!value || value.trim() === '') {
62
+ return 'Environment name cannot be empty';
63
+ }
64
+ if (!value.match(/^[a-zA-Z0-9_-]+$/)) {
65
+ return 'Environment name may only contain letters, numbers, underscores, and hyphens';
66
+ }
67
+ return true;
68
+ },
69
+ });
70
+ return customEnvironment;
71
+ }
42
72
  async function promptVariableVisibilityAsync(nonInteractive, selectedVisibility) {
43
73
  if (nonInteractive) {
44
74
  throw new Error('The `--visibility` flag must be set when running in `--non-interactive` mode.');
@@ -62,26 +92,55 @@ async function promptVariableVisibilityAsync(nonInteractive, selectedVisibility)
62
92
  ]);
63
93
  }
64
94
  exports.promptVariableVisibilityAsync = promptVariableVisibilityAsync;
65
- async function promptVariableEnvironmentAsync({ nonInteractive, selectedEnvironments, multiple = false, availableEnvironments, }) {
95
+ async function promptVariableEnvironmentAsync({ nonInteractive, selectedEnvironments, multiple = false, canEnterCustomEnvironment = false, graphqlClient, projectId, }) {
66
96
  if (nonInteractive) {
67
97
  throw new Error('The `--environment` flag must be set when running in `--non-interactive` mode.');
68
98
  }
99
+ let allEnvironments = DEFAULT_ENVIRONMENTS;
100
+ if (graphqlClient && projectId) {
101
+ const projectEnvironments = await getProjectEnvironmentVariableEnvironmentsAsync(graphqlClient, projectId);
102
+ allEnvironments = [...new Set([...DEFAULT_ENVIRONMENTS, ...projectEnvironments])];
103
+ }
69
104
  if (!multiple) {
70
- return await (0, prompts_1.selectAsync)('Select environment:', (availableEnvironments ?? Object.values(environment_1.EnvironmentVariableEnvironment)).map(environment => ({
71
- title: environment.toLocaleLowerCase(),
105
+ const choices = allEnvironments.map(environment => ({
106
+ title: environment,
72
107
  value: environment,
73
- })));
108
+ }));
109
+ if (canEnterCustomEnvironment) {
110
+ choices.push({
111
+ title: 'Other (enter custom environment)',
112
+ value: CUSTOM_ENVIRONMENT_VALUE,
113
+ });
114
+ }
115
+ const selectedEnvironment = await (0, prompts_1.selectAsync)('Select environment:', choices);
116
+ if (selectedEnvironment === CUSTOM_ENVIRONMENT_VALUE) {
117
+ return await promptCustomEnvironmentAsync();
118
+ }
119
+ return selectedEnvironment;
120
+ }
121
+ const choices = allEnvironments.map(environment => ({
122
+ title: environment,
123
+ value: environment,
124
+ selected: selectedEnvironments?.includes(environment),
125
+ }));
126
+ if (canEnterCustomEnvironment) {
127
+ choices.push({
128
+ title: 'Other (enter custom environment)',
129
+ value: CUSTOM_ENVIRONMENT_VALUE,
130
+ selected: false,
131
+ });
74
132
  }
75
133
  const { environments } = await (0, prompts_1.promptAsync)({
76
134
  message: 'Select environment:',
77
135
  name: 'environments',
78
136
  type: 'multiselect',
79
- choices: Object.values(environment_1.EnvironmentVariableEnvironment).map(environment => ({
80
- title: environment.toLocaleLowerCase(),
81
- value: environment,
82
- selected: selectedEnvironments?.includes(environment),
83
- })),
137
+ choices,
84
138
  });
139
+ if (environments?.includes(CUSTOM_ENVIRONMENT_VALUE)) {
140
+ const customEnvironment = await promptCustomEnvironmentAsync();
141
+ const filteredEnvironments = environments.filter((env) => env !== CUSTOM_ENVIRONMENT_VALUE);
142
+ return [...filteredEnvironments, customEnvironment];
143
+ }
85
144
  return environments;
86
145
  }
87
146
  exports.promptVariableEnvironmentAsync = promptVariableEnvironmentAsync;
@@ -1,8 +1,6 @@
1
- import { EnvironmentVariableEnvironment } from '../build/utils/environment';
2
1
  import { EnvironmentVariableFragment } from '../graphql/generated';
3
2
  import { EnvironmentVariableWithFileContent } from '../graphql/queries/EnvironmentVariablesQuery';
4
- export declare function isEnvironment(environment: string): environment is EnvironmentVariableEnvironment;
5
3
  export declare function formatVariableName(variable: EnvironmentVariableFragment): string;
6
4
  export declare function formatVariableValue(variable: EnvironmentVariableWithFileContent): string;
7
- export declare function performForEnvironmentsAsync(environments: EnvironmentVariableEnvironment[] | null, fun: (environment: EnvironmentVariableEnvironment | undefined) => Promise<any>): Promise<any[]>;
5
+ export declare function performForEnvironmentsAsync(environments: string[] | null, fun: (environment: string | undefined) => Promise<any>): Promise<any[]>;
8
6
  export declare function formatVariable(variable: EnvironmentVariableWithFileContent): string;
@@ -1,15 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatVariable = exports.performForEnvironmentsAsync = exports.formatVariableValue = exports.formatVariableName = exports.isEnvironment = void 0;
3
+ exports.formatVariable = exports.performForEnvironmentsAsync = exports.formatVariableValue = exports.formatVariableName = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const dateformat_1 = tslib_1.__importDefault(require("dateformat"));
6
6
  const formatFields_1 = tslib_1.__importDefault(require("./formatFields"));
7
- const environment_1 = require("../build/utils/environment");
8
7
  const generated_1 = require("../graphql/generated");
9
- function isEnvironment(environment) {
10
- return Object.values(environment_1.EnvironmentVariableEnvironment).includes(environment);
11
- }
12
- exports.isEnvironment = isEnvironment;
13
8
  function formatVariableName(variable) {
14
9
  const name = variable.name;
15
10
  const scope = variable.scope === generated_1.EnvironmentVariableScope.Project ? 'project' : 'shared';
@@ -1,6 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  import { GzipOptions } from 'minizlib';
3
- import { EnvironmentVariableEnvironment } from '../build/utils/environment';
4
3
  import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
5
4
  interface AssetMapOptions {
6
5
  maxFileSize: number;
@@ -36,7 +35,7 @@ export interface CreateManifestResult {
36
35
  interface CreateManifestParams {
37
36
  projectId: string;
38
37
  projectDir: string;
39
- environment?: EnvironmentVariableEnvironment;
38
+ environment?: string;
40
39
  }
41
40
  /** Creates a manifest configuration sent up for deployment */
42
41
  export declare function createManifestAsync(params: CreateManifestParams, graphqlClient: ExpoGraphqlClient): Promise<CreateManifestResult>;