eas-cli 12.5.1 → 12.5.3
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 +66 -62
- package/build/build/build.js +4 -4
- package/build/commandUtils/flags.d.ts +10 -0
- package/build/commandUtils/flags.js +15 -8
- package/build/commands/env/create.d.ts +4 -1
- package/build/commands/env/create.js +133 -74
- package/build/commands/env/delete.d.ts +2 -2
- package/build/commands/env/delete.js +37 -26
- package/build/commands/env/exec.js +2 -1
- package/build/commands/env/get.d.ts +2 -2
- package/build/commands/env/get.js +44 -28
- package/build/commands/env/link.d.ts +4 -2
- package/build/commands/env/link.js +53 -14
- package/build/commands/env/list.d.ts +2 -2
- package/build/commands/env/list.js +59 -42
- package/build/commands/env/pull.js +1 -1
- package/build/commands/env/unlink.d.ts +3 -2
- package/build/commands/env/unlink.js +48 -21
- package/build/commands/env/update.d.ts +6 -2
- package/build/commands/env/update.js +134 -70
- package/build/commands/update/index.js +0 -1
- package/build/commands/worker/deploy.js +31 -11
- package/build/graphql/generated.d.ts +103 -15
- package/build/graphql/mutations/EnvironmentVariableMutation.d.ts +13 -22
- package/build/graphql/mutations/EnvironmentVariableMutation.js +18 -2
- package/build/graphql/queries/EnvironmentVariablesQuery.d.ts +24 -11
- package/build/graphql/queries/EnvironmentVariablesQuery.js +40 -17
- package/build/graphql/types/EnvironmentVariable.js +3 -1
- package/build/graphql/types/EnvironmentVariableWithSecret.d.ts +1 -0
- package/build/graphql/types/EnvironmentVariableWithSecret.js +18 -0
- package/build/prompts.d.ts +1 -0
- package/build/prompts.js +2 -0
- package/build/update/republish.js +1 -0
- package/build/utils/prompts.d.ts +16 -3
- package/build/utils/prompts.js +52 -8
- package/build/utils/variableUtils.d.ts +6 -0
- package/build/utils/variableUtils.js +62 -0
- package/build/worker/assets.d.ts +6 -1
- package/build/worker/assets.js +1 -2
- package/build/worker/upload.d.ts +1 -0
- package/build/worker/upload.js +25 -1
- package/oclif.manifest.json +98 -41
- package/package.json +3 -3
- package/build/utils/formatVariable.d.ts +0 -2
- package/build/utils/formatVariable.js +0 -16
|
@@ -3,7 +3,10 @@ var _a;
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const core_1 = require("@oclif/core");
|
|
6
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
7
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
8
|
+
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
9
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
10
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
8
11
|
const flags_1 = require("../../commandUtils/flags");
|
|
9
12
|
const generated_1 = require("../../graphql/generated");
|
|
@@ -13,10 +16,11 @@ const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
|
13
16
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
14
17
|
const prompts_1 = require("../../prompts");
|
|
15
18
|
const prompts_2 = require("../../utils/prompts");
|
|
19
|
+
const variableUtils_1 = require("../../utils/variableUtils");
|
|
16
20
|
class EnvironmentVariableUpdate extends EasCommand_1.default {
|
|
17
21
|
async runAsync() {
|
|
18
22
|
const { flags } = await this.parse(_a);
|
|
19
|
-
|
|
23
|
+
const { name, value: rawValue, scope, 'variable-name': currentName, 'variable-environment': currentEnvironment, 'non-interactive': nonInteractive, environment: environments, type, visibility, } = this.validateFlags(flags);
|
|
20
24
|
const { privateProjectConfig: { projectId }, loggedIn: { graphqlClient }, } = await this.getContextAsync(_a, {
|
|
21
25
|
nonInteractive,
|
|
22
26
|
});
|
|
@@ -24,107 +28,167 @@ class EnvironmentVariableUpdate extends EasCommand_1.default {
|
|
|
24
28
|
(0, projectUtils_1.getDisplayNameForProjectIdAsync)(graphqlClient, projectId),
|
|
25
29
|
(0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId),
|
|
26
30
|
]);
|
|
31
|
+
let selectedVariable;
|
|
32
|
+
let existingVariables = [];
|
|
33
|
+
const suffix = scope === generated_1.EnvironmentVariableScope.Project
|
|
34
|
+
? `on project ${projectDisplayName}`
|
|
35
|
+
: `on account ${ownerAccount.name}`;
|
|
27
36
|
if (scope === generated_1.EnvironmentVariableScope.Project) {
|
|
28
|
-
|
|
29
|
-
environment = await (0, prompts_2.promptVariableEnvironmentAsync)(nonInteractive);
|
|
30
|
-
}
|
|
31
|
-
const existingVariables = await EnvironmentVariablesQuery_1.EnvironmentVariablesQuery.byAppIdAsync(graphqlClient, {
|
|
37
|
+
existingVariables = await EnvironmentVariablesQuery_1.EnvironmentVariablesQuery.byAppIdAsync(graphqlClient, {
|
|
32
38
|
appId: projectId,
|
|
33
|
-
environment,
|
|
39
|
+
environment: currentEnvironment,
|
|
40
|
+
filterNames: currentName ? [currentName] : undefined,
|
|
34
41
|
});
|
|
35
|
-
if (!name) {
|
|
36
|
-
name = await (0, prompts_1.selectAsync)('Select variable', existingVariables.map(variable => ({
|
|
37
|
-
title: variable.name,
|
|
38
|
-
value: variable.name,
|
|
39
|
-
})));
|
|
40
|
-
}
|
|
41
|
-
const existingVariable = existingVariables.find(variable => variable.name === name);
|
|
42
|
-
if (!existingVariable) {
|
|
43
|
-
throw new Error(`Variable with name ${name} does not exist on project ${projectDisplayName}`);
|
|
44
|
-
}
|
|
45
|
-
if (!value) {
|
|
46
|
-
value = await (0, prompts_2.promptVariableValueAsync)({
|
|
47
|
-
nonInteractive,
|
|
48
|
-
required: false,
|
|
49
|
-
initial: existingVariable.value,
|
|
50
|
-
});
|
|
51
|
-
if (!value || value.length === 0) {
|
|
52
|
-
value = '';
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
const variable = await EnvironmentVariableMutation_1.EnvironmentVariableMutation.createForAppAsync(graphqlClient, {
|
|
56
|
-
name,
|
|
57
|
-
value,
|
|
58
|
-
environment,
|
|
59
|
-
visibility,
|
|
60
|
-
overwrite: true,
|
|
61
|
-
}, projectId);
|
|
62
|
-
if (!variable) {
|
|
63
|
-
throw new Error(`Could not update variable with name ${name} on project ${projectDisplayName}`);
|
|
64
|
-
}
|
|
65
|
-
log_1.default.withTick(`Updated variable ${chalk_1.default.bold(name)} on project ${chalk_1.default.bold(projectDisplayName)}.`);
|
|
66
42
|
}
|
|
67
|
-
|
|
68
|
-
|
|
43
|
+
if (scope === generated_1.EnvironmentVariableScope.Shared) {
|
|
44
|
+
existingVariables = await EnvironmentVariablesQuery_1.EnvironmentVariablesQuery.sharedAsync(graphqlClient, {
|
|
69
45
|
appId: projectId,
|
|
46
|
+
environment: currentEnvironment,
|
|
47
|
+
filterNames: currentName ? [currentName] : undefined,
|
|
70
48
|
});
|
|
49
|
+
}
|
|
50
|
+
if (existingVariables.length === 0) {
|
|
51
|
+
throw new Error(`Variable with name ${currentName} ${currentEnvironment ? `in environment ${currentEnvironment}` : ''} does not exist ${suffix}.`);
|
|
52
|
+
}
|
|
53
|
+
else if (existingVariables.length > 1) {
|
|
54
|
+
selectedVariable = await (0, prompts_1.selectAsync)('Select variable', existingVariables.map(variable => ({
|
|
55
|
+
title: (0, variableUtils_1.formatVariableName)(variable),
|
|
56
|
+
value: variable,
|
|
57
|
+
})));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
selectedVariable = existingVariables[0];
|
|
61
|
+
}
|
|
62
|
+
(0, assert_1.default)(selectedVariable, 'Variable must be selected');
|
|
63
|
+
const { name: newName, value: newValue, environment: newEnvironments, visibility: newVisibility, type: newType, } = await this.promptForMissingFlagsAsync(selectedVariable, {
|
|
64
|
+
name,
|
|
65
|
+
value: rawValue,
|
|
66
|
+
environment: environments,
|
|
67
|
+
visibility,
|
|
68
|
+
'non-interactive': nonInteractive,
|
|
69
|
+
type,
|
|
70
|
+
});
|
|
71
|
+
const variable = await EnvironmentVariableMutation_1.EnvironmentVariableMutation.updateAsync(graphqlClient, {
|
|
72
|
+
id: selectedVariable.id,
|
|
73
|
+
name: newName,
|
|
74
|
+
value: newValue,
|
|
75
|
+
environments: newEnvironments,
|
|
76
|
+
type: newType,
|
|
77
|
+
visibility: newVisibility,
|
|
78
|
+
});
|
|
79
|
+
if (!variable) {
|
|
80
|
+
throw new Error(`Could not update variable with name ${name} ${suffix}`);
|
|
81
|
+
}
|
|
82
|
+
log_1.default.withTick(`Updated variable ${chalk_1.default.bold(selectedVariable.name)} ${suffix}.`);
|
|
83
|
+
}
|
|
84
|
+
validateFlags(flags) {
|
|
85
|
+
if (flags['non-interactive']) {
|
|
86
|
+
if (!flags['variable-name']) {
|
|
87
|
+
throw new Error('Current name is required in non-interactive mode. Run the command with --variable-name flag.');
|
|
88
|
+
}
|
|
89
|
+
if (flags['type'] && !flags['value']) {
|
|
90
|
+
throw new Error('Value is required when type is set. Run the command with --value flag.');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return flags;
|
|
94
|
+
}
|
|
95
|
+
async promptForMissingFlagsAsync(selectedVariable, { name, value, environment: environments, visibility, 'non-interactive': nonInteractive, type, ...rest }) {
|
|
96
|
+
let newType;
|
|
97
|
+
if (type === 'file') {
|
|
98
|
+
newType = generated_1.EnvironmentSecretType.FileBase64;
|
|
99
|
+
}
|
|
100
|
+
else if (type === 'string') {
|
|
101
|
+
newType = generated_1.EnvironmentSecretType.String;
|
|
102
|
+
}
|
|
103
|
+
if (!nonInteractive) {
|
|
71
104
|
if (!name) {
|
|
72
|
-
name = await (0,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
105
|
+
name = await (0, prompts_2.promptVariableNameAsync)(nonInteractive, selectedVariable.name);
|
|
106
|
+
if (!name || name.length === 0) {
|
|
107
|
+
name = undefined;
|
|
108
|
+
}
|
|
76
109
|
}
|
|
77
|
-
|
|
78
|
-
if (!
|
|
79
|
-
|
|
110
|
+
log_1.default.log(selectedVariable.type, generated_1.EnvironmentSecretType.String === selectedVariable.type, generated_1.EnvironmentSecretType.FileBase64 === selectedVariable.type);
|
|
111
|
+
if (!type && !value && !nonInteractive) {
|
|
112
|
+
newType = await (0, prompts_2.promptVariableTypeAsync)(nonInteractive, selectedVariable.type);
|
|
113
|
+
if (!newType || newType === selectedVariable.type) {
|
|
114
|
+
newType = undefined;
|
|
115
|
+
}
|
|
80
116
|
}
|
|
81
117
|
if (!value) {
|
|
82
118
|
value = await (0, prompts_2.promptVariableValueAsync)({
|
|
83
119
|
nonInteractive,
|
|
84
120
|
required: false,
|
|
85
|
-
initial:
|
|
121
|
+
initial: (newType ?? selectedVariable.type) === generated_1.EnvironmentSecretType.FileBase64
|
|
122
|
+
? undefined
|
|
123
|
+
: selectedVariable.value,
|
|
86
124
|
});
|
|
87
|
-
if (!value || value.length === 0) {
|
|
88
|
-
value =
|
|
125
|
+
if (!value || value.length === 0 || value === selectedVariable.value) {
|
|
126
|
+
value = undefined;
|
|
89
127
|
}
|
|
90
128
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
value
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (!variable) {
|
|
98
|
-
throw new Error(`Could not update variable with name ${name} on account ${ownerAccount.name}`);
|
|
129
|
+
let environmentFilePath;
|
|
130
|
+
if (newType === generated_1.EnvironmentSecretType.FileBase64 && value) {
|
|
131
|
+
environmentFilePath = path_1.default.resolve(value);
|
|
132
|
+
if (!(await fs_extra_1.default.pathExists(environmentFilePath))) {
|
|
133
|
+
throw new Error(`File "${value}" does not exist`);
|
|
134
|
+
}
|
|
99
135
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
136
|
+
value = environmentFilePath ? await fs_extra_1.default.readFile(environmentFilePath, 'base64') : value;
|
|
137
|
+
if (!environments || environments.length === 0) {
|
|
138
|
+
environments = await (0, prompts_2.promptVariableEnvironmentAsync)({
|
|
139
|
+
nonInteractive,
|
|
140
|
+
multiple: true,
|
|
141
|
+
selectedEnvironments: selectedVariable.environments ?? [],
|
|
142
|
+
});
|
|
143
|
+
if (!environments ||
|
|
144
|
+
environments.length === 0 ||
|
|
145
|
+
environments === selectedVariable.environments) {
|
|
146
|
+
environments = undefined;
|
|
147
|
+
}
|
|
107
148
|
}
|
|
108
|
-
if (
|
|
109
|
-
|
|
149
|
+
if (!visibility) {
|
|
150
|
+
visibility = await (0, prompts_2.promptVariableVisibilityAsync)(nonInteractive, selectedVariable.visibility);
|
|
151
|
+
if (!visibility || visibility === selectedVariable.visibility) {
|
|
152
|
+
visibility = undefined;
|
|
153
|
+
}
|
|
110
154
|
}
|
|
111
155
|
}
|
|
112
|
-
return
|
|
156
|
+
return {
|
|
157
|
+
name,
|
|
158
|
+
value,
|
|
159
|
+
environment: environments,
|
|
160
|
+
visibility,
|
|
161
|
+
scope: rest.scope ?? generated_1.EnvironmentVariableScope.Project,
|
|
162
|
+
'non-interactive': nonInteractive,
|
|
163
|
+
type: newType,
|
|
164
|
+
...rest,
|
|
165
|
+
};
|
|
113
166
|
}
|
|
114
167
|
}
|
|
115
168
|
_a = EnvironmentVariableUpdate;
|
|
116
169
|
EnvironmentVariableUpdate.description = 'update an environment variable on the current project or owner account';
|
|
117
170
|
EnvironmentVariableUpdate.hidden = true;
|
|
118
171
|
EnvironmentVariableUpdate.flags = {
|
|
172
|
+
'variable-name': core_1.Flags.string({
|
|
173
|
+
description: 'Current name of the variable',
|
|
174
|
+
}),
|
|
175
|
+
'variable-environment': core_1.Flags.enum({
|
|
176
|
+
...flags_1.EasEnvironmentFlagParameters,
|
|
177
|
+
description: 'Current environment of the variable to update',
|
|
178
|
+
}),
|
|
119
179
|
name: core_1.Flags.string({
|
|
120
|
-
description: '
|
|
180
|
+
description: 'New name of the variable',
|
|
121
181
|
}),
|
|
122
182
|
value: core_1.Flags.string({
|
|
123
|
-
description: '
|
|
183
|
+
description: 'New value or the variable',
|
|
184
|
+
}),
|
|
185
|
+
type: core_1.Flags.enum({
|
|
186
|
+
description: 'The type of variable',
|
|
187
|
+
options: ['string', 'file'],
|
|
124
188
|
}),
|
|
125
189
|
...flags_1.EASVariableVisibilityFlag,
|
|
126
190
|
...flags_1.EASVariableScopeFlag,
|
|
127
|
-
...flags_1.
|
|
191
|
+
...flags_1.EASMultiEnvironmentFlag,
|
|
128
192
|
...flags_1.EASNonInteractiveFlag,
|
|
129
193
|
};
|
|
130
194
|
EnvironmentVariableUpdate.contextDefinition = {
|
|
@@ -426,7 +426,6 @@ UpdatePublish.flags = {
|
|
|
426
426
|
'rollout-percentage': core_1.Flags.integer({
|
|
427
427
|
description: `Percentage of users this update should be immediately available to. Users not in the rollout will be served the previous latest update on the branch, even if that update is itself being rolled out. The specified number must be an integer between 1 and 100. When not specified, this defaults to 100.`,
|
|
428
428
|
required: false,
|
|
429
|
-
hidden: true,
|
|
430
429
|
min: 0,
|
|
431
430
|
max: 100,
|
|
432
431
|
}),
|
|
@@ -43,6 +43,19 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
+
async function finalizeDeployAsync(deployParams) {
|
|
47
|
+
const finalizeDeployUrl = new URL('/deploy/finalize', deployParams.baseURL);
|
|
48
|
+
finalizeDeployUrl.searchParams.set('token', deployParams.token);
|
|
49
|
+
const result = await (0, upload_1.callUploadApiAsync)(finalizeDeployUrl, {
|
|
50
|
+
method: 'POST',
|
|
51
|
+
headers: {
|
|
52
|
+
accept: 'application/json',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
if (!result || typeof result !== 'object' || !('success' in result) || !result.success) {
|
|
56
|
+
throw new Error('Deploy failed: Incomplete asset uploads. Please try again');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
46
59
|
async function uploadTarballAsync(tarPath, uploadUrl) {
|
|
47
60
|
const { response } = await (0, upload_1.uploadAsync)({
|
|
48
61
|
url: uploadUrl,
|
|
@@ -64,24 +77,30 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
64
77
|
if (!json.success || !json.result || typeof json.result !== 'object') {
|
|
65
78
|
throw new Error(json.message ? `Upload failed: ${json.message}` : 'Upload failed!');
|
|
66
79
|
}
|
|
67
|
-
|
|
80
|
+
const { id, fullName, token } = json.result;
|
|
81
|
+
if (typeof token !== 'string') {
|
|
82
|
+
throw new Error('Upload failed: API failed to return a deployment token');
|
|
83
|
+
}
|
|
84
|
+
else if (typeof id !== 'string') {
|
|
85
|
+
throw new Error('Upload failed: API failed to return a deployment identifier');
|
|
86
|
+
}
|
|
87
|
+
else if (typeof fullName !== 'string') {
|
|
88
|
+
throw new Error('Upload failed: API failed to return a script name');
|
|
89
|
+
}
|
|
90
|
+
const baseURL = new URL('/', uploadUrl).toString();
|
|
91
|
+
return { id, fullName, baseURL, token };
|
|
68
92
|
}
|
|
69
93
|
}
|
|
70
|
-
async function uploadAssetsAsync(assetMap,
|
|
71
|
-
if (typeof uploads !== 'object' || !uploads) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
// TODO(@kitten): Batch and upload multiple files in parallel
|
|
94
|
+
async function uploadAssetsAsync(assetMap, deployParams) {
|
|
75
95
|
const uploadParams = [];
|
|
76
96
|
const assetPath = projectDist.type === 'server' ? projectDist.clientPath : projectDist.path;
|
|
77
97
|
if (!assetPath) {
|
|
78
98
|
return;
|
|
79
99
|
}
|
|
80
100
|
for await (const asset of WorkerAssets.listAssetMapFilesAsync(assetPath, assetMap)) {
|
|
81
|
-
const uploadURL =
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
101
|
+
const uploadURL = new URL(`/asset/${asset.sha512}`, deployParams.baseURL);
|
|
102
|
+
uploadURL.searchParams.set('token', deployParams.token);
|
|
103
|
+
uploadParams.push({ url: uploadURL.toString(), filePath: asset.path });
|
|
85
104
|
}
|
|
86
105
|
const progress = {
|
|
87
106
|
total: uploadParams.length,
|
|
@@ -147,7 +166,8 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
147
166
|
progress.fail('Failed to create deployment');
|
|
148
167
|
throw error;
|
|
149
168
|
}
|
|
150
|
-
await uploadAssetsAsync(assetMap, deployResult
|
|
169
|
+
await uploadAssetsAsync(assetMap, deployResult);
|
|
170
|
+
await finalizeDeployAsync(deployResult);
|
|
151
171
|
let deploymentAlias = null;
|
|
152
172
|
if (flags.aliasName) {
|
|
153
173
|
progress = (0, ora_1.ora)((0, chalk_1.default) `Assigning alias {bold ${flags.aliasName}} to deployment`).start();
|