eas-cli 16.21.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.
- package/README.md +210 -209
- package/build/build/android/graphql.js +1 -2
- package/build/build/evaluateConfigWithEnvVarsAsync.js +5 -11
- package/build/build/ios/graphql.js +1 -2
- package/build/build/utils/environment.d.ts +1 -4
- package/build/build/utils/environment.js +7 -24
- package/build/commandUtils/EasCommand.d.ts +1 -2
- package/build/commandUtils/context/ContextField.d.ts +1 -2
- package/build/commandUtils/context/contextUtils/loadServerSideEnvironmentVariablesAsync.d.ts +1 -2
- package/build/commandUtils/context/contextUtils/loadServerSideEnvironmentVariablesAsync.js +3 -8
- package/build/commandUtils/flags.d.ts +3 -5
- package/build/commandUtils/flags.js +8 -22
- package/build/commandUtils/workflow/buildProfileUtils.d.ts +36 -0
- package/build/commandUtils/workflow/buildProfileUtils.js +210 -0
- package/build/commandUtils/workflow/creation.d.ts +20 -0
- package/build/commandUtils/workflow/creation.js +462 -0
- package/build/commandUtils/workflow/validation.d.ts +4 -0
- package/build/commandUtils/workflow/validation.js +8 -4
- package/build/commands/build/resign.d.ts +2 -3
- package/build/commands/deploy/index.d.ts +1 -2
- package/build/commands/env/create.d.ts +1 -2
- package/build/commands/env/create.js +12 -14
- package/build/commands/env/delete.d.ts +1 -2
- package/build/commands/env/delete.js +2 -6
- package/build/commands/env/exec.js +6 -7
- package/build/commands/env/get.d.ts +1 -2
- package/build/commands/env/get.js +4 -6
- package/build/commands/env/list.d.ts +1 -2
- package/build/commands/env/list.js +8 -6
- package/build/commands/env/pull.d.ts +1 -1
- package/build/commands/env/pull.js +8 -8
- package/build/commands/env/push.d.ts +6 -4
- package/build/commands/env/push.js +42 -30
- package/build/commands/env/update.d.ts +2 -3
- package/build/commands/env/update.js +7 -8
- package/build/commands/fingerprint/compare.d.ts +1 -2
- package/build/commands/fingerprint/compare.js +1 -1
- package/build/commands/fingerprint/generate.d.ts +1 -2
- package/build/commands/fingerprint/generate.js +1 -1
- package/build/commands/update/configure.d.ts +1 -1
- package/build/commands/update/configure.js +1 -1
- package/build/commands/update/index.d.ts +1 -2
- package/build/commands/update/index.js +1 -1
- package/build/commands/workflow/create.d.ts +4 -3
- package/build/commands/workflow/create.js +130 -56
- package/build/graphql/generated.d.ts +44 -0
- package/build/graphql/queries/EnvironmentVariablesQuery.d.ts +6 -6
- package/build/graphql/queries/EnvironmentVariablesQuery.js +15 -0
- package/build/graphql/types/Workflow.js +11 -0
- package/build/utils/prompts.d.ts +8 -5
- package/build/utils/prompts.js +69 -10
- package/build/utils/variableUtils.d.ts +1 -3
- package/build/utils/variableUtils.js +1 -6
- package/build/worker/assets.d.ts +1 -2
- package/oclif.manifest.json +43 -114
- package/package.json +4 -4
|
@@ -2,28 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkflowCreate = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const core_1 = require("@oclif/core");
|
|
5
6
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
7
|
const promises_1 = tslib_1.__importDefault(require("fs/promises"));
|
|
7
8
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
8
9
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
9
|
-
const prompts_1 = tslib_1.__importDefault(require("prompts"));
|
|
10
10
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
11
|
-
const
|
|
11
|
+
const buildProfileUtils_1 = require("../../commandUtils/workflow/buildProfileUtils");
|
|
12
|
+
const creation_1 = require("../../commandUtils/workflow/creation");
|
|
13
|
+
const validation_1 = require("../../commandUtils/workflow/validation");
|
|
12
14
|
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
15
|
+
const prompts_1 = require("../../prompts");
|
|
16
|
+
const formatFields_1 = tslib_1.__importDefault(require("../../utils/formatFields"));
|
|
13
17
|
const workflowFile_1 = require("../../utils/workflowFile");
|
|
14
|
-
const DEFAULT_WORKFLOW_NAME = 'workflow.yml';
|
|
15
|
-
const HELLO_WORLD_TEMPLATE = `name: Hello World
|
|
16
|
-
|
|
17
|
-
on:
|
|
18
|
-
push:
|
|
19
|
-
branches: ['*']
|
|
20
|
-
|
|
21
|
-
jobs:
|
|
22
|
-
hello_world:
|
|
23
|
-
steps:
|
|
24
|
-
- uses: eas/checkout
|
|
25
|
-
- run: echo "Hello, World"
|
|
26
|
-
`;
|
|
27
18
|
class WorkflowCreate extends EasCommand_1.default {
|
|
28
19
|
static description = 'create a new workflow configuration YAML file';
|
|
29
20
|
static args = [
|
|
@@ -34,65 +25,148 @@ class WorkflowCreate extends EasCommand_1.default {
|
|
|
34
25
|
},
|
|
35
26
|
];
|
|
36
27
|
static flags = {
|
|
37
|
-
|
|
28
|
+
'skip-validation': core_1.Flags.boolean({
|
|
29
|
+
description: 'If set, the workflow file will not be validated before being created',
|
|
30
|
+
default: false,
|
|
31
|
+
}),
|
|
38
32
|
};
|
|
39
33
|
static contextDefinition = {
|
|
34
|
+
...this.ContextOptions.DynamicProjectConfig,
|
|
40
35
|
...this.ContextOptions.ProjectDir,
|
|
36
|
+
...this.ContextOptions.LoggedIn,
|
|
41
37
|
};
|
|
42
38
|
async runAsync() {
|
|
43
39
|
const { args: { name: argFileName }, flags, } = await this.parse(WorkflowCreate);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
40
|
+
try {
|
|
41
|
+
const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, projectDir, } = await this.getContextAsync(WorkflowCreate, {
|
|
42
|
+
nonInteractive: false,
|
|
43
|
+
withServerSideEnvironment: null,
|
|
44
|
+
});
|
|
45
|
+
const { exp: originalExpoConfig, projectId } = await getDynamicPrivateProjectConfigAsync();
|
|
46
|
+
let expoConfig = originalExpoConfig;
|
|
47
|
+
let workflowStarter;
|
|
48
|
+
while (!workflowStarter) {
|
|
49
|
+
workflowStarter = await chooseTemplateAsync();
|
|
50
|
+
switch (workflowStarter.name) {
|
|
51
|
+
case creation_1.WorkflowStarterName.BUILD:
|
|
52
|
+
case creation_1.WorkflowStarterName.DEPLOY:
|
|
53
|
+
case creation_1.WorkflowStarterName.UPDATE: {
|
|
54
|
+
const shouldProceed = await (0, buildProfileUtils_1.runBuildConfigureIfNeededAsync)({
|
|
55
|
+
projectDir,
|
|
56
|
+
expoConfig,
|
|
57
|
+
});
|
|
58
|
+
if (!shouldProceed) {
|
|
59
|
+
workflowStarter = undefined;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
58
63
|
}
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
default:
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
switch (workflowStarter.name) {
|
|
68
|
+
case creation_1.WorkflowStarterName.DEPLOY:
|
|
69
|
+
case creation_1.WorkflowStarterName.UPDATE: {
|
|
70
|
+
const shouldProceed = await (0, buildProfileUtils_1.runUpdateConfigureIfNeededAsync)({
|
|
71
|
+
projectDir,
|
|
72
|
+
expoConfig,
|
|
73
|
+
});
|
|
74
|
+
if (!shouldProceed) {
|
|
75
|
+
workflowStarter = undefined;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// Need to refetch the Expo config because it may have changed
|
|
79
|
+
expoConfig = (await getDynamicPrivateProjectConfigAsync()).exp;
|
|
80
|
+
break;
|
|
61
81
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
82
|
+
default:
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const { fileName, filePath } = await chooseFileNameAsync(argFileName, projectDir, workflowStarter);
|
|
87
|
+
// Customize the template if needed
|
|
88
|
+
workflowStarter = await (0, creation_1.customizeTemplateIfNeededAsync)(workflowStarter, projectDir, expoConfig);
|
|
89
|
+
log_1.default.debug(`Creating workflow file ${fileName} from template ${workflowStarter.name}`);
|
|
90
|
+
const yamlString = [
|
|
91
|
+
workflowStarter.header,
|
|
92
|
+
(0, validation_1.workflowContentsFromParsedYaml)(workflowStarter.template),
|
|
93
|
+
].join('\n');
|
|
94
|
+
if (!flags['skip-validation']) {
|
|
95
|
+
await (0, validation_1.validateWorkflowFileAsync)({ yamlConfig: yamlString, filePath: fileName }, projectDir, graphqlClient, projectId);
|
|
96
|
+
}
|
|
97
|
+
await ensureWorkflowsDirectoryExistsAsync({ projectDir });
|
|
98
|
+
filePath && (await promises_1.default.writeFile(filePath, yamlString));
|
|
99
|
+
log_1.default.withTick(`Created ${chalk_1.default.bold(filePath)}`);
|
|
100
|
+
log_1.default.addNewLineIfNone();
|
|
101
|
+
log_1.default.log((0, creation_1.howToRunWorkflow)(fileName, workflowStarter));
|
|
102
|
+
// Next steps
|
|
103
|
+
if (workflowStarter.nextSteps && workflowStarter.nextSteps.length > 0) {
|
|
104
|
+
log_1.default.addNewLineIfNone();
|
|
105
|
+
log_1.default.log('Next steps:');
|
|
106
|
+
log_1.default.addNewLineIfNone();
|
|
107
|
+
log_1.default.log((0, formatFields_1.default)(workflowStarter.nextSteps.map((step, index) => ({
|
|
108
|
+
label: `${index + 1}.`,
|
|
109
|
+
value: step,
|
|
110
|
+
}))));
|
|
67
111
|
}
|
|
68
|
-
fileName = response.fileName;
|
|
69
|
-
}
|
|
70
|
-
try {
|
|
71
|
-
await this.ensureWorkflowsDirectoryExistsAsync({ projectDir });
|
|
72
|
-
await this.createWorkflowFileAsync({ fileName, projectDir });
|
|
73
112
|
}
|
|
74
113
|
catch (error) {
|
|
114
|
+
(0, validation_1.logWorkflowValidationErrors)(error);
|
|
75
115
|
log_1.default.error('Failed to create workflow file.');
|
|
76
|
-
throw error;
|
|
77
116
|
}
|
|
78
117
|
}
|
|
79
|
-
|
|
118
|
+
}
|
|
119
|
+
exports.WorkflowCreate = WorkflowCreate;
|
|
120
|
+
async function ensureWorkflowsDirectoryExistsAsync({ projectDir, }) {
|
|
121
|
+
try {
|
|
122
|
+
await promises_1.default.access(path_1.default.join(projectDir, '.eas', 'workflows'));
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
await promises_1.default.mkdir(path_1.default.join(projectDir, '.eas', 'workflows'), { recursive: true });
|
|
126
|
+
log_1.default.withTick(`Created directory ${chalk_1.default.bold(path_1.default.join(projectDir, '.eas', 'workflows'))}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function chooseTemplateAsync() {
|
|
130
|
+
const workflowStarter = (await (0, prompts_1.promptAsync)({
|
|
131
|
+
type: 'select',
|
|
132
|
+
name: 'starter',
|
|
133
|
+
message: 'Select a workflow template:',
|
|
134
|
+
choices: creation_1.workflowStarters.map(starter => ({
|
|
135
|
+
title: starter.displayName,
|
|
136
|
+
value: starter,
|
|
137
|
+
})),
|
|
138
|
+
})).starter;
|
|
139
|
+
return workflowStarter;
|
|
140
|
+
}
|
|
141
|
+
async function chooseFileNameAsync(initialValue, projectDir, workflowStarter) {
|
|
142
|
+
let fileName = initialValue;
|
|
143
|
+
let filePath = '';
|
|
144
|
+
while ((fileName?.length ?? 0) === 0) {
|
|
145
|
+
fileName = (await (0, prompts_1.promptAsync)({
|
|
146
|
+
type: 'text',
|
|
147
|
+
name: 'fileName',
|
|
148
|
+
message: 'What would you like to name your workflow file?',
|
|
149
|
+
initial: workflowStarter.defaultFileName,
|
|
150
|
+
})).fileName;
|
|
151
|
+
if (!fileName) {
|
|
152
|
+
fileName = undefined;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
80
155
|
try {
|
|
81
|
-
|
|
156
|
+
workflowFile_1.WorkflowFile.validateYamlExtension(fileName);
|
|
82
157
|
}
|
|
83
|
-
catch {
|
|
84
|
-
|
|
85
|
-
|
|
158
|
+
catch (error) {
|
|
159
|
+
log_1.default.error(error instanceof Error ? error.message : 'Invalid YAML file name extension');
|
|
160
|
+
fileName = undefined;
|
|
161
|
+
continue;
|
|
86
162
|
}
|
|
87
|
-
|
|
88
|
-
async createWorkflowFileAsync({ fileName, projectDir, }) {
|
|
89
|
-
workflowFile_1.WorkflowFile.validateYamlExtension(fileName);
|
|
90
|
-
const filePath = path_1.default.join(projectDir, '.eas', 'workflows', fileName);
|
|
163
|
+
filePath = path_1.default.join(projectDir, '.eas', 'workflows', fileName);
|
|
91
164
|
if (await fs_extra_1.default.pathExists(filePath)) {
|
|
92
|
-
|
|
165
|
+
log_1.default.error(`Workflow file already exists: ${filePath}`);
|
|
166
|
+
log_1.default.error('Please choose a different file name.');
|
|
167
|
+
log_1.default.newLine();
|
|
168
|
+
fileName = undefined;
|
|
93
169
|
}
|
|
94
|
-
await promises_1.default.writeFile(filePath, HELLO_WORLD_TEMPLATE);
|
|
95
|
-
log_1.default.withTick(`Created ${chalk_1.default.bold(filePath)}`);
|
|
96
170
|
}
|
|
171
|
+
return { fileName: fileName ?? '', filePath };
|
|
97
172
|
}
|
|
98
|
-
exports.WorkflowCreate = WorkflowCreate;
|
|
@@ -166,6 +166,7 @@ export type Account = {
|
|
|
166
166
|
displayName?: Maybe<Scalars['String']['output']>;
|
|
167
167
|
/** Environment secrets for an account */
|
|
168
168
|
environmentSecrets: Array<EnvironmentSecret>;
|
|
169
|
+
environmentVariableEnvironments: Array<Scalars['EnvironmentVariableEnvironment']['output']>;
|
|
169
170
|
/** Environment variables for an account */
|
|
170
171
|
environmentVariables: Array<EnvironmentVariable>;
|
|
171
172
|
/** Environment variables for an account with decrypted secret values */
|
|
@@ -1139,6 +1140,7 @@ export type App = Project & {
|
|
|
1139
1140
|
devDomainName?: Maybe<AppDevDomainName>;
|
|
1140
1141
|
/** Environment secrets for an app */
|
|
1141
1142
|
environmentSecrets: Array<EnvironmentSecret>;
|
|
1143
|
+
environmentVariableEnvironments: Array<Scalars['EnvironmentVariableEnvironment']['output']>;
|
|
1142
1144
|
/** Environment variables for an app */
|
|
1143
1145
|
environmentVariables: Array<EnvironmentVariable>;
|
|
1144
1146
|
/** Environment variables for an app with decrypted secret values */
|
|
@@ -12704,6 +12706,20 @@ export type AppByIdWorkflowsQuery = {
|
|
|
12704
12706
|
fileName: string;
|
|
12705
12707
|
createdAt: any;
|
|
12706
12708
|
updatedAt: any;
|
|
12709
|
+
revisionsPaginated: {
|
|
12710
|
+
__typename?: 'WorkflowRevisionsConnection';
|
|
12711
|
+
edges: Array<{
|
|
12712
|
+
__typename?: 'WorkflowRevisionEdge';
|
|
12713
|
+
node: {
|
|
12714
|
+
__typename?: 'WorkflowRevision';
|
|
12715
|
+
id: string;
|
|
12716
|
+
blobSha: string;
|
|
12717
|
+
commitSha?: string | null;
|
|
12718
|
+
createdAt: any;
|
|
12719
|
+
yamlConfig: string;
|
|
12720
|
+
};
|
|
12721
|
+
}>;
|
|
12722
|
+
};
|
|
12707
12723
|
}>;
|
|
12708
12724
|
};
|
|
12709
12725
|
};
|
|
@@ -13749,6 +13765,20 @@ export type EnvironmentSecretsByAppIdQuery = {
|
|
|
13749
13765
|
};
|
|
13750
13766
|
};
|
|
13751
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
|
+
};
|
|
13752
13782
|
export type EnvironmentVariablesIncludingSensitiveByAppIdQueryVariables = Exact<{
|
|
13753
13783
|
appId: Scalars['String']['input'];
|
|
13754
13784
|
filterNames?: InputMaybe<Array<Scalars['String']['input']> | Scalars['String']['input']>;
|
|
@@ -15670,6 +15700,20 @@ export type WorkflowFragment = {
|
|
|
15670
15700
|
fileName: string;
|
|
15671
15701
|
createdAt: any;
|
|
15672
15702
|
updatedAt: any;
|
|
15703
|
+
revisionsPaginated: {
|
|
15704
|
+
__typename?: 'WorkflowRevisionsConnection';
|
|
15705
|
+
edges: Array<{
|
|
15706
|
+
__typename?: 'WorkflowRevisionEdge';
|
|
15707
|
+
node: {
|
|
15708
|
+
__typename?: 'WorkflowRevision';
|
|
15709
|
+
id: string;
|
|
15710
|
+
blobSha: string;
|
|
15711
|
+
commitSha?: string | null;
|
|
15712
|
+
createdAt: any;
|
|
15713
|
+
yamlConfig: string;
|
|
15714
|
+
};
|
|
15715
|
+
}>;
|
|
15716
|
+
};
|
|
15673
15717
|
};
|
|
15674
15718
|
export type WorkflowJobFragment = {
|
|
15675
15719
|
__typename?: 'WorkflowJob';
|
|
@@ -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?:
|
|
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?:
|
|
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?:
|
|
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?:
|
|
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?:
|
|
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) `
|
package/build/utils/prompts.d.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import {
|
|
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?:
|
|
10
|
-
|
|
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<
|
|
17
|
+
}): Promise<string[]>;
|
|
15
18
|
export declare function promptVariableEnvironmentAsync(input: EnvironmentPromptArgs & {
|
|
16
19
|
multiple?: false;
|
|
17
|
-
}): Promise<
|
|
20
|
+
}): Promise<string>;
|
|
18
21
|
export declare function promptVariableValueAsync({ nonInteractive, required, hidden, filePath, initial, }: {
|
|
19
22
|
nonInteractive: boolean;
|
|
20
23
|
required?: boolean;
|
package/build/utils/prompts.js
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
71
|
-
title: environment
|
|
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
|
|
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:
|
|
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 =
|
|
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';
|
package/build/worker/assets.d.ts
CHANGED
|
@@ -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?:
|
|
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>;
|