vercel 59.4.0 → 59.6.2
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/dist/chunks/{add-FQMB3XPM.js → add-4GQZ22ZN.js} +20 -16
- package/dist/chunks/{add-73X2SKBH.js → add-HJSEM4YJ.js} +17 -13
- package/dist/chunks/{add-QJ3WT4FW.js → add-SIGUSM3Y.js} +21 -17
- package/dist/chunks/{build-YUYCLCXD.js → build-XOMJDX4M.js} +18 -15
- package/dist/chunks/{chunk-F7OXZLY2.js → chunk-26XDDLXM.js} +2 -2
- package/dist/chunks/{chunk-VCE6QKFE.js → chunk-2O5J3KMT.js} +4 -4
- package/dist/chunks/{chunk-XI6NJLI4.js → chunk-2YRAWYGE.js} +3 -3
- package/dist/chunks/{chunk-X6O6XJEA.js → chunk-37V5P4VO.js} +16 -14
- package/dist/chunks/{chunk-EB7NJKPL.js → chunk-3F5EGINT.js} +3 -3
- package/dist/chunks/{chunk-RIB4S2IB.js → chunk-3HZLXCVL.js} +1 -1
- package/dist/chunks/{chunk-KQRVZWJU.js → chunk-3T7WSWZH.js} +1 -1
- package/dist/chunks/{chunk-3KNPVXJ3.js → chunk-4KD5BYHB.js} +1 -1
- package/dist/chunks/{chunk-XLKFJPMT.js → chunk-57RHXXXG.js} +1 -1
- package/dist/chunks/chunk-5GGUB4EO.js +31 -0
- package/dist/chunks/{chunk-R6IGDGX3.js → chunk-5XECIWME.js} +1 -1
- package/dist/chunks/{chunk-KAYSW4CJ.js → chunk-6JPVTPTU.js} +3 -3
- package/dist/chunks/{chunk-ZFWNMVNR.js → chunk-6M2KZUED.js} +19 -8
- package/dist/chunks/{chunk-HT2XWSAJ.js → chunk-7AEEQOD4.js} +2 -29
- package/dist/chunks/{chunk-HURL5EBN.js → chunk-7HE63HCR.js} +124 -161
- package/dist/chunks/chunk-7Q45OKWR.js +149 -0
- package/dist/chunks/{chunk-RI7KKKII.js → chunk-7R6M3BHM.js} +4 -18
- package/dist/chunks/{chunk-XBN2O34P.js → chunk-7ST552E3.js} +17 -4
- package/dist/chunks/{chunk-JKQWQA2T.js → chunk-AINIBIP4.js} +1 -1
- package/dist/chunks/{chunk-CV4S27SS.js → chunk-ASBP32T6.js} +1 -1
- package/dist/chunks/chunk-AYLY3ZVL.js +104 -0
- package/dist/chunks/{chunk-SOFC4MLS.js → chunk-BMKU5KEL.js} +9 -569
- package/dist/chunks/{chunk-KDYRLN6H.js → chunk-C5HKWXRR.js} +1 -1
- package/dist/chunks/{chunk-2MF3ZAVW.js → chunk-CJV7J7B5.js} +6 -6
- package/dist/chunks/{chunk-HJVTLJHO.js → chunk-DE7MBNHQ.js} +6 -6
- package/dist/chunks/{chunk-3L2YLLHC.js → chunk-DWIC7MRV.js} +2 -2
- package/dist/chunks/{chunk-GFCTRJI5.js → chunk-EZKW5YJ2.js} +1 -1
- package/dist/chunks/{chunk-MWYQ24FO.js → chunk-FRAXI2WT.js} +3 -3
- package/dist/chunks/{chunk-DDIZGOCK.js → chunk-FRZULOVH.js} +8 -6
- package/dist/chunks/{chunk-Y3J4VU2H.js → chunk-FWKSJYDV.js} +2 -2
- package/dist/chunks/chunk-FXD67VN5.js +467 -0
- package/dist/chunks/{chunk-EB5NBVTV.js → chunk-GISTGGBO.js} +8 -8
- package/dist/chunks/chunk-GY5I4AYD.js +122 -0
- package/dist/chunks/{chunk-PD4DYNSB.js → chunk-GZQQNLF5.js} +5 -5
- package/dist/chunks/{chunk-PIMIKY4X.js → chunk-IJ4X426J.js} +1 -1
- package/dist/chunks/{chunk-KSZ4MNHO.js → chunk-JH4WQRIU.js} +2 -2
- package/dist/chunks/{chunk-TVXCXIRO.js → chunk-L3UXB2CW.js} +1 -1
- package/dist/chunks/{chunk-O5DLWLT7.js → chunk-LXZVOR6F.js} +9 -9
- package/dist/chunks/{chunk-EG5BSAXD.js → chunk-MTWHQEXI.js} +1 -1
- package/dist/chunks/{chunk-WC7IINFV.js → chunk-NFU4XJIR.js} +1 -1
- package/dist/chunks/{chunk-TH2XUVDP.js → chunk-NGGLYKNU.js} +30 -6
- package/dist/chunks/{chunk-2PX6N4FE.js → chunk-NGNN6WF2.js} +10 -10
- package/dist/chunks/{chunk-GGPE5377.js → chunk-O26N2UPI.js} +1 -1
- package/dist/chunks/chunk-O75LSD3C.js +34 -0
- package/dist/chunks/{chunk-BBSS3XIW.js → chunk-OQ3C5VXZ.js} +1 -1
- package/dist/chunks/{chunk-M22O6CYY.js → chunk-POOO7W47.js} +1 -1
- package/dist/chunks/{chunk-LKTQR5JE.js → chunk-PRH6KRUT.js} +2 -2
- package/dist/chunks/chunk-Q2DGFCO7.js +579 -0
- package/dist/chunks/{chunk-OX7KI3LF.js → chunk-QFAS4OVW.js} +18 -0
- package/dist/chunks/{chunk-CHEZBD7H.js → chunk-R5PULMHT.js} +3 -3
- package/dist/chunks/{chunk-VAFU7DXZ.js → chunk-RKDCNQ4S.js} +1 -91
- package/dist/chunks/{chunk-BLYBHFIE.js → chunk-SF3AYAIF.js} +61 -24
- package/dist/chunks/{chunk-GMWRTZVZ.js → chunk-SLPSPYVR.js} +1 -1
- package/dist/chunks/{chunk-J5Y2QGGU.js → chunk-SWI6F4X3.js} +2 -2
- package/dist/chunks/chunk-V3MDDR2X.js +249 -0
- package/dist/chunks/{chunk-HMJVUXE6.js → chunk-VJ5NAOWB.js} +867 -625
- package/dist/chunks/{chunk-O5GNPPTU.js → chunk-VP5Y3SZG.js} +1 -1
- package/dist/chunks/{chunk-G75NFPIT.js → chunk-WNAKOXGK.js} +1 -1
- package/dist/chunks/{chunk-NP6BQPCN.js → chunk-WZ2S3A2A.js} +8 -6
- package/dist/chunks/{chunk-7QVJTI5H.js → chunk-XDGOOW3K.js} +1 -1
- package/dist/chunks/{chunk-UMA66MKW.js → chunk-XM3LOQIX.js} +1 -1
- package/dist/chunks/{chunk-CYNB6LL4.js → chunk-XNFHNTS2.js} +1 -1
- package/dist/chunks/{chunk-VDJN4WKH.js → chunk-XRWOTCDO.js} +1 -1
- package/dist/chunks/{chunk-UV2ZMFVG.js → chunk-YJKZQEHS.js} +2 -2
- package/dist/chunks/{chunk-STPH4Y62.js → chunk-YJUO3EKH.js} +1 -1
- package/dist/chunks/{chunk-Y42SPI2H.js → chunk-ZNMTDLYH.js} +6 -6
- package/dist/chunks/{chunk-VLPLCJZC.js → chunk-ZSFEACZU.js} +1 -1
- package/dist/chunks/{clear-USQM5VW5.js → clear-BWT2FJY4.js} +17 -13
- package/dist/chunks/{compile-vercel-config-2JNYMI6W.js → compile-vercel-config-DGM4NISW.js} +10 -7
- package/dist/chunks/{config-VTRIDLY4.js → config-NJAN3RMU.js} +20 -16
- package/dist/chunks/config-RSE6Z4LB.js +122 -0
- package/dist/chunks/{constants-YMCRE6IG.js → constants-WEQVJSYS.js} +1 -1
- package/dist/chunks/{delete-ILLSBCVQ.js → delete-LROBRBAH.js} +15 -11
- package/dist/chunks/{delete-VTPHK3EB.js → delete-SSL2PK2F.js} +12 -9
- package/dist/chunks/{disable-VTOMO64V.js → disable-ASG5JDZR.js} +12 -9
- package/dist/chunks/{discard-ZIOZ34ZI.js → discard-PV47B6IL.js} +12 -9
- package/dist/chunks/{edit-E3AMR4KM.js → edit-5ATYIOLX.js} +14 -11
- package/dist/chunks/{edit-JMZ5XWVW.js → edit-REI7HXGG.js} +16 -12
- package/dist/chunks/{enable-A4PMZ7QZ.js → enable-LZXL7XAG.js} +12 -9
- package/dist/chunks/{exec-CNBOV577.js → exec-XH4K34JM.js} +3 -3
- package/dist/chunks/{export-Y6AJ3WRZ.js → export-ZAZFQU2E.js} +12 -9
- package/dist/chunks/{image-26BKPAUB.js → image-QPHN5V7L.js} +7 -6
- package/dist/chunks/{import-builders-3H7J2SEK.js → import-builders-W3YE2V6A.js} +12 -9
- package/dist/chunks/{inspect-7DGKYHKW.js → inspect-BFGK72WY.js} +18 -14
- package/dist/chunks/{inspect-OEY4DJRI.js → inspect-FRXJRM6T.js} +18 -14
- package/dist/chunks/{inspect-ZW5N6O5P.js → inspect-RDMC2Z3Q.js} +17 -13
- package/dist/chunks/{inspect-GJFVAZIJ.js → inspect-SJEZVGPK.js} +20 -16
- package/dist/chunks/{inspect-N3E2PO6K.js → inspect-SSOM3FXS.js} +17 -13
- package/dist/chunks/{list-MIQ5D6PM.js → list-2HTR7Q3J.js} +18 -14
- package/dist/chunks/{list-2VTCNQEB.js → list-PHDUZVMR.js} +15 -11
- package/dist/chunks/{list-DTJBW7OQ.js → list-W33GXKDA.js} +18 -14
- package/dist/chunks/{login-L34UHAU5.js → login-JWAFHVDG.js} +30 -17
- package/dist/chunks/{ls-OBUDC4SB.js → ls-3AN2DZHN.js} +20 -15
- package/dist/chunks/{ls-SXJFBLUT.js → ls-3MH2OCP3.js} +20 -15
- package/dist/chunks/ls-D2POUHI7.js +176 -0
- package/dist/chunks/{ls-VDYUFSSC.js → ls-KDFU224B.js} +20 -15
- package/dist/chunks/{ls-OKO4IHWB.js → ls-KX2VBOGV.js} +18 -14
- package/dist/chunks/{ls-NCPQY4FV.js → ls-RWKNJQNT.js} +23 -18
- package/dist/chunks/{open-V5JDGXUP.js → open-IEYRB6RL.js} +15 -11
- package/dist/chunks/{permissions-6CPRPPBY.js → permissions-ZWZUMEHR.js} +10 -9
- package/dist/chunks/{publish-R27DPHFO.js → publish-UWZYBDHK.js} +12 -9
- package/dist/chunks/{push-VLVTBS42.js → push-IAEQ3FBF.js} +18 -15
- package/dist/chunks/{query-IVVRYMJN.js → query-NNOZYSED.js} +18 -14
- package/dist/chunks/{reorder-LJ2RBZM2.js → reorder-TKBM244W.js} +12 -9
- package/dist/chunks/{reply-USAISZYC.js → reply-FLBSBMTW.js} +16 -12
- package/dist/chunks/{resolve-CRCJYVS5.js → resolve-GJYPMWUE.js} +15 -11
- package/dist/chunks/{restore-6PBPEAMU.js → restore-PNI3TM3U.js} +12 -9
- package/dist/chunks/{rm-HHELZB7R.js → rm-76CSSSSV.js} +17 -13
- package/dist/chunks/{rm-TWU3JR6Z.js → rm-FN7LTIIL.js} +17 -13
- package/dist/chunks/{rm-KGOEOWVK.js → rm-FTE33UHE.js} +16 -12
- package/dist/chunks/rm-FXA5DLXQ.js +315 -0
- package/dist/chunks/{rm-EOD7RDSO.js → rm-PGJ4KR6U.js} +20 -16
- package/dist/chunks/{routes-SZI2G4SE.js → routes-2OLIBRYX.js} +3 -3
- package/dist/chunks/{rule-inspect-WFTVRK6B.js → rule-inspect-LJIGPTWS.js} +18 -14
- package/dist/chunks/{rules-AQYTFJI6.js → rules-6BMNO6M5.js} +11 -10
- package/dist/chunks/{schema-LUVFYPWN.js → schema-45SJNY5L.js} +9 -7
- package/dist/chunks/{schema-ZCDCJC7E.js → schema-HATXEQDP.js} +14 -11
- package/dist/chunks/set-C3UQUQ42.js +243 -0
- package/dist/chunks/{tags-RCNRFX7U.js → tags-BTVDROFG.js} +6 -5
- package/dist/chunks/{types-AJHILHO5.js → types-JGANJ5EQ.js} +12 -8
- package/dist/chunks/{update-I7QGAOYF.js → update-B6PSOHUW.js} +19 -15
- package/dist/commands/build/builder-worker.cjs +281 -0
- package/dist/commands/build/index.js +695 -236
- package/dist/commands/deploy/index.js +131 -50
- package/dist/commands/dev/index.js +677 -144
- package/dist/commands/env/index.js +1199 -565
- package/dist/commands/link/index.js +27 -22
- package/dist/commands/list/index.js +21 -14
- package/dist/commands-bulk.js +2051 -1019
- package/dist/help.js +1 -1
- package/dist/index.js +39 -33
- package/dist/version.mjs +1 -1
- package/package.json +48 -48
|
@@ -9,24 +9,27 @@ import {
|
|
|
9
9
|
getCustomEnvironments,
|
|
10
10
|
readStandardInput,
|
|
11
11
|
require_dist as require_dist3
|
|
12
|
-
} from "../../chunks/chunk-
|
|
12
|
+
} from "../../chunks/chunk-ZSFEACZU.js";
|
|
13
13
|
import {
|
|
14
14
|
getInvalidSubcommand
|
|
15
15
|
} from "../../chunks/chunk-VGIMO3ZK.js";
|
|
16
16
|
import {
|
|
17
17
|
ellipsis
|
|
18
|
-
} from "../../chunks/chunk-
|
|
18
|
+
} from "../../chunks/chunk-C5HKWXRR.js";
|
|
19
19
|
import {
|
|
20
20
|
formatTable
|
|
21
|
-
} from "../../chunks/chunk-
|
|
22
|
-
import "../../chunks/chunk-
|
|
21
|
+
} from "../../chunks/chunk-OQ3C5VXZ.js";
|
|
22
|
+
import "../../chunks/chunk-XRWOTCDO.js";
|
|
23
23
|
import {
|
|
24
|
+
isGuidanceEnabled,
|
|
24
25
|
suggestNextCommands
|
|
25
|
-
} from "../../chunks/chunk-
|
|
26
|
+
} from "../../chunks/chunk-7ST552E3.js";
|
|
27
|
+
import {
|
|
28
|
+
formatEnvironment
|
|
29
|
+
} from "../../chunks/chunk-7R6M3BHM.js";
|
|
26
30
|
import {
|
|
27
|
-
formatEnvironment,
|
|
28
31
|
validateLsArgs
|
|
29
|
-
} from "../../chunks/chunk-
|
|
32
|
+
} from "../../chunks/chunk-O75LSD3C.js";
|
|
30
33
|
import {
|
|
31
34
|
validateJsonOutput
|
|
32
35
|
} from "../../chunks/chunk-KXDWXXJH.js";
|
|
@@ -35,61 +38,85 @@ import {
|
|
|
35
38
|
} from "../../chunks/chunk-YPQSDAEW.js";
|
|
36
39
|
import {
|
|
37
40
|
getCommandAliases
|
|
38
|
-
} from "../../chunks/chunk-
|
|
39
|
-
import "../../chunks/chunk-
|
|
40
|
-
import "../../chunks/chunk-
|
|
41
|
-
import "../../chunks/chunk-
|
|
42
|
-
import "../../chunks/chunk-
|
|
43
|
-
import "../../chunks/chunk-
|
|
44
|
-
import "../../chunks/chunk-
|
|
45
|
-
import "../../chunks/chunk-
|
|
46
|
-
import "../../chunks/chunk-
|
|
47
|
-
import "../../chunks/chunk-
|
|
48
|
-
import "../../chunks/chunk-
|
|
49
|
-
import "../../chunks/chunk-
|
|
50
|
-
import "../../chunks/chunk-
|
|
51
|
-
import
|
|
52
|
-
|
|
53
|
-
} from "../../chunks/chunk-R6IGDGX3.js";
|
|
41
|
+
} from "../../chunks/chunk-7HE63HCR.js";
|
|
42
|
+
import "../../chunks/chunk-7Q45OKWR.js";
|
|
43
|
+
import "../../chunks/chunk-GY5I4AYD.js";
|
|
44
|
+
import "../../chunks/chunk-CJV7J7B5.js";
|
|
45
|
+
import "../../chunks/chunk-EZKW5YJ2.js";
|
|
46
|
+
import "../../chunks/chunk-NFU4XJIR.js";
|
|
47
|
+
import "../../chunks/chunk-3HZLXCVL.js";
|
|
48
|
+
import "../../chunks/chunk-MTWHQEXI.js";
|
|
49
|
+
import "../../chunks/chunk-POOO7W47.js";
|
|
50
|
+
import "../../chunks/chunk-SLPSPYVR.js";
|
|
51
|
+
import "../../chunks/chunk-4KD5BYHB.js";
|
|
52
|
+
import "../../chunks/chunk-DWIC7MRV.js";
|
|
53
|
+
import "../../chunks/chunk-XM3LOQIX.js";
|
|
54
|
+
import "../../chunks/chunk-XDGOOW3K.js";
|
|
55
|
+
import "../../chunks/chunk-VP5Y3SZG.js";
|
|
54
56
|
import {
|
|
55
57
|
autoInstallVercelPlugin
|
|
56
|
-
} from "../../chunks/chunk-
|
|
58
|
+
} from "../../chunks/chunk-7AEEQOD4.js";
|
|
59
|
+
import {
|
|
60
|
+
require_execa
|
|
61
|
+
} from "../../chunks/chunk-5XECIWME.js";
|
|
57
62
|
import {
|
|
58
63
|
stamp_default
|
|
59
64
|
} from "../../chunks/chunk-64IF634X.js";
|
|
60
65
|
import "../../chunks/chunk-VXYGCOKL.js";
|
|
61
|
-
import "../../chunks/chunk-
|
|
66
|
+
import "../../chunks/chunk-FWKSJYDV.js";
|
|
62
67
|
import {
|
|
63
68
|
help
|
|
64
|
-
} from "../../chunks/chunk-
|
|
69
|
+
} from "../../chunks/chunk-2YRAWYGE.js";
|
|
65
70
|
import {
|
|
71
|
+
ENV_VISIBILITY_DEPRECATION_MESSAGE,
|
|
72
|
+
SENSITIVE_ENV_VALUE_PLACEHOLDER,
|
|
66
73
|
STANDARD_ENVIRONMENTS,
|
|
67
|
-
addSubcommand,
|
|
68
|
-
envCommand,
|
|
69
|
-
envTargetChoices,
|
|
70
74
|
formatProject,
|
|
75
|
+
formatVisibilityLabel,
|
|
76
|
+
getApiPublicPrefix,
|
|
77
|
+
getEnvKeyWarnings,
|
|
71
78
|
getEnvRecords,
|
|
72
|
-
|
|
79
|
+
getFrameworkPublicPrefix,
|
|
80
|
+
getLocalSecretFallbackMessage,
|
|
81
|
+
getLocalSvelteKitPublicPrefixes,
|
|
82
|
+
getPublicPrefix,
|
|
83
|
+
getPublicPrefixSecretVisibilityError,
|
|
73
84
|
getTeamById,
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
getUnavailableSecretValuesMessage,
|
|
86
|
+
isFlagsSecretNeedingSplit,
|
|
87
|
+
isSecretEnvVar,
|
|
88
|
+
looksLikeSecret,
|
|
89
|
+
looksLikeSecretValue,
|
|
90
|
+
normalizeStdinEnvValue,
|
|
76
91
|
param,
|
|
77
|
-
parseEnvTargetArg,
|
|
78
92
|
parseTarget,
|
|
79
93
|
printAlignedLabel,
|
|
80
94
|
pull,
|
|
81
95
|
pullEnvRecords,
|
|
96
|
+
removePublicPrefix,
|
|
97
|
+
resolveEnvVarTypeOption,
|
|
98
|
+
resolveEnvVarVisibility,
|
|
99
|
+
resolveProjectContext,
|
|
100
|
+
shouldConfirmRotationBeforeDelete,
|
|
101
|
+
validateEnvValue
|
|
102
|
+
} from "../../chunks/chunk-VJ5NAOWB.js";
|
|
103
|
+
import {
|
|
104
|
+
addSubcommand,
|
|
105
|
+
envCommand,
|
|
106
|
+
envTargetChoices,
|
|
107
|
+
getEnvTargetPlaceholder,
|
|
108
|
+
isValidEnvTarget,
|
|
109
|
+
listSubcommand,
|
|
110
|
+
parseEnvTargetArg,
|
|
82
111
|
pullSubcommand,
|
|
83
112
|
removeSubcommand,
|
|
84
|
-
require_frameworks,
|
|
85
|
-
resolveProjectContext,
|
|
86
113
|
runSubcommand,
|
|
87
114
|
updateSubcommand
|
|
88
|
-
} from "../../chunks/chunk-
|
|
115
|
+
} from "../../chunks/chunk-FXD67VN5.js";
|
|
89
116
|
import {
|
|
90
117
|
TelemetryClient,
|
|
91
118
|
require_dist as require_dist2
|
|
92
|
-
} from "../../chunks/chunk-
|
|
119
|
+
} from "../../chunks/chunk-XNFHNTS2.js";
|
|
93
120
|
import {
|
|
94
121
|
buildCommandWithYes,
|
|
95
122
|
buildEnvAddCommandWithPreservedArgs,
|
|
@@ -99,25 +126,31 @@ import {
|
|
|
99
126
|
getPreservedArgsForEnvRm,
|
|
100
127
|
getPreservedArgsForEnvUpdate,
|
|
101
128
|
outputActionRequired,
|
|
102
|
-
outputAgentError
|
|
103
|
-
|
|
129
|
+
outputAgentError,
|
|
130
|
+
quoteArg,
|
|
131
|
+
redactEnvValueArgs,
|
|
132
|
+
withGlobalFlags
|
|
133
|
+
} from "../../chunks/chunk-NGGLYKNU.js";
|
|
104
134
|
import {
|
|
105
135
|
require_ms
|
|
106
136
|
} from "../../chunks/chunk-GGP5R3FU.js";
|
|
107
137
|
import {
|
|
108
138
|
printError
|
|
109
|
-
} from "../../chunks/chunk-
|
|
139
|
+
} from "../../chunks/chunk-AYLY3ZVL.js";
|
|
110
140
|
import {
|
|
111
141
|
parseArguments
|
|
112
|
-
} from "../../chunks/chunk-
|
|
142
|
+
} from "../../chunks/chunk-57RHXXXG.js";
|
|
143
|
+
import "../../chunks/chunk-RKDCNQ4S.js";
|
|
144
|
+
import {
|
|
145
|
+
isAPIError
|
|
146
|
+
} from "../../chunks/chunk-BMKU5KEL.js";
|
|
113
147
|
import {
|
|
114
148
|
getCommandName,
|
|
115
149
|
getCommandNamePlain,
|
|
116
150
|
getFlagsSpecification,
|
|
117
151
|
getGlobalFlagsFromArgs,
|
|
118
|
-
isAPIError,
|
|
119
152
|
require_lib
|
|
120
|
-
} from "../../chunks/chunk-
|
|
153
|
+
} from "../../chunks/chunk-Q2DGFCO7.js";
|
|
121
154
|
import "../../chunks/chunk-P4QNYOFB.js";
|
|
122
155
|
import "../../chunks/chunk-52QYYTM5.js";
|
|
123
156
|
import {
|
|
@@ -125,7 +158,7 @@ import {
|
|
|
125
158
|
output_manager_default,
|
|
126
159
|
prependEmoji,
|
|
127
160
|
require_dist
|
|
128
|
-
} from "../../chunks/chunk-
|
|
161
|
+
} from "../../chunks/chunk-QFAS4OVW.js";
|
|
129
162
|
import {
|
|
130
163
|
require_source
|
|
131
164
|
} from "../../chunks/chunk-S7KYDPEM.js";
|
|
@@ -203,180 +236,6 @@ function isKnownError(error) {
|
|
|
203
236
|
return knownErrorsCodes.has(code.toUpperCase());
|
|
204
237
|
}
|
|
205
238
|
|
|
206
|
-
// src/util/env/validate-env.ts
|
|
207
|
-
var import_frameworks = __toESM(require_frameworks(), 1);
|
|
208
|
-
function getEnvValueWarnings(value) {
|
|
209
|
-
const warnings = [];
|
|
210
|
-
const normalized = value.replace(/\n$/, "");
|
|
211
|
-
if (/^[ \t]+/.test(normalized)) {
|
|
212
|
-
warnings.push({
|
|
213
|
-
message: "starts with whitespace",
|
|
214
|
-
requiresConfirmation: false
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
if (/[ \t]+$/.test(normalized)) {
|
|
218
|
-
warnings.push({
|
|
219
|
-
message: "ends with whitespace",
|
|
220
|
-
requiresConfirmation: false
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
if (normalized.includes("\r") || normalized.includes("\n")) {
|
|
224
|
-
warnings.push({
|
|
225
|
-
message: "contains newlines",
|
|
226
|
-
requiresConfirmation: false
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
if (value.includes("\0")) {
|
|
230
|
-
warnings.push({
|
|
231
|
-
message: "contains null characters",
|
|
232
|
-
requiresConfirmation: false
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
if (value === "") {
|
|
236
|
-
warnings.push({
|
|
237
|
-
message: "is empty",
|
|
238
|
-
requiresConfirmation: true
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
if (value.length > 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
|
|
242
|
-
warnings.push({
|
|
243
|
-
message: "includes surrounding quotes (these will be stored literally)",
|
|
244
|
-
requiresConfirmation: false
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
return warnings;
|
|
248
|
-
}
|
|
249
|
-
function formatWarnings(warnings) {
|
|
250
|
-
if (warnings.length === 0)
|
|
251
|
-
return null;
|
|
252
|
-
const messages = warnings.map((w) => w.message);
|
|
253
|
-
const startsIdx = messages.indexOf("starts with whitespace");
|
|
254
|
-
const endsIdx = messages.indexOf("ends with whitespace");
|
|
255
|
-
if (startsIdx !== -1 && endsIdx !== -1) {
|
|
256
|
-
messages.splice(Math.max(startsIdx, endsIdx), 1);
|
|
257
|
-
messages[Math.min(startsIdx, endsIdx)] = "starts and ends with whitespace";
|
|
258
|
-
}
|
|
259
|
-
if (messages.length === 1) {
|
|
260
|
-
return `Value ${messages[0]}`;
|
|
261
|
-
}
|
|
262
|
-
if (messages.length === 2) {
|
|
263
|
-
return `Value ${messages[0]} and ${messages[1]}`;
|
|
264
|
-
}
|
|
265
|
-
const last = messages.pop();
|
|
266
|
-
return `Value ${messages.join(", ")}, and ${last}`;
|
|
267
|
-
}
|
|
268
|
-
var PUBLIC_PREFIXES = [
|
|
269
|
-
...new Set(
|
|
270
|
-
import_frameworks.frameworkList.map((f) => f.envPrefix).filter((p) => !!p)
|
|
271
|
-
)
|
|
272
|
-
];
|
|
273
|
-
var SENSITIVE_PATTERN = /(?:^|_)(password|secret|private|token|key|auth|jwt|signature)(?:_|$)/i;
|
|
274
|
-
function hasOnlyWhitespaceWarnings(warnings) {
|
|
275
|
-
return warnings.length > 0 && warnings.every(
|
|
276
|
-
(w) => w.message === "starts with whitespace" || w.message === "ends with whitespace"
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
function trimValue(value) {
|
|
280
|
-
return value.replace(/\n$/, "").trim();
|
|
281
|
-
}
|
|
282
|
-
function normalizeStdinEnvValue(value) {
|
|
283
|
-
let valueWithoutTrailingNewline = value;
|
|
284
|
-
if (value.endsWith("\r\n")) {
|
|
285
|
-
valueWithoutTrailingNewline = value.slice(0, -2);
|
|
286
|
-
} else if (value.endsWith("\n")) {
|
|
287
|
-
valueWithoutTrailingNewline = value.slice(0, -1);
|
|
288
|
-
} else {
|
|
289
|
-
return {
|
|
290
|
-
value,
|
|
291
|
-
strippedTrailingNewline: false
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
if (valueWithoutTrailingNewline.includes("\n") || valueWithoutTrailingNewline.includes("\r")) {
|
|
295
|
-
return {
|
|
296
|
-
value,
|
|
297
|
-
strippedTrailingNewline: false
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
return {
|
|
301
|
-
value: valueWithoutTrailingNewline,
|
|
302
|
-
strippedTrailingNewline: true
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
function getPublicPrefix(key) {
|
|
306
|
-
const upperKey = key.toUpperCase();
|
|
307
|
-
return PUBLIC_PREFIXES.find((p) => upperKey.startsWith(p)) || null;
|
|
308
|
-
}
|
|
309
|
-
function removePublicPrefix(key) {
|
|
310
|
-
const prefix = getPublicPrefix(key);
|
|
311
|
-
if (!prefix)
|
|
312
|
-
return key;
|
|
313
|
-
return key.slice(prefix.length);
|
|
314
|
-
}
|
|
315
|
-
async function validateEnvValue(opts) {
|
|
316
|
-
let finalValue = opts.initialValue;
|
|
317
|
-
let alreadyConfirmed = false;
|
|
318
|
-
if (!opts.skipConfirm) {
|
|
319
|
-
let valueAccepted = false;
|
|
320
|
-
while (!valueAccepted) {
|
|
321
|
-
const valueWarnings = getEnvValueWarnings(finalValue);
|
|
322
|
-
const warningMessage = formatWarnings(valueWarnings);
|
|
323
|
-
if (!warningMessage) {
|
|
324
|
-
valueAccepted = true;
|
|
325
|
-
break;
|
|
326
|
-
}
|
|
327
|
-
opts.showWarning(warningMessage);
|
|
328
|
-
const canTrim = hasOnlyWhitespaceWarnings(valueWarnings);
|
|
329
|
-
const choices = canTrim ? [
|
|
330
|
-
{ name: "Leave as is", value: "c" },
|
|
331
|
-
{ name: "Re-enter", value: "r" },
|
|
332
|
-
{ name: "Trim whitespace", value: "t" }
|
|
333
|
-
] : [
|
|
334
|
-
{ name: "Leave as is", value: "c" },
|
|
335
|
-
{ name: "Re-enter", value: "r" }
|
|
336
|
-
];
|
|
337
|
-
const action = await opts.selectAction(choices);
|
|
338
|
-
if (action === "c") {
|
|
339
|
-
valueAccepted = true;
|
|
340
|
-
if (valueWarnings.some((w) => w.requiresConfirmation)) {
|
|
341
|
-
alreadyConfirmed = true;
|
|
342
|
-
}
|
|
343
|
-
} else if (action === "t") {
|
|
344
|
-
finalValue = trimValue(finalValue);
|
|
345
|
-
opts.showLog("Trimmed whitespace");
|
|
346
|
-
} else {
|
|
347
|
-
finalValue = await opts.promptForValue();
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
} else {
|
|
351
|
-
const valueWarnings = getEnvValueWarnings(finalValue);
|
|
352
|
-
const warningMessage = formatWarnings(valueWarnings);
|
|
353
|
-
if (warningMessage) {
|
|
354
|
-
opts.showWarning(warningMessage);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return { finalValue, alreadyConfirmed };
|
|
358
|
-
}
|
|
359
|
-
function getEnvKeyWarnings(key) {
|
|
360
|
-
const warnings = [];
|
|
361
|
-
const matchingPrefix = getPublicPrefix(key);
|
|
362
|
-
if (matchingPrefix) {
|
|
363
|
-
const sensitiveMatch = SENSITIVE_PATTERN.exec(key);
|
|
364
|
-
const nameWithoutPrefix = key.slice(matchingPrefix.length);
|
|
365
|
-
if (sensitiveMatch) {
|
|
366
|
-
warnings.push({
|
|
367
|
-
message: `The ${matchingPrefix} prefix will make ${nameWithoutPrefix} visible to anyone visiting your site`,
|
|
368
|
-
requiresConfirmation: true
|
|
369
|
-
});
|
|
370
|
-
} else {
|
|
371
|
-
warnings.push({
|
|
372
|
-
message: `${matchingPrefix} variables can be seen by anyone visiting your site`,
|
|
373
|
-
requiresConfirmation: false
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return warnings;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
239
|
// src/util/telemetry/commands/env/add.ts
|
|
381
240
|
var EnvAddTelemetryClient = class extends TelemetryClient {
|
|
382
241
|
trackCliArgumentName(name) {
|
|
@@ -429,6 +288,15 @@ var EnvAddTelemetryClient = class extends TelemetryClient {
|
|
|
429
288
|
});
|
|
430
289
|
}
|
|
431
290
|
}
|
|
291
|
+
trackCliOptionType(type) {
|
|
292
|
+
if (type) {
|
|
293
|
+
const validTypes = ["config", "secret"];
|
|
294
|
+
this.trackCliOption({
|
|
295
|
+
option: "type",
|
|
296
|
+
value: validTypes.includes(type) ? type : this.redactedValue
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
432
300
|
trackCliFlagSensitive(sensitive) {
|
|
433
301
|
if (sensitive) {
|
|
434
302
|
this.trackCliFlag("sensitive");
|
|
@@ -459,100 +327,42 @@ var EnvAddTelemetryClient = class extends TelemetryClient {
|
|
|
459
327
|
// src/commands/env/add.ts
|
|
460
328
|
import { determineAgent } from "@vercel/detect-agent";
|
|
461
329
|
|
|
462
|
-
// src/util/env/
|
|
463
|
-
function
|
|
464
|
-
|
|
465
|
-
if (resolved === "config") {
|
|
466
|
-
return "Config";
|
|
467
|
-
}
|
|
468
|
-
if (resolved === "secret") {
|
|
469
|
-
return "Secret";
|
|
470
|
-
}
|
|
471
|
-
return void 0;
|
|
330
|
+
// src/util/env/secret-storage-guidance.ts
|
|
331
|
+
function includesDevelopment(targets) {
|
|
332
|
+
return targets.length === 0 || targets.includes("development");
|
|
472
333
|
}
|
|
473
|
-
function
|
|
474
|
-
if (
|
|
475
|
-
|
|
334
|
+
function getProductionSecretPolicyErrorKind(message) {
|
|
335
|
+
if (/production secrets?.*different value|different value.*production secrets?/i.test(
|
|
336
|
+
message
|
|
337
|
+
)) {
|
|
338
|
+
return "different-values";
|
|
476
339
|
}
|
|
477
|
-
if (
|
|
478
|
-
|
|
340
|
+
if (/production secrets?.*(?:own environment group|separat)|(?:own environment group|separat).*production secrets?/i.test(
|
|
341
|
+
message
|
|
342
|
+
)) {
|
|
343
|
+
return "separate-environments";
|
|
479
344
|
}
|
|
480
|
-
return
|
|
481
|
-
}
|
|
482
|
-
function hasNonDevelopmentTarget(envTargets) {
|
|
483
|
-
return envTargets.some((target) => target !== "development");
|
|
345
|
+
return null;
|
|
484
346
|
}
|
|
485
|
-
function
|
|
486
|
-
|
|
487
|
-
if (!publicPrefix) {
|
|
488
|
-
return null;
|
|
489
|
-
}
|
|
490
|
-
const wouldBeSecret = options.visibility === "secret" || options.type === "sensitive";
|
|
491
|
-
if (!wouldBeSecret) {
|
|
492
|
-
return null;
|
|
493
|
-
}
|
|
494
|
-
const prefixLabel = publicPrefix.replace(/_$/, "");
|
|
495
|
-
if (hasNonDevelopmentTarget(options.envTargets)) {
|
|
496
|
-
return `Environment variables with a public framework prefix (${prefixLabel}) cannot use secret visibility on Production or Preview. Target Development only, rename to remove the public prefix, or use \`--visibility config\` with \`--no-sensitive\` on Development.`;
|
|
497
|
-
}
|
|
498
|
-
return `Environment variables with a public framework prefix (${prefixLabel}) cannot use secret visibility. Rename to remove the public prefix or use \`--visibility config\` with \`--no-sensitive\`.`;
|
|
347
|
+
function getProductionSecretPolicyRecovery(kind) {
|
|
348
|
+
return kind === "different-values" ? "Use different Secret values for Production and non-Production." : "Create separate Production and non-Production variables with different values.";
|
|
499
349
|
}
|
|
500
|
-
function
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
}
|
|
504
|
-
if (!hasNonDevelopmentTarget(envTargets)) {
|
|
505
|
-
return false;
|
|
506
|
-
}
|
|
507
|
-
return teamSensitivePolicyOn;
|
|
350
|
+
function getSecretStorageChoice(targets, recommendedReason) {
|
|
351
|
+
const availability = includesDevelopment(targets) ? "hidden in the dashboard; Development values can be pulled" : "hidden in the dashboard and unavailable to pulls";
|
|
352
|
+
const recommendation = recommendedReason ? `; recommended ${recommendedReason}` : "";
|
|
353
|
+
return `Secret (${availability}${recommendation})`;
|
|
508
354
|
}
|
|
509
|
-
function
|
|
510
|
-
if (
|
|
511
|
-
|
|
512
|
-
return {
|
|
513
|
-
error: "The `--visibility` flag must be either `config` or `secret`."
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
const publicPrefixError2 = getPublicPrefixSecretVisibilityError(
|
|
517
|
-
options.key,
|
|
518
|
-
{
|
|
519
|
-
visibility: options.explicitVisibility,
|
|
520
|
-
type: options.type,
|
|
521
|
-
envTargets: options.envTargets
|
|
522
|
-
}
|
|
523
|
-
);
|
|
524
|
-
if (publicPrefixError2) {
|
|
525
|
-
return { error: publicPrefixError2 };
|
|
526
|
-
}
|
|
527
|
-
return { visibility: options.explicitVisibility };
|
|
528
|
-
}
|
|
529
|
-
const inferred = visibilityFromEnvType(options.type);
|
|
530
|
-
if (inferred === void 0) {
|
|
531
|
-
return {};
|
|
532
|
-
}
|
|
533
|
-
if (shouldOmitInferredVisibility(
|
|
534
|
-
options.key,
|
|
535
|
-
options.envTargets,
|
|
536
|
-
options.teamSensitivePolicyOn
|
|
537
|
-
)) {
|
|
538
|
-
return {};
|
|
539
|
-
}
|
|
540
|
-
const publicPrefixError = getPublicPrefixSecretVisibilityError(options.key, {
|
|
541
|
-
visibility: inferred,
|
|
542
|
-
type: options.type,
|
|
543
|
-
envTargets: options.envTargets
|
|
544
|
-
});
|
|
545
|
-
if (publicPrefixError) {
|
|
546
|
-
return { error: publicPrefixError };
|
|
355
|
+
function getDefaultSecretStorageGuidance(targets) {
|
|
356
|
+
if (includesDevelopment(targets)) {
|
|
357
|
+
return "Stored as Secret by default. This value is hidden in the dashboard; Development values can be pulled. Use `--type config` for other values you need to read later.";
|
|
547
358
|
}
|
|
548
|
-
return
|
|
359
|
+
return "Stored as Secret by default. This value is hidden in the dashboard and unavailable to pulls; use `--type config` for values you need to read later.";
|
|
549
360
|
}
|
|
550
361
|
|
|
551
362
|
// src/commands/env/add.ts
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
)}`;
|
|
363
|
+
function looksLikeCredentialName(key, publicPrefix = getPublicPrefix(key)) {
|
|
364
|
+
return looksLikeSecret(publicPrefix ? key.slice(publicPrefix.length) : key);
|
|
365
|
+
}
|
|
556
366
|
function filterEnvChoicesForSensitivity(choices, opts) {
|
|
557
367
|
if (opts.policyOn) {
|
|
558
368
|
return choices.filter((c) => c.value === "development");
|
|
@@ -583,19 +393,13 @@ function resolveFinalType(envTargets, isSensitive, opts) {
|
|
|
583
393
|
}
|
|
584
394
|
function fillEnvAddTemplate(template, opts) {
|
|
585
395
|
const targetPlaceholder = getEnvTargetPlaceholder();
|
|
586
|
-
return template.replace(/<name>/g, opts.envName
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
i++;
|
|
594
|
-
} else if (redacted[i].startsWith("--value=")) {
|
|
595
|
-
redacted[i] = '--value="<value>"';
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
return redacted;
|
|
396
|
+
return template.replace(/<name>/g, opts.envName ? quoteArg(opts.envName) : "<name>").split(targetPlaceholder).join(opts.envTargetArg ? quoteArg(opts.envTargetArg) : targetPlaceholder).replace(
|
|
397
|
+
/<git-branch>/g,
|
|
398
|
+
opts.envGitBranch ? quoteArg(opts.envGitBranch) : "<git-branch>"
|
|
399
|
+
).replace(
|
|
400
|
+
/<gitbranch>/g,
|
|
401
|
+
opts.envGitBranch ? quoteArg(opts.envGitBranch) : "<gitbranch>"
|
|
402
|
+
).replace(/<value>/g, "<value>");
|
|
599
403
|
}
|
|
600
404
|
function multiTargetSuggestion(argv, envName, targets, addNoSensitive) {
|
|
601
405
|
const flag = addNoSensitive ? " --no-sensitive" : "";
|
|
@@ -628,9 +432,6 @@ function formatEnvironmentTarget(target, customEnvironments) {
|
|
|
628
432
|
function formatEnvironmentTargets(envTargets, customEnvironments) {
|
|
629
433
|
return envTargets.map((target) => formatEnvironmentTarget(target, customEnvironments)).join(", ");
|
|
630
434
|
}
|
|
631
|
-
function typeLabel(type) {
|
|
632
|
-
return type === "sensitive" ? "Sensitive" : "Non-sensitive";
|
|
633
|
-
}
|
|
634
435
|
function printEnvAddResult(link, envName, envTargets, envGitBranch, customEnvironments, finalType, force, visibility) {
|
|
635
436
|
output_manager_default.print("\n");
|
|
636
437
|
printAlignedLabel(force ? "Overrode" : "Added", envName, { gutter: "\u2713" });
|
|
@@ -642,10 +443,9 @@ function printEnvAddResult(link, envName, envTargets, envGitBranch, customEnviro
|
|
|
642
443
|
if (envGitBranch) {
|
|
643
444
|
printAlignedLabel("Branch", envGitBranch);
|
|
644
445
|
}
|
|
645
|
-
printAlignedLabel("Type", typeLabel(finalType));
|
|
646
446
|
const visibilityLabel = formatVisibilityLabel(visibility, finalType);
|
|
647
447
|
if (visibilityLabel) {
|
|
648
|
-
printAlignedLabel("
|
|
448
|
+
printAlignedLabel("Type", visibilityLabel);
|
|
649
449
|
}
|
|
650
450
|
}
|
|
651
451
|
function printEnvAddWarning(message) {
|
|
@@ -658,6 +458,13 @@ function promptEnvValue(client, opts) {
|
|
|
658
458
|
...opts.isSensitive ? { transformer: (value) => "*".repeat(value.length) } : {}
|
|
659
459
|
});
|
|
660
460
|
}
|
|
461
|
+
function buildHumanEnvAddCommand(argv, commandTemplate) {
|
|
462
|
+
const globalFlags = getGlobalFlagsFromArgs(argv.slice(2), {
|
|
463
|
+
preserveProject: true
|
|
464
|
+
}).filter((flag) => !flag.startsWith("--non-interactive"));
|
|
465
|
+
const suffix = globalFlags.length > 0 ? ` ${globalFlags.map(quoteArg).join(" ")}` : "";
|
|
466
|
+
return getCommandNamePlain(`${commandTemplate}${suffix}`);
|
|
467
|
+
}
|
|
661
468
|
async function add(client, argv) {
|
|
662
469
|
let parsedArgs;
|
|
663
470
|
const flagsSpecification = getFlagsSpecification(addSubcommand.options);
|
|
@@ -685,6 +492,14 @@ async function add(client, argv) {
|
|
|
685
492
|
const positionalGitBranch = args[2];
|
|
686
493
|
const optionGitBranch = typeof opts["--git-branch"] === "string" ? opts["--git-branch"] : void 0;
|
|
687
494
|
let envGitBranch = optionGitBranch ?? positionalGitBranch;
|
|
495
|
+
const forceSensitive = Boolean(opts["--sensitive"]);
|
|
496
|
+
const forceEncrypted = Boolean(opts["--no-sensitive"]);
|
|
497
|
+
const typeOption = resolveEnvVarTypeOption({
|
|
498
|
+
type: typeof opts["--type"] === "string" ? opts["--type"] : void 0,
|
|
499
|
+
visibility: typeof opts["--visibility"] === "string" ? opts["--visibility"] : void 0
|
|
500
|
+
});
|
|
501
|
+
let explicitType = typeOption.explicitVisibility;
|
|
502
|
+
let typeSource = explicitType || forceSensitive || forceEncrypted ? "argv" : void 0;
|
|
688
503
|
const telemetryClient = new EnvAddTelemetryClient({
|
|
689
504
|
opts: {
|
|
690
505
|
store: client.telemetryEventStore
|
|
@@ -702,10 +517,47 @@ async function add(client, argv) {
|
|
|
702
517
|
telemetryClient.trackCliFlagForce(opts["--force"]);
|
|
703
518
|
telemetryClient.trackCliFlagGuidance(opts["--guidance"]);
|
|
704
519
|
telemetryClient.trackCliFlagYes(opts["--yes"]);
|
|
520
|
+
telemetryClient.trackCliOptionType(
|
|
521
|
+
typeof opts["--type"] === "string" ? opts["--type"] : void 0
|
|
522
|
+
);
|
|
705
523
|
telemetryClient.trackCliOptionVisibility(
|
|
706
524
|
typeof opts["--visibility"] === "string" ? opts["--visibility"] : void 0
|
|
707
525
|
);
|
|
708
526
|
telemetryClient.trackCliOptionProject(opts["--project"]);
|
|
527
|
+
if (typeOption.error) {
|
|
528
|
+
if (client.nonInteractive) {
|
|
529
|
+
outputAgentError(
|
|
530
|
+
client,
|
|
531
|
+
{
|
|
532
|
+
status: "error",
|
|
533
|
+
reason: typeOption.errorReason ?? "invalid_type",
|
|
534
|
+
message: typeOption.error
|
|
535
|
+
},
|
|
536
|
+
1
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
output_manager_default.fatal(typeOption.error);
|
|
540
|
+
return 1;
|
|
541
|
+
}
|
|
542
|
+
if (typeOption.usedDeprecatedVisibility) {
|
|
543
|
+
printEnvAddWarning(ENV_VISIBILITY_DEPRECATION_MESSAGE);
|
|
544
|
+
}
|
|
545
|
+
const typeConflictMessage = forceSensitive ? forceEncrypted ? "`--sensitive` and `--no-sensitive` cannot be used together. Pick one." : explicitType === "config" ? "`--type config` cannot be used with `--sensitive`. Pick one." : null : forceEncrypted && explicitType === "secret" ? "`--type secret` cannot be used with `--no-sensitive`. Pick one." : null;
|
|
546
|
+
if (typeConflictMessage) {
|
|
547
|
+
if (client.nonInteractive) {
|
|
548
|
+
outputAgentError(
|
|
549
|
+
client,
|
|
550
|
+
{
|
|
551
|
+
status: "error",
|
|
552
|
+
reason: "conflicting_type_flags",
|
|
553
|
+
message: typeConflictMessage
|
|
554
|
+
},
|
|
555
|
+
1
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
output_manager_default.fatal(typeConflictMessage);
|
|
559
|
+
return 1;
|
|
560
|
+
}
|
|
709
561
|
if (positionalGitBranch && optionGitBranch) {
|
|
710
562
|
output_manager_default.error(
|
|
711
563
|
"Git branch was provided twice. Use either `--git-branch <git-branch>` or the legacy third argument."
|
|
@@ -729,6 +581,7 @@ async function add(client, argv) {
|
|
|
729
581
|
return 1;
|
|
730
582
|
}
|
|
731
583
|
let envTargets = envTargetArg ? parseEnvTargetArg(envTargetArg) : [];
|
|
584
|
+
let resolvedLink;
|
|
732
585
|
if (client.nonInteractive) {
|
|
733
586
|
const link2 = await resolveProjectContext({
|
|
734
587
|
client,
|
|
@@ -779,9 +632,9 @@ async function add(client, argv) {
|
|
|
779
632
|
{
|
|
780
633
|
status: "error",
|
|
781
634
|
reason: "not_linked",
|
|
782
|
-
message: `Your codebase isn't linked to a project on Vercel. Run
|
|
635
|
+
message: `Your codebase isn't linked to a project on Vercel. Run \`${getCommandNamePlain(
|
|
783
636
|
"link"
|
|
784
|
-
)} to begin. Use
|
|
637
|
+
)}\` to begin. Use \`--yes\` for non-interactive mode; use \`--scope\` or \`--project\` to specify a team or project. Then run your \`env add\` command.`,
|
|
785
638
|
next: [
|
|
786
639
|
{ command: buildCommandWithYes(linkArgv) },
|
|
787
640
|
{ command: buildCommandWithYes(envAddRetryArgv) }
|
|
@@ -792,6 +645,7 @@ async function add(client, argv) {
|
|
|
792
645
|
}
|
|
793
646
|
if (link2.status !== "linked")
|
|
794
647
|
return 1;
|
|
648
|
+
resolvedLink = link2;
|
|
795
649
|
const { project: project2 } = link2;
|
|
796
650
|
const org = link2.org;
|
|
797
651
|
client.config.currentTeam = org.type === "team" ? org.id : void 0;
|
|
@@ -913,7 +767,7 @@ async function add(client, argv) {
|
|
|
913
767
|
status: "action_required",
|
|
914
768
|
reason: "missing_requirements",
|
|
915
769
|
missing,
|
|
916
|
-
message: `Provide all required inputs for non-interactive mode: ${parts.join("; ")}. Example:
|
|
770
|
+
message: `Provide all required inputs for non-interactive mode: ${parts.join("; ")}. Example: \`${filledTemplate}\``,
|
|
917
771
|
next
|
|
918
772
|
},
|
|
919
773
|
1
|
|
@@ -926,147 +780,246 @@ async function add(client, argv) {
|
|
|
926
780
|
validate: (val) => val ? true : "Name cannot be empty"
|
|
927
781
|
});
|
|
928
782
|
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
783
|
+
if (!resolvedLink) {
|
|
784
|
+
const link2 = await resolveProjectContext({
|
|
785
|
+
client,
|
|
786
|
+
projectNameOrId: opts["--project"]
|
|
787
|
+
});
|
|
788
|
+
if (link2.status === "error") {
|
|
789
|
+
return link2.exitCode;
|
|
790
|
+
} else if (link2.status === "not_linked") {
|
|
791
|
+
if (client.nonInteractive) {
|
|
792
|
+
const preserved = getPreservedArgsForEnvAdd(client.argv);
|
|
793
|
+
const linkPreserved = preserved.filter((a, i) => {
|
|
794
|
+
if (a === "--value")
|
|
795
|
+
return false;
|
|
796
|
+
if (a.startsWith("--value="))
|
|
797
|
+
return false;
|
|
798
|
+
if (i > 0 && preserved[i - 1] === "--value")
|
|
799
|
+
return false;
|
|
800
|
+
return true;
|
|
801
|
+
});
|
|
802
|
+
const linkArgv = [
|
|
803
|
+
...client.argv.slice(0, 2),
|
|
804
|
+
"link",
|
|
805
|
+
"--scope",
|
|
806
|
+
"<scope>",
|
|
807
|
+
...linkPreserved
|
|
808
|
+
];
|
|
809
|
+
outputAgentError(
|
|
810
|
+
client,
|
|
811
|
+
{
|
|
812
|
+
status: "error",
|
|
813
|
+
reason: "not_linked",
|
|
814
|
+
message: `Your codebase isn't linked to a project on Vercel. Run ${getCommandNamePlain(
|
|
815
|
+
"link"
|
|
816
|
+
)} to begin. Use --yes for non-interactive; use --scope or --project to specify team or project. Then run your env add command.`,
|
|
817
|
+
next: [
|
|
818
|
+
{ command: buildCommandWithYes(linkArgv) },
|
|
819
|
+
{ command: buildCommandWithYes(redactEnvValueArgs(client.argv)) }
|
|
820
|
+
]
|
|
821
|
+
},
|
|
822
|
+
1
|
|
823
|
+
);
|
|
824
|
+
} else {
|
|
825
|
+
output_manager_default.error(
|
|
826
|
+
`Your codebase isn\u2019t linked to a project on Vercel. Run ${getCommandName(
|
|
827
|
+
"link"
|
|
828
|
+
)} to begin.`
|
|
829
|
+
);
|
|
941
830
|
}
|
|
831
|
+
return 1;
|
|
832
|
+
}
|
|
833
|
+
resolvedLink = link2;
|
|
834
|
+
}
|
|
835
|
+
const link = resolvedLink;
|
|
836
|
+
client.config.currentTeam = link.org.type === "team" ? link.org.id : void 0;
|
|
837
|
+
const { project } = link;
|
|
838
|
+
if (explicitType === "secret" || forceSensitive) {
|
|
839
|
+
const publicPrefixError = getPublicPrefixSecretVisibilityError(envName, {
|
|
840
|
+
visibility: explicitType === "secret" ? "secret" : void 0,
|
|
841
|
+
type: "sensitive",
|
|
842
|
+
context: "add"
|
|
843
|
+
});
|
|
844
|
+
if (publicPrefixError) {
|
|
845
|
+
if (client.nonInteractive) {
|
|
846
|
+
outputAgentError(
|
|
847
|
+
client,
|
|
848
|
+
{
|
|
849
|
+
status: "error",
|
|
850
|
+
reason: "invalid_type",
|
|
851
|
+
message: publicPrefixError
|
|
852
|
+
},
|
|
853
|
+
1
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
output_manager_default.fatal(publicPrefixError);
|
|
857
|
+
return 1;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
let keyAccepted = false;
|
|
861
|
+
while (!keyAccepted) {
|
|
862
|
+
const apiPublicPrefix2 = getApiPublicPrefix(envName);
|
|
863
|
+
const frameworkPublicPrefix = getFrameworkPublicPrefix(
|
|
864
|
+
project.framework,
|
|
865
|
+
envName
|
|
866
|
+
);
|
|
867
|
+
const globallyKnownPrefix = getPublicPrefix(envName);
|
|
868
|
+
const deferFrameworkSecretError = frameworkPublicPrefix !== null && (explicitType === "secret" || forceSensitive);
|
|
869
|
+
const keyWarnings = deferFrameworkSecretError || globallyKnownPrefix !== null && apiPublicPrefix2 === null && frameworkPublicPrefix === null ? [] : getEnvKeyWarnings(envName);
|
|
870
|
+
const sensitiveWarning = keyWarnings.find((w) => w.requiresConfirmation);
|
|
871
|
+
if (!sensitiveWarning) {
|
|
872
|
+
for (const warning of keyWarnings) {
|
|
873
|
+
printEnvAddWarning(warning.message);
|
|
874
|
+
}
|
|
875
|
+
keyAccepted = true;
|
|
876
|
+
break;
|
|
877
|
+
}
|
|
878
|
+
const nameWithoutPrefix = removePublicPrefix(envName);
|
|
879
|
+
const publicPrefix = getPublicPrefix(envName);
|
|
880
|
+
if (typeSource === "argv") {
|
|
881
|
+
for (const warning of keyWarnings) {
|
|
882
|
+
printEnvAddWarning(warning.message);
|
|
883
|
+
}
|
|
884
|
+
keyAccepted = true;
|
|
885
|
+
break;
|
|
886
|
+
}
|
|
887
|
+
const privateCommand = buildEnvAddCommandWithPreservedArgs(
|
|
888
|
+
client.argv,
|
|
889
|
+
`env add ${nameWithoutPrefix} ${envTargetArg ?? getEnvTargetPlaceholder()} --type secret --value "<value>" --yes`
|
|
890
|
+
);
|
|
891
|
+
const publicCommand = buildEnvAddCommandWithPreservedArgs(
|
|
892
|
+
client.argv,
|
|
893
|
+
`env add ${envName} ${envTargetArg ?? getEnvTargetPlaceholder()} --type config --value "<value>" --yes`
|
|
894
|
+
);
|
|
895
|
+
const humanTargetArg = envTargetArg ? ` ${envTargetArg}` : "";
|
|
896
|
+
const privateHumanCommand = buildHumanEnvAddCommand(
|
|
897
|
+
client.argv,
|
|
898
|
+
`env add ${nameWithoutPrefix}${humanTargetArg} --type secret`
|
|
899
|
+
);
|
|
900
|
+
const publicHumanCommand = buildHumanEnvAddCommand(
|
|
901
|
+
client.argv,
|
|
902
|
+
`env add ${envName}${humanTargetArg} --type config`
|
|
903
|
+
);
|
|
904
|
+
const message = `\`${envName}\` looks like a credential, and \`${publicPrefix}\` exposes its value to anyone visiting your site. Choose explicitly: rename to \`${nameWithoutPrefix}\` with \`--type secret\` to keep it private, or keep the name with \`--type config\` to expose it.`;
|
|
905
|
+
if (client.nonInteractive || opts["--yes"] || !!stdInput) {
|
|
942
906
|
if (client.nonInteractive) {
|
|
943
|
-
const nameWithoutPrefix2 = removePublicPrefix(envName);
|
|
944
907
|
outputActionRequired(client, {
|
|
945
908
|
status: "action_required",
|
|
946
|
-
reason: "
|
|
947
|
-
message
|
|
909
|
+
reason: "public_prefix_requires_type",
|
|
910
|
+
message,
|
|
948
911
|
choices: [
|
|
949
|
-
{
|
|
950
|
-
|
|
912
|
+
{
|
|
913
|
+
id: "private",
|
|
914
|
+
name: `Keep private: rename to ${nameWithoutPrefix} and use Secret`
|
|
915
|
+
},
|
|
916
|
+
{
|
|
917
|
+
id: "public",
|
|
918
|
+
name: `Expose publicly: keep ${envName} as Config`
|
|
919
|
+
}
|
|
951
920
|
],
|
|
952
921
|
next: [
|
|
953
922
|
{
|
|
954
|
-
command:
|
|
955
|
-
|
|
956
|
-
`env add ${envName} ${getEnvTargetPlaceholder()} --value "<value>" --yes`
|
|
957
|
-
),
|
|
958
|
-
when: "Leave as is"
|
|
923
|
+
command: privateCommand,
|
|
924
|
+
when: "Keep it private; replace <value> before running"
|
|
959
925
|
},
|
|
960
926
|
{
|
|
961
|
-
command:
|
|
962
|
-
|
|
963
|
-
`env add ${nameWithoutPrefix2} ${getEnvTargetPlaceholder()} --value "<value>" --yes`
|
|
964
|
-
),
|
|
965
|
-
when: "Rename"
|
|
927
|
+
command: publicCommand,
|
|
928
|
+
when: "Expose it publicly; replace <value> before running"
|
|
966
929
|
}
|
|
967
930
|
]
|
|
968
931
|
});
|
|
969
932
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
];
|
|
979
|
-
const action = await client.input.select({
|
|
980
|
-
message: "Variable name?",
|
|
981
|
-
choices: choices2
|
|
982
|
-
});
|
|
983
|
-
if (action === "c") {
|
|
984
|
-
keyAccepted = true;
|
|
985
|
-
} else if (action === "p") {
|
|
986
|
-
envName = nameWithoutPrefix;
|
|
987
|
-
output_manager_default.log(`Renamed to ${envName}`);
|
|
988
|
-
} else {
|
|
989
|
-
envName = await client.input.text({
|
|
990
|
-
message: `Name?`,
|
|
991
|
-
validate: (val) => val ? true : "Name cannot be empty"
|
|
992
|
-
});
|
|
993
|
-
}
|
|
933
|
+
output_manager_default.fatal(message);
|
|
934
|
+
output_manager_default.print(` Keep it private:
|
|
935
|
+
${privateHumanCommand}
|
|
936
|
+
`);
|
|
937
|
+
output_manager_default.print(` Expose it publicly:
|
|
938
|
+
${publicHumanCommand}
|
|
939
|
+
`);
|
|
940
|
+
return 1;
|
|
994
941
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
942
|
+
for (const warning of keyWarnings) {
|
|
943
|
+
printEnvAddWarning(warning.message);
|
|
944
|
+
}
|
|
945
|
+
const action = await client.input.select({
|
|
946
|
+
message: "How should this variable be stored?",
|
|
947
|
+
choices: [
|
|
948
|
+
{
|
|
949
|
+
name: `Keep private: rename to ${nameWithoutPrefix} and use Secret`,
|
|
950
|
+
value: "p"
|
|
951
|
+
},
|
|
952
|
+
{
|
|
953
|
+
name: `Expose to anyone visiting your site: keep ${envName} as Config`,
|
|
954
|
+
value: "c"
|
|
955
|
+
},
|
|
956
|
+
{ name: "Enter a different name", value: "r" }
|
|
957
|
+
]
|
|
958
|
+
});
|
|
959
|
+
if (action === "p") {
|
|
960
|
+
envName = nameWithoutPrefix;
|
|
961
|
+
explicitType = "secret";
|
|
962
|
+
typeSource = "prompt";
|
|
963
|
+
output_manager_default.log(`Renamed to ${envName}`);
|
|
964
|
+
} else if (action === "c") {
|
|
965
|
+
explicitType = "config";
|
|
966
|
+
typeSource = "prompt";
|
|
967
|
+
keyAccepted = true;
|
|
968
|
+
} else {
|
|
969
|
+
envName = await client.input.text({
|
|
970
|
+
message: `Name?`,
|
|
971
|
+
validate: (val) => val ? true : "Name cannot be empty"
|
|
972
|
+
});
|
|
999
973
|
}
|
|
1000
974
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
975
|
+
let customSveltePublicPrefix;
|
|
976
|
+
const apiPublicPrefix = getApiPublicPrefix(envName);
|
|
977
|
+
const matchingFrameworkPublicPrefix = getFrameworkPublicPrefix(
|
|
978
|
+
project.framework,
|
|
979
|
+
envName
|
|
980
|
+
);
|
|
981
|
+
if (matchingFrameworkPublicPrefix !== null && (explicitType === "secret" || forceSensitive)) {
|
|
982
|
+
const message = `\`${matchingFrameworkPublicPrefix}\` exposes this value to anyone visiting your site, so \`${envName}\` cannot be kept private as a Secret. Rename the variable without the framework's public prefix to keep it private, or use \`--type config\` only if the value is safe to expose.`;
|
|
1008
983
|
if (client.nonInteractive) {
|
|
1009
|
-
const preserved = getPreservedArgsForEnvAdd(client.argv);
|
|
1010
|
-
const linkPreserved = preserved.filter((a, i) => {
|
|
1011
|
-
if (a === "--value")
|
|
1012
|
-
return false;
|
|
1013
|
-
if (a.startsWith("--value="))
|
|
1014
|
-
return false;
|
|
1015
|
-
if (i > 0 && preserved[i - 1] === "--value")
|
|
1016
|
-
return false;
|
|
1017
|
-
return true;
|
|
1018
|
-
});
|
|
1019
|
-
const linkArgv = [
|
|
1020
|
-
...client.argv.slice(0, 2),
|
|
1021
|
-
"link",
|
|
1022
|
-
...link.status === "not_linked" ? ["--scope", "<scope>"] : [],
|
|
1023
|
-
...linkPreserved
|
|
1024
|
-
];
|
|
1025
|
-
let envAddRetryArgv = redactEnvValueArgs(client.argv);
|
|
1026
|
-
if (envTargetArg === "preview" && envGitBranch === void 0) {
|
|
1027
|
-
const argvArgs = client.argv.slice(2);
|
|
1028
|
-
const addIdx = argvArgs.indexOf("add");
|
|
1029
|
-
if (addIdx !== -1) {
|
|
1030
|
-
let pos = addIdx + 1;
|
|
1031
|
-
let positionals = 0;
|
|
1032
|
-
while (pos < argvArgs.length && positionals < 3 && !argvArgs[pos].startsWith("-")) {
|
|
1033
|
-
positionals++;
|
|
1034
|
-
pos++;
|
|
1035
|
-
}
|
|
1036
|
-
const insertAt = 2 + pos;
|
|
1037
|
-
envAddRetryArgv = redactEnvValueArgs([
|
|
1038
|
-
...client.argv.slice(0, insertAt),
|
|
1039
|
-
"<gitbranch>",
|
|
1040
|
-
...client.argv.slice(insertAt)
|
|
1041
|
-
]);
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
984
|
outputAgentError(
|
|
1045
985
|
client,
|
|
1046
|
-
{
|
|
1047
|
-
status: "error",
|
|
1048
|
-
reason: "not_linked",
|
|
1049
|
-
message: `Your codebase isn't linked to a project on Vercel. Run ${getCommandNamePlain(
|
|
1050
|
-
"link"
|
|
1051
|
-
)} to begin. Use --yes for non-interactive; use --scope or --project to specify team or project. Then run your env add command.`,
|
|
1052
|
-
next: [
|
|
1053
|
-
{ command: buildCommandWithYes(linkArgv) },
|
|
1054
|
-
{ command: buildCommandWithYes(envAddRetryArgv) }
|
|
1055
|
-
]
|
|
1056
|
-
},
|
|
986
|
+
{ status: "error", reason: "invalid_type", message },
|
|
1057
987
|
1
|
|
1058
988
|
);
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
989
|
+
}
|
|
990
|
+
output_manager_default.fatal(message);
|
|
991
|
+
return 1;
|
|
992
|
+
}
|
|
993
|
+
if (project.framework === "sveltekit" || project.framework === "sveltekit-1" || project.framework === "sveltekit-2") {
|
|
994
|
+
const localPublicPrefixes = await getLocalSvelteKitPublicPrefixes(
|
|
995
|
+
link.repoRoot ?? client.cwd,
|
|
996
|
+
project.rootDirectory
|
|
997
|
+
);
|
|
998
|
+
const matchingLocalPrefix = localPublicPrefixes?.find(
|
|
999
|
+
(prefix) => envName.startsWith(prefix)
|
|
1000
|
+
);
|
|
1001
|
+
if (matchingLocalPrefix !== void 0 && apiPublicPrefix === null && matchingFrameworkPublicPrefix === null) {
|
|
1002
|
+
customSveltePublicPrefix = matchingLocalPrefix;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
if (customSveltePublicPrefix !== void 0 && (explicitType === "secret" || forceSensitive)) {
|
|
1006
|
+
const message = customSveltePublicPrefix === "" ? "This SvelteKit project uses an empty `publicPrefix`, so every Environment Variable is exposed to the browser and cannot be kept private as a Secret. Change the SvelteKit `publicPrefix`, or use `--type config` only if the value is safe to expose." : `\`${customSveltePublicPrefix}\` exposes this value to anyone visiting your site, so \`${envName}\` cannot be kept private as a Secret. Rename the variable without the configured public prefix, or use \`--type config\` only if the value is safe to expose.`;
|
|
1007
|
+
if (client.nonInteractive) {
|
|
1008
|
+
outputAgentError(
|
|
1009
|
+
client,
|
|
1010
|
+
{ status: "error", reason: "invalid_type", message },
|
|
1011
|
+
1
|
|
1064
1012
|
);
|
|
1065
1013
|
}
|
|
1014
|
+
output_manager_default.fatal(message);
|
|
1066
1015
|
return 1;
|
|
1067
1016
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1017
|
+
if (customSveltePublicPrefix !== void 0) {
|
|
1018
|
+
printEnvAddWarning(
|
|
1019
|
+
customSveltePublicPrefix === "" ? "This SvelteKit project uses an empty `publicPrefix`, so every Environment Variable is exposed to the browser." : `\`${customSveltePublicPrefix}\` variables are exposed to the browser by this SvelteKit project.`
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
const skipConfirm = opts["--yes"] || !!stdInput || valueFromFlag !== void 0;
|
|
1070
1023
|
const [{ envs }, customEnvironments] = await Promise.all([
|
|
1071
1024
|
getEnvRecords(client, project.id, "vercel-cli:env:add"),
|
|
1072
1025
|
getCustomEnvironments(client, project.id)
|
|
@@ -1154,50 +1107,54 @@ async function add(client, argv) {
|
|
|
1154
1107
|
);
|
|
1155
1108
|
return 1;
|
|
1156
1109
|
}
|
|
1157
|
-
const forceSensitive = Boolean(opts["--sensitive"]);
|
|
1158
|
-
const forceEncrypted = Boolean(opts["--no-sensitive"]);
|
|
1159
|
-
if (forceSensitive && forceEncrypted) {
|
|
1160
|
-
output_manager_default.error(
|
|
1161
|
-
`--sensitive and --no-sensitive cannot be used together. Pick one.`
|
|
1162
|
-
);
|
|
1163
|
-
return 1;
|
|
1164
|
-
}
|
|
1165
|
-
const explicitVisibility = typeof opts["--visibility"] === "string" ? opts["--visibility"] : void 0;
|
|
1166
|
-
if (explicitVisibility === "secret" && forceEncrypted) {
|
|
1167
|
-
output_manager_default.error(
|
|
1168
|
-
"`--visibility secret` cannot be used with `--no-sensitive`. Pick one."
|
|
1169
|
-
);
|
|
1170
|
-
return 1;
|
|
1171
|
-
}
|
|
1172
|
-
if (explicitVisibility === "config" && forceSensitive) {
|
|
1173
|
-
output_manager_default.error(
|
|
1174
|
-
"`--visibility config` cannot be used with `--sensitive`. Pick one."
|
|
1175
|
-
);
|
|
1176
|
-
return 1;
|
|
1177
|
-
}
|
|
1178
1110
|
const policyOn = false;
|
|
1179
1111
|
let teamSensitivePolicyOn = false;
|
|
1112
|
+
let disjunctiveProductionSecretPolicyOn = false;
|
|
1180
1113
|
if (link.org.type === "team") {
|
|
1181
1114
|
try {
|
|
1182
1115
|
const team = await getTeamById(client, link.org.id);
|
|
1183
1116
|
teamSensitivePolicyOn = team?.sensitiveEnvironmentVariablePolicy === "on";
|
|
1117
|
+
disjunctiveProductionSecretPolicyOn = team?.disjunctiveProductionSecretPolicy === "on";
|
|
1184
1118
|
} catch {
|
|
1185
1119
|
}
|
|
1186
1120
|
}
|
|
1121
|
+
const userWasExplicit = forceSensitive || forceEncrypted || !!explicitType;
|
|
1122
|
+
const skipSensitivePrompt = userWasExplicit || client.nonInteractive || skipConfirm;
|
|
1187
1123
|
const isDevelopmentOnlyTarget = envTargets.length === 1 && envTargets[0] === "development";
|
|
1188
|
-
const userWasExplicit = forceSensitive || forceEncrypted;
|
|
1189
|
-
const skipSensitivePrompt = userWasExplicit || client.nonInteractive || skipConfirm || isDevelopmentOnlyTarget;
|
|
1190
1124
|
let isSensitive;
|
|
1191
1125
|
if (forceSensitive) {
|
|
1192
1126
|
isSensitive = true;
|
|
1193
1127
|
} else if (forceEncrypted) {
|
|
1194
1128
|
isSensitive = false;
|
|
1129
|
+
} else if (explicitType) {
|
|
1130
|
+
isSensitive = explicitType === "secret";
|
|
1131
|
+
} else if (apiPublicPrefix || matchingFrameworkPublicPrefix || customSveltePublicPrefix !== void 0) {
|
|
1132
|
+
isSensitive = false;
|
|
1133
|
+
explicitType = "config";
|
|
1134
|
+
typeSource = "inferred";
|
|
1195
1135
|
} else if (isDevelopmentOnlyTarget) {
|
|
1196
1136
|
isSensitive = false;
|
|
1137
|
+
typeSource = "inferred";
|
|
1197
1138
|
} else if (skipSensitivePrompt) {
|
|
1198
1139
|
isSensitive = true;
|
|
1140
|
+
typeSource = "default";
|
|
1199
1141
|
} else {
|
|
1200
|
-
|
|
1142
|
+
const selectedType = await client.input.select({
|
|
1143
|
+
message: "Environment Variable type?",
|
|
1144
|
+
choices: [
|
|
1145
|
+
{
|
|
1146
|
+
name: getSecretStorageChoice(
|
|
1147
|
+
envTargets,
|
|
1148
|
+
looksLikeCredentialName(envName) ? "because this name looks like a credential" : void 0
|
|
1149
|
+
),
|
|
1150
|
+
value: "secret"
|
|
1151
|
+
},
|
|
1152
|
+
{ name: "Config (can be revealed after saving)", value: "config" }
|
|
1153
|
+
]
|
|
1154
|
+
});
|
|
1155
|
+
isSensitive = selectedType === "secret";
|
|
1156
|
+
explicitType = selectedType;
|
|
1157
|
+
typeSource = "prompt";
|
|
1201
1158
|
}
|
|
1202
1159
|
if (envTargets.length > 0) {
|
|
1203
1160
|
const compatibilityError = getTargetCompatibilityError(
|
|
@@ -1277,7 +1234,7 @@ async function add(client, argv) {
|
|
|
1277
1234
|
}
|
|
1278
1235
|
envValue = await promptEnvValue(client, { isSensitive });
|
|
1279
1236
|
}
|
|
1280
|
-
|
|
1237
|
+
let { finalValue } = await validateEnvValue({
|
|
1281
1238
|
envName,
|
|
1282
1239
|
initialValue: envValue,
|
|
1283
1240
|
skipConfirm,
|
|
@@ -1398,13 +1355,189 @@ async function add(client, argv) {
|
|
|
1398
1355
|
finalType = "sensitive";
|
|
1399
1356
|
}
|
|
1400
1357
|
}
|
|
1358
|
+
while (finalType === "encrypted" && (looksLikeCredentialName(envName, customSveltePublicPrefix) || looksLikeSecretValue(finalValue))) {
|
|
1359
|
+
printEnvAddWarning(
|
|
1360
|
+
"This name or value looks like a credential. Config values can be revealed after saving."
|
|
1361
|
+
);
|
|
1362
|
+
const publicPrefix = getApiPublicPrefix(envName) ?? getFrameworkPublicPrefix(project.framework, envName) ?? customSveltePublicPrefix;
|
|
1363
|
+
if (publicPrefix !== void 0 && typeSource === "inferred") {
|
|
1364
|
+
const privateName = envName.slice(publicPrefix.length);
|
|
1365
|
+
const privateCommand = buildEnvAddCommandWithPreservedArgs(
|
|
1366
|
+
client.argv,
|
|
1367
|
+
`env add ${privateName} ${envTargets.join(
|
|
1368
|
+
","
|
|
1369
|
+
)} --type secret --value "<value>" --yes`
|
|
1370
|
+
);
|
|
1371
|
+
const publicCommand = buildEnvAddCommandWithPreservedArgs(
|
|
1372
|
+
client.argv,
|
|
1373
|
+
`env add ${envName} ${envTargets.join(
|
|
1374
|
+
","
|
|
1375
|
+
)} --type config --value "<value>" --yes`
|
|
1376
|
+
);
|
|
1377
|
+
const privateHumanCommand = buildHumanEnvAddCommand(
|
|
1378
|
+
client.argv,
|
|
1379
|
+
`env add ${privateName} ${envTargets.join(",")} --type secret`
|
|
1380
|
+
);
|
|
1381
|
+
const publicHumanCommand = buildHumanEnvAddCommand(
|
|
1382
|
+
client.argv,
|
|
1383
|
+
`env add ${envName} ${envTargets.join(",")} --type config`
|
|
1384
|
+
);
|
|
1385
|
+
const message = publicPrefix === "" ? `\`${envName}\` looks like a credential, and this SvelteKit project exposes every Environment Variable to the browser. Change the SvelteKit \`publicPrefix\` to keep it private, or use \`--type config\` only if the value is safe to expose.` : `\`${envName}\` looks like a credential, and \`${publicPrefix}\` exposes its value to anyone visiting your site. Choose explicitly: rename to \`${privateName}\` with \`--type secret\` to keep it private, or keep the name with \`--type config\` to expose it.`;
|
|
1386
|
+
if (client.nonInteractive) {
|
|
1387
|
+
outputActionRequired(client, {
|
|
1388
|
+
status: "action_required",
|
|
1389
|
+
reason: "public_prefix_requires_type",
|
|
1390
|
+
message,
|
|
1391
|
+
next: [
|
|
1392
|
+
...publicPrefix === "" ? [] : [
|
|
1393
|
+
{
|
|
1394
|
+
command: privateCommand,
|
|
1395
|
+
when: "Keep it private; replace <value> before running"
|
|
1396
|
+
}
|
|
1397
|
+
],
|
|
1398
|
+
{
|
|
1399
|
+
command: publicCommand,
|
|
1400
|
+
when: "Expose it publicly; replace <value> before running"
|
|
1401
|
+
}
|
|
1402
|
+
]
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
if (opts["--yes"]) {
|
|
1406
|
+
output_manager_default.fatal(message);
|
|
1407
|
+
if (publicPrefix !== "") {
|
|
1408
|
+
output_manager_default.print(` Keep it private:
|
|
1409
|
+
${privateHumanCommand}
|
|
1410
|
+
`);
|
|
1411
|
+
}
|
|
1412
|
+
output_manager_default.print(` Expose it publicly:
|
|
1413
|
+
${publicHumanCommand}
|
|
1414
|
+
`);
|
|
1415
|
+
return 1;
|
|
1416
|
+
}
|
|
1417
|
+
const selectedAction = await client.input.select({
|
|
1418
|
+
message: "How should this variable be stored?",
|
|
1419
|
+
choices: [
|
|
1420
|
+
...publicPrefix === "" ? [] : [
|
|
1421
|
+
{
|
|
1422
|
+
name: `Keep private: rename to ${privateName} and use Secret`,
|
|
1423
|
+
value: "private"
|
|
1424
|
+
}
|
|
1425
|
+
],
|
|
1426
|
+
{
|
|
1427
|
+
name: `Expose to anyone visiting your site: keep ${envName} as Config`,
|
|
1428
|
+
value: "public"
|
|
1429
|
+
},
|
|
1430
|
+
{ name: "Enter a different value", value: "reenter" }
|
|
1431
|
+
]
|
|
1432
|
+
});
|
|
1433
|
+
if (selectedAction === "private") {
|
|
1434
|
+
envName = privateName;
|
|
1435
|
+
finalType = "sensitive";
|
|
1436
|
+
explicitType = "secret";
|
|
1437
|
+
typeSource = "prompt";
|
|
1438
|
+
output_manager_default.log(`Renamed to ${envName}`);
|
|
1439
|
+
break;
|
|
1440
|
+
}
|
|
1441
|
+
if (selectedAction === "reenter") {
|
|
1442
|
+
const reenteredValue = await promptEnvValue(client, {
|
|
1443
|
+
isSensitive: false
|
|
1444
|
+
});
|
|
1445
|
+
const validated = await validateEnvValue({
|
|
1446
|
+
envName,
|
|
1447
|
+
initialValue: reenteredValue,
|
|
1448
|
+
skipConfirm: false,
|
|
1449
|
+
promptForValue: () => promptEnvValue(client, { isSensitive: false }),
|
|
1450
|
+
selectAction: (choices2) => client.input.select({ message: "Value?", choices: choices2 }),
|
|
1451
|
+
showWarning: (msg) => printEnvAddWarning(msg),
|
|
1452
|
+
showLog: (msg) => output_manager_default.log(msg)
|
|
1453
|
+
});
|
|
1454
|
+
finalValue = validated.finalValue;
|
|
1455
|
+
continue;
|
|
1456
|
+
}
|
|
1457
|
+
} else if (typeSource !== "argv" && typeSource !== "prompt" && !opts["--yes"] && !client.nonInteractive) {
|
|
1458
|
+
const selectedType = await client.input.select({
|
|
1459
|
+
message: "Store this value as?",
|
|
1460
|
+
choices: [
|
|
1461
|
+
{
|
|
1462
|
+
name: getSecretStorageChoice(envTargets, "for this value"),
|
|
1463
|
+
value: "secret"
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
name: "Config (can be revealed after saving)",
|
|
1467
|
+
value: "config"
|
|
1468
|
+
}
|
|
1469
|
+
]
|
|
1470
|
+
});
|
|
1471
|
+
if (selectedType === "secret") {
|
|
1472
|
+
finalType = "sensitive";
|
|
1473
|
+
explicitType = "secret";
|
|
1474
|
+
typeSource = "prompt";
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
break;
|
|
1478
|
+
}
|
|
1479
|
+
if (finalType === "sensitive" && customSveltePublicPrefix !== void 0 && envName.startsWith(customSveltePublicPrefix)) {
|
|
1480
|
+
printEnvAddWarning(
|
|
1481
|
+
"This SvelteKit project exposes this variable to the browser; the Secret type does not prevent that. Rename the variable without the configured public prefix to keep it private."
|
|
1482
|
+
);
|
|
1483
|
+
}
|
|
1484
|
+
if (isFlagsSecretNeedingSplit({
|
|
1485
|
+
key: envName,
|
|
1486
|
+
type: finalType,
|
|
1487
|
+
targets: envTargets.filter(isValidEnvTarget),
|
|
1488
|
+
customEnvironmentIds: envTargets.filter(
|
|
1489
|
+
(target) => !isValidEnvTarget(target)
|
|
1490
|
+
)
|
|
1491
|
+
})) {
|
|
1492
|
+
printEnvAddWarning(
|
|
1493
|
+
"FLAGS_SECRET should use a separate value for each environment so Development overrides cannot affect Preview or Production."
|
|
1494
|
+
);
|
|
1495
|
+
}
|
|
1496
|
+
const hasProduction = envTargets.includes("production");
|
|
1497
|
+
const hasNonProduction = envTargets.some((target) => target !== "production");
|
|
1498
|
+
if (finalType === "sensitive" && disjunctiveProductionSecretPolicyOn && hasProduction && hasNonProduction) {
|
|
1499
|
+
const message = "Your team requires Production and non-Production Secrets to be stored separately with different values. Run one command for Production and another for the remaining environments.";
|
|
1500
|
+
if (client.nonInteractive) {
|
|
1501
|
+
outputAgentError(
|
|
1502
|
+
client,
|
|
1503
|
+
{
|
|
1504
|
+
status: "error",
|
|
1505
|
+
reason: "production_secret_must_be_separate",
|
|
1506
|
+
message,
|
|
1507
|
+
next: [
|
|
1508
|
+
{
|
|
1509
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
1510
|
+
client.argv,
|
|
1511
|
+
`env add ${envName} production --type secret --value "<production-value>" --yes`
|
|
1512
|
+
),
|
|
1513
|
+
when: "Set the Production Secret"
|
|
1514
|
+
},
|
|
1515
|
+
{
|
|
1516
|
+
command: buildEnvAddCommandWithPreservedArgs(
|
|
1517
|
+
client.argv,
|
|
1518
|
+
`env add ${envName} ${envTargets.filter((target) => target !== "production").join(
|
|
1519
|
+
","
|
|
1520
|
+
)} --type secret --value "<non-production-value>" --yes`
|
|
1521
|
+
),
|
|
1522
|
+
when: "Set the non-Production Secret"
|
|
1523
|
+
}
|
|
1524
|
+
]
|
|
1525
|
+
},
|
|
1526
|
+
1
|
|
1527
|
+
);
|
|
1528
|
+
}
|
|
1529
|
+
output_manager_default.fatal(message);
|
|
1530
|
+
return 1;
|
|
1531
|
+
}
|
|
1401
1532
|
const upsert = opts["--force"] ? "true" : "";
|
|
1402
1533
|
const { visibility, error: visibilityError } = resolveEnvVarVisibility({
|
|
1403
|
-
explicitVisibility,
|
|
1534
|
+
explicitVisibility: explicitType,
|
|
1535
|
+
explicitOptionSource: typeOption.source,
|
|
1404
1536
|
type: finalType,
|
|
1405
1537
|
key: envName,
|
|
1406
1538
|
envTargets,
|
|
1407
|
-
teamSensitivePolicyOn
|
|
1539
|
+
teamSensitivePolicyOn,
|
|
1540
|
+
context: "add"
|
|
1408
1541
|
});
|
|
1409
1542
|
if (visibilityError) {
|
|
1410
1543
|
if (client.nonInteractive) {
|
|
@@ -1412,13 +1545,13 @@ async function add(client, argv) {
|
|
|
1412
1545
|
client,
|
|
1413
1546
|
{
|
|
1414
1547
|
status: "error",
|
|
1415
|
-
reason: "
|
|
1548
|
+
reason: "invalid_type",
|
|
1416
1549
|
message: visibilityError
|
|
1417
1550
|
},
|
|
1418
1551
|
1
|
|
1419
1552
|
);
|
|
1420
1553
|
}
|
|
1421
|
-
output_manager_default.
|
|
1554
|
+
output_manager_default.fatal(visibilityError);
|
|
1422
1555
|
return 1;
|
|
1423
1556
|
}
|
|
1424
1557
|
try {
|
|
@@ -1436,13 +1569,18 @@ async function add(client, argv) {
|
|
|
1436
1569
|
);
|
|
1437
1570
|
} catch (err) {
|
|
1438
1571
|
if (client.nonInteractive && isAPIError(err)) {
|
|
1439
|
-
const
|
|
1572
|
+
const productionSecretPolicyError = getProductionSecretPolicyErrorKind(
|
|
1573
|
+
err.serverMessage
|
|
1574
|
+
);
|
|
1575
|
+
const reason = productionSecretPolicyError ? productionSecretPolicyError === "different-values" ? "production_secret_requires_different_value" : "production_secret_must_be_separate" : err.slug || (err.serverMessage?.toLowerCase().includes("branch") ? "branch_not_found" : "api_error");
|
|
1440
1576
|
outputAgentError(
|
|
1441
1577
|
client,
|
|
1442
1578
|
{
|
|
1443
1579
|
status: "error",
|
|
1444
1580
|
reason,
|
|
1445
|
-
message: err.serverMessage
|
|
1581
|
+
message: productionSecretPolicyError ? `${err.serverMessage} ${getProductionSecretPolicyRecovery(
|
|
1582
|
+
productionSecretPolicyError
|
|
1583
|
+
)}` : err.serverMessage
|
|
1446
1584
|
},
|
|
1447
1585
|
1
|
|
1448
1586
|
);
|
|
@@ -1463,13 +1601,30 @@ async function add(client, argv) {
|
|
|
1463
1601
|
Boolean(opts["--force"]),
|
|
1464
1602
|
visibility
|
|
1465
1603
|
);
|
|
1466
|
-
|
|
1467
|
-
|
|
1604
|
+
if (typeSource === "default") {
|
|
1605
|
+
output_manager_default.print(
|
|
1606
|
+
` ${import_chalk.default.dim(getDefaultSecretStorageGuidance(envTargets))}
|
|
1607
|
+
`
|
|
1608
|
+
);
|
|
1609
|
+
}
|
|
1610
|
+
const { isAgent } = await determineAgent();
|
|
1611
|
+
const guidanceMode = isGuidanceEnabled(
|
|
1612
|
+
client,
|
|
1613
|
+
parsedArgs.flags["--guidance"],
|
|
1614
|
+
isAgent
|
|
1615
|
+
);
|
|
1468
1616
|
if (guidanceMode) {
|
|
1469
|
-
const projectFlag = opts["--project"] ? ` --project ${opts["--project"]}` : "";
|
|
1470
1617
|
suggestNextCommands([
|
|
1471
|
-
|
|
1472
|
-
|
|
1618
|
+
{
|
|
1619
|
+
description: "List Environment Variables",
|
|
1620
|
+
command: withGlobalFlags(client, "env ls", { preserveProject: true })
|
|
1621
|
+
},
|
|
1622
|
+
{
|
|
1623
|
+
description: "Pull Development Environment Variables into .env.local",
|
|
1624
|
+
command: withGlobalFlags(client, "env pull", {
|
|
1625
|
+
preserveProject: true
|
|
1626
|
+
})
|
|
1627
|
+
}
|
|
1473
1628
|
]);
|
|
1474
1629
|
}
|
|
1475
1630
|
return 0;
|
|
@@ -1597,7 +1752,7 @@ async function ls(client, argv) {
|
|
|
1597
1752
|
const jsonOutput = {
|
|
1598
1753
|
envs: envs.map((env) => ({
|
|
1599
1754
|
key: env.key,
|
|
1600
|
-
value:
|
|
1755
|
+
value: isSecretEnvVar(env) ? void 0 : env.value,
|
|
1601
1756
|
type: env.type,
|
|
1602
1757
|
visibility: env.visibility,
|
|
1603
1758
|
target: env.target,
|
|
@@ -1622,13 +1777,31 @@ async function ls(client, argv) {
|
|
|
1622
1777
|
}
|
|
1623
1778
|
if (!asJson) {
|
|
1624
1779
|
const { isAgent } = await determineAgent2();
|
|
1625
|
-
const guidanceMode =
|
|
1780
|
+
const guidanceMode = isGuidanceEnabled(
|
|
1781
|
+
client,
|
|
1782
|
+
parsedArgs.flags["--guidance"],
|
|
1783
|
+
isAgent
|
|
1784
|
+
);
|
|
1626
1785
|
if (guidanceMode) {
|
|
1627
|
-
const projectFlag = projectName ? ` --project ${projectName}` : "";
|
|
1628
1786
|
suggestNextCommands([
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1787
|
+
{
|
|
1788
|
+
description: "Add an Environment Variable",
|
|
1789
|
+
command: withGlobalFlags(client, "env add", {
|
|
1790
|
+
preserveProject: true
|
|
1791
|
+
})
|
|
1792
|
+
},
|
|
1793
|
+
{
|
|
1794
|
+
description: "Remove an Environment Variable",
|
|
1795
|
+
command: withGlobalFlags(client, "env rm", {
|
|
1796
|
+
preserveProject: true
|
|
1797
|
+
})
|
|
1798
|
+
},
|
|
1799
|
+
{
|
|
1800
|
+
description: "Pull Development Environment Variables into .env.local",
|
|
1801
|
+
command: withGlobalFlags(client, "env pull", {
|
|
1802
|
+
preserveProject: true
|
|
1803
|
+
})
|
|
1804
|
+
}
|
|
1632
1805
|
]);
|
|
1633
1806
|
}
|
|
1634
1807
|
}
|
|
@@ -1649,7 +1822,7 @@ function getTable(link, records, customEnvironments) {
|
|
|
1649
1822
|
}
|
|
1650
1823
|
function getRow(link, env, customEnvironments) {
|
|
1651
1824
|
let value;
|
|
1652
|
-
if (
|
|
1825
|
+
if (isSecretEnvVar(env)) {
|
|
1653
1826
|
value = import_chalk2.default.gray.italic("Hidden");
|
|
1654
1827
|
} else if (env.type === "system") {
|
|
1655
1828
|
value = import_chalk2.default.gray.italic(env.value);
|
|
@@ -1666,14 +1839,14 @@ function getRow(link, env, customEnvironments) {
|
|
|
1666
1839
|
env.createdAt ? `${(0, import_ms.default)(now - env.createdAt)} ago` : ""
|
|
1667
1840
|
];
|
|
1668
1841
|
}
|
|
1669
|
-
function isSensitiveEnvironmentVariable(env) {
|
|
1670
|
-
return env.type === "sensitive" || env.visibility === "secret";
|
|
1671
|
-
}
|
|
1672
1842
|
function getEnvironmentVariableTypeLabel(env) {
|
|
1673
|
-
if (
|
|
1674
|
-
return "
|
|
1843
|
+
if (isSecretEnvVar(env)) {
|
|
1844
|
+
return "Secret";
|
|
1845
|
+
}
|
|
1846
|
+
if (env.type === "system") {
|
|
1847
|
+
return "System";
|
|
1675
1848
|
}
|
|
1676
|
-
return
|
|
1849
|
+
return "Config";
|
|
1677
1850
|
}
|
|
1678
1851
|
|
|
1679
1852
|
// src/commands/env/rm.ts
|
|
@@ -1724,6 +1897,10 @@ var EnvRmTelemetryClient = class extends TelemetryClient {
|
|
|
1724
1897
|
};
|
|
1725
1898
|
|
|
1726
1899
|
// src/commands/env/rm.ts
|
|
1900
|
+
function printEnvRmWarning(message) {
|
|
1901
|
+
output_manager_default.print(`${import_chalk3.default.yellow("!")} ${message}
|
|
1902
|
+
`);
|
|
1903
|
+
}
|
|
1727
1904
|
async function rm(client, argv) {
|
|
1728
1905
|
const telemetryClient = new EnvRmTelemetryClient({
|
|
1729
1906
|
opts: {
|
|
@@ -1757,9 +1934,9 @@ async function rm(client, argv) {
|
|
|
1757
1934
|
{
|
|
1758
1935
|
status: "error",
|
|
1759
1936
|
reason: "invalid_arguments",
|
|
1760
|
-
message: `Invalid number of arguments. Usage:
|
|
1937
|
+
message: `Invalid number of arguments. Usage: \`${getCommandNamePlain(
|
|
1761
1938
|
`env rm <name> ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
1762
|
-
)}
|
|
1939
|
+
)}\``
|
|
1763
1940
|
},
|
|
1764
1941
|
1
|
|
1765
1942
|
);
|
|
@@ -1800,9 +1977,9 @@ async function rm(client, argv) {
|
|
|
1800
1977
|
{
|
|
1801
1978
|
status: "error",
|
|
1802
1979
|
reason: "not_linked",
|
|
1803
|
-
message: `Your codebase isn't linked to a project on Vercel. Run
|
|
1980
|
+
message: `Your codebase isn't linked to a project on Vercel. Run \`${getCommandNamePlain(
|
|
1804
1981
|
"link"
|
|
1805
|
-
)} to begin. Use
|
|
1982
|
+
)}\` to begin. Use \`--yes\` for non-interactive; use \`--scope\` or \`--project\` to specify team or project.`,
|
|
1806
1983
|
next: [
|
|
1807
1984
|
{ command: buildCommandWithYes(linkArgv) },
|
|
1808
1985
|
{ command: buildCommandWithYes(client.argv) }
|
|
@@ -1828,7 +2005,7 @@ async function rm(client, argv) {
|
|
|
1828
2005
|
{
|
|
1829
2006
|
status: "action_required",
|
|
1830
2007
|
reason: "missing_name",
|
|
1831
|
-
message: "Provide the variable name as an argument. Example: vercel env rm <name> --yes",
|
|
2008
|
+
message: "Provide the variable name as an argument. Example: `vercel env rm <name> --yes`",
|
|
1832
2009
|
next: [
|
|
1833
2010
|
{
|
|
1834
2011
|
command: buildEnvRmCommandWithPreservedArgs(
|
|
@@ -1903,6 +2080,15 @@ async function rm(client, argv) {
|
|
|
1903
2080
|
envs = envs.filter((env2) => env2.id === id);
|
|
1904
2081
|
}
|
|
1905
2082
|
const env = envs[0];
|
|
2083
|
+
const shouldWarnAboutRotation = shouldConfirmRotationBeforeDelete({
|
|
2084
|
+
key: env.key,
|
|
2085
|
+
type: env.type,
|
|
2086
|
+
hasPublicPrefix: getPublicPrefix(env.key) !== null
|
|
2087
|
+
});
|
|
2088
|
+
const rotationWarning = "Removing this variable from Vercel does not revoke the credential. Rotate or disable it at its provider.";
|
|
2089
|
+
if (shouldWarnAboutRotation) {
|
|
2090
|
+
printEnvRmWarning(rotationWarning);
|
|
2091
|
+
}
|
|
1906
2092
|
const skipConfirmation = opts["--yes"];
|
|
1907
2093
|
if (!skipConfirmation) {
|
|
1908
2094
|
if (client.nonInteractive) {
|
|
@@ -1911,18 +2097,18 @@ async function rm(client, argv) {
|
|
|
1911
2097
|
{
|
|
1912
2098
|
status: "action_required",
|
|
1913
2099
|
reason: "confirmation_required",
|
|
1914
|
-
message: `Removing Environment Variable ${env.key}. Use --yes to confirm.`,
|
|
2100
|
+
message: `Removing Environment Variable ${env.key}. ${shouldWarnAboutRotation ? `${rotationWarning} ` : ""}Use --yes to confirm.`,
|
|
1915
2101
|
next: [{ command: buildCommandWithYes(client.argv) }]
|
|
1916
2102
|
},
|
|
1917
2103
|
1
|
|
1918
2104
|
);
|
|
1919
2105
|
}
|
|
1920
2106
|
if (!await client.input.confirm(
|
|
1921
|
-
`
|
|
2107
|
+
`Remove ${param(env.key)} from ${formatEnvironments(
|
|
1922
2108
|
link,
|
|
1923
2109
|
env,
|
|
1924
2110
|
customEnvironments
|
|
1925
|
-
)} in Project ${import_chalk3.default.bold(project.name)}
|
|
2111
|
+
)} in Project ${import_chalk3.default.bold(project.name)}?`,
|
|
1926
2112
|
false
|
|
1927
2113
|
)) {
|
|
1928
2114
|
output_manager_default.log("Canceled");
|
|
@@ -1964,7 +2150,21 @@ async function rm(client, argv) {
|
|
|
1964
2150
|
|
|
1965
2151
|
// src/commands/env/run.ts
|
|
1966
2152
|
var import_env = __toESM(require_dist3(), 1);
|
|
2153
|
+
var import_chalk4 = __toESM(require_source(), 1);
|
|
1967
2154
|
var import_execa = __toESM(require_execa(), 1);
|
|
2155
|
+
function printEnvRunWarning(message) {
|
|
2156
|
+
output_manager_default.print(`${import_chalk4.default.yellow("!")} ${message}
|
|
2157
|
+
`);
|
|
2158
|
+
}
|
|
2159
|
+
function omitUnavailableSecretPlaceholders(localEnv, secretKeys) {
|
|
2160
|
+
const safeLocalEnv = { ...localEnv };
|
|
2161
|
+
for (const key of secretKeys) {
|
|
2162
|
+
if (safeLocalEnv[key] === SENSITIVE_ENV_VALUE_PLACEHOLDER) {
|
|
2163
|
+
delete safeLocalEnv[key];
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
return safeLocalEnv;
|
|
2167
|
+
}
|
|
1968
2168
|
function parseRunArgs(argv) {
|
|
1969
2169
|
const argvIndex = argv.indexOf("--");
|
|
1970
2170
|
const hasDoubleDash = argvIndex !== -1;
|
|
@@ -1993,6 +2193,16 @@ async function run(client, telemetry) {
|
|
|
1993
2193
|
return 1;
|
|
1994
2194
|
}
|
|
1995
2195
|
if (userCommand.length === 0) {
|
|
2196
|
+
outputActionRequired(
|
|
2197
|
+
client,
|
|
2198
|
+
{
|
|
2199
|
+
status: "action_required",
|
|
2200
|
+
reason: "missing_command",
|
|
2201
|
+
message: "No command provided. Use `--` to separate Vercel flags from your command.",
|
|
2202
|
+
next: [{ command: getCommandNamePlain("env run -- <command>") }]
|
|
2203
|
+
},
|
|
2204
|
+
1
|
|
2205
|
+
);
|
|
1996
2206
|
output_manager_default.error(
|
|
1997
2207
|
`No command provided. Use \`--\` to separate vercel flags from your command.`
|
|
1998
2208
|
);
|
|
@@ -2007,6 +2217,16 @@ async function run(client, telemetry) {
|
|
|
2007
2217
|
if (link.status === "error") {
|
|
2008
2218
|
return link.exitCode;
|
|
2009
2219
|
} else if (link.status === "not_linked") {
|
|
2220
|
+
outputActionRequired(
|
|
2221
|
+
client,
|
|
2222
|
+
{
|
|
2223
|
+
status: "action_required",
|
|
2224
|
+
reason: "not_linked",
|
|
2225
|
+
message: "Your codebase isn't linked to a project on Vercel. Run `vercel link`, then retry this command.",
|
|
2226
|
+
next: [{ command: getCommandNamePlain("link") }]
|
|
2227
|
+
},
|
|
2228
|
+
1
|
|
2229
|
+
);
|
|
2010
2230
|
output_manager_default.error(
|
|
2011
2231
|
`Your codebase isn't linked to a project on Vercel. Run ${getCommandName(
|
|
2012
2232
|
"link"
|
|
@@ -2040,6 +2260,45 @@ async function run(client, telemetry) {
|
|
|
2040
2260
|
} catch (err) {
|
|
2041
2261
|
output_manager_default.debug(`Failed to load local env files: ${err}`);
|
|
2042
2262
|
}
|
|
2263
|
+
const localPlaceholderKeys = Object.entries(localEnv).filter(([, value]) => value === SENSITIVE_ENV_VALUE_PLACEHOLDER).map(([key]) => key);
|
|
2264
|
+
const safeLocalEnv = omitUnavailableSecretPlaceholders(
|
|
2265
|
+
localEnv,
|
|
2266
|
+
localPlaceholderKeys
|
|
2267
|
+
);
|
|
2268
|
+
const processPlaceholderKeys = Object.keys(records.env).filter(
|
|
2269
|
+
(key) => process.env[key] === SENSITIVE_ENV_VALUE_PLACEHOLDER
|
|
2270
|
+
);
|
|
2271
|
+
const safeProcessEnv = omitUnavailableSecretPlaceholders(
|
|
2272
|
+
process.env,
|
|
2273
|
+
processPlaceholderKeys
|
|
2274
|
+
);
|
|
2275
|
+
const unavailableCandidateKeys = new Set(
|
|
2276
|
+
Object.entries(records.env).filter(
|
|
2277
|
+
([key, value]) => !value && !safeLocalEnv[key] && !safeProcessEnv[key]
|
|
2278
|
+
).map(([key]) => key)
|
|
2279
|
+
);
|
|
2280
|
+
if (unavailableCandidateKeys.size > 0) {
|
|
2281
|
+
try {
|
|
2282
|
+
const { envs } = await getEnvRecords(
|
|
2283
|
+
client,
|
|
2284
|
+
link.project.id,
|
|
2285
|
+
"vercel-cli:env:run",
|
|
2286
|
+
{ target: environment, gitBranch }
|
|
2287
|
+
);
|
|
2288
|
+
const unavailableSecretKeys = envs.filter(
|
|
2289
|
+
(env) => isSecretEnvVar(env) && unavailableCandidateKeys.has(env.key)
|
|
2290
|
+
);
|
|
2291
|
+
if (unavailableSecretKeys.length > 0) {
|
|
2292
|
+
printEnvRunWarning(
|
|
2293
|
+
`${getUnavailableSecretValuesMessage(
|
|
2294
|
+
environment,
|
|
2295
|
+
unavailableSecretKeys.length
|
|
2296
|
+
)}${getLocalSecretFallbackMessage(unavailableSecretKeys.length)}`
|
|
2297
|
+
);
|
|
2298
|
+
}
|
|
2299
|
+
} catch {
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2043
2302
|
try {
|
|
2044
2303
|
const result = await (0, import_execa.default)(userCommand[0], userCommand.slice(1), {
|
|
2045
2304
|
cwd: client.cwd,
|
|
@@ -2047,8 +2306,8 @@ async function run(client, telemetry) {
|
|
|
2047
2306
|
reject: false,
|
|
2048
2307
|
env: {
|
|
2049
2308
|
...records.env,
|
|
2050
|
-
...
|
|
2051
|
-
...
|
|
2309
|
+
...safeLocalEnv,
|
|
2310
|
+
...safeProcessEnv
|
|
2052
2311
|
}
|
|
2053
2312
|
});
|
|
2054
2313
|
if (result instanceof Error && typeof result.exitCode !== "number") {
|
|
@@ -2063,10 +2322,10 @@ async function run(client, telemetry) {
|
|
|
2063
2322
|
}
|
|
2064
2323
|
|
|
2065
2324
|
// src/commands/env/update.ts
|
|
2066
|
-
var
|
|
2325
|
+
var import_chalk5 = __toESM(require_source(), 1);
|
|
2067
2326
|
|
|
2068
2327
|
// src/util/env/update-env-record.ts
|
|
2069
|
-
var
|
|
2328
|
+
var import_constants3 = __toESM(require_dist2(), 1);
|
|
2070
2329
|
async function updateEnvRecord(client, projectId, envId, type, key, value, targets, gitBranch, visibility) {
|
|
2071
2330
|
output_manager_default.debug(
|
|
2072
2331
|
`Updating ${type} Environment Variable ${key} in ${targets.length} targets`
|
|
@@ -2074,7 +2333,7 @@ async function updateEnvRecord(client, projectId, envId, type, key, value, targe
|
|
|
2074
2333
|
const target = [];
|
|
2075
2334
|
const customEnvironmentIds = [];
|
|
2076
2335
|
for (const t of targets) {
|
|
2077
|
-
const arr =
|
|
2336
|
+
const arr = import_constants3.PROJECT_ENV_TARGET.includes(t) ? target : customEnvironmentIds;
|
|
2078
2337
|
arr.push(t);
|
|
2079
2338
|
}
|
|
2080
2339
|
const body = {
|
|
@@ -2150,9 +2409,51 @@ var EnvUpdateTelemetryClient = class extends TelemetryClient {
|
|
|
2150
2409
|
});
|
|
2151
2410
|
}
|
|
2152
2411
|
}
|
|
2412
|
+
trackCliOptionType(type) {
|
|
2413
|
+
if (type) {
|
|
2414
|
+
const validTypes = ["config", "secret"];
|
|
2415
|
+
this.trackCliOption({
|
|
2416
|
+
option: "type",
|
|
2417
|
+
value: validTypes.includes(type) ? type : this.redactedValue
|
|
2418
|
+
});
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2153
2421
|
};
|
|
2154
2422
|
|
|
2155
2423
|
// src/commands/env/update.ts
|
|
2424
|
+
function looksLikeCredentialName2(key, publicPrefix = getPublicPrefix(key)) {
|
|
2425
|
+
return looksLikeSecret(publicPrefix ? key.slice(publicPrefix.length) : key);
|
|
2426
|
+
}
|
|
2427
|
+
function printEnvUpdateWarning(message) {
|
|
2428
|
+
output_manager_default.print(`${import_chalk5.default.yellow("!")} ${message}
|
|
2429
|
+
`);
|
|
2430
|
+
}
|
|
2431
|
+
function omitEnvValueArgs(argv) {
|
|
2432
|
+
const out = [];
|
|
2433
|
+
for (let i = 0; i < argv.length; i++) {
|
|
2434
|
+
if (argv[i] === "--value") {
|
|
2435
|
+
i++;
|
|
2436
|
+
continue;
|
|
2437
|
+
}
|
|
2438
|
+
if (argv[i].startsWith("--value="))
|
|
2439
|
+
continue;
|
|
2440
|
+
out.push(argv[i]);
|
|
2441
|
+
}
|
|
2442
|
+
return out;
|
|
2443
|
+
}
|
|
2444
|
+
function formatTargetArg(targets, customEnvironments) {
|
|
2445
|
+
return targets.map(
|
|
2446
|
+
(target) => customEnvironments.find(
|
|
2447
|
+
(environment) => environment.id === target || environment.slug === target
|
|
2448
|
+
)?.slug ?? target
|
|
2449
|
+
).join(",");
|
|
2450
|
+
}
|
|
2451
|
+
function promptEnvUpdateValue(client, envName, isSecret) {
|
|
2452
|
+
return client.input.text({
|
|
2453
|
+
message: `What's the new value of ${envName}?`,
|
|
2454
|
+
...isSecret ? { transformer: (value) => "*".repeat(value.length) } : {}
|
|
2455
|
+
});
|
|
2456
|
+
}
|
|
2156
2457
|
async function update(client, argv) {
|
|
2157
2458
|
let parsedArgs;
|
|
2158
2459
|
const flagsSpecification = getFlagsSpecification(updateSubcommand.options);
|
|
@@ -2177,6 +2478,12 @@ async function update(client, argv) {
|
|
|
2177
2478
|
const valueFromFlag = typeof opts["--value"] === "string" ? opts["--value"] : void 0;
|
|
2178
2479
|
const stdInput = await readStandardInput(client.stdin);
|
|
2179
2480
|
let [envName, envTargetArg, envGitBranch] = args;
|
|
2481
|
+
const typeOption = resolveEnvVarTypeOption({
|
|
2482
|
+
type: typeof opts["--type"] === "string" ? opts["--type"] : void 0,
|
|
2483
|
+
visibility: typeof opts["--visibility"] === "string" ? opts["--visibility"] : void 0
|
|
2484
|
+
});
|
|
2485
|
+
let explicitType = typeOption.explicitVisibility;
|
|
2486
|
+
const typeWasExplicit = explicitType !== void 0 || Boolean(opts["--sensitive"]);
|
|
2180
2487
|
const telemetryClient = new EnvUpdateTelemetryClient({
|
|
2181
2488
|
opts: {
|
|
2182
2489
|
store: client.telemetryEventStore
|
|
@@ -2187,10 +2494,49 @@ async function update(client, argv) {
|
|
|
2187
2494
|
telemetryClient.trackCliArgumentGitBranch(envGitBranch);
|
|
2188
2495
|
telemetryClient.trackCliFlagSensitive(opts["--sensitive"]);
|
|
2189
2496
|
telemetryClient.trackCliFlagYes(opts["--yes"]);
|
|
2190
|
-
telemetryClient.trackCliOptionValue(
|
|
2497
|
+
telemetryClient.trackCliOptionValue(
|
|
2498
|
+
valueFromFlag === void 0 ? void 0 : "<redacted>"
|
|
2499
|
+
);
|
|
2500
|
+
telemetryClient.trackCliOptionType(
|
|
2501
|
+
typeof opts["--type"] === "string" ? opts["--type"] : void 0
|
|
2502
|
+
);
|
|
2191
2503
|
telemetryClient.trackCliOptionVisibility(
|
|
2192
2504
|
typeof opts["--visibility"] === "string" ? opts["--visibility"] : void 0
|
|
2193
2505
|
);
|
|
2506
|
+
if (typeOption.error) {
|
|
2507
|
+
if (client.nonInteractive) {
|
|
2508
|
+
outputAgentError(
|
|
2509
|
+
client,
|
|
2510
|
+
{
|
|
2511
|
+
status: "error",
|
|
2512
|
+
reason: typeOption.errorReason ?? "invalid_type",
|
|
2513
|
+
message: typeOption.error
|
|
2514
|
+
},
|
|
2515
|
+
1
|
|
2516
|
+
);
|
|
2517
|
+
}
|
|
2518
|
+
output_manager_default.fatal(typeOption.error);
|
|
2519
|
+
return 1;
|
|
2520
|
+
}
|
|
2521
|
+
if (typeOption.usedDeprecatedVisibility) {
|
|
2522
|
+
printEnvUpdateWarning(ENV_VISIBILITY_DEPRECATION_MESSAGE);
|
|
2523
|
+
}
|
|
2524
|
+
if (explicitType === "config" && opts["--sensitive"]) {
|
|
2525
|
+
const message = "`--type config` cannot be used with `--sensitive`. Pick one.";
|
|
2526
|
+
if (client.nonInteractive) {
|
|
2527
|
+
outputAgentError(
|
|
2528
|
+
client,
|
|
2529
|
+
{
|
|
2530
|
+
status: "error",
|
|
2531
|
+
reason: "conflicting_type_flags",
|
|
2532
|
+
message
|
|
2533
|
+
},
|
|
2534
|
+
1
|
|
2535
|
+
);
|
|
2536
|
+
}
|
|
2537
|
+
output_manager_default.fatal(message);
|
|
2538
|
+
return 1;
|
|
2539
|
+
}
|
|
2194
2540
|
if (args.length > 3) {
|
|
2195
2541
|
if (client.nonInteractive) {
|
|
2196
2542
|
outputAgentError(
|
|
@@ -2198,9 +2544,9 @@ async function update(client, argv) {
|
|
|
2198
2544
|
{
|
|
2199
2545
|
status: "error",
|
|
2200
2546
|
reason: "invalid_arguments",
|
|
2201
|
-
message: `Invalid number of arguments. Usage:
|
|
2547
|
+
message: `Invalid number of arguments. Usage: \`${getCommandNamePlain(
|
|
2202
2548
|
`env update <name> ${getEnvTargetPlaceholder()} <gitbranch>`
|
|
2203
|
-
)}
|
|
2549
|
+
)}\``
|
|
2204
2550
|
},
|
|
2205
2551
|
1
|
|
2206
2552
|
);
|
|
@@ -2292,9 +2638,9 @@ async function update(client, argv) {
|
|
|
2292
2638
|
return link.exitCode;
|
|
2293
2639
|
} else if (link.status === "not_linked") {
|
|
2294
2640
|
if (client.nonInteractive) {
|
|
2295
|
-
const preserved =
|
|
2296
|
-
(
|
|
2297
|
-
);
|
|
2641
|
+
const preserved = omitEnvValueArgs(
|
|
2642
|
+
getPreservedArgsForEnvUpdate(client.argv)
|
|
2643
|
+
).filter((a) => a !== "--yes" && a !== "-y");
|
|
2298
2644
|
const linkArgv = [
|
|
2299
2645
|
...client.argv.slice(0, 2),
|
|
2300
2646
|
"link",
|
|
@@ -2312,7 +2658,9 @@ async function update(client, argv) {
|
|
|
2312
2658
|
)} to begin. Use --yes for non-interactive; use --scope or --project to specify team or project.`,
|
|
2313
2659
|
next: [
|
|
2314
2660
|
{ command: buildCommandWithYes(linkArgv) },
|
|
2315
|
-
{
|
|
2661
|
+
{
|
|
2662
|
+
command: buildCommandWithYes(redactEnvValueArgs(client.argv))
|
|
2663
|
+
}
|
|
2316
2664
|
]
|
|
2317
2665
|
},
|
|
2318
2666
|
1
|
|
@@ -2395,7 +2743,7 @@ async function update(client, argv) {
|
|
|
2395
2743
|
{
|
|
2396
2744
|
command: buildEnvUpdateCommandWithPreservedArgs(
|
|
2397
2745
|
client.argv,
|
|
2398
|
-
`env update ${envName} ${getEnvTargetPlaceholder()} <gitbranch
|
|
2746
|
+
`env update ${envName} ${getEnvTargetPlaceholder()} <gitbranch> --value "<value>" --yes`
|
|
2399
2747
|
)
|
|
2400
2748
|
}
|
|
2401
2749
|
]
|
|
@@ -2430,7 +2778,7 @@ async function update(client, argv) {
|
|
|
2430
2778
|
{
|
|
2431
2779
|
command: buildEnvUpdateCommandWithPreservedArgs(
|
|
2432
2780
|
client.argv,
|
|
2433
|
-
`env update ${envName} ${getEnvTargetPlaceholder()} <gitbranch
|
|
2781
|
+
`env update ${envName} ${getEnvTargetPlaceholder()} <gitbranch> --value "<value>" --yes`
|
|
2434
2782
|
)
|
|
2435
2783
|
}
|
|
2436
2784
|
]
|
|
@@ -2451,15 +2799,178 @@ async function update(client, argv) {
|
|
|
2451
2799
|
});
|
|
2452
2800
|
selectedEnv = matchingEnvs[selectedIndex];
|
|
2453
2801
|
}
|
|
2802
|
+
let customSveltePublicPrefix;
|
|
2803
|
+
const apiPublicPrefix = getApiPublicPrefix(envName);
|
|
2804
|
+
const frameworkPublicPrefix = getFrameworkPublicPrefix(
|
|
2805
|
+
project.framework,
|
|
2806
|
+
envName
|
|
2807
|
+
);
|
|
2808
|
+
if (project.framework === "sveltekit" || project.framework === "sveltekit-1" || project.framework === "sveltekit-2") {
|
|
2809
|
+
const localPublicPrefixes = await getLocalSvelteKitPublicPrefixes(
|
|
2810
|
+
link.repoRoot ?? client.cwd,
|
|
2811
|
+
project.rootDirectory
|
|
2812
|
+
);
|
|
2813
|
+
const matchingLocalPrefix = localPublicPrefixes?.find(
|
|
2814
|
+
(prefix) => envName.startsWith(prefix)
|
|
2815
|
+
);
|
|
2816
|
+
if (matchingLocalPrefix !== void 0 && apiPublicPrefix === null && frameworkPublicPrefix === null) {
|
|
2817
|
+
customSveltePublicPrefix = matchingLocalPrefix;
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
const targets = Array.isArray(selectedEnv.target) ? selectedEnv.target : [selectedEnv.target].filter(
|
|
2821
|
+
(r) => Boolean(r)
|
|
2822
|
+
);
|
|
2823
|
+
const allTargets = [...targets, ...selectedEnv.customEnvironmentIds || []];
|
|
2824
|
+
const selectedEnvIsSecret = isSecretEnvVar(selectedEnv);
|
|
2825
|
+
if (explicitType === "config" && selectedEnvIsSecret) {
|
|
2826
|
+
const removeTargetArg = envTargetArg || targets[0] || allTargets[0] || getEnvTargetPlaceholder();
|
|
2827
|
+
const addTargetArg = formatTargetArg(allTargets, customEnvironments) || removeTargetArg;
|
|
2828
|
+
const removeBranchArg = selectedEnv.gitBranch ? ` ${quoteArg(selectedEnv.gitBranch)}` : "";
|
|
2829
|
+
const addBranchArg = selectedEnv.gitBranch ? ` --git-branch ${quoteArg(selectedEnv.gitBranch)}` : "";
|
|
2830
|
+
const globalFlags = getGlobalFlagsFromArgs(client.argv.slice(2), {
|
|
2831
|
+
preserveProject: true
|
|
2832
|
+
});
|
|
2833
|
+
const humanGlobalFlags = globalFlags.filter(
|
|
2834
|
+
(flag) => !flag.startsWith("--non-interactive")
|
|
2835
|
+
);
|
|
2836
|
+
const globalSuffix = globalFlags.length > 0 ? ` ${globalFlags.map(quoteArg).join(" ")}` : "";
|
|
2837
|
+
const humanGlobalSuffix = humanGlobalFlags.length > 0 ? ` ${humanGlobalFlags.map(quoteArg).join(" ")}` : "";
|
|
2838
|
+
const removeCommand = getCommandNamePlain(
|
|
2839
|
+
`env rm ${envName} ${removeTargetArg}${removeBranchArg} --yes${globalSuffix}`
|
|
2840
|
+
);
|
|
2841
|
+
const addCommand = getCommandNamePlain(
|
|
2842
|
+
`env add ${envName} ${addTargetArg}${addBranchArg} --type config --value "<value>" --yes${globalSuffix}`
|
|
2843
|
+
);
|
|
2844
|
+
const removeHumanCommand = getCommandNamePlain(
|
|
2845
|
+
`env rm ${envName} ${removeTargetArg}${removeBranchArg}${humanGlobalSuffix}`
|
|
2846
|
+
);
|
|
2847
|
+
const addHumanCommand = getCommandNamePlain(
|
|
2848
|
+
`env add ${envName} ${addTargetArg}${addBranchArg} --type config${humanGlobalSuffix}`
|
|
2849
|
+
);
|
|
2850
|
+
const message = "A Secret cannot be changed to Config. To store this value as Config, remove the variable and add it again with `--type config`.";
|
|
2851
|
+
if (client.nonInteractive) {
|
|
2852
|
+
outputAgentError(
|
|
2853
|
+
client,
|
|
2854
|
+
{
|
|
2855
|
+
status: "error",
|
|
2856
|
+
reason: "secret_cannot_become_config",
|
|
2857
|
+
message,
|
|
2858
|
+
next: [
|
|
2859
|
+
{
|
|
2860
|
+
command: removeCommand,
|
|
2861
|
+
when: "Remove the Secret from all of its environments"
|
|
2862
|
+
},
|
|
2863
|
+
{
|
|
2864
|
+
command: addCommand,
|
|
2865
|
+
when: "Add it again as Config; replace <value> before running"
|
|
2866
|
+
}
|
|
2867
|
+
]
|
|
2868
|
+
},
|
|
2869
|
+
1
|
|
2870
|
+
);
|
|
2871
|
+
}
|
|
2872
|
+
output_manager_default.fatal(
|
|
2873
|
+
`A Secret cannot be changed to Config. Remove the variable, then add it again as Config. ${param(envName)} will be unavailable to new builds between these commands.`
|
|
2874
|
+
);
|
|
2875
|
+
output_manager_default.print(` Remove:
|
|
2876
|
+
${removeHumanCommand}
|
|
2877
|
+
`);
|
|
2878
|
+
output_manager_default.print(
|
|
2879
|
+
` Add as Config (prompts for the value):
|
|
2880
|
+
${addHumanCommand}
|
|
2881
|
+
`
|
|
2882
|
+
);
|
|
2883
|
+
return 1;
|
|
2884
|
+
}
|
|
2885
|
+
if (explicitType === "secret" || opts["--sensitive"]) {
|
|
2886
|
+
const knownPublicPrefix = apiPublicPrefix ?? frameworkPublicPrefix;
|
|
2887
|
+
const publicPrefix = knownPublicPrefix ?? customSveltePublicPrefix;
|
|
2888
|
+
const apiPublicPrefixError = apiPublicPrefix ? getPublicPrefixSecretVisibilityError(envName, {
|
|
2889
|
+
visibility: explicitType === "secret" ? "secret" : void 0,
|
|
2890
|
+
type: "sensitive",
|
|
2891
|
+
context: "update"
|
|
2892
|
+
}) : null;
|
|
2893
|
+
const publicPrefixError = apiPublicPrefixError ? apiPublicPrefixError : knownPublicPrefix ? `\`${knownPublicPrefix}\` exposes this value to anyone visiting your site, so \`${envName}\` cannot be kept private as a Secret. Add a new Secret without the public prefix, then remove this Config.` : customSveltePublicPrefix === "" ? "This SvelteKit project uses an empty `publicPrefix`, so every Environment Variable is exposed to the browser and cannot be kept private as a Secret. Change the SvelteKit `publicPrefix`, or keep this variable as Config only if the value is safe to expose." : customSveltePublicPrefix !== void 0 ? `\`${customSveltePublicPrefix}\` exposes this value to anyone visiting your site, so \`${envName}\` cannot be kept private as a Secret. Add a new Secret without the configured public prefix, then remove this Config.` : null;
|
|
2894
|
+
if (publicPrefixError) {
|
|
2895
|
+
const privateName = publicPrefix === void 0 ? envName : envName.slice(publicPrefix.length);
|
|
2896
|
+
const removeTargetArg = envTargetArg || targets[0] || allTargets[0] || getEnvTargetPlaceholder();
|
|
2897
|
+
const addTargetArg = formatTargetArg(allTargets, customEnvironments) || removeTargetArg;
|
|
2898
|
+
const removeBranchArg = selectedEnv.gitBranch ? ` ${quoteArg(selectedEnv.gitBranch)}` : "";
|
|
2899
|
+
const addBranchArg = selectedEnv.gitBranch ? ` --git-branch ${quoteArg(selectedEnv.gitBranch)}` : "";
|
|
2900
|
+
const globalFlags = getGlobalFlagsFromArgs(client.argv.slice(2), {
|
|
2901
|
+
preserveProject: true
|
|
2902
|
+
});
|
|
2903
|
+
const humanGlobalFlags = globalFlags.filter(
|
|
2904
|
+
(flag) => !flag.startsWith("--non-interactive")
|
|
2905
|
+
);
|
|
2906
|
+
const globalSuffix = globalFlags.length > 0 ? ` ${globalFlags.map(quoteArg).join(" ")}` : "";
|
|
2907
|
+
const humanGlobalSuffix = humanGlobalFlags.length > 0 ? ` ${humanGlobalFlags.map(quoteArg).join(" ")}` : "";
|
|
2908
|
+
const addCommand = publicPrefix === "" ? void 0 : getCommandNamePlain(
|
|
2909
|
+
`env add ${privateName} ${addTargetArg}${addBranchArg} --type secret --value "<value>" --yes${globalSuffix}`
|
|
2910
|
+
);
|
|
2911
|
+
const removeCommand = getCommandNamePlain(
|
|
2912
|
+
`env rm ${envName} ${removeTargetArg}${removeBranchArg} --yes${globalSuffix}`
|
|
2913
|
+
);
|
|
2914
|
+
const addHumanCommand = publicPrefix === "" ? void 0 : getCommandNamePlain(
|
|
2915
|
+
`env add ${privateName} ${addTargetArg}${addBranchArg} --type secret${humanGlobalSuffix}`
|
|
2916
|
+
);
|
|
2917
|
+
const removeHumanCommand = getCommandNamePlain(
|
|
2918
|
+
`env rm ${envName} ${removeTargetArg}${removeBranchArg}${humanGlobalSuffix}`
|
|
2919
|
+
);
|
|
2920
|
+
if (client.nonInteractive) {
|
|
2921
|
+
outputAgentError(
|
|
2922
|
+
client,
|
|
2923
|
+
{
|
|
2924
|
+
status: "error",
|
|
2925
|
+
reason: "invalid_type",
|
|
2926
|
+
message: publicPrefixError,
|
|
2927
|
+
next: addCommand ? [
|
|
2928
|
+
{
|
|
2929
|
+
command: addCommand,
|
|
2930
|
+
when: "Add the private Secret; replace <value> before running"
|
|
2931
|
+
},
|
|
2932
|
+
{
|
|
2933
|
+
command: removeCommand,
|
|
2934
|
+
when: "Remove the public Config after the Secret is available"
|
|
2935
|
+
}
|
|
2936
|
+
] : []
|
|
2937
|
+
},
|
|
2938
|
+
1
|
|
2939
|
+
);
|
|
2940
|
+
}
|
|
2941
|
+
output_manager_default.fatal(publicPrefixError);
|
|
2942
|
+
if (addHumanCommand) {
|
|
2943
|
+
output_manager_default.print(
|
|
2944
|
+
` Add the private Secret (prompts for the value):
|
|
2945
|
+
${addHumanCommand}
|
|
2946
|
+
`
|
|
2947
|
+
);
|
|
2948
|
+
output_manager_default.print(
|
|
2949
|
+
` Remove the public Config:
|
|
2950
|
+
${removeHumanCommand}
|
|
2951
|
+
`
|
|
2952
|
+
);
|
|
2953
|
+
}
|
|
2954
|
+
return 1;
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
if (customSveltePublicPrefix !== void 0) {
|
|
2958
|
+
printEnvUpdateWarning(
|
|
2959
|
+
customSveltePublicPrefix === "" ? "This SvelteKit project uses an empty `publicPrefix`, so every Environment Variable is exposed to the browser." : `\`${customSveltePublicPrefix}\` variables are exposed to the browser by this SvelteKit project.`
|
|
2960
|
+
);
|
|
2961
|
+
}
|
|
2454
2962
|
let teamSensitivePolicyOn = false;
|
|
2963
|
+
let disjunctiveProductionSecretPolicyOn = false;
|
|
2455
2964
|
if (link.org.type === "team") {
|
|
2456
2965
|
try {
|
|
2457
2966
|
const team = await getTeamById(client, link.org.id);
|
|
2458
2967
|
teamSensitivePolicyOn = team?.sensitiveEnvironmentVariablePolicy === "on";
|
|
2968
|
+
disjunctiveProductionSecretPolicyOn = team?.disjunctiveProductionSecretPolicy === "on";
|
|
2459
2969
|
} catch {
|
|
2460
2970
|
}
|
|
2461
2971
|
}
|
|
2462
2972
|
let envValue;
|
|
2973
|
+
const shouldMaskValue = Boolean(opts["--sensitive"]) || explicitType === "secret" || explicitType === void 0 && selectedEnvIsSecret;
|
|
2463
2974
|
if (stdInput) {
|
|
2464
2975
|
const normalizedStdinValue = normalizeStdinEnvValue(stdInput);
|
|
2465
2976
|
envValue = normalizedStdinValue.value;
|
|
@@ -2477,7 +2988,7 @@ async function update(client, argv) {
|
|
|
2477
2988
|
{
|
|
2478
2989
|
status: "action_required",
|
|
2479
2990
|
reason: "missing_value",
|
|
2480
|
-
message:
|
|
2991
|
+
message: 'In non-interactive mode, provide the new value with `--value` or stdin. Example: `vercel env update <name> <environment> --value "<value>" --yes`',
|
|
2481
2992
|
next: [
|
|
2482
2993
|
{
|
|
2483
2994
|
command: buildEnvUpdateCommandWithPreservedArgs(
|
|
@@ -2490,85 +3001,205 @@ async function update(client, argv) {
|
|
|
2490
3001
|
1
|
|
2491
3002
|
);
|
|
2492
3003
|
}
|
|
2493
|
-
envValue = await client
|
|
2494
|
-
message: `What's the new value of ${envName}?`
|
|
2495
|
-
});
|
|
3004
|
+
envValue = await promptEnvUpdateValue(client, envName, shouldMaskValue);
|
|
2496
3005
|
}
|
|
2497
3006
|
const skipConfirm = opts["--yes"] || !!stdInput || valueFromFlag !== void 0;
|
|
2498
|
-
const { finalValue
|
|
3007
|
+
const { finalValue } = await validateEnvValue({
|
|
2499
3008
|
envName,
|
|
2500
3009
|
initialValue: envValue,
|
|
2501
3010
|
skipConfirm,
|
|
2502
|
-
promptForValue: () => client
|
|
3011
|
+
promptForValue: () => promptEnvUpdateValue(client, envName, shouldMaskValue),
|
|
2503
3012
|
selectAction: (choices) => client.input.select({ message: "How to proceed?", choices }),
|
|
2504
|
-
showWarning:
|
|
3013
|
+
showWarning: printEnvUpdateWarning,
|
|
2505
3014
|
showLog: (msg) => output_manager_default.log(msg)
|
|
2506
3015
|
});
|
|
2507
|
-
|
|
3016
|
+
let type = opts["--sensitive"] || explicitType === "secret" ? "sensitive" : explicitType === "config" ? "encrypted" : selectedEnv.type;
|
|
3017
|
+
const isFinalSecret = () => type === "sensitive" || explicitType === void 0 && selectedEnvIsSecret;
|
|
3018
|
+
if (!isFinalSecret() && (type === "plain" || type === "encrypted") && (looksLikeCredentialName2(envName, customSveltePublicPrefix) || looksLikeSecretValue(finalValue))) {
|
|
3019
|
+
printEnvUpdateWarning(
|
|
3020
|
+
"This name or value looks like a credential. Config values can be revealed after saving."
|
|
3021
|
+
);
|
|
3022
|
+
const publicPrefix = apiPublicPrefix ?? frameworkPublicPrefix ?? customSveltePublicPrefix;
|
|
3023
|
+
if (publicPrefix !== null && publicPrefix !== void 0) {
|
|
3024
|
+
printEnvUpdateWarning(
|
|
3025
|
+
publicPrefix === "" ? "This SvelteKit project exposes every Environment Variable to the browser. Keep Config only if the value is safe to expose." : `\`${publicPrefix}\` exposes this value to anyone visiting your site. Keep Config only if the value is safe to expose.`
|
|
3026
|
+
);
|
|
3027
|
+
if (!typeWasExplicit && (opts["--yes"] || client.nonInteractive)) {
|
|
3028
|
+
const message = publicPrefix === "" ? "This SvelteKit project exposes every Environment Variable to the browser. To keep this value private, change the configured public prefix before storing it as Secret. If the value is safe to expose, rerun with `--type config`." : `\`${publicPrefix}\` exposes \`${envName}\` to anyone visiting your site. To keep this value private, add \`${envName.slice(
|
|
3029
|
+
publicPrefix.length
|
|
3030
|
+
)}\` as Secret, then remove \`${envName}\`. If the value is safe to expose, rerun with \`--type config\`.`;
|
|
3031
|
+
if (client.nonInteractive) {
|
|
3032
|
+
outputAgentError(
|
|
3033
|
+
client,
|
|
3034
|
+
{
|
|
3035
|
+
status: "error",
|
|
3036
|
+
reason: "unsafe_public_config",
|
|
3037
|
+
message
|
|
3038
|
+
},
|
|
3039
|
+
1
|
|
3040
|
+
);
|
|
3041
|
+
}
|
|
3042
|
+
output_manager_default.fatal(message);
|
|
3043
|
+
return 1;
|
|
3044
|
+
}
|
|
3045
|
+
if (publicPrefix !== "" && !typeWasExplicit && !opts["--yes"] && !client.nonInteractive) {
|
|
3046
|
+
const privateName = envName.slice(publicPrefix.length);
|
|
3047
|
+
const removeTargetArg = envTargetArg || targets[0] || allTargets[0] || getEnvTargetPlaceholder();
|
|
3048
|
+
const addTargetArg = formatTargetArg(allTargets, customEnvironments) || removeTargetArg;
|
|
3049
|
+
const removeBranchArg = selectedEnv.gitBranch ? ` ${quoteArg(selectedEnv.gitBranch)}` : "";
|
|
3050
|
+
const addBranchArg = selectedEnv.gitBranch ? ` --git-branch ${quoteArg(selectedEnv.gitBranch)}` : "";
|
|
3051
|
+
const humanGlobalFlags = getGlobalFlagsFromArgs(client.argv.slice(2), {
|
|
3052
|
+
preserveProject: true
|
|
3053
|
+
}).filter((flag) => !flag.startsWith("--non-interactive"));
|
|
3054
|
+
const humanGlobalSuffix = humanGlobalFlags.length > 0 ? ` ${humanGlobalFlags.map(quoteArg).join(" ")}` : "";
|
|
3055
|
+
const addPrivateCommand = getCommandNamePlain(
|
|
3056
|
+
`env add ${privateName} ${addTargetArg}${addBranchArg} --type secret${humanGlobalSuffix}`
|
|
3057
|
+
);
|
|
3058
|
+
const removePublicCommand = getCommandNamePlain(
|
|
3059
|
+
`env rm ${envName} ${removeTargetArg}${removeBranchArg}${humanGlobalSuffix}`
|
|
3060
|
+
);
|
|
3061
|
+
const selectedAction = await client.input.select({
|
|
3062
|
+
message: "How should this variable be stored?",
|
|
3063
|
+
choices: [
|
|
3064
|
+
{
|
|
3065
|
+
name: `Keep private: add ${privateName} as Secret, then remove ${envName}`,
|
|
3066
|
+
value: "private"
|
|
3067
|
+
},
|
|
3068
|
+
{
|
|
3069
|
+
name: `Expose to anyone visiting your site: keep ${envName} as Config`,
|
|
3070
|
+
value: "config"
|
|
3071
|
+
}
|
|
3072
|
+
]
|
|
3073
|
+
});
|
|
3074
|
+
if (selectedAction === "private") {
|
|
3075
|
+
output_manager_default.print(" Add the private Secret (prompts for the value):\n");
|
|
3076
|
+
output_manager_default.print(` ${addPrivateCommand}
|
|
3077
|
+
`);
|
|
3078
|
+
output_manager_default.print(" Remove the public Config:\n");
|
|
3079
|
+
output_manager_default.print(` ${removePublicCommand}
|
|
3080
|
+
`);
|
|
3081
|
+
return 1;
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
} else if (!typeWasExplicit && !opts["--yes"] && !client.nonInteractive) {
|
|
3085
|
+
const selectedType = await client.input.select({
|
|
3086
|
+
message: "Store this value as?",
|
|
3087
|
+
choices: [
|
|
3088
|
+
{
|
|
3089
|
+
name: getSecretStorageChoice(targets, "for this value"),
|
|
3090
|
+
value: "secret"
|
|
3091
|
+
},
|
|
3092
|
+
{
|
|
3093
|
+
name: "Config (can be revealed after saving)",
|
|
3094
|
+
value: "config"
|
|
3095
|
+
}
|
|
3096
|
+
]
|
|
3097
|
+
});
|
|
3098
|
+
if (selectedType === "secret") {
|
|
3099
|
+
type = "sensitive";
|
|
3100
|
+
explicitType = "secret";
|
|
3101
|
+
}
|
|
3102
|
+
} else if (!typeWasExplicit) {
|
|
3103
|
+
printEnvUpdateWarning("Re-run with `--type secret` to protect it.");
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
if (isFinalSecret() && !selectedEnvIsSecret) {
|
|
3107
|
+
printEnvUpdateWarning(
|
|
3108
|
+
"The previous value was readable as Config and may have been exposed. If this variable still holds the same credential, rotate it at its provider and update this variable again."
|
|
3109
|
+
);
|
|
3110
|
+
}
|
|
3111
|
+
const finalPublicPrefix = apiPublicPrefix ?? frameworkPublicPrefix ?? customSveltePublicPrefix;
|
|
3112
|
+
if (isFinalSecret() && finalPublicPrefix !== null && finalPublicPrefix !== void 0) {
|
|
3113
|
+
printEnvUpdateWarning(
|
|
3114
|
+
finalPublicPrefix === "" ? "This SvelteKit project exposes every Environment Variable to the browser; the Secret type does not prevent that. Change the configured public prefix to keep values private." : `\`${finalPublicPrefix}\` exposes this variable to the browser; the Secret type does not prevent that. Rename the variable without the public prefix to keep it private.`
|
|
3115
|
+
);
|
|
3116
|
+
}
|
|
3117
|
+
if (isFinalSecret() && disjunctiveProductionSecretPolicyOn && targets.includes("production") && allTargets.some((target) => target !== "production")) {
|
|
3118
|
+
const message = "Your team requires Production and non-Production Secrets to be stored separately with different values. Create separate variables with different values before converting this one.";
|
|
2508
3119
|
if (client.nonInteractive) {
|
|
2509
|
-
|
|
3120
|
+
outputAgentError(
|
|
2510
3121
|
client,
|
|
2511
3122
|
{
|
|
2512
|
-
status: "
|
|
2513
|
-
reason: "
|
|
2514
|
-
message
|
|
2515
|
-
next: [{ command: buildCommandWithYes(client.argv) }]
|
|
3123
|
+
status: "error",
|
|
3124
|
+
reason: "production_secret_must_be_separate",
|
|
3125
|
+
message
|
|
2516
3126
|
},
|
|
2517
3127
|
1
|
|
2518
3128
|
);
|
|
2519
3129
|
}
|
|
2520
|
-
|
|
2521
|
-
link,
|
|
2522
|
-
selectedEnv,
|
|
2523
|
-
customEnvironments
|
|
2524
|
-
);
|
|
2525
|
-
const confirmed = await client.input.confirm(
|
|
2526
|
-
`Updating Environment Variable ${param(envName)} in ${currentTargets} in Project ${import_chalk4.default.bold(project.name)}. Are you sure?`,
|
|
2527
|
-
false
|
|
2528
|
-
);
|
|
2529
|
-
if (!confirmed) {
|
|
2530
|
-
output_manager_default.log("Canceled");
|
|
2531
|
-
return 0;
|
|
2532
|
-
}
|
|
2533
|
-
}
|
|
2534
|
-
const type = opts["--sensitive"] ? "sensitive" : selectedEnv.type;
|
|
2535
|
-
const explicitVisibility = typeof opts["--visibility"] === "string" ? opts["--visibility"] : void 0;
|
|
2536
|
-
if (explicitVisibility === "config" && opts["--sensitive"]) {
|
|
2537
|
-
output_manager_default.error(
|
|
2538
|
-
"`--visibility config` cannot be used with `--sensitive`. Pick one."
|
|
2539
|
-
);
|
|
3130
|
+
output_manager_default.fatal(message);
|
|
2540
3131
|
return 1;
|
|
2541
3132
|
}
|
|
2542
|
-
const
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
const { visibility, error: visibilityError } = resolveEnvVarVisibility({
|
|
2547
|
-
explicitVisibility,
|
|
3133
|
+
const preserveExistingVisibility = explicitType === void 0 && selectedEnv.visibility === "secret" && type !== "sensitive";
|
|
3134
|
+
const { visibility: resolvedVisibility, error: visibilityError } = resolveEnvVarVisibility({
|
|
3135
|
+
explicitVisibility: typeOption.source ? explicitType : void 0,
|
|
3136
|
+
explicitOptionSource: typeOption.source,
|
|
2548
3137
|
type,
|
|
2549
3138
|
key: envName,
|
|
2550
3139
|
envTargets: allTargets,
|
|
2551
|
-
teamSensitivePolicyOn
|
|
3140
|
+
teamSensitivePolicyOn,
|
|
3141
|
+
context: "update"
|
|
2552
3142
|
});
|
|
3143
|
+
const visibility = preserveExistingVisibility ? void 0 : resolvedVisibility;
|
|
3144
|
+
const displayVisibility = preserveExistingVisibility ? selectedEnv.visibility : visibility;
|
|
2553
3145
|
if (visibilityError) {
|
|
2554
3146
|
if (client.nonInteractive) {
|
|
2555
3147
|
outputAgentError(
|
|
2556
3148
|
client,
|
|
2557
3149
|
{
|
|
2558
3150
|
status: "error",
|
|
2559
|
-
reason: "
|
|
3151
|
+
reason: "invalid_type",
|
|
2560
3152
|
message: visibilityError
|
|
2561
3153
|
},
|
|
2562
3154
|
1
|
|
2563
3155
|
);
|
|
2564
3156
|
}
|
|
2565
|
-
output_manager_default.
|
|
3157
|
+
output_manager_default.fatal(visibilityError);
|
|
2566
3158
|
return 1;
|
|
2567
3159
|
}
|
|
2568
|
-
|
|
3160
|
+
if (!opts["--yes"]) {
|
|
3161
|
+
const visibilityLabel2 = formatVisibilityLabel(displayVisibility, type);
|
|
3162
|
+
if (client.nonInteractive) {
|
|
3163
|
+
outputActionRequired(
|
|
3164
|
+
client,
|
|
3165
|
+
{
|
|
3166
|
+
status: "action_required",
|
|
3167
|
+
reason: "confirmation_required",
|
|
3168
|
+
message: `Update ${envName} as ${visibilityLabel2} in ${formatEnvironments(
|
|
3169
|
+
link,
|
|
3170
|
+
selectedEnv,
|
|
3171
|
+
customEnvironments
|
|
3172
|
+
)}? Use --yes to confirm.`,
|
|
3173
|
+
next: [
|
|
3174
|
+
{
|
|
3175
|
+
command: buildCommandWithYes(redactEnvValueArgs(client.argv))
|
|
3176
|
+
}
|
|
3177
|
+
]
|
|
3178
|
+
},
|
|
3179
|
+
1
|
|
3180
|
+
);
|
|
3181
|
+
}
|
|
3182
|
+
output_manager_default.print("\n");
|
|
3183
|
+
printAlignedLabel("Project", `${link.org.slug}/${project.name}`);
|
|
3184
|
+
printAlignedLabel(
|
|
3185
|
+
"Environments",
|
|
3186
|
+
formatEnvironments(link, selectedEnv, customEnvironments)
|
|
3187
|
+
);
|
|
3188
|
+
if (visibilityLabel2) {
|
|
3189
|
+
printAlignedLabel("Type", visibilityLabel2);
|
|
3190
|
+
}
|
|
3191
|
+
const confirmed = await client.input.confirm(
|
|
3192
|
+
"Update this Environment Variable?",
|
|
3193
|
+
false
|
|
3194
|
+
);
|
|
3195
|
+
if (!confirmed) {
|
|
3196
|
+
output_manager_default.log("Canceled");
|
|
3197
|
+
return 0;
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
2569
3200
|
try {
|
|
2570
3201
|
output_manager_default.spinner("Updating");
|
|
2571
|
-
const keyToUpdate =
|
|
3202
|
+
const keyToUpdate = isFinalSecret() ? void 0 : envName;
|
|
2572
3203
|
await updateEnvRecord(
|
|
2573
3204
|
client,
|
|
2574
3205
|
project.id,
|
|
@@ -2582,13 +3213,18 @@ async function update(client, argv) {
|
|
|
2582
3213
|
);
|
|
2583
3214
|
} catch (err) {
|
|
2584
3215
|
if (client.nonInteractive && isAPIError(err)) {
|
|
2585
|
-
const
|
|
3216
|
+
const productionSecretPolicyError = getProductionSecretPolicyErrorKind(
|
|
3217
|
+
err.serverMessage
|
|
3218
|
+
);
|
|
3219
|
+
const reason = productionSecretPolicyError ? productionSecretPolicyError === "different-values" ? "production_secret_requires_different_value" : "production_secret_must_be_separate" : err.slug || (err.serverMessage?.toLowerCase().includes("branch") ? "branch_not_found" : "api_error");
|
|
2586
3220
|
outputAgentError(
|
|
2587
3221
|
client,
|
|
2588
3222
|
{
|
|
2589
3223
|
status: "error",
|
|
2590
3224
|
reason,
|
|
2591
|
-
message: err.serverMessage
|
|
3225
|
+
message: productionSecretPolicyError ? `${err.serverMessage} ${getProductionSecretPolicyRecovery(
|
|
3226
|
+
productionSecretPolicyError
|
|
3227
|
+
)}` : err.serverMessage
|
|
2592
3228
|
},
|
|
2593
3229
|
1
|
|
2594
3230
|
);
|
|
@@ -2599,18 +3235,16 @@ async function update(client, argv) {
|
|
|
2599
3235
|
}
|
|
2600
3236
|
throw err;
|
|
2601
3237
|
}
|
|
2602
|
-
output_manager_default.print(
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
)}
|
|
2609
|
-
`
|
|
3238
|
+
output_manager_default.print("\n");
|
|
3239
|
+
printAlignedLabel("Updated", envName, { gutter: "\u2713" });
|
|
3240
|
+
printAlignedLabel("Project", `${link.org.slug}/${project.name}`);
|
|
3241
|
+
printAlignedLabel(
|
|
3242
|
+
"Environments",
|
|
3243
|
+
formatEnvironments(link, selectedEnv, customEnvironments)
|
|
2610
3244
|
);
|
|
2611
|
-
const visibilityLabel = formatVisibilityLabel(
|
|
3245
|
+
const visibilityLabel = formatVisibilityLabel(displayVisibility, type);
|
|
2612
3246
|
if (visibilityLabel) {
|
|
2613
|
-
printAlignedLabel("
|
|
3247
|
+
printAlignedLabel("Type", visibilityLabel);
|
|
2614
3248
|
}
|
|
2615
3249
|
return 0;
|
|
2616
3250
|
}
|