@depup/vercel 50.32.5-depup.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/LICENSE +202 -0
- package/README.md +38 -0
- package/changes.json +38 -0
- package/dist/chunks/chunk-2DLBVZWU.js +197 -0
- package/dist/chunks/chunk-2HSQ7YUK.js +93 -0
- package/dist/chunks/chunk-2IQTNMUG.js +86 -0
- package/dist/chunks/chunk-3FRG2XGZ.js +466 -0
- package/dist/chunks/chunk-3KMKI2FP.js +34 -0
- package/dist/chunks/chunk-3XFFP2BA.js +110 -0
- package/dist/chunks/chunk-4S3Y3ATR.js +5383 -0
- package/dist/chunks/chunk-7EHTK7LP.js +359 -0
- package/dist/chunks/chunk-7YHZDJ4G.js +116 -0
- package/dist/chunks/chunk-A3NYPUKZ.js +17 -0
- package/dist/chunks/chunk-AA7QEJFB.js +5204 -0
- package/dist/chunks/chunk-AHU7WNL2.js +24 -0
- package/dist/chunks/chunk-AKQZ7KG3.js +4172 -0
- package/dist/chunks/chunk-AQLVWVEN.js +39155 -0
- package/dist/chunks/chunk-BQ3DXZNT.js +968 -0
- package/dist/chunks/chunk-E65JE2CC.js +102 -0
- package/dist/chunks/chunk-EKPSCRJZ.js +26 -0
- package/dist/chunks/chunk-EOZFDJSY.js +18 -0
- package/dist/chunks/chunk-FDJURQMQ.js +4676 -0
- package/dist/chunks/chunk-FLKHKWZV.js +1854 -0
- package/dist/chunks/chunk-G6BUEBF5.js +192 -0
- package/dist/chunks/chunk-GBNIO3KP.js +771 -0
- package/dist/chunks/chunk-GGP5R3FU.js +129 -0
- package/dist/chunks/chunk-H5XJSH37.js +91 -0
- package/dist/chunks/chunk-IB5L4LKZ.js +1082 -0
- package/dist/chunks/chunk-IE7MNZ56.js +149 -0
- package/dist/chunks/chunk-IK7DLK2T.js +16112 -0
- package/dist/chunks/chunk-IUGPWINM.js +104 -0
- package/dist/chunks/chunk-J7HDA5GH.js +54 -0
- package/dist/chunks/chunk-JLYZNGYY.js +293 -0
- package/dist/chunks/chunk-JQ4NA5MX.js +250 -0
- package/dist/chunks/chunk-LL26LVRR.js +81 -0
- package/dist/chunks/chunk-LW5ZNGW7.js +127 -0
- package/dist/chunks/chunk-LWBSOTJP.js +1772 -0
- package/dist/chunks/chunk-MBGJBHYD.js +388 -0
- package/dist/chunks/chunk-NUKAG3YM.js +168 -0
- package/dist/chunks/chunk-O7I4ZOCC.js +58 -0
- package/dist/chunks/chunk-OWR3XNE3.js +48 -0
- package/dist/chunks/chunk-P3SKP5WM.js +27 -0
- package/dist/chunks/chunk-P4I4DMEU.js +342 -0
- package/dist/chunks/chunk-P5Q6F5IA.js +107 -0
- package/dist/chunks/chunk-PMSMUMUO.js +30 -0
- package/dist/chunks/chunk-QXRJ52T4.js +2977 -0
- package/dist/chunks/chunk-RQXPRFRM.js +90 -0
- package/dist/chunks/chunk-S7KYDPEM.js +1564 -0
- package/dist/chunks/chunk-SGGLJFUZ.js +68 -0
- package/dist/chunks/chunk-SOTR4CXR.js +34 -0
- package/dist/chunks/chunk-TEVP63TU.js +1717 -0
- package/dist/chunks/chunk-TNBMKNET.js +323 -0
- package/dist/chunks/chunk-TZ2YI2VH.js +87 -0
- package/dist/chunks/chunk-U6XOC6E4.js +903 -0
- package/dist/chunks/chunk-V5P25P7F.js +22 -0
- package/dist/chunks/chunk-WQ5CUZWR.js +333 -0
- package/dist/chunks/chunk-WU2BPWRP.js +12237 -0
- package/dist/chunks/chunk-XPKWKPWA.js +44 -0
- package/dist/chunks/chunk-XR53KVJD.js +33 -0
- package/dist/chunks/chunk-Y4JJYHUG.js +16 -0
- package/dist/chunks/chunk-YPQSDAEW.js +29 -0
- package/dist/chunks/chunk-ZB2UO4V2.js +135 -0
- package/dist/chunks/chunk-ZLCMHY2G.js +1528 -0
- package/dist/chunks/compile-vercel-config-XU3YY2CZ.js +32 -0
- package/dist/chunks/delete-EJ2V7KQO.js +144 -0
- package/dist/chunks/disable-BKRFMX4U.js +122 -0
- package/dist/chunks/discard-4WF34DXK.js +118 -0
- package/dist/chunks/edit-FQE7JGU3.js +509 -0
- package/dist/chunks/emit-flags-datafiles-QYKPNWPX.js +17 -0
- package/dist/chunks/enable-VCNMX63U.js +122 -0
- package/dist/chunks/export-3KNVJCQR.js +133 -0
- package/dist/chunks/list-43XQCGKH.js +382 -0
- package/dist/chunks/list-DUL6PHUR.js +394 -0
- package/dist/chunks/publish-CF7GVZK3.js +128 -0
- package/dist/chunks/query-KWKO7VWO.js +954 -0
- package/dist/chunks/reorder-GU65YMIN.js +259 -0
- package/dist/chunks/restore-Q7ENGWVJ.js +158 -0
- package/dist/chunks/routes-Q5CWG44T.js +20 -0
- package/dist/chunks/schema-PJKLO2K2.js +176 -0
- package/dist/chunks/stamp-RTPE2EBB.js +15 -0
- package/dist/chunks/types-563KUQRV.js +108 -0
- package/dist/chunks/update-route-version-E3V47KNI.js +13 -0
- package/dist/commands/build/index.js +1597 -0
- package/dist/commands/deploy/index.js +1711 -0
- package/dist/commands/dev/builder-worker.cjs +95 -0
- package/dist/commands/dev/index.js +20810 -0
- package/dist/commands/env/index.js +2154 -0
- package/dist/commands/link/index.js +225 -0
- package/dist/commands/list/index.js +528 -0
- package/dist/commands-bulk.js +29627 -0
- package/dist/get-latest-worker.cjs +272 -0
- package/dist/help.js +14 -0
- package/dist/index.js +24274 -0
- package/dist/vc.js +36 -0
- package/dist/version.mjs +1 -0
- package/package.json +254 -0
|
@@ -0,0 +1,2154 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from 'node:module';
|
|
2
|
+
import { fileURLToPath as __fileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname as __dirname_ } from 'node:path';
|
|
4
|
+
const require = __createRequire(import.meta.url);
|
|
5
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = __dirname_(__filename);
|
|
7
|
+
import {
|
|
8
|
+
getCustomEnvironments,
|
|
9
|
+
getInvalidSubcommand,
|
|
10
|
+
readStandardInput,
|
|
11
|
+
require_dist as require_dist3
|
|
12
|
+
} from "../../chunks/chunk-JLYZNGYY.js";
|
|
13
|
+
import {
|
|
14
|
+
formatTable
|
|
15
|
+
} from "../../chunks/chunk-SGGLJFUZ.js";
|
|
16
|
+
import {
|
|
17
|
+
suggestNextCommands
|
|
18
|
+
} from "../../chunks/chunk-XR53KVJD.js";
|
|
19
|
+
import {
|
|
20
|
+
formatEnvironment,
|
|
21
|
+
validateLsArgs
|
|
22
|
+
} from "../../chunks/chunk-J7HDA5GH.js";
|
|
23
|
+
import {
|
|
24
|
+
validateJsonOutput
|
|
25
|
+
} from "../../chunks/chunk-XPKWKPWA.js";
|
|
26
|
+
import {
|
|
27
|
+
getSubcommand
|
|
28
|
+
} from "../../chunks/chunk-YPQSDAEW.js";
|
|
29
|
+
import {
|
|
30
|
+
getCommandAliases
|
|
31
|
+
} from "../../chunks/chunk-AA7QEJFB.js";
|
|
32
|
+
import "../../chunks/chunk-U6XOC6E4.js";
|
|
33
|
+
import "../../chunks/chunk-O7I4ZOCC.js";
|
|
34
|
+
import "../../chunks/chunk-LW5ZNGW7.js";
|
|
35
|
+
import "../../chunks/chunk-P5Q6F5IA.js";
|
|
36
|
+
import "../../chunks/chunk-2DLBVZWU.js";
|
|
37
|
+
import "../../chunks/chunk-E65JE2CC.js";
|
|
38
|
+
import {
|
|
39
|
+
require_execa
|
|
40
|
+
} from "../../chunks/chunk-FLKHKWZV.js";
|
|
41
|
+
import "../../chunks/chunk-IUGPWINM.js";
|
|
42
|
+
import "../../chunks/chunk-ZB2UO4V2.js";
|
|
43
|
+
import {
|
|
44
|
+
help
|
|
45
|
+
} from "../../chunks/chunk-JQ4NA5MX.js";
|
|
46
|
+
import {
|
|
47
|
+
STANDARD_ENVIRONMENTS,
|
|
48
|
+
addSubcommand,
|
|
49
|
+
buildCommandWithYes,
|
|
50
|
+
buildEnvAddCommandWithPreservedArgs,
|
|
51
|
+
buildEnvRmCommandWithPreservedArgs,
|
|
52
|
+
buildEnvUpdateCommandWithPreservedArgs,
|
|
53
|
+
envCommand,
|
|
54
|
+
envTargetChoices,
|
|
55
|
+
formatProject,
|
|
56
|
+
getEnvRecords,
|
|
57
|
+
getEnvTargetPlaceholder,
|
|
58
|
+
getLinkedProject,
|
|
59
|
+
getPreservedArgsForEnvAdd,
|
|
60
|
+
getPreservedArgsForEnvRm,
|
|
61
|
+
getPreservedArgsForEnvUpdate,
|
|
62
|
+
listSubcommand,
|
|
63
|
+
outputActionRequired,
|
|
64
|
+
outputAgentError,
|
|
65
|
+
param,
|
|
66
|
+
parseTarget,
|
|
67
|
+
pull,
|
|
68
|
+
pullEnvRecords,
|
|
69
|
+
pullSubcommand,
|
|
70
|
+
removeSubcommand,
|
|
71
|
+
require_frameworks,
|
|
72
|
+
runSubcommand,
|
|
73
|
+
updateSubcommand
|
|
74
|
+
} from "../../chunks/chunk-AQLVWVEN.js";
|
|
75
|
+
import {
|
|
76
|
+
TelemetryClient,
|
|
77
|
+
require_dist as require_dist2
|
|
78
|
+
} from "../../chunks/chunk-P4I4DMEU.js";
|
|
79
|
+
import {
|
|
80
|
+
stamp_default
|
|
81
|
+
} from "../../chunks/chunk-SOTR4CXR.js";
|
|
82
|
+
import "../../chunks/chunk-LWBSOTJP.js";
|
|
83
|
+
import "../../chunks/chunk-7EHTK7LP.js";
|
|
84
|
+
import {
|
|
85
|
+
require_ms
|
|
86
|
+
} from "../../chunks/chunk-GGP5R3FU.js";
|
|
87
|
+
import {
|
|
88
|
+
getCommandName,
|
|
89
|
+
getCommandNamePlain,
|
|
90
|
+
getFlagsSpecification,
|
|
91
|
+
isAPIError,
|
|
92
|
+
parseArguments,
|
|
93
|
+
printError,
|
|
94
|
+
require_lib
|
|
95
|
+
} from "../../chunks/chunk-ZLCMHY2G.js";
|
|
96
|
+
import "../../chunks/chunk-3XFFP2BA.js";
|
|
97
|
+
import {
|
|
98
|
+
emoji,
|
|
99
|
+
output_manager_default,
|
|
100
|
+
prependEmoji,
|
|
101
|
+
require_dist
|
|
102
|
+
} from "../../chunks/chunk-FDJURQMQ.js";
|
|
103
|
+
import {
|
|
104
|
+
require_source
|
|
105
|
+
} from "../../chunks/chunk-S7KYDPEM.js";
|
|
106
|
+
import {
|
|
107
|
+
__toESM
|
|
108
|
+
} from "../../chunks/chunk-TZ2YI2VH.js";
|
|
109
|
+
|
|
110
|
+
// src/commands/env/add.ts
|
|
111
|
+
var import_chalk = __toESM(require_source(), 1);
|
|
112
|
+
|
|
113
|
+
// src/util/env/add-env-record.ts
|
|
114
|
+
var import_constants = __toESM(require_dist2(), 1);
|
|
115
|
+
async function addEnvRecord(client, projectId, upsert, type, key, value, targets, gitBranch) {
|
|
116
|
+
const actionWord = upsert ? "Overriding" : "Adding";
|
|
117
|
+
output_manager_default.debug(
|
|
118
|
+
`${actionWord} ${type} Environment Variable ${key} to ${targets.length} targets`
|
|
119
|
+
);
|
|
120
|
+
const target = [];
|
|
121
|
+
const customEnvironmentIds = [];
|
|
122
|
+
for (const t of targets) {
|
|
123
|
+
const arr = import_constants.PROJECT_ENV_TARGET.includes(t) ? target : customEnvironmentIds;
|
|
124
|
+
arr.push(t);
|
|
125
|
+
}
|
|
126
|
+
const body = {
|
|
127
|
+
type,
|
|
128
|
+
key,
|
|
129
|
+
value,
|
|
130
|
+
target,
|
|
131
|
+
customEnvironmentIds: customEnvironmentIds.length > 0 ? customEnvironmentIds : void 0,
|
|
132
|
+
gitBranch: gitBranch || void 0
|
|
133
|
+
};
|
|
134
|
+
const args = upsert ? `?upsert=${upsert}` : "";
|
|
135
|
+
const url = `/v10/projects/${projectId}/env${args}`;
|
|
136
|
+
await client.fetch(url, {
|
|
137
|
+
method: "POST",
|
|
138
|
+
body
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/util/env/known-error.ts
|
|
143
|
+
var import_error_utils = __toESM(require_dist(), 1);
|
|
144
|
+
var knownErrorsCodes = /* @__PURE__ */ new Set([
|
|
145
|
+
"BAD_REQUEST",
|
|
146
|
+
"ENV_ALREADY_EXISTS",
|
|
147
|
+
"ENV_CONFLICT",
|
|
148
|
+
"EXISTING_KEY_AND_TARGET",
|
|
149
|
+
"FORBIDDEN",
|
|
150
|
+
"ID_NOT_FOUND",
|
|
151
|
+
"INVALID_KEY",
|
|
152
|
+
"INVALID_VALUE",
|
|
153
|
+
"KEY_INVALID_CHARACTERS",
|
|
154
|
+
"KEY_INVALID_LENGTH",
|
|
155
|
+
"KEY_RESERVED",
|
|
156
|
+
"RESERVED_ENV_VARIABLE",
|
|
157
|
+
"MAX_ENVS_EXCEEDED",
|
|
158
|
+
"MISSING_ID",
|
|
159
|
+
"MISSING_KEY",
|
|
160
|
+
"MISSING_TARGET",
|
|
161
|
+
"MISSING_VALUE",
|
|
162
|
+
"NOT_AUTHORIZED",
|
|
163
|
+
"NOT_DECRYPTABLE",
|
|
164
|
+
"SYSTEM_ENV_WITH_VALUE",
|
|
165
|
+
"TEAM_NOT_FOUND",
|
|
166
|
+
"TOO_MANY_IDS",
|
|
167
|
+
"TOO_MANY_KEYS",
|
|
168
|
+
"UNKNOWN_ERROR",
|
|
169
|
+
"VALUE_INVALID_LENGTH",
|
|
170
|
+
"VALUE_INVALID_TYPE"
|
|
171
|
+
]);
|
|
172
|
+
function isKnownError(error) {
|
|
173
|
+
const code = (0, import_error_utils.isErrnoException)(error) ? error.code : null;
|
|
174
|
+
if (!code)
|
|
175
|
+
return false;
|
|
176
|
+
return knownErrorsCodes.has(code.toUpperCase());
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/util/env/validate-env.ts
|
|
180
|
+
var import_frameworks = __toESM(require_frameworks(), 1);
|
|
181
|
+
function getEnvValueWarnings(value) {
|
|
182
|
+
const warnings = [];
|
|
183
|
+
const normalized = value.replace(/\n$/, "");
|
|
184
|
+
if (/^[ \t]+/.test(normalized)) {
|
|
185
|
+
warnings.push({
|
|
186
|
+
message: "starts with whitespace",
|
|
187
|
+
requiresConfirmation: false
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
if (/[ \t]+$/.test(normalized)) {
|
|
191
|
+
warnings.push({
|
|
192
|
+
message: "ends with whitespace",
|
|
193
|
+
requiresConfirmation: false
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
if (normalized.includes("\r") || normalized.includes("\n")) {
|
|
197
|
+
warnings.push({
|
|
198
|
+
message: "contains newlines",
|
|
199
|
+
requiresConfirmation: false
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (value.includes("\0")) {
|
|
203
|
+
warnings.push({
|
|
204
|
+
message: "contains null characters",
|
|
205
|
+
requiresConfirmation: false
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (value === "") {
|
|
209
|
+
warnings.push({
|
|
210
|
+
message: "is empty",
|
|
211
|
+
requiresConfirmation: true
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
if (value.length > 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
|
|
215
|
+
warnings.push({
|
|
216
|
+
message: "includes surrounding quotes (these will be stored literally)",
|
|
217
|
+
requiresConfirmation: false
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
return warnings;
|
|
221
|
+
}
|
|
222
|
+
function formatWarnings(warnings) {
|
|
223
|
+
if (warnings.length === 0)
|
|
224
|
+
return null;
|
|
225
|
+
const messages = warnings.map((w) => w.message);
|
|
226
|
+
const startsIdx = messages.indexOf("starts with whitespace");
|
|
227
|
+
const endsIdx = messages.indexOf("ends with whitespace");
|
|
228
|
+
if (startsIdx !== -1 && endsIdx !== -1) {
|
|
229
|
+
messages.splice(Math.max(startsIdx, endsIdx), 1);
|
|
230
|
+
messages[Math.min(startsIdx, endsIdx)] = "starts and ends with whitespace";
|
|
231
|
+
}
|
|
232
|
+
if (messages.length === 1) {
|
|
233
|
+
return `Value ${messages[0]}`;
|
|
234
|
+
}
|
|
235
|
+
if (messages.length === 2) {
|
|
236
|
+
return `Value ${messages[0]} and ${messages[1]}`;
|
|
237
|
+
}
|
|
238
|
+
const last = messages.pop();
|
|
239
|
+
return `Value ${messages.join(", ")}, and ${last}`;
|
|
240
|
+
}
|
|
241
|
+
var PUBLIC_PREFIXES = [
|
|
242
|
+
...new Set(
|
|
243
|
+
import_frameworks.frameworkList.map((f) => f.envPrefix).filter((p) => !!p)
|
|
244
|
+
)
|
|
245
|
+
];
|
|
246
|
+
var SENSITIVE_PATTERN = /(?:^|_)(password|secret|private|token|key|auth|jwt|signature)(?:_|$)/i;
|
|
247
|
+
function hasOnlyWhitespaceWarnings(warnings) {
|
|
248
|
+
return warnings.length > 0 && warnings.every(
|
|
249
|
+
(w) => w.message === "starts with whitespace" || w.message === "ends with whitespace"
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
function trimValue(value) {
|
|
253
|
+
return value.replace(/\n$/, "").trim();
|
|
254
|
+
}
|
|
255
|
+
function getPublicPrefix(key) {
|
|
256
|
+
const upperKey = key.toUpperCase();
|
|
257
|
+
return PUBLIC_PREFIXES.find((p) => upperKey.startsWith(p)) || null;
|
|
258
|
+
}
|
|
259
|
+
function removePublicPrefix(key) {
|
|
260
|
+
const prefix = getPublicPrefix(key);
|
|
261
|
+
if (!prefix)
|
|
262
|
+
return key;
|
|
263
|
+
return key.slice(prefix.length);
|
|
264
|
+
}
|
|
265
|
+
async function validateEnvValue(opts) {
|
|
266
|
+
let finalValue = opts.initialValue;
|
|
267
|
+
let alreadyConfirmed = false;
|
|
268
|
+
if (!opts.skipConfirm) {
|
|
269
|
+
let valueAccepted = false;
|
|
270
|
+
while (!valueAccepted) {
|
|
271
|
+
const valueWarnings = getEnvValueWarnings(finalValue);
|
|
272
|
+
const warningMessage = formatWarnings(valueWarnings);
|
|
273
|
+
if (!warningMessage) {
|
|
274
|
+
valueAccepted = true;
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
opts.showWarning(warningMessage);
|
|
278
|
+
const canTrim = hasOnlyWhitespaceWarnings(valueWarnings);
|
|
279
|
+
const choices = canTrim ? [
|
|
280
|
+
{ name: "Leave as is", value: "c" },
|
|
281
|
+
{ name: "Re-enter", value: "r" },
|
|
282
|
+
{ name: "Trim whitespace", value: "t" }
|
|
283
|
+
] : [
|
|
284
|
+
{ name: "Leave as is", value: "c" },
|
|
285
|
+
{ name: "Re-enter", value: "r" }
|
|
286
|
+
];
|
|
287
|
+
const action = await opts.selectAction(choices);
|
|
288
|
+
if (action === "c") {
|
|
289
|
+
valueAccepted = true;
|
|
290
|
+
if (valueWarnings.some((w) => w.requiresConfirmation)) {
|
|
291
|
+
alreadyConfirmed = true;
|
|
292
|
+
}
|
|
293
|
+
} else if (action === "t") {
|
|
294
|
+
finalValue = trimValue(finalValue);
|
|
295
|
+
opts.showLog("Trimmed whitespace");
|
|
296
|
+
} else {
|
|
297
|
+
finalValue = await opts.promptForValue();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
} else {
|
|
301
|
+
const valueWarnings = getEnvValueWarnings(finalValue);
|
|
302
|
+
const warningMessage = formatWarnings(valueWarnings);
|
|
303
|
+
if (warningMessage) {
|
|
304
|
+
opts.showWarning(warningMessage);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return { finalValue, alreadyConfirmed };
|
|
308
|
+
}
|
|
309
|
+
function getEnvKeyWarnings(key) {
|
|
310
|
+
const warnings = [];
|
|
311
|
+
const matchingPrefix = getPublicPrefix(key);
|
|
312
|
+
if (matchingPrefix) {
|
|
313
|
+
const sensitiveMatch = SENSITIVE_PATTERN.exec(key);
|
|
314
|
+
const nameWithoutPrefix = key.slice(matchingPrefix.length);
|
|
315
|
+
if (sensitiveMatch) {
|
|
316
|
+
warnings.push({
|
|
317
|
+
message: `The ${matchingPrefix} prefix will make ${nameWithoutPrefix} visible to anyone visiting your site`,
|
|
318
|
+
requiresConfirmation: true
|
|
319
|
+
});
|
|
320
|
+
} else {
|
|
321
|
+
warnings.push({
|
|
322
|
+
message: `${matchingPrefix} variables can be seen by anyone visiting your site`,
|
|
323
|
+
requiresConfirmation: false
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return warnings;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// src/util/telemetry/commands/env/add.ts
|
|
331
|
+
var EnvAddTelemetryClient = class extends TelemetryClient {
|
|
332
|
+
trackCliArgumentName(name) {
|
|
333
|
+
if (name) {
|
|
334
|
+
this.trackCliArgument({
|
|
335
|
+
arg: "name",
|
|
336
|
+
value: this.redactedValue
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
trackCliArgumentEnvironment(environment) {
|
|
341
|
+
if (environment) {
|
|
342
|
+
this.trackCliArgument({
|
|
343
|
+
arg: "environment",
|
|
344
|
+
value: STANDARD_ENVIRONMENTS.includes(
|
|
345
|
+
environment
|
|
346
|
+
) ? environment : this.redactedValue
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
trackCliArgumentGitBranch(gitBranch) {
|
|
351
|
+
if (gitBranch) {
|
|
352
|
+
this.trackCliArgument({
|
|
353
|
+
arg: "git-branch",
|
|
354
|
+
value: this.redactedValue
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
trackCliOptionValue(value) {
|
|
359
|
+
if (value) {
|
|
360
|
+
this.trackCliOption({
|
|
361
|
+
option: "value",
|
|
362
|
+
value: this.redactedValue
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
trackCliFlagSensitive(sensitive) {
|
|
367
|
+
if (sensitive) {
|
|
368
|
+
this.trackCliFlag("sensitive");
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
trackCliFlagForce(force) {
|
|
372
|
+
if (force) {
|
|
373
|
+
this.trackCliFlag("force");
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
trackCliFlagGuidance(guidance) {
|
|
377
|
+
if (guidance) {
|
|
378
|
+
this.trackCliFlag("guidance");
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
trackCliFlagYes(yes) {
|
|
382
|
+
if (yes) {
|
|
383
|
+
this.trackCliFlag("yes");
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
// src/commands/env/add.ts
|
|
389
|
+
import { determineAgent } from "@vercel/detect-agent";
|
|
390
|
+
function valueForNextCommand(value) {
|
|
391
|
+
if (!/[\s'"\\]/.test(value))
|
|
392
|
+
return value;
|
|
393
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
394
|
+
}
|
|
395
|
+
function fillEnvAddTemplate(template, opts) {
|
|
396
|
+
const targetPlaceholder = getEnvTargetPlaceholder();
|
|
397
|
+
let out = template.replace(/<name>/g, opts.envName ?? "<name>").split(targetPlaceholder).join(opts.envTargetArg ?? targetPlaceholder).replace(/<gitbranch>/g, opts.envGitBranch ?? "<gitbranch>");
|
|
398
|
+
if (opts.valueFromFlag !== void 0) {
|
|
399
|
+
out = out.replace(/<value>/g, valueForNextCommand(opts.valueFromFlag));
|
|
400
|
+
} else {
|
|
401
|
+
out = out.replace(/<value>/g, "<value>");
|
|
402
|
+
}
|
|
403
|
+
return out;
|
|
404
|
+
}
|
|
405
|
+
async function add(client, argv) {
|
|
406
|
+
let parsedArgs;
|
|
407
|
+
const flagsSpecification = getFlagsSpecification(addSubcommand.options);
|
|
408
|
+
try {
|
|
409
|
+
parsedArgs = parseArguments(argv, flagsSpecification);
|
|
410
|
+
} catch (err) {
|
|
411
|
+
if (client.nonInteractive) {
|
|
412
|
+
outputAgentError(
|
|
413
|
+
client,
|
|
414
|
+
{
|
|
415
|
+
status: "error",
|
|
416
|
+
reason: "invalid_arguments",
|
|
417
|
+
message: err instanceof Error ? err.message : String(err)
|
|
418
|
+
},
|
|
419
|
+
1
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
printError(err);
|
|
423
|
+
return 1;
|
|
424
|
+
}
|
|
425
|
+
const { args, flags: opts } = parsedArgs;
|
|
426
|
+
const stdInput = await readStandardInput(client.stdin);
|
|
427
|
+
const valueFromFlag = typeof opts["--value"] === "string" ? opts["--value"] : void 0;
|
|
428
|
+
let [envName, envTargetArg, envGitBranch] = args;
|
|
429
|
+
const telemetryClient = new EnvAddTelemetryClient({
|
|
430
|
+
opts: {
|
|
431
|
+
store: client.telemetryEventStore
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
telemetryClient.trackCliArgumentName(envName);
|
|
435
|
+
telemetryClient.trackCliArgumentEnvironment(envTargetArg);
|
|
436
|
+
telemetryClient.trackCliArgumentGitBranch(envGitBranch);
|
|
437
|
+
telemetryClient.trackCliOptionValue(opts["--value"]);
|
|
438
|
+
telemetryClient.trackCliFlagSensitive(opts["--sensitive"]);
|
|
439
|
+
telemetryClient.trackCliFlagForce(opts["--force"]);
|
|
440
|
+
telemetryClient.trackCliFlagGuidance(opts["--guidance"]);
|
|
441
|
+
telemetryClient.trackCliFlagYes(opts["--yes"]);
|
|
442
|
+
if (args.length > 3) {
|
|
443
|
+
output_manager_default.error(
|
|
444
|
+
`Invalid number of arguments. Usage: ${getCommandName(
|
|
445
|
+
`env add <name> ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
446
|
+
)}`
|
|
447
|
+
);
|
|
448
|
+
return 1;
|
|
449
|
+
}
|
|
450
|
+
if (stdInput && (!envName || !envTargetArg)) {
|
|
451
|
+
output_manager_default.error(
|
|
452
|
+
`Invalid number of arguments. Usage: ${getCommandName(
|
|
453
|
+
`env add <name> <target> <gitbranch> < <file>`
|
|
454
|
+
)}`
|
|
455
|
+
);
|
|
456
|
+
return 1;
|
|
457
|
+
}
|
|
458
|
+
let envTargets = [];
|
|
459
|
+
if (envTargetArg) {
|
|
460
|
+
envTargets.push(envTargetArg);
|
|
461
|
+
}
|
|
462
|
+
if (client.nonInteractive) {
|
|
463
|
+
const link2 = await getLinkedProject(client);
|
|
464
|
+
if (link2.status === "error") {
|
|
465
|
+
return link2.exitCode;
|
|
466
|
+
}
|
|
467
|
+
if (link2.status === "not_linked") {
|
|
468
|
+
const preserved = getPreservedArgsForEnvAdd(client.argv);
|
|
469
|
+
const linkPreserved = preserved.filter((a, i) => {
|
|
470
|
+
if (a === "--value")
|
|
471
|
+
return false;
|
|
472
|
+
if (a.startsWith("--value="))
|
|
473
|
+
return false;
|
|
474
|
+
if (i > 0 && preserved[i - 1] === "--value")
|
|
475
|
+
return false;
|
|
476
|
+
return true;
|
|
477
|
+
});
|
|
478
|
+
const linkArgv = [
|
|
479
|
+
...client.argv.slice(0, 2),
|
|
480
|
+
"link",
|
|
481
|
+
"--scope",
|
|
482
|
+
"<scope>",
|
|
483
|
+
...linkPreserved
|
|
484
|
+
];
|
|
485
|
+
let envAddRetryArgv = client.argv;
|
|
486
|
+
if (envTargetArg === "preview" && envGitBranch === void 0) {
|
|
487
|
+
const argvArgs = client.argv.slice(2);
|
|
488
|
+
const addIdx = argvArgs.indexOf("add");
|
|
489
|
+
if (addIdx !== -1) {
|
|
490
|
+
let pos = addIdx + 1;
|
|
491
|
+
let positionals = 0;
|
|
492
|
+
while (pos < argvArgs.length && positionals < 3 && !argvArgs[pos].startsWith("-")) {
|
|
493
|
+
positionals++;
|
|
494
|
+
pos++;
|
|
495
|
+
}
|
|
496
|
+
const insertAt = 2 + pos;
|
|
497
|
+
envAddRetryArgv = [
|
|
498
|
+
...client.argv.slice(0, insertAt),
|
|
499
|
+
"<gitbranch>",
|
|
500
|
+
...client.argv.slice(insertAt)
|
|
501
|
+
];
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
outputAgentError(
|
|
505
|
+
client,
|
|
506
|
+
{
|
|
507
|
+
status: "error",
|
|
508
|
+
reason: "not_linked",
|
|
509
|
+
message: `Your codebase isn't linked to a project on Vercel. Run ${getCommandNamePlain(
|
|
510
|
+
"link"
|
|
511
|
+
)} to begin. Use --yes for non-interactive; use --scope or --project to specify team or project. Then run your env add command.`,
|
|
512
|
+
next: [
|
|
513
|
+
{ command: buildCommandWithYes(linkArgv) },
|
|
514
|
+
{ command: buildCommandWithYes(envAddRetryArgv) }
|
|
515
|
+
]
|
|
516
|
+
},
|
|
517
|
+
1
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
if (link2.status !== "linked")
|
|
521
|
+
return 1;
|
|
522
|
+
const { project: project2 } = link2;
|
|
523
|
+
const org = link2.org;
|
|
524
|
+
client.config.currentTeam = org.type === "team" ? org.id : void 0;
|
|
525
|
+
const [{ envs: envs2 }, customEnvironments2] = await Promise.all([
|
|
526
|
+
getEnvRecords(client, project2.id, "vercel-cli:env:add"),
|
|
527
|
+
getCustomEnvironments(client, project2.id)
|
|
528
|
+
]);
|
|
529
|
+
const matchingEnvs2 = envs2.filter((r) => r.key === envName);
|
|
530
|
+
const existingTargets2 = /* @__PURE__ */ new Set();
|
|
531
|
+
const existingCustomEnvs2 = /* @__PURE__ */ new Set();
|
|
532
|
+
for (const env of matchingEnvs2) {
|
|
533
|
+
if (typeof env.target === "string") {
|
|
534
|
+
existingTargets2.add(env.target);
|
|
535
|
+
} else if (Array.isArray(env.target)) {
|
|
536
|
+
for (const target of env.target) {
|
|
537
|
+
existingTargets2.add(target);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
if (env.customEnvironmentIds) {
|
|
541
|
+
for (const customEnvId of env.customEnvironmentIds) {
|
|
542
|
+
existingCustomEnvs2.add(customEnvId);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
const choices2 = [
|
|
547
|
+
...envTargetChoices.filter((c) => !existingTargets2.has(c.value)),
|
|
548
|
+
...customEnvironments2.filter((c) => !existingCustomEnvs2.has(c.id)).map((c) => ({
|
|
549
|
+
name: c.slug,
|
|
550
|
+
value: c.id
|
|
551
|
+
}))
|
|
552
|
+
];
|
|
553
|
+
const missing = [];
|
|
554
|
+
if (!envName)
|
|
555
|
+
missing.push("missing_name");
|
|
556
|
+
if (valueFromFlag === void 0 && !stdInput)
|
|
557
|
+
missing.push("missing_value");
|
|
558
|
+
if (!envTargetArg && choices2.length > 0)
|
|
559
|
+
missing.push("missing_environment");
|
|
560
|
+
if (envTargetArg === "preview" && envGitBranch === void 0 && !(client.nonInteractive && args.length === 2)) {
|
|
561
|
+
missing.push("git_branch_required");
|
|
562
|
+
}
|
|
563
|
+
if (missing.length > 0) {
|
|
564
|
+
const parts = missing.map((m) => {
|
|
565
|
+
if (m === "missing_name")
|
|
566
|
+
return "variable name";
|
|
567
|
+
if (m === "missing_value")
|
|
568
|
+
return "--value or stdin";
|
|
569
|
+
if (m === "missing_environment")
|
|
570
|
+
return "environment (production, preview, or development)";
|
|
571
|
+
if (m === "git_branch_required")
|
|
572
|
+
return "third argument <gitbranch> for Preview, or omit for all Preview branches";
|
|
573
|
+
return m;
|
|
574
|
+
});
|
|
575
|
+
const fullTemplate = `env add <name> ${getEnvTargetPlaceholder()} <gitbranch> --value <value> --yes`;
|
|
576
|
+
const filledTemplate = fillEnvAddTemplate(fullTemplate, {
|
|
577
|
+
envName,
|
|
578
|
+
envTargetArg,
|
|
579
|
+
valueFromFlag,
|
|
580
|
+
envGitBranch
|
|
581
|
+
});
|
|
582
|
+
const next = [];
|
|
583
|
+
const onlyGitBranchMissing = missing.length === 1 && missing[0] === "git_branch_required";
|
|
584
|
+
if (!onlyGitBranchMissing) {
|
|
585
|
+
next.push({
|
|
586
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
587
|
+
client.argv,
|
|
588
|
+
filledTemplate
|
|
589
|
+
)
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
if (missing.includes("git_branch_required") && envName && (valueFromFlag !== void 0 || stdInput)) {
|
|
593
|
+
const branchSpecific = fillEnvAddTemplate(
|
|
594
|
+
"env add <name> preview <gitbranch> --value <value> --yes",
|
|
595
|
+
{ envName, envTargetArg: "preview", valueFromFlag }
|
|
596
|
+
);
|
|
597
|
+
const branchAll = fillEnvAddTemplate(
|
|
598
|
+
"env add <name> preview --value <value> --yes",
|
|
599
|
+
{ envName, envTargetArg: "preview", valueFromFlag }
|
|
600
|
+
);
|
|
601
|
+
next.push(
|
|
602
|
+
{
|
|
603
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
604
|
+
client.argv,
|
|
605
|
+
branchSpecific
|
|
606
|
+
),
|
|
607
|
+
when: "Add to a specific Git branch"
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
611
|
+
client.argv,
|
|
612
|
+
branchAll
|
|
613
|
+
),
|
|
614
|
+
when: "Add to all Preview branches"
|
|
615
|
+
}
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
outputActionRequired(
|
|
619
|
+
client,
|
|
620
|
+
{
|
|
621
|
+
status: "action_required",
|
|
622
|
+
reason: "missing_requirements",
|
|
623
|
+
missing,
|
|
624
|
+
message: `Provide all required inputs for non-interactive mode: ${parts.join("; ")}. Example: ${filledTemplate}`,
|
|
625
|
+
next
|
|
626
|
+
},
|
|
627
|
+
1
|
|
628
|
+
);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
if (!envName) {
|
|
632
|
+
envName = await client.input.text({
|
|
633
|
+
message: `What's the name of the variable?`,
|
|
634
|
+
validate: (val) => val ? true : "Name cannot be empty"
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
const skipConfirm = opts["--yes"] || !!stdInput || valueFromFlag !== void 0;
|
|
638
|
+
if (!skipConfirm) {
|
|
639
|
+
let keyAccepted = false;
|
|
640
|
+
while (!keyAccepted) {
|
|
641
|
+
const keyWarnings = getEnvKeyWarnings(envName);
|
|
642
|
+
const sensitiveWarning = keyWarnings.find((w) => w.requiresConfirmation);
|
|
643
|
+
if (!sensitiveWarning) {
|
|
644
|
+
for (const w of keyWarnings) {
|
|
645
|
+
output_manager_default.warn(w.message);
|
|
646
|
+
}
|
|
647
|
+
keyAccepted = true;
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
if (client.nonInteractive) {
|
|
651
|
+
const nameWithoutPrefix2 = removePublicPrefix(envName);
|
|
652
|
+
outputActionRequired(client, {
|
|
653
|
+
status: "action_required",
|
|
654
|
+
reason: "env_key_sensitive",
|
|
655
|
+
message: `Key ${envName} may expose sensitive data (public prefix). Use --yes to keep as is, or rename to ${nameWithoutPrefix2}.`,
|
|
656
|
+
choices: [
|
|
657
|
+
{ id: "keep", name: "Leave as is (use --yes)" },
|
|
658
|
+
{ id: "rename", name: `Rename to ${nameWithoutPrefix2}` }
|
|
659
|
+
],
|
|
660
|
+
next: [
|
|
661
|
+
{
|
|
662
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
663
|
+
client.argv,
|
|
664
|
+
`env add ${envName} ${getEnvTargetPlaceholder()} --value <value> --yes`
|
|
665
|
+
),
|
|
666
|
+
when: "Leave as is"
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
670
|
+
client.argv,
|
|
671
|
+
`env add ${nameWithoutPrefix2} ${getEnvTargetPlaceholder()} --value <value> --yes`
|
|
672
|
+
),
|
|
673
|
+
when: "Rename"
|
|
674
|
+
}
|
|
675
|
+
]
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
for (const w of keyWarnings) {
|
|
679
|
+
output_manager_default.warn(w.message);
|
|
680
|
+
}
|
|
681
|
+
const nameWithoutPrefix = removePublicPrefix(envName);
|
|
682
|
+
const choices2 = [
|
|
683
|
+
{ name: "Leave as is", value: "c" },
|
|
684
|
+
{ name: `Rename to ${nameWithoutPrefix}`, value: "p" },
|
|
685
|
+
{ name: "Re-enter", value: "r" }
|
|
686
|
+
];
|
|
687
|
+
const action = await client.input.select({
|
|
688
|
+
message: "How to proceed?",
|
|
689
|
+
choices: choices2
|
|
690
|
+
});
|
|
691
|
+
if (action === "c") {
|
|
692
|
+
keyAccepted = true;
|
|
693
|
+
} else if (action === "p") {
|
|
694
|
+
envName = nameWithoutPrefix;
|
|
695
|
+
output_manager_default.log(`Renamed to ${envName}`);
|
|
696
|
+
} else {
|
|
697
|
+
envName = await client.input.text({
|
|
698
|
+
message: `What's the name of the variable?`,
|
|
699
|
+
validate: (val) => val ? true : "Name cannot be empty"
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
} else {
|
|
704
|
+
const keyWarnings = getEnvKeyWarnings(envName);
|
|
705
|
+
for (const w of keyWarnings) {
|
|
706
|
+
output_manager_default.warn(w.message);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
const link = await getLinkedProject(client);
|
|
710
|
+
if (link.status === "error") {
|
|
711
|
+
return link.exitCode;
|
|
712
|
+
} else if (link.status === "not_linked") {
|
|
713
|
+
if (client.nonInteractive) {
|
|
714
|
+
const preserved = getPreservedArgsForEnvAdd(client.argv);
|
|
715
|
+
const linkPreserved = preserved.filter((a, i) => {
|
|
716
|
+
if (a === "--value")
|
|
717
|
+
return false;
|
|
718
|
+
if (a.startsWith("--value="))
|
|
719
|
+
return false;
|
|
720
|
+
if (i > 0 && preserved[i - 1] === "--value")
|
|
721
|
+
return false;
|
|
722
|
+
return true;
|
|
723
|
+
});
|
|
724
|
+
const linkArgv = [
|
|
725
|
+
...client.argv.slice(0, 2),
|
|
726
|
+
"link",
|
|
727
|
+
...link.status === "not_linked" ? ["--scope", "<scope>"] : [],
|
|
728
|
+
...linkPreserved
|
|
729
|
+
];
|
|
730
|
+
let envAddRetryArgv = client.argv;
|
|
731
|
+
if (envTargetArg === "preview" && envGitBranch === void 0) {
|
|
732
|
+
const argvArgs = client.argv.slice(2);
|
|
733
|
+
const addIdx = argvArgs.indexOf("add");
|
|
734
|
+
if (addIdx !== -1) {
|
|
735
|
+
let pos = addIdx + 1;
|
|
736
|
+
let positionals = 0;
|
|
737
|
+
while (pos < argvArgs.length && positionals < 3 && !argvArgs[pos].startsWith("-")) {
|
|
738
|
+
positionals++;
|
|
739
|
+
pos++;
|
|
740
|
+
}
|
|
741
|
+
const insertAt = 2 + pos;
|
|
742
|
+
envAddRetryArgv = [
|
|
743
|
+
...client.argv.slice(0, insertAt),
|
|
744
|
+
"<gitbranch>",
|
|
745
|
+
...client.argv.slice(insertAt)
|
|
746
|
+
];
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
outputAgentError(
|
|
750
|
+
client,
|
|
751
|
+
{
|
|
752
|
+
status: "error",
|
|
753
|
+
reason: "not_linked",
|
|
754
|
+
message: `Your codebase isn't linked to a project on Vercel. Run ${getCommandNamePlain(
|
|
755
|
+
"link"
|
|
756
|
+
)} to begin. Use --yes for non-interactive; use --scope or --project to specify team or project. Then run your env add command.`,
|
|
757
|
+
next: [
|
|
758
|
+
{ command: buildCommandWithYes(linkArgv) },
|
|
759
|
+
{ command: buildCommandWithYes(envAddRetryArgv) }
|
|
760
|
+
]
|
|
761
|
+
},
|
|
762
|
+
1
|
|
763
|
+
);
|
|
764
|
+
} else {
|
|
765
|
+
output_manager_default.error(
|
|
766
|
+
`Your codebase isn\u2019t linked to a project on Vercel. Run ${getCommandName(
|
|
767
|
+
"link"
|
|
768
|
+
)} to begin.`
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
return 1;
|
|
772
|
+
}
|
|
773
|
+
client.config.currentTeam = link.org.type === "team" ? link.org.id : void 0;
|
|
774
|
+
const { project } = link;
|
|
775
|
+
const [{ envs }, customEnvironments] = await Promise.all([
|
|
776
|
+
getEnvRecords(client, project.id, "vercel-cli:env:add"),
|
|
777
|
+
getCustomEnvironments(client, project.id)
|
|
778
|
+
]);
|
|
779
|
+
const matchingEnvs = envs.filter((r) => r.key === envName);
|
|
780
|
+
const existingTargets = /* @__PURE__ */ new Set();
|
|
781
|
+
const existingCustomEnvs = /* @__PURE__ */ new Set();
|
|
782
|
+
for (const env of matchingEnvs) {
|
|
783
|
+
if (typeof env.target === "string") {
|
|
784
|
+
existingTargets.add(env.target);
|
|
785
|
+
} else if (Array.isArray(env.target)) {
|
|
786
|
+
for (const target of env.target) {
|
|
787
|
+
existingTargets.add(target);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
if (env.customEnvironmentIds) {
|
|
791
|
+
for (const customEnvId of env.customEnvironmentIds) {
|
|
792
|
+
existingCustomEnvs.add(customEnvId);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
const choices = [
|
|
797
|
+
...envTargetChoices.filter((c) => !existingTargets.has(c.value)),
|
|
798
|
+
...customEnvironments.filter((c) => !existingCustomEnvs.has(c.id)).map((c) => ({
|
|
799
|
+
name: c.slug,
|
|
800
|
+
value: c.id
|
|
801
|
+
}))
|
|
802
|
+
];
|
|
803
|
+
if (!envGitBranch && choices.length === 0 && !opts["--force"]) {
|
|
804
|
+
output_manager_default.error(
|
|
805
|
+
`The variable ${param(
|
|
806
|
+
envName
|
|
807
|
+
)} has already been added to all Environments. To remove, run ${getCommandName(
|
|
808
|
+
`env rm ${envName}`
|
|
809
|
+
)}.`
|
|
810
|
+
);
|
|
811
|
+
return 1;
|
|
812
|
+
}
|
|
813
|
+
let type = opts["--sensitive"] ? "sensitive" : "encrypted";
|
|
814
|
+
let envValue;
|
|
815
|
+
if (stdInput) {
|
|
816
|
+
envValue = stdInput;
|
|
817
|
+
} else if (valueFromFlag !== void 0) {
|
|
818
|
+
envValue = valueFromFlag;
|
|
819
|
+
} else {
|
|
820
|
+
if (client.nonInteractive) {
|
|
821
|
+
outputActionRequired(client, {
|
|
822
|
+
status: "action_required",
|
|
823
|
+
reason: "missing_value",
|
|
824
|
+
message: "In non-interactive mode provide the value via --value or stdin. Example: vercel env add <name> <environment> --value 'value' --yes",
|
|
825
|
+
next: [
|
|
826
|
+
{
|
|
827
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
828
|
+
client.argv,
|
|
829
|
+
`env add <name> ${getEnvTargetPlaceholder()} --value <value> --yes`
|
|
830
|
+
)
|
|
831
|
+
}
|
|
832
|
+
]
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
if (type === "encrypted") {
|
|
836
|
+
const isSensitive = await client.input.confirm(
|
|
837
|
+
`Your value will be encrypted. Mark as sensitive?`,
|
|
838
|
+
false
|
|
839
|
+
);
|
|
840
|
+
if (isSensitive) {
|
|
841
|
+
type = "sensitive";
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
envValue = await client.input.password({
|
|
845
|
+
message: `What's the value of ${envName}?`,
|
|
846
|
+
mask: true
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
const { finalValue } = await validateEnvValue({
|
|
850
|
+
envName,
|
|
851
|
+
initialValue: envValue,
|
|
852
|
+
skipConfirm,
|
|
853
|
+
promptForValue: () => client.input.password({
|
|
854
|
+
message: `What's the value of ${envName}?`,
|
|
855
|
+
mask: true
|
|
856
|
+
}),
|
|
857
|
+
selectAction: (choices2) => client.input.select({ message: "How to proceed?", choices: choices2 }),
|
|
858
|
+
showWarning: (msg) => output_manager_default.warn(msg),
|
|
859
|
+
showLog: (msg) => output_manager_default.log(msg)
|
|
860
|
+
});
|
|
861
|
+
while (envTargets.length === 0) {
|
|
862
|
+
if (client.nonInteractive && choices.length > 0) {
|
|
863
|
+
outputActionRequired(client, {
|
|
864
|
+
status: "action_required",
|
|
865
|
+
reason: "missing_environment",
|
|
866
|
+
message: `Specify at least one environment. Add as argument or use: ${buildEnvAddCommandWithPreservedArgs(
|
|
867
|
+
client.argv,
|
|
868
|
+
`env add ${envName} <environment> --value <value> --yes`
|
|
869
|
+
)}`,
|
|
870
|
+
choices: choices.map((c) => ({
|
|
871
|
+
id: c.value,
|
|
872
|
+
name: typeof c.name === "string" ? c.name : c.value
|
|
873
|
+
})),
|
|
874
|
+
next: choices.slice(0, 5).map((c) => ({
|
|
875
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
876
|
+
client.argv,
|
|
877
|
+
`env add ${envName} ${c.value} --value <value> --yes`
|
|
878
|
+
)
|
|
879
|
+
}))
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
envTargets = await client.input.checkbox({
|
|
883
|
+
message: `Add ${envName} to which Environments (select multiple)?`,
|
|
884
|
+
choices
|
|
885
|
+
});
|
|
886
|
+
if (envTargets.length === 0) {
|
|
887
|
+
output_manager_default.error("Please select at least one Environment");
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
if (envGitBranch === void 0 && envTargets.length === 1 && envTargets[0] === "preview") {
|
|
891
|
+
if (client.nonInteractive) {
|
|
892
|
+
outputActionRequired(
|
|
893
|
+
client,
|
|
894
|
+
{
|
|
895
|
+
status: "action_required",
|
|
896
|
+
reason: "git_branch_required",
|
|
897
|
+
message: `Add ${envName} to which Git branch for Preview? Pass branch as third argument, or omit for all Preview branches.`,
|
|
898
|
+
next: [
|
|
899
|
+
{
|
|
900
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
901
|
+
client.argv,
|
|
902
|
+
`env add ${envName} preview <gitbranch> --value <value> --yes`
|
|
903
|
+
),
|
|
904
|
+
when: "Add to a specific Git branch"
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
908
|
+
client.argv,
|
|
909
|
+
`env add ${envName} preview --value <value> --yes`
|
|
910
|
+
),
|
|
911
|
+
when: "Add to all Preview branches"
|
|
912
|
+
}
|
|
913
|
+
]
|
|
914
|
+
},
|
|
915
|
+
1
|
|
916
|
+
);
|
|
917
|
+
} else {
|
|
918
|
+
envGitBranch = await client.input.text({
|
|
919
|
+
message: `Add ${envName} to which Git branch? (leave empty for all Preview branches)?`
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
const upsert = opts["--force"] ? "true" : "";
|
|
924
|
+
const addStamp = stamp_default();
|
|
925
|
+
try {
|
|
926
|
+
output_manager_default.spinner("Saving");
|
|
927
|
+
await addEnvRecord(
|
|
928
|
+
client,
|
|
929
|
+
project.id,
|
|
930
|
+
upsert,
|
|
931
|
+
type,
|
|
932
|
+
envName,
|
|
933
|
+
finalValue,
|
|
934
|
+
envTargets,
|
|
935
|
+
envGitBranch
|
|
936
|
+
);
|
|
937
|
+
} catch (err) {
|
|
938
|
+
if (client.nonInteractive && isAPIError(err)) {
|
|
939
|
+
const reason = err.slug || (err.serverMessage?.toLowerCase().includes("branch") ? "branch_not_found" : "api_error");
|
|
940
|
+
outputAgentError(
|
|
941
|
+
client,
|
|
942
|
+
{
|
|
943
|
+
status: "error",
|
|
944
|
+
reason,
|
|
945
|
+
message: err.serverMessage
|
|
946
|
+
},
|
|
947
|
+
1
|
|
948
|
+
);
|
|
949
|
+
}
|
|
950
|
+
if (isAPIError(err) && isKnownError(err)) {
|
|
951
|
+
output_manager_default.error(err.serverMessage);
|
|
952
|
+
return 1;
|
|
953
|
+
}
|
|
954
|
+
throw err;
|
|
955
|
+
}
|
|
956
|
+
output_manager_default.print(
|
|
957
|
+
`${prependEmoji(
|
|
958
|
+
`${opts["--force"] ? "Overrode" : "Added"} Environment Variable ${import_chalk.default.bold(envName)} to Project ${import_chalk.default.bold(
|
|
959
|
+
project.name
|
|
960
|
+
)} ${import_chalk.default.gray(addStamp())}`,
|
|
961
|
+
emoji("success")
|
|
962
|
+
)}
|
|
963
|
+
`
|
|
964
|
+
);
|
|
965
|
+
const { isAgent } = await determineAgent();
|
|
966
|
+
const guidanceMode = parsedArgs.flags["--guidance"] ?? isAgent;
|
|
967
|
+
if (guidanceMode) {
|
|
968
|
+
suggestNextCommands([getCommandName(`env ls`), getCommandName(`env pull`)]);
|
|
969
|
+
}
|
|
970
|
+
return 0;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
// src/commands/env/ls.ts
|
|
974
|
+
var import_chalk2 = __toESM(require_source(), 1);
|
|
975
|
+
var import_ms = __toESM(require_ms(), 1);
|
|
976
|
+
|
|
977
|
+
// src/util/output/ellipsis.ts
|
|
978
|
+
function ellipsis(str, length) {
|
|
979
|
+
return str.length > length ? `${str.slice(0, length - 1)}\u2026` : str;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
// src/util/env/format-environments.ts
|
|
983
|
+
var import_title = __toESM(require_lib(), 1);
|
|
984
|
+
function formatEnvironments(link, env, customEnvironments) {
|
|
985
|
+
const defaultTargets = (Array.isArray(env.target) ? env.target : [env.target || ""]).map((t) => {
|
|
986
|
+
return formatEnvironment(link.org.slug, link.project.name, {
|
|
987
|
+
id: t,
|
|
988
|
+
slug: (0, import_title.default)(t)
|
|
989
|
+
});
|
|
990
|
+
});
|
|
991
|
+
const customTargets = env.customEnvironmentIds ? env.customEnvironmentIds.map((id) => customEnvironments.find((e) => e.id === id)).filter(Boolean).map((e) => formatEnvironment(link.org.slug, link.project.name, e)) : [];
|
|
992
|
+
const targetsString = [...defaultTargets, ...customTargets].join(", ");
|
|
993
|
+
return env.gitBranch ? `${targetsString} (${env.gitBranch})` : targetsString;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
// src/util/telemetry/commands/env/ls.ts
|
|
997
|
+
var EnvLsTelemetryClient = class extends TelemetryClient {
|
|
998
|
+
trackCliArgumentEnvironment(environment) {
|
|
999
|
+
if (environment) {
|
|
1000
|
+
this.trackCliArgument({
|
|
1001
|
+
arg: "environment",
|
|
1002
|
+
value: STANDARD_ENVIRONMENTS.includes(
|
|
1003
|
+
environment
|
|
1004
|
+
) ? environment : this.redactedValue
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
trackCliArgumentGitBranch(gitBranch) {
|
|
1009
|
+
if (gitBranch) {
|
|
1010
|
+
this.trackCliArgument({
|
|
1011
|
+
arg: "git-branch",
|
|
1012
|
+
value: this.redactedValue
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
trackCliFlagGuidance(guidance) {
|
|
1017
|
+
if (guidance) {
|
|
1018
|
+
this.trackCliFlag("guidance");
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
|
|
1023
|
+
// src/commands/env/ls.ts
|
|
1024
|
+
import { determineAgent as determineAgent2 } from "@vercel/detect-agent";
|
|
1025
|
+
async function ls(client, argv) {
|
|
1026
|
+
const telemetryClient = new EnvLsTelemetryClient({
|
|
1027
|
+
opts: {
|
|
1028
|
+
store: client.telemetryEventStore
|
|
1029
|
+
}
|
|
1030
|
+
});
|
|
1031
|
+
let parsedArgs;
|
|
1032
|
+
const flagsSpecification = getFlagsSpecification(listSubcommand.options);
|
|
1033
|
+
try {
|
|
1034
|
+
parsedArgs = parseArguments(argv, flagsSpecification);
|
|
1035
|
+
} catch (err) {
|
|
1036
|
+
printError(err);
|
|
1037
|
+
return 1;
|
|
1038
|
+
}
|
|
1039
|
+
const { args, flags } = parsedArgs;
|
|
1040
|
+
const validationResult = validateLsArgs({
|
|
1041
|
+
commandName: "env ls",
|
|
1042
|
+
args,
|
|
1043
|
+
maxArgs: 2,
|
|
1044
|
+
exitCode: 1,
|
|
1045
|
+
usageString: getCommandName(
|
|
1046
|
+
`env ls ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
1047
|
+
)
|
|
1048
|
+
});
|
|
1049
|
+
if (validationResult !== 0) {
|
|
1050
|
+
return validationResult;
|
|
1051
|
+
}
|
|
1052
|
+
const [envTarget, envGitBranch] = args;
|
|
1053
|
+
const formatResult = validateJsonOutput(flags);
|
|
1054
|
+
if (!formatResult.valid) {
|
|
1055
|
+
output_manager_default.error(formatResult.error);
|
|
1056
|
+
return 1;
|
|
1057
|
+
}
|
|
1058
|
+
const asJson = formatResult.jsonOutput;
|
|
1059
|
+
telemetryClient.trackCliArgumentEnvironment(envTarget);
|
|
1060
|
+
telemetryClient.trackCliArgumentGitBranch(envGitBranch);
|
|
1061
|
+
telemetryClient.trackCliFlagGuidance(flags["--guidance"]);
|
|
1062
|
+
telemetryClient.trackCliOptionFormat(flags["--format"]);
|
|
1063
|
+
const link = await getLinkedProject(client);
|
|
1064
|
+
if (link.status === "error") {
|
|
1065
|
+
return link.exitCode;
|
|
1066
|
+
} else if (link.status === "not_linked") {
|
|
1067
|
+
output_manager_default.error(
|
|
1068
|
+
`Your codebase isn\u2019t linked to a project on Vercel. ${client.nonInteractive ? `Run ${getCommandName("link --yes --team <team-id> --project <project-id>")} to link non-interactively.` : `Run ${getCommandName("link")} to begin.`}`
|
|
1069
|
+
);
|
|
1070
|
+
return 1;
|
|
1071
|
+
}
|
|
1072
|
+
client.config.currentTeam = link.org.type === "team" ? link.org.id : void 0;
|
|
1073
|
+
const { project, org } = link;
|
|
1074
|
+
const lsStamp = stamp_default();
|
|
1075
|
+
const [envsResult, customEnvs] = await Promise.all([
|
|
1076
|
+
getEnvRecords(client, project.id, "vercel-cli:env:ls", {
|
|
1077
|
+
target: envTarget,
|
|
1078
|
+
gitBranch: envGitBranch
|
|
1079
|
+
}),
|
|
1080
|
+
getCustomEnvironments(client, project.id)
|
|
1081
|
+
]);
|
|
1082
|
+
const { envs } = envsResult;
|
|
1083
|
+
const projectSlugLink = formatProject(org.slug, project.name);
|
|
1084
|
+
if (asJson) {
|
|
1085
|
+
output_manager_default.stopSpinner();
|
|
1086
|
+
const jsonOutput = {
|
|
1087
|
+
envs: envs.map((env) => ({
|
|
1088
|
+
key: env.key,
|
|
1089
|
+
value: env.type === "plain" ? env.value : void 0,
|
|
1090
|
+
type: env.type,
|
|
1091
|
+
target: env.target,
|
|
1092
|
+
gitBranch: env.gitBranch,
|
|
1093
|
+
configurationId: env.configurationId,
|
|
1094
|
+
createdAt: env.createdAt,
|
|
1095
|
+
updatedAt: env.updatedAt
|
|
1096
|
+
}))
|
|
1097
|
+
};
|
|
1098
|
+
client.stdout.write(`${JSON.stringify(jsonOutput, null, 2)}
|
|
1099
|
+
`);
|
|
1100
|
+
} else if (envs.length === 0) {
|
|
1101
|
+
output_manager_default.log(
|
|
1102
|
+
`No Environment Variables found for ${projectSlugLink} ${import_chalk2.default.gray(lsStamp())}`
|
|
1103
|
+
);
|
|
1104
|
+
} else {
|
|
1105
|
+
output_manager_default.log(
|
|
1106
|
+
`Environment Variables found for ${projectSlugLink} ${import_chalk2.default.gray(lsStamp())}`
|
|
1107
|
+
);
|
|
1108
|
+
client.stdout.write(`${getTable(link, envs, customEnvs)}
|
|
1109
|
+
`);
|
|
1110
|
+
}
|
|
1111
|
+
if (!asJson) {
|
|
1112
|
+
const { isAgent } = await determineAgent2();
|
|
1113
|
+
const guidanceMode = parsedArgs.flags["--guidance"] ?? isAgent;
|
|
1114
|
+
if (guidanceMode) {
|
|
1115
|
+
suggestNextCommands([
|
|
1116
|
+
getCommandName(`env add`),
|
|
1117
|
+
getCommandName("env rm"),
|
|
1118
|
+
getCommandName(`env pull`)
|
|
1119
|
+
]);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
return 0;
|
|
1123
|
+
}
|
|
1124
|
+
function getTable(link, records, customEnvironments) {
|
|
1125
|
+
const label = records.some((env) => env.gitBranch) ? "environments (git branch)" : "environments";
|
|
1126
|
+
return formatTable(
|
|
1127
|
+
["name", "value", label, "created"],
|
|
1128
|
+
["l", "l", "l", "l", "l"],
|
|
1129
|
+
[
|
|
1130
|
+
{
|
|
1131
|
+
name: "",
|
|
1132
|
+
rows: records.map((row) => getRow(link, row, customEnvironments))
|
|
1133
|
+
}
|
|
1134
|
+
]
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
function getRow(link, env, customEnvironments) {
|
|
1138
|
+
let value;
|
|
1139
|
+
if (env.type === "plain") {
|
|
1140
|
+
const singleLineValue = env.value.replace(/\s/g, " ");
|
|
1141
|
+
value = import_chalk2.default.gray(ellipsis(singleLineValue, 19));
|
|
1142
|
+
} else if (env.type === "system") {
|
|
1143
|
+
value = import_chalk2.default.gray.italic(env.value);
|
|
1144
|
+
} else {
|
|
1145
|
+
value = import_chalk2.default.gray.italic("Encrypted");
|
|
1146
|
+
}
|
|
1147
|
+
const now = Date.now();
|
|
1148
|
+
return [
|
|
1149
|
+
import_chalk2.default.bold(env.key),
|
|
1150
|
+
value,
|
|
1151
|
+
formatEnvironments(link, env, customEnvironments),
|
|
1152
|
+
env.createdAt ? `${(0, import_ms.default)(now - env.createdAt)} ago` : ""
|
|
1153
|
+
];
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
// src/commands/env/rm.ts
|
|
1157
|
+
var import_chalk3 = __toESM(require_source(), 1);
|
|
1158
|
+
|
|
1159
|
+
// src/util/env/remove-env-record.ts
|
|
1160
|
+
async function removeEnvRecord(client, projectId, env) {
|
|
1161
|
+
output_manager_default.debug(`Removing Environment Variable ${env.key}`);
|
|
1162
|
+
const url = `/v10/projects/${projectId}/env/${env.id}`;
|
|
1163
|
+
await client.fetch(url, {
|
|
1164
|
+
method: "DELETE"
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
// src/util/telemetry/commands/env/rm.ts
|
|
1169
|
+
var EnvRmTelemetryClient = class extends TelemetryClient {
|
|
1170
|
+
trackCliArgumentName(name) {
|
|
1171
|
+
if (name) {
|
|
1172
|
+
this.trackCliArgument({
|
|
1173
|
+
arg: "name",
|
|
1174
|
+
value: this.redactedValue
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
trackCliArgumentEnvironment(environment) {
|
|
1179
|
+
if (environment) {
|
|
1180
|
+
this.trackCliArgument({
|
|
1181
|
+
arg: "environment",
|
|
1182
|
+
value: STANDARD_ENVIRONMENTS.includes(
|
|
1183
|
+
environment
|
|
1184
|
+
) ? environment : this.redactedValue
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
trackCliArgumentGitBranch(gitBranch) {
|
|
1189
|
+
if (gitBranch) {
|
|
1190
|
+
this.trackCliArgument({
|
|
1191
|
+
arg: "git-branch",
|
|
1192
|
+
value: this.redactedValue
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
trackCliFlagYes(yes) {
|
|
1197
|
+
if (yes) {
|
|
1198
|
+
this.trackCliFlag("yes");
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
|
|
1203
|
+
// src/commands/env/rm.ts
|
|
1204
|
+
async function rm(client, argv) {
|
|
1205
|
+
const telemetryClient = new EnvRmTelemetryClient({
|
|
1206
|
+
opts: {
|
|
1207
|
+
store: client.telemetryEventStore
|
|
1208
|
+
}
|
|
1209
|
+
});
|
|
1210
|
+
let parsedArgs;
|
|
1211
|
+
const flagsSpecification = getFlagsSpecification(removeSubcommand.options);
|
|
1212
|
+
try {
|
|
1213
|
+
parsedArgs = parseArguments(argv, flagsSpecification);
|
|
1214
|
+
} catch (err) {
|
|
1215
|
+
if (client.nonInteractive) {
|
|
1216
|
+
outputAgentError(
|
|
1217
|
+
client,
|
|
1218
|
+
{
|
|
1219
|
+
status: "error",
|
|
1220
|
+
reason: "invalid_arguments",
|
|
1221
|
+
message: err instanceof Error ? err.message : String(err)
|
|
1222
|
+
},
|
|
1223
|
+
1
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1226
|
+
printError(err);
|
|
1227
|
+
return 1;
|
|
1228
|
+
}
|
|
1229
|
+
const { args, flags: opts } = parsedArgs;
|
|
1230
|
+
if (args.length > 3) {
|
|
1231
|
+
if (client.nonInteractive) {
|
|
1232
|
+
outputAgentError(
|
|
1233
|
+
client,
|
|
1234
|
+
{
|
|
1235
|
+
status: "error",
|
|
1236
|
+
reason: "invalid_arguments",
|
|
1237
|
+
message: `Invalid number of arguments. Usage: ${getCommandNamePlain(
|
|
1238
|
+
`env rm <name> ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
1239
|
+
)}`
|
|
1240
|
+
},
|
|
1241
|
+
1
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1244
|
+
output_manager_default.error(
|
|
1245
|
+
`Invalid number of arguments. Usage: ${getCommandName(
|
|
1246
|
+
`env rm <name> ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
1247
|
+
)}`
|
|
1248
|
+
);
|
|
1249
|
+
return 1;
|
|
1250
|
+
}
|
|
1251
|
+
let [envName, envTarget, envGitBranch] = args;
|
|
1252
|
+
telemetryClient.trackCliArgumentName(envName);
|
|
1253
|
+
telemetryClient.trackCliArgumentEnvironment(envTarget);
|
|
1254
|
+
telemetryClient.trackCliArgumentGitBranch(envGitBranch);
|
|
1255
|
+
telemetryClient.trackCliFlagYes(opts["--yes"]);
|
|
1256
|
+
const link = await getLinkedProject(client);
|
|
1257
|
+
if (link.status === "error") {
|
|
1258
|
+
return link.exitCode;
|
|
1259
|
+
} else if (link.status === "not_linked") {
|
|
1260
|
+
if (client.nonInteractive) {
|
|
1261
|
+
const preserved = getPreservedArgsForEnvRm(client.argv).filter(
|
|
1262
|
+
(a) => a !== "--yes" && a !== "-y"
|
|
1263
|
+
);
|
|
1264
|
+
const linkArgv = [
|
|
1265
|
+
...client.argv.slice(0, 2),
|
|
1266
|
+
"link",
|
|
1267
|
+
"--scope",
|
|
1268
|
+
"<scope>",
|
|
1269
|
+
...preserved
|
|
1270
|
+
];
|
|
1271
|
+
outputAgentError(
|
|
1272
|
+
client,
|
|
1273
|
+
{
|
|
1274
|
+
status: "error",
|
|
1275
|
+
reason: "not_linked",
|
|
1276
|
+
message: `Your codebase isn't linked to a project on Vercel. Run ${getCommandNamePlain(
|
|
1277
|
+
"link"
|
|
1278
|
+
)} to begin. Use --yes for non-interactive; use --scope or --project to specify team or project.`,
|
|
1279
|
+
next: [
|
|
1280
|
+
{ command: buildCommandWithYes(linkArgv) },
|
|
1281
|
+
{ command: buildCommandWithYes(client.argv) }
|
|
1282
|
+
]
|
|
1283
|
+
},
|
|
1284
|
+
1
|
|
1285
|
+
);
|
|
1286
|
+
} else {
|
|
1287
|
+
output_manager_default.error(
|
|
1288
|
+
`Your codebase isn\u2019t linked to a project on Vercel. Run ${getCommandName(
|
|
1289
|
+
"link"
|
|
1290
|
+
)} to begin.`
|
|
1291
|
+
);
|
|
1292
|
+
}
|
|
1293
|
+
return 1;
|
|
1294
|
+
}
|
|
1295
|
+
client.config.currentTeam = link.org.type === "team" ? link.org.id : void 0;
|
|
1296
|
+
const { project } = link;
|
|
1297
|
+
if (!envName) {
|
|
1298
|
+
if (client.nonInteractive) {
|
|
1299
|
+
outputActionRequired(
|
|
1300
|
+
client,
|
|
1301
|
+
{
|
|
1302
|
+
status: "action_required",
|
|
1303
|
+
reason: "missing_name",
|
|
1304
|
+
message: "Provide the variable name as an argument. Example: vercel env rm <name> --yes",
|
|
1305
|
+
next: [
|
|
1306
|
+
{
|
|
1307
|
+
command: buildEnvRmCommandWithPreservedArgs(
|
|
1308
|
+
client.argv,
|
|
1309
|
+
`env rm <name> ${getEnvTargetPlaceholder()} --yes`
|
|
1310
|
+
)
|
|
1311
|
+
}
|
|
1312
|
+
]
|
|
1313
|
+
},
|
|
1314
|
+
1
|
|
1315
|
+
);
|
|
1316
|
+
}
|
|
1317
|
+
envName = await client.input.text({
|
|
1318
|
+
message: "What's the name of the variable?",
|
|
1319
|
+
validate: (val) => val ? true : "Name cannot be empty"
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
const [result, customEnvironments] = await Promise.all([
|
|
1323
|
+
getEnvRecords(client, project.id, "vercel-cli:env:rm", {
|
|
1324
|
+
target: envTarget,
|
|
1325
|
+
gitBranch: envGitBranch
|
|
1326
|
+
}),
|
|
1327
|
+
getCustomEnvironments(client, project.id)
|
|
1328
|
+
]);
|
|
1329
|
+
let envs = result.envs.filter((env2) => env2.key === envName);
|
|
1330
|
+
if (envs.length === 0) {
|
|
1331
|
+
if (client.nonInteractive) {
|
|
1332
|
+
outputAgentError(
|
|
1333
|
+
client,
|
|
1334
|
+
{
|
|
1335
|
+
status: "error",
|
|
1336
|
+
reason: "env_not_found",
|
|
1337
|
+
message: `Environment Variable ${envName} was not found.`
|
|
1338
|
+
},
|
|
1339
|
+
1
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
output_manager_default.error(`Environment Variable was not found.
|
|
1343
|
+
`);
|
|
1344
|
+
return 1;
|
|
1345
|
+
}
|
|
1346
|
+
while (envs.length > 1) {
|
|
1347
|
+
if (client.nonInteractive) {
|
|
1348
|
+
outputActionRequired(
|
|
1349
|
+
client,
|
|
1350
|
+
{
|
|
1351
|
+
status: "action_required",
|
|
1352
|
+
reason: "multiple_envs",
|
|
1353
|
+
message: `Multiple Environment Variables match ${envName}. Specify target and/or branch to remove one.`,
|
|
1354
|
+
next: [
|
|
1355
|
+
{
|
|
1356
|
+
command: buildEnvRmCommandWithPreservedArgs(
|
|
1357
|
+
client.argv,
|
|
1358
|
+
`env rm ${envName} ${getEnvTargetPlaceholder()} --yes`
|
|
1359
|
+
)
|
|
1360
|
+
}
|
|
1361
|
+
]
|
|
1362
|
+
},
|
|
1363
|
+
1
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
const id = await client.input.select({
|
|
1367
|
+
message: `Remove ${envName} from which Environments?`,
|
|
1368
|
+
choices: envs.map((env2) => ({
|
|
1369
|
+
value: env2.id,
|
|
1370
|
+
name: formatEnvironments(link, env2, customEnvironments)
|
|
1371
|
+
}))
|
|
1372
|
+
});
|
|
1373
|
+
if (!id) {
|
|
1374
|
+
output_manager_default.error("Please select at least one Environment Variable to remove");
|
|
1375
|
+
}
|
|
1376
|
+
envs = envs.filter((env2) => env2.id === id);
|
|
1377
|
+
}
|
|
1378
|
+
const env = envs[0];
|
|
1379
|
+
const skipConfirmation = opts["--yes"];
|
|
1380
|
+
if (!skipConfirmation) {
|
|
1381
|
+
if (client.nonInteractive) {
|
|
1382
|
+
outputActionRequired(
|
|
1383
|
+
client,
|
|
1384
|
+
{
|
|
1385
|
+
status: "action_required",
|
|
1386
|
+
reason: "confirmation_required",
|
|
1387
|
+
message: `Removing Environment Variable ${env.key}. Use --yes to confirm.`,
|
|
1388
|
+
next: [{ command: buildCommandWithYes(client.argv) }]
|
|
1389
|
+
},
|
|
1390
|
+
1
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
if (!await client.input.confirm(
|
|
1394
|
+
`Removing Environment Variable ${param(env.key)} from ${formatEnvironments(
|
|
1395
|
+
link,
|
|
1396
|
+
env,
|
|
1397
|
+
customEnvironments
|
|
1398
|
+
)} in Project ${import_chalk3.default.bold(project.name)}. Are you sure?`,
|
|
1399
|
+
false
|
|
1400
|
+
)) {
|
|
1401
|
+
output_manager_default.log("Canceled");
|
|
1402
|
+
return 0;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
const rmStamp = stamp_default();
|
|
1406
|
+
try {
|
|
1407
|
+
output_manager_default.spinner("Removing");
|
|
1408
|
+
await removeEnvRecord(client, project.id, env);
|
|
1409
|
+
} catch (err) {
|
|
1410
|
+
if (client.nonInteractive && isAPIError(err)) {
|
|
1411
|
+
const reason = err.slug || (err.serverMessage?.toLowerCase().includes("branch") ? "branch_not_found" : "api_error");
|
|
1412
|
+
outputAgentError(
|
|
1413
|
+
client,
|
|
1414
|
+
{
|
|
1415
|
+
status: "error",
|
|
1416
|
+
reason,
|
|
1417
|
+
message: err.serverMessage
|
|
1418
|
+
},
|
|
1419
|
+
1
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
if (isAPIError(err) && isKnownError(err)) {
|
|
1423
|
+
output_manager_default.error(err.serverMessage);
|
|
1424
|
+
return 1;
|
|
1425
|
+
}
|
|
1426
|
+
throw err;
|
|
1427
|
+
}
|
|
1428
|
+
output_manager_default.print(
|
|
1429
|
+
`${prependEmoji(
|
|
1430
|
+
`Removed Environment Variable ${import_chalk3.default.gray(rmStamp())}`,
|
|
1431
|
+
emoji("success")
|
|
1432
|
+
)}
|
|
1433
|
+
`
|
|
1434
|
+
);
|
|
1435
|
+
return 0;
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
// src/commands/env/run.ts
|
|
1439
|
+
var import_env = __toESM(require_dist3(), 1);
|
|
1440
|
+
var import_execa = __toESM(require_execa(), 1);
|
|
1441
|
+
function parseRunArgs(argv) {
|
|
1442
|
+
const argvIndex = argv.indexOf("--");
|
|
1443
|
+
const hasDoubleDash = argvIndex !== -1;
|
|
1444
|
+
const vercelArgs = hasDoubleDash ? argv.slice(2, argvIndex) : argv.slice(2);
|
|
1445
|
+
const userCommand = hasDoubleDash ? argv.slice(argvIndex + 1) : [];
|
|
1446
|
+
return { vercelArgs, userCommand };
|
|
1447
|
+
}
|
|
1448
|
+
function needsHelpForRun(client) {
|
|
1449
|
+
const { vercelArgs } = parseRunArgs(client.argv);
|
|
1450
|
+
const flagsSpecification = getFlagsSpecification(runSubcommand.options);
|
|
1451
|
+
try {
|
|
1452
|
+
const parsedArgs = parseArguments(vercelArgs, flagsSpecification);
|
|
1453
|
+
return Boolean(parsedArgs.flags["--help"]);
|
|
1454
|
+
} catch {
|
|
1455
|
+
return false;
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
async function run(client) {
|
|
1459
|
+
const { vercelArgs, userCommand } = parseRunArgs(client.argv);
|
|
1460
|
+
let parsedArgs;
|
|
1461
|
+
const flagsSpecification = getFlagsSpecification(runSubcommand.options);
|
|
1462
|
+
try {
|
|
1463
|
+
parsedArgs = parseArguments(vercelArgs, flagsSpecification);
|
|
1464
|
+
} catch (error) {
|
|
1465
|
+
printError(error);
|
|
1466
|
+
return 1;
|
|
1467
|
+
}
|
|
1468
|
+
if (userCommand.length === 0) {
|
|
1469
|
+
output_manager_default.error(
|
|
1470
|
+
`No command provided. Use \`--\` to separate vercel flags from your command.`
|
|
1471
|
+
);
|
|
1472
|
+
return 1;
|
|
1473
|
+
}
|
|
1474
|
+
const link = await getLinkedProject(client);
|
|
1475
|
+
if (link.status === "error") {
|
|
1476
|
+
return link.exitCode;
|
|
1477
|
+
} else if (link.status === "not_linked") {
|
|
1478
|
+
output_manager_default.error(
|
|
1479
|
+
`Your codebase isn't linked to a project on Vercel. Run ${getCommandName(
|
|
1480
|
+
"link"
|
|
1481
|
+
)} to begin.`
|
|
1482
|
+
);
|
|
1483
|
+
return 1;
|
|
1484
|
+
}
|
|
1485
|
+
client.config.currentTeam = link.org.type === "team" ? link.org.id : void 0;
|
|
1486
|
+
const environment = parseTarget({
|
|
1487
|
+
flagName: "environment",
|
|
1488
|
+
flags: parsedArgs.flags
|
|
1489
|
+
}) || "development";
|
|
1490
|
+
const gitBranch = parsedArgs.flags["--git-branch"];
|
|
1491
|
+
output_manager_default.spinner(`Downloading \`${environment}\` Environment Variables`);
|
|
1492
|
+
const records = await pullEnvRecords(
|
|
1493
|
+
client,
|
|
1494
|
+
link.project.id,
|
|
1495
|
+
"vercel-cli:env:run",
|
|
1496
|
+
{
|
|
1497
|
+
target: environment,
|
|
1498
|
+
gitBranch
|
|
1499
|
+
}
|
|
1500
|
+
);
|
|
1501
|
+
output_manager_default.stopSpinner();
|
|
1502
|
+
output_manager_default.debug(
|
|
1503
|
+
`Running command with ${Object.keys(records.env).length} environment variables`
|
|
1504
|
+
);
|
|
1505
|
+
let localEnv = {};
|
|
1506
|
+
try {
|
|
1507
|
+
localEnv = (0, import_env.loadEnvConfig)(client.cwd, true).combinedEnv;
|
|
1508
|
+
} catch (err) {
|
|
1509
|
+
output_manager_default.debug(`Failed to load local env files: ${err}`);
|
|
1510
|
+
}
|
|
1511
|
+
try {
|
|
1512
|
+
const result = await (0, import_execa.default)(userCommand[0], userCommand.slice(1), {
|
|
1513
|
+
cwd: client.cwd,
|
|
1514
|
+
stdio: "inherit",
|
|
1515
|
+
reject: false,
|
|
1516
|
+
env: {
|
|
1517
|
+
...records.env,
|
|
1518
|
+
...localEnv,
|
|
1519
|
+
...process.env
|
|
1520
|
+
}
|
|
1521
|
+
});
|
|
1522
|
+
if (result instanceof Error && typeof result.exitCode !== "number") {
|
|
1523
|
+
output_manager_default.prettyError(result);
|
|
1524
|
+
return 1;
|
|
1525
|
+
}
|
|
1526
|
+
return result.exitCode;
|
|
1527
|
+
} catch (err) {
|
|
1528
|
+
output_manager_default.prettyError(err);
|
|
1529
|
+
return 1;
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
// src/commands/env/update.ts
|
|
1534
|
+
var import_chalk4 = __toESM(require_source(), 1);
|
|
1535
|
+
|
|
1536
|
+
// src/util/env/update-env-record.ts
|
|
1537
|
+
var import_constants2 = __toESM(require_dist2(), 1);
|
|
1538
|
+
async function updateEnvRecord(client, projectId, envId, type, key, value, targets, gitBranch) {
|
|
1539
|
+
output_manager_default.debug(
|
|
1540
|
+
`Updating ${type} Environment Variable ${key} in ${targets.length} targets`
|
|
1541
|
+
);
|
|
1542
|
+
const target = [];
|
|
1543
|
+
const customEnvironmentIds = [];
|
|
1544
|
+
for (const t of targets) {
|
|
1545
|
+
const arr = import_constants2.PROJECT_ENV_TARGET.includes(t) ? target : customEnvironmentIds;
|
|
1546
|
+
arr.push(t);
|
|
1547
|
+
}
|
|
1548
|
+
const body = {
|
|
1549
|
+
type,
|
|
1550
|
+
key,
|
|
1551
|
+
value,
|
|
1552
|
+
target,
|
|
1553
|
+
customEnvironmentIds: customEnvironmentIds.length > 0 ? customEnvironmentIds : void 0,
|
|
1554
|
+
gitBranch: gitBranch || void 0
|
|
1555
|
+
};
|
|
1556
|
+
const url = `/v10/projects/${projectId}/env/${envId}`;
|
|
1557
|
+
await client.fetch(url, {
|
|
1558
|
+
method: "PATCH",
|
|
1559
|
+
body
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
// src/util/telemetry/commands/env/update.ts
|
|
1564
|
+
var EnvUpdateTelemetryClient = class extends TelemetryClient {
|
|
1565
|
+
trackCliArgumentName(name) {
|
|
1566
|
+
if (name) {
|
|
1567
|
+
this.trackCliArgument({
|
|
1568
|
+
arg: "name",
|
|
1569
|
+
value: this.redactedValue
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
trackCliArgumentEnvironment(environment) {
|
|
1574
|
+
if (environment) {
|
|
1575
|
+
this.trackCliArgument({
|
|
1576
|
+
arg: "environment",
|
|
1577
|
+
value: STANDARD_ENVIRONMENTS.includes(
|
|
1578
|
+
environment
|
|
1579
|
+
) ? environment : this.redactedValue
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
trackCliArgumentGitBranch(gitBranch) {
|
|
1584
|
+
if (gitBranch) {
|
|
1585
|
+
this.trackCliArgument({
|
|
1586
|
+
arg: "git-branch",
|
|
1587
|
+
value: this.redactedValue
|
|
1588
|
+
});
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
trackCliFlagSensitive(sensitive) {
|
|
1592
|
+
if (sensitive) {
|
|
1593
|
+
this.trackCliFlag("sensitive");
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
trackCliFlagYes(yes) {
|
|
1597
|
+
if (yes) {
|
|
1598
|
+
this.trackCliFlag("yes");
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
trackCliOptionValue(value) {
|
|
1602
|
+
if (value) {
|
|
1603
|
+
this.trackCliOption({
|
|
1604
|
+
option: "value",
|
|
1605
|
+
value: this.redactedValue
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
};
|
|
1610
|
+
|
|
1611
|
+
// src/commands/env/update.ts
|
|
1612
|
+
async function update(client, argv) {
|
|
1613
|
+
let parsedArgs;
|
|
1614
|
+
const flagsSpecification = getFlagsSpecification(updateSubcommand.options);
|
|
1615
|
+
try {
|
|
1616
|
+
parsedArgs = parseArguments(argv, flagsSpecification);
|
|
1617
|
+
} catch (err) {
|
|
1618
|
+
if (client.nonInteractive) {
|
|
1619
|
+
outputAgentError(
|
|
1620
|
+
client,
|
|
1621
|
+
{
|
|
1622
|
+
status: "error",
|
|
1623
|
+
reason: "invalid_arguments",
|
|
1624
|
+
message: err instanceof Error ? err.message : String(err)
|
|
1625
|
+
},
|
|
1626
|
+
1
|
|
1627
|
+
);
|
|
1628
|
+
}
|
|
1629
|
+
printError(err);
|
|
1630
|
+
return 1;
|
|
1631
|
+
}
|
|
1632
|
+
const { args, flags: opts } = parsedArgs;
|
|
1633
|
+
const valueFromFlag = typeof opts["--value"] === "string" ? opts["--value"] : void 0;
|
|
1634
|
+
const stdInput = await readStandardInput(client.stdin);
|
|
1635
|
+
let [envName, envTargetArg, envGitBranch] = args;
|
|
1636
|
+
const telemetryClient = new EnvUpdateTelemetryClient({
|
|
1637
|
+
opts: {
|
|
1638
|
+
store: client.telemetryEventStore
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
telemetryClient.trackCliArgumentName(envName);
|
|
1642
|
+
telemetryClient.trackCliArgumentEnvironment(envTargetArg);
|
|
1643
|
+
telemetryClient.trackCliArgumentGitBranch(envGitBranch);
|
|
1644
|
+
telemetryClient.trackCliFlagSensitive(opts["--sensitive"]);
|
|
1645
|
+
telemetryClient.trackCliFlagYes(opts["--yes"]);
|
|
1646
|
+
telemetryClient.trackCliOptionValue(valueFromFlag);
|
|
1647
|
+
if (args.length > 3) {
|
|
1648
|
+
if (client.nonInteractive) {
|
|
1649
|
+
outputAgentError(
|
|
1650
|
+
client,
|
|
1651
|
+
{
|
|
1652
|
+
status: "error",
|
|
1653
|
+
reason: "invalid_arguments",
|
|
1654
|
+
message: `Invalid number of arguments. Usage: ${getCommandNamePlain(
|
|
1655
|
+
`env update <name> ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
1656
|
+
)}`
|
|
1657
|
+
},
|
|
1658
|
+
1
|
|
1659
|
+
);
|
|
1660
|
+
}
|
|
1661
|
+
output_manager_default.error(
|
|
1662
|
+
`Invalid number of arguments. Usage: ${getCommandName(
|
|
1663
|
+
`env update <name> ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
1664
|
+
)}`
|
|
1665
|
+
);
|
|
1666
|
+
return 1;
|
|
1667
|
+
}
|
|
1668
|
+
if (stdInput && (!envName || !envTargetArg)) {
|
|
1669
|
+
output_manager_default.error(
|
|
1670
|
+
`Invalid number of arguments. Usage: ${getCommandName(
|
|
1671
|
+
`env update <name> <target> <gitbranch> < <file>`
|
|
1672
|
+
)}`
|
|
1673
|
+
);
|
|
1674
|
+
return 1;
|
|
1675
|
+
}
|
|
1676
|
+
if (client.nonInteractive) {
|
|
1677
|
+
const missing = [];
|
|
1678
|
+
if (!envName)
|
|
1679
|
+
missing.push("missing_name");
|
|
1680
|
+
if (!stdInput && valueFromFlag === void 0)
|
|
1681
|
+
missing.push("missing_value");
|
|
1682
|
+
if (missing.length > 0) {
|
|
1683
|
+
const parts = missing.map(
|
|
1684
|
+
(m) => m === "missing_name" ? "name" : "--value or stdin"
|
|
1685
|
+
);
|
|
1686
|
+
const targetPart = envTargetArg || getEnvTargetPlaceholder();
|
|
1687
|
+
const branchPart = envTargetArg === "preview" || envTargetArg === "development" ? " <gitbranch>" : "";
|
|
1688
|
+
const template = `env update ${envName || "<name>"} ${targetPart}${branchPart} --value <value> --yes`;
|
|
1689
|
+
outputActionRequired(
|
|
1690
|
+
client,
|
|
1691
|
+
{
|
|
1692
|
+
status: "action_required",
|
|
1693
|
+
reason: "missing_requirements",
|
|
1694
|
+
missing,
|
|
1695
|
+
message: `Provide all required inputs for non-interactive mode: ${parts.join("; ")}. Example: ${getCommandNamePlain(template)}`,
|
|
1696
|
+
next: [
|
|
1697
|
+
{
|
|
1698
|
+
command: buildEnvUpdateCommandWithPreservedArgs(
|
|
1699
|
+
client.argv,
|
|
1700
|
+
template
|
|
1701
|
+
)
|
|
1702
|
+
}
|
|
1703
|
+
]
|
|
1704
|
+
},
|
|
1705
|
+
1
|
|
1706
|
+
);
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
const envTargets = [];
|
|
1710
|
+
if (envTargetArg) {
|
|
1711
|
+
envTargets.push(envTargetArg);
|
|
1712
|
+
}
|
|
1713
|
+
if (!envName) {
|
|
1714
|
+
if (client.nonInteractive) {
|
|
1715
|
+
outputActionRequired(
|
|
1716
|
+
client,
|
|
1717
|
+
{
|
|
1718
|
+
status: "action_required",
|
|
1719
|
+
reason: "missing_name",
|
|
1720
|
+
message: "Provide the variable name as an argument. Example: vercel env update <name>",
|
|
1721
|
+
next: [
|
|
1722
|
+
{
|
|
1723
|
+
command: buildEnvUpdateCommandWithPreservedArgs(
|
|
1724
|
+
client.argv,
|
|
1725
|
+
`env update <name> ${getEnvTargetPlaceholder()} --value <value> --yes`
|
|
1726
|
+
)
|
|
1727
|
+
}
|
|
1728
|
+
]
|
|
1729
|
+
},
|
|
1730
|
+
1
|
|
1731
|
+
);
|
|
1732
|
+
} else {
|
|
1733
|
+
envName = await client.input.text({
|
|
1734
|
+
message: `What's the name of the variable to update?`,
|
|
1735
|
+
validate: (val) => val ? true : "Name cannot be empty"
|
|
1736
|
+
});
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
const link = await getLinkedProject(client);
|
|
1740
|
+
if (link.status === "error") {
|
|
1741
|
+
return link.exitCode;
|
|
1742
|
+
} else if (link.status === "not_linked") {
|
|
1743
|
+
if (client.nonInteractive) {
|
|
1744
|
+
const preserved = getPreservedArgsForEnvUpdate(client.argv).filter(
|
|
1745
|
+
(a) => a !== "--yes" && a !== "-y"
|
|
1746
|
+
);
|
|
1747
|
+
const linkArgv = [
|
|
1748
|
+
...client.argv.slice(0, 2),
|
|
1749
|
+
"link",
|
|
1750
|
+
"--scope",
|
|
1751
|
+
"<scope>",
|
|
1752
|
+
...preserved
|
|
1753
|
+
];
|
|
1754
|
+
outputAgentError(
|
|
1755
|
+
client,
|
|
1756
|
+
{
|
|
1757
|
+
status: "error",
|
|
1758
|
+
reason: "not_linked",
|
|
1759
|
+
message: `Your codebase isn't linked to a project on Vercel. Run ${getCommandNamePlain(
|
|
1760
|
+
"link"
|
|
1761
|
+
)} to begin. Use --yes for non-interactive; use --scope or --project to specify team or project.`,
|
|
1762
|
+
next: [
|
|
1763
|
+
{ command: buildCommandWithYes(linkArgv) },
|
|
1764
|
+
{ command: buildCommandWithYes(client.argv) }
|
|
1765
|
+
]
|
|
1766
|
+
},
|
|
1767
|
+
1
|
|
1768
|
+
);
|
|
1769
|
+
}
|
|
1770
|
+
output_manager_default.error(
|
|
1771
|
+
`Your codebase isn't linked to a project on Vercel. Run ${getCommandName(
|
|
1772
|
+
"link"
|
|
1773
|
+
)} to begin.`
|
|
1774
|
+
);
|
|
1775
|
+
return 1;
|
|
1776
|
+
}
|
|
1777
|
+
client.config.currentTeam = link.org.type === "team" ? link.org.id : void 0;
|
|
1778
|
+
const { project } = link;
|
|
1779
|
+
const [{ envs }, customEnvironments] = await Promise.all([
|
|
1780
|
+
getEnvRecords(client, project.id, "vercel-cli:env:update"),
|
|
1781
|
+
getCustomEnvironments(client, project.id)
|
|
1782
|
+
]);
|
|
1783
|
+
const matchingEnvs = envs.filter((r) => r.key === envName);
|
|
1784
|
+
if (matchingEnvs.length === 0) {
|
|
1785
|
+
if (client.nonInteractive) {
|
|
1786
|
+
outputAgentError(
|
|
1787
|
+
client,
|
|
1788
|
+
{
|
|
1789
|
+
status: "error",
|
|
1790
|
+
reason: "env_not_found",
|
|
1791
|
+
message: `The variable ${envName} was not found. Run ${getCommandNamePlain(
|
|
1792
|
+
"env ls"
|
|
1793
|
+
)} to see all available Environment Variables.`
|
|
1794
|
+
},
|
|
1795
|
+
1
|
|
1796
|
+
);
|
|
1797
|
+
}
|
|
1798
|
+
output_manager_default.error(
|
|
1799
|
+
`The variable ${param(envName)} was not found. Run ${getCommandName(
|
|
1800
|
+
`env ls`
|
|
1801
|
+
)} to see all available Environment Variables.`
|
|
1802
|
+
);
|
|
1803
|
+
return 1;
|
|
1804
|
+
}
|
|
1805
|
+
let selectedEnv;
|
|
1806
|
+
if (envTargetArg || envGitBranch) {
|
|
1807
|
+
const filteredEnvs = matchingEnvs.filter((env) => {
|
|
1808
|
+
const matchesTarget = !envTargetArg || (Array.isArray(env.target) ? env.target.includes(envTargetArg) : env.target === envTargetArg) || env.customEnvironmentIds && env.customEnvironmentIds.includes(envTargetArg);
|
|
1809
|
+
const matchesGitBranch = !envGitBranch || env.gitBranch === envGitBranch;
|
|
1810
|
+
return matchesTarget && matchesGitBranch;
|
|
1811
|
+
});
|
|
1812
|
+
if (filteredEnvs.length === 0) {
|
|
1813
|
+
if (client.nonInteractive) {
|
|
1814
|
+
outputAgentError(
|
|
1815
|
+
client,
|
|
1816
|
+
{
|
|
1817
|
+
status: "error",
|
|
1818
|
+
reason: "env_not_found",
|
|
1819
|
+
message: `No Environment Variable ${envName} found matching the specified target/branch.`
|
|
1820
|
+
},
|
|
1821
|
+
1
|
|
1822
|
+
);
|
|
1823
|
+
}
|
|
1824
|
+
output_manager_default.error(
|
|
1825
|
+
`No Environment Variable ${param(envName)} found matching the specified criteria.`
|
|
1826
|
+
);
|
|
1827
|
+
return 1;
|
|
1828
|
+
}
|
|
1829
|
+
if (filteredEnvs.length === 1) {
|
|
1830
|
+
selectedEnv = filteredEnvs[0];
|
|
1831
|
+
} else {
|
|
1832
|
+
if (client.nonInteractive) {
|
|
1833
|
+
outputActionRequired(
|
|
1834
|
+
client,
|
|
1835
|
+
{
|
|
1836
|
+
status: "action_required",
|
|
1837
|
+
reason: "multiple_envs",
|
|
1838
|
+
message: `Multiple Environment Variables match ${envName}. Specify target and/or branch to update one.`,
|
|
1839
|
+
next: [
|
|
1840
|
+
{
|
|
1841
|
+
command: buildEnvUpdateCommandWithPreservedArgs(
|
|
1842
|
+
client.argv,
|
|
1843
|
+
`env update ${envName} ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
1844
|
+
)
|
|
1845
|
+
}
|
|
1846
|
+
]
|
|
1847
|
+
},
|
|
1848
|
+
1
|
|
1849
|
+
);
|
|
1850
|
+
}
|
|
1851
|
+
const choices = filteredEnvs.map((env, index) => {
|
|
1852
|
+
const targets2 = formatEnvironments(link, env, customEnvironments);
|
|
1853
|
+
return {
|
|
1854
|
+
name: targets2,
|
|
1855
|
+
value: index
|
|
1856
|
+
};
|
|
1857
|
+
});
|
|
1858
|
+
const selectedIndex = await client.input.select({
|
|
1859
|
+
message: `Multiple Environment Variables found for ${param(envName)}. Which one do you want to update?`,
|
|
1860
|
+
choices
|
|
1861
|
+
});
|
|
1862
|
+
selectedEnv = filteredEnvs[selectedIndex];
|
|
1863
|
+
}
|
|
1864
|
+
} else if (matchingEnvs.length === 1) {
|
|
1865
|
+
selectedEnv = matchingEnvs[0];
|
|
1866
|
+
} else {
|
|
1867
|
+
if (client.nonInteractive) {
|
|
1868
|
+
outputActionRequired(
|
|
1869
|
+
client,
|
|
1870
|
+
{
|
|
1871
|
+
status: "action_required",
|
|
1872
|
+
reason: "multiple_envs",
|
|
1873
|
+
message: `Multiple Environment Variables match ${envName}. Specify target and/or branch to update one.`,
|
|
1874
|
+
next: [
|
|
1875
|
+
{
|
|
1876
|
+
command: buildEnvUpdateCommandWithPreservedArgs(
|
|
1877
|
+
client.argv,
|
|
1878
|
+
`env update ${envName} ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
1879
|
+
)
|
|
1880
|
+
}
|
|
1881
|
+
]
|
|
1882
|
+
},
|
|
1883
|
+
1
|
|
1884
|
+
);
|
|
1885
|
+
}
|
|
1886
|
+
const choices = matchingEnvs.map((env, index) => {
|
|
1887
|
+
const targets2 = formatEnvironments(link, env, customEnvironments);
|
|
1888
|
+
return {
|
|
1889
|
+
name: targets2,
|
|
1890
|
+
value: index
|
|
1891
|
+
};
|
|
1892
|
+
});
|
|
1893
|
+
const selectedIndex = await client.input.select({
|
|
1894
|
+
message: `Multiple Environment Variables found for ${param(envName)}. Which one do you want to update?`,
|
|
1895
|
+
choices
|
|
1896
|
+
});
|
|
1897
|
+
selectedEnv = matchingEnvs[selectedIndex];
|
|
1898
|
+
}
|
|
1899
|
+
let envValue;
|
|
1900
|
+
if (stdInput) {
|
|
1901
|
+
envValue = stdInput;
|
|
1902
|
+
} else if (valueFromFlag !== void 0) {
|
|
1903
|
+
envValue = valueFromFlag;
|
|
1904
|
+
} else {
|
|
1905
|
+
if (client.nonInteractive) {
|
|
1906
|
+
const branchPart = envTargetArg === "preview" || envTargetArg === "development" ? " <gitbranch>" : "";
|
|
1907
|
+
const targetPart = envTargetArg || getEnvTargetPlaceholder();
|
|
1908
|
+
outputActionRequired(
|
|
1909
|
+
client,
|
|
1910
|
+
{
|
|
1911
|
+
status: "action_required",
|
|
1912
|
+
reason: "missing_value",
|
|
1913
|
+
message: "In non-interactive mode provide the new value via --value or stdin. Example: vercel env update <name> <environment> --value 'value' --yes",
|
|
1914
|
+
next: [
|
|
1915
|
+
{
|
|
1916
|
+
command: buildEnvUpdateCommandWithPreservedArgs(
|
|
1917
|
+
client.argv,
|
|
1918
|
+
`env update ${envName} ${targetPart}${branchPart} --value <value> --yes`
|
|
1919
|
+
)
|
|
1920
|
+
}
|
|
1921
|
+
]
|
|
1922
|
+
},
|
|
1923
|
+
1
|
|
1924
|
+
);
|
|
1925
|
+
}
|
|
1926
|
+
envValue = await client.input.text({
|
|
1927
|
+
message: `What's the new value of ${envName}?`
|
|
1928
|
+
});
|
|
1929
|
+
}
|
|
1930
|
+
const skipConfirm = opts["--yes"] || !!stdInput || valueFromFlag !== void 0;
|
|
1931
|
+
const { finalValue, alreadyConfirmed } = await validateEnvValue({
|
|
1932
|
+
envName,
|
|
1933
|
+
initialValue: envValue,
|
|
1934
|
+
skipConfirm,
|
|
1935
|
+
promptForValue: () => client.input.text({ message: `What's the new value of ${envName}?` }),
|
|
1936
|
+
selectAction: (choices) => client.input.select({ message: "How to proceed?", choices }),
|
|
1937
|
+
showWarning: (msg) => output_manager_default.warn(msg),
|
|
1938
|
+
showLog: (msg) => output_manager_default.log(msg)
|
|
1939
|
+
});
|
|
1940
|
+
if (!opts["--yes"] && !alreadyConfirmed) {
|
|
1941
|
+
if (client.nonInteractive) {
|
|
1942
|
+
outputActionRequired(
|
|
1943
|
+
client,
|
|
1944
|
+
{
|
|
1945
|
+
status: "action_required",
|
|
1946
|
+
reason: "confirmation_required",
|
|
1947
|
+
message: `Updating Environment Variable ${envName}. Use --yes to confirm.`,
|
|
1948
|
+
next: [{ command: buildCommandWithYes(client.argv) }]
|
|
1949
|
+
},
|
|
1950
|
+
1
|
|
1951
|
+
);
|
|
1952
|
+
}
|
|
1953
|
+
const currentTargets = formatEnvironments(
|
|
1954
|
+
link,
|
|
1955
|
+
selectedEnv,
|
|
1956
|
+
customEnvironments
|
|
1957
|
+
);
|
|
1958
|
+
const confirmed = await client.input.confirm(
|
|
1959
|
+
`Updating Environment Variable ${param(envName)} in ${currentTargets} in Project ${import_chalk4.default.bold(project.name)}. Are you sure?`,
|
|
1960
|
+
false
|
|
1961
|
+
);
|
|
1962
|
+
if (!confirmed) {
|
|
1963
|
+
output_manager_default.log("Canceled");
|
|
1964
|
+
return 0;
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
const type = opts["--sensitive"] ? "sensitive" : selectedEnv.type;
|
|
1968
|
+
const targets = Array.isArray(selectedEnv.target) ? selectedEnv.target : [selectedEnv.target].filter(
|
|
1969
|
+
(r) => Boolean(r)
|
|
1970
|
+
);
|
|
1971
|
+
const allTargets = [...targets, ...selectedEnv.customEnvironmentIds || []];
|
|
1972
|
+
const updateStamp = stamp_default();
|
|
1973
|
+
try {
|
|
1974
|
+
output_manager_default.spinner("Updating");
|
|
1975
|
+
await updateEnvRecord(
|
|
1976
|
+
client,
|
|
1977
|
+
project.id,
|
|
1978
|
+
selectedEnv.id,
|
|
1979
|
+
type,
|
|
1980
|
+
envName,
|
|
1981
|
+
finalValue,
|
|
1982
|
+
allTargets,
|
|
1983
|
+
selectedEnv.gitBranch || ""
|
|
1984
|
+
);
|
|
1985
|
+
} catch (err) {
|
|
1986
|
+
if (client.nonInteractive && isAPIError(err)) {
|
|
1987
|
+
const reason = err.slug || (err.serverMessage?.toLowerCase().includes("branch") ? "branch_not_found" : "api_error");
|
|
1988
|
+
outputAgentError(
|
|
1989
|
+
client,
|
|
1990
|
+
{
|
|
1991
|
+
status: "error",
|
|
1992
|
+
reason,
|
|
1993
|
+
message: err.serverMessage
|
|
1994
|
+
},
|
|
1995
|
+
1
|
|
1996
|
+
);
|
|
1997
|
+
}
|
|
1998
|
+
if (isAPIError(err) && isKnownError(err)) {
|
|
1999
|
+
output_manager_default.error(err.serverMessage);
|
|
2000
|
+
return 1;
|
|
2001
|
+
}
|
|
2002
|
+
throw err;
|
|
2003
|
+
}
|
|
2004
|
+
output_manager_default.print(
|
|
2005
|
+
`${prependEmoji(
|
|
2006
|
+
`Updated Environment Variable ${import_chalk4.default.bold(envName)} in Project ${import_chalk4.default.bold(
|
|
2007
|
+
project.name
|
|
2008
|
+
)} ${import_chalk4.default.gray(updateStamp())}`,
|
|
2009
|
+
emoji("success")
|
|
2010
|
+
)}
|
|
2011
|
+
`
|
|
2012
|
+
);
|
|
2013
|
+
return 0;
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
// src/util/telemetry/commands/env/index.ts
|
|
2017
|
+
var EnvTelemetryClient = class extends TelemetryClient {
|
|
2018
|
+
trackCliSubcommandList(actual) {
|
|
2019
|
+
this.trackCliSubcommand({
|
|
2020
|
+
subcommand: "ls",
|
|
2021
|
+
value: actual
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
trackCliSubcommandAdd(actual) {
|
|
2025
|
+
this.trackCliSubcommand({
|
|
2026
|
+
subcommand: "add",
|
|
2027
|
+
value: actual
|
|
2028
|
+
});
|
|
2029
|
+
}
|
|
2030
|
+
trackCliSubcommandRemove(actual) {
|
|
2031
|
+
this.trackCliSubcommand({
|
|
2032
|
+
subcommand: "rm",
|
|
2033
|
+
value: actual
|
|
2034
|
+
});
|
|
2035
|
+
}
|
|
2036
|
+
trackCliSubcommandPull(actual) {
|
|
2037
|
+
this.trackCliSubcommand({
|
|
2038
|
+
subcommand: "pull",
|
|
2039
|
+
value: actual
|
|
2040
|
+
});
|
|
2041
|
+
}
|
|
2042
|
+
trackCliSubcommandRun(actual) {
|
|
2043
|
+
this.trackCliSubcommand({
|
|
2044
|
+
subcommand: "run",
|
|
2045
|
+
value: actual
|
|
2046
|
+
});
|
|
2047
|
+
}
|
|
2048
|
+
trackCliSubcommandUpdate(actual) {
|
|
2049
|
+
this.trackCliSubcommand({
|
|
2050
|
+
subcommand: "update",
|
|
2051
|
+
value: actual
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
2054
|
+
};
|
|
2055
|
+
|
|
2056
|
+
// src/commands/env/index.ts
|
|
2057
|
+
var COMMAND_CONFIG = {
|
|
2058
|
+
ls: getCommandAliases(listSubcommand),
|
|
2059
|
+
add: getCommandAliases(addSubcommand),
|
|
2060
|
+
rm: getCommandAliases(removeSubcommand),
|
|
2061
|
+
pull: getCommandAliases(pullSubcommand),
|
|
2062
|
+
run: getCommandAliases(runSubcommand),
|
|
2063
|
+
update: getCommandAliases(updateSubcommand)
|
|
2064
|
+
};
|
|
2065
|
+
async function main(client) {
|
|
2066
|
+
const telemetry = new EnvTelemetryClient({
|
|
2067
|
+
opts: {
|
|
2068
|
+
store: client.telemetryEventStore
|
|
2069
|
+
}
|
|
2070
|
+
});
|
|
2071
|
+
let parsedArgs;
|
|
2072
|
+
const flagsSpecification = getFlagsSpecification(envCommand.options);
|
|
2073
|
+
try {
|
|
2074
|
+
parsedArgs = parseArguments(client.argv.slice(2), flagsSpecification, {
|
|
2075
|
+
permissive: true
|
|
2076
|
+
});
|
|
2077
|
+
} catch (err) {
|
|
2078
|
+
printError(err);
|
|
2079
|
+
return 1;
|
|
2080
|
+
}
|
|
2081
|
+
const subArgs = parsedArgs.args.slice(1);
|
|
2082
|
+
const { subcommand, args, subcommandOriginal } = getSubcommand(
|
|
2083
|
+
subArgs,
|
|
2084
|
+
COMMAND_CONFIG
|
|
2085
|
+
);
|
|
2086
|
+
const needHelp = parsedArgs.flags["--help"];
|
|
2087
|
+
if (!subcommand && needHelp) {
|
|
2088
|
+
telemetry.trackCliFlagHelp("env", subcommand);
|
|
2089
|
+
output_manager_default.print(help(envCommand, { columns: client.stderr.columns }));
|
|
2090
|
+
return 2;
|
|
2091
|
+
}
|
|
2092
|
+
function printHelp(command) {
|
|
2093
|
+
output_manager_default.print(
|
|
2094
|
+
help(command, { parent: envCommand, columns: client.stderr.columns })
|
|
2095
|
+
);
|
|
2096
|
+
}
|
|
2097
|
+
switch (subcommand) {
|
|
2098
|
+
case "ls":
|
|
2099
|
+
if (needHelp) {
|
|
2100
|
+
telemetry.trackCliFlagHelp("env", subcommandOriginal);
|
|
2101
|
+
printHelp(listSubcommand);
|
|
2102
|
+
return 2;
|
|
2103
|
+
}
|
|
2104
|
+
telemetry.trackCliSubcommandList(subcommandOriginal);
|
|
2105
|
+
return ls(client, args);
|
|
2106
|
+
case "add":
|
|
2107
|
+
if (needHelp) {
|
|
2108
|
+
telemetry.trackCliFlagHelp("env", subcommandOriginal);
|
|
2109
|
+
printHelp(addSubcommand);
|
|
2110
|
+
return 2;
|
|
2111
|
+
}
|
|
2112
|
+
telemetry.trackCliSubcommandAdd(subcommandOriginal);
|
|
2113
|
+
return add(client, args);
|
|
2114
|
+
case "rm":
|
|
2115
|
+
if (needHelp) {
|
|
2116
|
+
telemetry.trackCliFlagHelp("env", subcommandOriginal);
|
|
2117
|
+
printHelp(removeSubcommand);
|
|
2118
|
+
return 2;
|
|
2119
|
+
}
|
|
2120
|
+
telemetry.trackCliSubcommandRemove(subcommandOriginal);
|
|
2121
|
+
return rm(client, args);
|
|
2122
|
+
case "pull":
|
|
2123
|
+
if (needHelp) {
|
|
2124
|
+
telemetry.trackCliFlagHelp("env", subcommandOriginal);
|
|
2125
|
+
printHelp(pullSubcommand);
|
|
2126
|
+
return 2;
|
|
2127
|
+
}
|
|
2128
|
+
telemetry.trackCliSubcommandPull(subcommandOriginal);
|
|
2129
|
+
return pull(client, args);
|
|
2130
|
+
case "run":
|
|
2131
|
+
if (needsHelpForRun(client)) {
|
|
2132
|
+
telemetry.trackCliFlagHelp("env", subcommandOriginal);
|
|
2133
|
+
printHelp(runSubcommand);
|
|
2134
|
+
return 2;
|
|
2135
|
+
}
|
|
2136
|
+
telemetry.trackCliSubcommandRun(subcommandOriginal);
|
|
2137
|
+
return run(client);
|
|
2138
|
+
case "update":
|
|
2139
|
+
if (needHelp) {
|
|
2140
|
+
telemetry.trackCliFlagHelp("env", subcommandOriginal);
|
|
2141
|
+
printHelp(updateSubcommand);
|
|
2142
|
+
return 2;
|
|
2143
|
+
}
|
|
2144
|
+
telemetry.trackCliSubcommandUpdate(subcommandOriginal);
|
|
2145
|
+
return update(client, args);
|
|
2146
|
+
default:
|
|
2147
|
+
output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG));
|
|
2148
|
+
output_manager_default.print(help(envCommand, { columns: client.stderr.columns }));
|
|
2149
|
+
return 2;
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
export {
|
|
2153
|
+
main as default
|
|
2154
|
+
};
|