netlify-cli 17.3.1 → 17.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -139
- package/npm-shrinkwrap.json +82 -82
- package/package.json +16 -15
- package/src/commands/addons/addons-auth.mjs +27 -30
- package/src/commands/addons/addons-config.mjs +145 -154
- package/src/commands/addons/addons-create.mjs +94 -108
- package/src/commands/addons/addons-delete.mjs +36 -41
- package/src/commands/addons/addons-list.mjs +38 -42
- package/src/commands/addons/addons.mjs +26 -28
- package/src/commands/addons/index.mjs +1 -1
- package/src/commands/api/api.mjs +45 -53
- package/src/commands/api/index.mjs +1 -1
- package/src/commands/base-command.mjs +597 -684
- package/src/commands/blobs/blobs-delete.mjs +35 -0
- package/src/commands/blobs/blobs-get.mjs +44 -0
- package/src/commands/blobs/blobs-list.mjs +48 -0
- package/src/commands/blobs/blobs-set.mjs +54 -0
- package/src/commands/blobs/blobs.mjs +32 -0
- package/src/commands/blobs/index.mjs +1 -0
- package/src/commands/build/build.mjs +55 -67
- package/src/commands/build/index.mjs +1 -1
- package/src/commands/completion/completion.mjs +41 -46
- package/src/commands/completion/index.mjs +1 -1
- package/src/commands/deploy/deploy.mjs +675 -710
- package/src/commands/deploy/index.mjs +1 -1
- package/src/commands/dev/dev-exec.mjs +20 -32
- package/src/commands/dev/dev.mjs +217 -302
- package/src/commands/dev/index.mjs +1 -1
- package/src/commands/dev/types.d.ts +30 -0
- package/src/commands/env/env-clone.mjs +157 -184
- package/src/commands/env/env-get.mjs +49 -68
- package/src/commands/env/env-import.mjs +100 -119
- package/src/commands/env/env-list.mjs +104 -129
- package/src/commands/env/env-set.mjs +160 -185
- package/src/commands/env/env-unset.mjs +104 -122
- package/src/commands/env/env.mjs +28 -30
- package/src/commands/env/index.mjs +1 -1
- package/src/commands/functions/functions-build.mjs +29 -41
- package/src/commands/functions/functions-create.mjs +533 -601
- package/src/commands/functions/functions-invoke.mjs +193 -216
- package/src/commands/functions/functions-list.mjs +45 -55
- package/src/commands/functions/functions-serve.mjs +51 -61
- package/src/commands/functions/functions.mjs +26 -32
- package/src/commands/functions/index.mjs +1 -1
- package/src/commands/index.mjs +2 -2
- package/src/commands/init/index.mjs +1 -1
- package/src/commands/init/init.mjs +138 -167
- package/src/commands/integration/deploy.mjs +337 -399
- package/src/commands/integration/index.mjs +12 -13
- package/src/commands/link/index.mjs +1 -1
- package/src/commands/link/link.mjs +298 -317
- package/src/commands/lm/index.mjs +1 -1
- package/src/commands/lm/lm-info.mjs +23 -31
- package/src/commands/lm/lm-install.mjs +13 -17
- package/src/commands/lm/lm-setup.mjs +80 -84
- package/src/commands/lm/lm-uninstall.mjs +7 -12
- package/src/commands/lm/lm.mjs +18 -22
- package/src/commands/login/index.mjs +1 -1
- package/src/commands/login/login.mjs +35 -41
- package/src/commands/logout/index.mjs +1 -1
- package/src/commands/logout/logout.mjs +25 -31
- package/src/commands/main.mjs +166 -201
- package/src/commands/open/index.mjs +1 -1
- package/src/commands/open/open-admin.mjs +15 -18
- package/src/commands/open/open-site.mjs +16 -19
- package/src/commands/open/open.mjs +24 -27
- package/src/commands/recipes/common.mjs +23 -34
- package/src/commands/recipes/index.mjs +1 -1
- package/src/commands/recipes/recipes-list.mjs +13 -20
- package/src/commands/recipes/recipes.mjs +59 -72
- package/src/commands/serve/index.mjs +1 -1
- package/src/commands/serve/serve.mjs +142 -189
- package/src/commands/sites/index.mjs +2 -2
- package/src/commands/sites/sites-create-template.mjs +214 -236
- package/src/commands/sites/sites-create.mjs +145 -157
- package/src/commands/sites/sites-delete.mjs +75 -81
- package/src/commands/sites/sites-list.mjs +63 -66
- package/src/commands/sites/sites.mjs +18 -20
- package/src/commands/status/index.mjs +1 -1
- package/src/commands/status/status-hooks.mjs +32 -34
- package/src/commands/status/status.mjs +99 -106
- package/src/commands/switch/index.mjs +1 -1
- package/src/commands/switch/switch.mjs +32 -37
- package/src/commands/types.d.ts +31 -0
- package/src/commands/unlink/index.mjs +1 -1
- package/src/commands/unlink/unlink.mjs +23 -29
- package/src/commands/watch/index.mjs +1 -1
- package/src/commands/watch/watch.mjs +91 -105
- package/src/functions-templates/javascript/hello/{{name}}.js +2 -3
- package/src/lib/account.mjs +4 -5
- package/src/lib/api.mjs +22 -20
- package/src/lib/blobs/blobs.mjs +36 -45
- package/src/lib/build.mjs +82 -85
- package/src/lib/completion/constants.mjs +2 -4
- package/src/lib/completion/generate-autocompletion.mjs +33 -36
- package/src/lib/completion/get-autocompletion.mjs +31 -35
- package/src/lib/completion/index.mjs +1 -1
- package/src/lib/completion/script.mjs +12 -19
- package/src/lib/edge-functions/bootstrap.mjs +3 -5
- package/src/lib/edge-functions/consts.mjs +9 -10
- package/src/lib/edge-functions/deploy.mjs +28 -34
- package/src/lib/edge-functions/editor-helper.mjs +29 -42
- package/src/lib/edge-functions/headers.mjs +24 -26
- package/src/lib/edge-functions/internal.mjs +38 -44
- package/src/lib/edge-functions/proxy.mjs +229 -228
- package/src/lib/edge-functions/registry.mjs +473 -574
- package/src/lib/exec-fetcher.mjs +115 -122
- package/src/lib/fs.mjs +28 -27
- package/src/lib/functions/background.mjs +16 -20
- package/src/lib/functions/config.mjs +12 -9
- package/src/lib/functions/form-submissions-handler.mjs +143 -149
- package/src/lib/functions/local-proxy.mjs +40 -44
- package/src/lib/functions/memoized-build.mjs +19 -21
- package/src/lib/functions/netlify-function.mjs +269 -249
- package/src/lib/functions/registry.mjs +509 -568
- package/src/lib/functions/runtimes/go/index.mjs +62 -71
- package/src/lib/functions/runtimes/index.mjs +8 -15
- package/src/lib/functions/runtimes/js/builders/netlify-lambda.mjs +55 -64
- package/src/lib/functions/runtimes/js/builders/zisi.mjs +135 -154
- package/src/lib/functions/runtimes/js/constants.mjs +1 -1
- package/src/lib/functions/runtimes/js/index.mjs +92 -109
- package/src/lib/functions/runtimes/js/worker.mjs +43 -45
- package/src/lib/functions/runtimes/rust/index.mjs +64 -73
- package/src/lib/functions/scheduled.mjs +70 -88
- package/src/lib/functions/server.mjs +269 -327
- package/src/lib/functions/synchronous.mjs +118 -147
- package/src/lib/functions/utils.mjs +38 -46
- package/src/lib/geo-location.mjs +69 -81
- package/src/lib/http-agent.mjs +87 -90
- package/src/lib/images/proxy.mjs +97 -89
- package/src/lib/log.mjs +6 -9
- package/src/lib/path.mjs +2 -1
- package/src/lib/render-error-template.mjs +19 -20
- package/src/lib/settings.mjs +17 -19
- package/src/lib/spinner.mjs +21 -23
- package/src/lib/string.mjs +4 -2
- package/src/recipes/vscode/index.mjs +69 -85
- package/src/recipes/vscode/settings.mjs +53 -58
- package/src/utils/addons/compare.mjs +31 -32
- package/src/utils/addons/diffs/index.mjs +16 -17
- package/src/utils/addons/diffs/options.mjs +99 -101
- package/src/utils/addons/prepare.mjs +100 -97
- package/src/utils/addons/prompts.mjs +73 -76
- package/src/utils/addons/render.mjs +33 -36
- package/src/utils/addons/validation.mjs +19 -15
- package/src/utils/banner.mjs +11 -16
- package/src/utils/build-info.mjs +65 -66
- package/src/utils/command-helpers.mjs +185 -199
- package/src/utils/create-deferred.mjs +9 -12
- package/src/utils/create-stream-promise.mjs +54 -47
- package/src/utils/deploy/constants.mjs +9 -11
- package/src/utils/deploy/deploy-site.mjs +162 -182
- package/src/utils/deploy/hash-config.mjs +21 -21
- package/src/utils/deploy/hash-files.mjs +34 -38
- package/src/utils/deploy/hash-fns.mjs +149 -154
- package/src/utils/deploy/hasher-segments.mjs +58 -52
- package/src/utils/deploy/upload-files.mjs +99 -113
- package/src/utils/deploy/util.mjs +85 -91
- package/src/utils/detect-server-settings.mjs +236 -268
- package/src/utils/dev.mjs +163 -178
- package/src/utils/dot-env.mjs +37 -42
- package/src/utils/env/index.mjs +148 -148
- package/src/utils/execa.mjs +9 -13
- package/src/utils/feature-flags.mjs +6 -5
- package/src/utils/framework-server.mjs +43 -52
- package/src/utils/functions/constants.mjs +1 -1
- package/src/utils/functions/functions.mjs +30 -40
- package/src/utils/functions/get-functions.mjs +28 -29
- package/src/utils/functions/index.mjs +3 -3
- package/src/utils/get-global-config.mjs +33 -36
- package/src/utils/get-package-json.mjs +14 -15
- package/src/utils/get-repo-data.mjs +54 -64
- package/src/utils/get-site.mjs +14 -14
- package/src/utils/gh-auth.mjs +79 -100
- package/src/utils/gitignore.mjs +37 -40
- package/src/utils/headers.mjs +33 -35
- package/src/utils/hooks/requires-site-info.mjs +26 -22
- package/src/utils/init/config-github.mjs +207 -219
- package/src/utils/init/config-manual.mjs +83 -100
- package/src/utils/init/config.mjs +25 -26
- package/src/utils/init/node-version.mjs +23 -30
- package/src/utils/init/plugins.mjs +12 -8
- package/src/utils/init/utils.mjs +152 -172
- package/src/utils/live-tunnel.mjs +118 -141
- package/src/utils/lm/install.mjs +220 -259
- package/src/utils/lm/requirements.mjs +54 -63
- package/src/utils/lm/steps.mjs +31 -31
- package/src/utils/lm/ui.mjs +13 -20
- package/src/utils/open-browser.mjs +31 -32
- package/src/utils/parse-raw-flags.mjs +39 -35
- package/src/utils/proxy-server.mjs +84 -71
- package/src/utils/proxy.mjs +696 -750
- package/src/utils/read-repo-url.mjs +48 -47
- package/src/utils/redirects.mjs +49 -49
- package/src/utils/request-id.mjs +2 -4
- package/src/utils/rules-proxy.mjs +96 -100
- package/src/utils/run-build.mjs +109 -132
- package/src/utils/shell.mjs +99 -106
- package/src/utils/sign-redirect.mjs +14 -14
- package/src/utils/sites/utils.mjs +48 -55
- package/src/utils/state-config.mjs +101 -101
- package/src/utils/static-server.mjs +28 -34
- package/src/utils/telemetry/index.mjs +2 -2
- package/src/utils/telemetry/report-error.mjs +45 -49
- package/src/utils/telemetry/request.mjs +36 -43
- package/src/utils/telemetry/telemetry.mjs +90 -105
- package/src/utils/telemetry/utils.mjs +5 -6
- package/src/utils/telemetry/validation.mjs +55 -53
- package/src/utils/types.d.ts +46 -0
- package/src/utils/validation.mjs +10 -13
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { chalk, error, log, logJson } from '../../utils/command-helpers.mjs'
|
|
5
|
-
import {
|
|
6
|
-
AVAILABLE_CONTEXTS,
|
|
7
|
-
AVAILABLE_SCOPES,
|
|
8
|
-
normalizeContext,
|
|
9
|
-
translateFromEnvelopeToMongo,
|
|
10
|
-
} from '../../utils/env/index.mjs'
|
|
11
|
-
|
|
1
|
+
import { Option } from 'commander';
|
|
2
|
+
import { chalk, error, log, logJson } from '../../utils/command-helpers.mjs';
|
|
3
|
+
import { AVAILABLE_CONTEXTS, AVAILABLE_SCOPES, normalizeContext, translateFromEnvelopeToMongo, } from '../../utils/env/index.mjs';
|
|
12
4
|
/**
|
|
13
5
|
* The env:set command
|
|
14
6
|
* @param {string} key Environment variable key
|
|
@@ -17,203 +9,186 @@ import {
|
|
|
17
9
|
* @param {import('../base-command.mjs').default} command
|
|
18
10
|
* @returns {Promise<boolean>}
|
|
19
11
|
*/
|
|
12
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'key' implicitly has an 'any' type.
|
|
20
13
|
const envSet = async (key, value, options, command) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
logJson(finalEnv)
|
|
55
|
-
return false
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const withScope = scope ? ` scoped to ${chalk.white(scope)}` : ''
|
|
59
|
-
const withSecret = secret ? ` as a ${chalk.blue('secret')}` : ''
|
|
60
|
-
const contextType = AVAILABLE_CONTEXTS.includes(context || 'all') ? 'context' : 'branch'
|
|
61
|
-
log(
|
|
62
|
-
`Set environment variable ${chalk.yellow(
|
|
63
|
-
`${key}${value && !secret ? `=${value}` : ''}`,
|
|
64
|
-
)}${withScope}${withSecret} in the ${chalk.magenta(context || 'all')} ${contextType}`,
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
14
|
+
const { context, scope, secret } = options;
|
|
15
|
+
const { api, cachedConfig, site } = command.netlify;
|
|
16
|
+
const siteId = site.id;
|
|
17
|
+
if (!siteId) {
|
|
18
|
+
log('No site id found, please run inside a site folder or `netlify link`');
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const { siteInfo } = cachedConfig;
|
|
22
|
+
let finalEnv;
|
|
23
|
+
// Get current environment variables set in the UI
|
|
24
|
+
if (siteInfo.use_envelope) {
|
|
25
|
+
finalEnv = await setInEnvelope({ api, siteInfo, key, value, context, scope, secret });
|
|
26
|
+
}
|
|
27
|
+
else if (context || scope) {
|
|
28
|
+
error(`To specify a context or scope, please run ${chalk.yellow('netlify open:admin')} to open the Netlify UI and opt in to the new environment variables experience from Site settings`);
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
finalEnv = await setInMongo({ api, siteInfo, key, value });
|
|
33
|
+
}
|
|
34
|
+
if (!finalEnv) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
// Return new environment variables of site if using json flag
|
|
38
|
+
if (options.json) {
|
|
39
|
+
logJson(finalEnv);
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const withScope = scope ? ` scoped to ${chalk.white(scope)}` : '';
|
|
43
|
+
const withSecret = secret ? ` as a ${chalk.blue('secret')}` : '';
|
|
44
|
+
const contextType = AVAILABLE_CONTEXTS.includes(context || 'all') ? 'context' : 'branch';
|
|
45
|
+
log(`Set environment variable ${chalk.yellow(`${key}${value && !secret ? `=${value}` : ''}`)}${withScope}${withSecret} in the ${chalk.magenta(context || 'all')} ${contextType}`);
|
|
46
|
+
};
|
|
68
47
|
/**
|
|
69
48
|
* Updates the env for a site record with a new key/value pair
|
|
70
49
|
* @returns {Promise<object>}
|
|
71
50
|
*/
|
|
51
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
72
52
|
const setInMongo = async ({ api, key, siteInfo, value }) => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
53
|
+
const { env = {} } = siteInfo.build_settings;
|
|
54
|
+
const newEnv = {
|
|
55
|
+
...env,
|
|
56
|
+
[key]: value,
|
|
57
|
+
};
|
|
58
|
+
// Apply environment variable updates
|
|
59
|
+
await api.updateSite({
|
|
60
|
+
siteId: siteInfo.id,
|
|
61
|
+
body: {
|
|
62
|
+
build_settings: {
|
|
63
|
+
env: newEnv,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
return newEnv;
|
|
68
|
+
};
|
|
90
69
|
/**
|
|
91
70
|
* Updates the env for a site configured with Envelope with a new key/value pair
|
|
92
71
|
* @returns {Promise<object | boolean>}
|
|
93
72
|
*/
|
|
73
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
94
74
|
const setInEnvelope = async ({ api, context, key, scope, secret, siteInfo, value }) => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
75
|
+
const accountId = siteInfo.account_slug;
|
|
76
|
+
const siteId = siteInfo.id;
|
|
77
|
+
// secret values may not be used in the post-processing scope
|
|
78
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'sco' implicitly has an 'any' type.
|
|
79
|
+
if (secret && scope && scope.some((sco) => /post[-_]processing/.test(sco))) {
|
|
80
|
+
error(`Secret values cannot be used within the post-processing scope.`);
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
// secret values must specify deploy contexts. `all` or `dev` are not allowed
|
|
84
|
+
if (secret && value && (!context || context.includes('dev'))) {
|
|
85
|
+
error(`To set a secret environment variable value, please specify a non-development context with the \`--context\` flag.`);
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
// fetch envelope env vars
|
|
89
|
+
const envelopeVariables = await api.getEnvVars({ accountId, siteId });
|
|
90
|
+
const contexts = context || ['all'];
|
|
91
|
+
let scopes = scope || AVAILABLE_SCOPES;
|
|
92
|
+
if (secret) {
|
|
93
|
+
// post_processing (aka post-processing) scope is not allowed with secrets
|
|
94
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'sco' implicitly has an 'any' type.
|
|
95
|
+
scopes = scopes.filter((sco) => !/post[-_]processing/.test(sco));
|
|
96
|
+
}
|
|
97
|
+
// if the passed context is unknown, it is actually a branch name
|
|
98
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'ctx' implicitly has an 'any' type.
|
|
99
|
+
let values = contexts.map((ctx) => AVAILABLE_CONTEXTS.includes(ctx) ? { context: ctx, value } : { context: 'branch', context_parameter: ctx, value });
|
|
100
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'envVar' implicitly has an 'any' type.
|
|
101
|
+
const existing = envelopeVariables.find((envVar) => envVar.key === key);
|
|
102
|
+
const params = { accountId, siteId, key };
|
|
103
|
+
try {
|
|
104
|
+
if (existing) {
|
|
105
|
+
if (!value) {
|
|
106
|
+
// eslint-disable-next-line prefer-destructuring
|
|
107
|
+
values = existing.values;
|
|
108
|
+
if (!scope) {
|
|
109
|
+
// eslint-disable-next-line prefer-destructuring
|
|
110
|
+
scopes = existing.scopes;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (context && scope) {
|
|
114
|
+
error('Setting the context and scope at the same time on an existing env var is not allowed. Run the set command separately for each update.');
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (context) {
|
|
118
|
+
// update individual value(s)
|
|
119
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'val' implicitly has an 'any' type.
|
|
120
|
+
await Promise.all(values.map((val) => api.setEnvVarValue({ ...params, body: val })));
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// otherwise update whole env var
|
|
124
|
+
if (secret) {
|
|
125
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'sco' implicitly has an 'any' type.
|
|
126
|
+
scopes = scopes.filter((sco) => !/post[-_]processing/.test(sco));
|
|
127
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'val' implicitly has an 'any' type.
|
|
128
|
+
if (values.some((val) => val.context === 'all')) {
|
|
129
|
+
log(`This secret's value will be empty in the dev context.`);
|
|
130
|
+
log(`Run \`netlify env:set ${key} <value> --context dev\` to set a new value for the dev context.`);
|
|
131
|
+
values = AVAILABLE_CONTEXTS.filter((ctx) => ctx !== 'all').map((ctx) => ({
|
|
132
|
+
context: ctx,
|
|
133
|
+
// empty out dev value so that secret is indeed secret
|
|
134
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'val' implicitly has an 'any' type.
|
|
135
|
+
value: ctx === 'dev' ? '' : values.find((val) => val.context === 'all').value,
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const body = { key, is_secret: secret, scopes, values };
|
|
140
|
+
await api.updateEnvVar({ ...params, body });
|
|
141
|
+
}
|
|
138
142
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
)
|
|
144
|
-
return false
|
|
145
|
-
}
|
|
146
|
-
if (context) {
|
|
147
|
-
// update individual value(s)
|
|
148
|
-
await Promise.all(values.map((val) => api.setEnvVarValue({ ...params, body: val })))
|
|
149
|
-
} else {
|
|
150
|
-
// otherwise update whole env var
|
|
151
|
-
if (secret) {
|
|
152
|
-
scopes = scopes.filter((sco) => !/post[-_]processing/.test(sco))
|
|
153
|
-
if (values.some((val) => val.context === 'all')) {
|
|
154
|
-
log(`This secret's value will be empty in the dev context.`)
|
|
155
|
-
log(`Run \`netlify env:set ${key} <value> --context dev\` to set a new value for the dev context.`)
|
|
156
|
-
values = AVAILABLE_CONTEXTS.filter((ctx) => ctx !== 'all').map((ctx) => ({
|
|
157
|
-
context: ctx,
|
|
158
|
-
// empty out dev value so that secret is indeed secret
|
|
159
|
-
value: ctx === 'dev' ? '' : values.find((val) => val.context === 'all').value,
|
|
160
|
-
}))
|
|
161
|
-
}
|
|
143
|
+
else {
|
|
144
|
+
// create whole env var
|
|
145
|
+
const body = [{ key, is_secret: secret, scopes, values }];
|
|
146
|
+
await api.createEnvVars({ ...params, body });
|
|
162
147
|
}
|
|
163
|
-
const body = { key, is_secret: secret, scopes, values }
|
|
164
|
-
await api.updateEnvVar({ ...params, body })
|
|
165
|
-
}
|
|
166
|
-
} else {
|
|
167
|
-
// create whole env var
|
|
168
|
-
const body = [{ key, is_secret: secret, scopes, values }]
|
|
169
|
-
await api.createEnvVars({ ...params, body })
|
|
170
148
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
|
|
149
|
+
catch (error_) {
|
|
150
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
151
|
+
throw error_.json ? error_.json.msg : error_;
|
|
152
|
+
}
|
|
153
|
+
const env = translateFromEnvelopeToMongo(envelopeVariables, context ? context[0] : 'dev');
|
|
154
|
+
return {
|
|
155
|
+
...env,
|
|
156
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
157
|
+
[key]: value || env[key],
|
|
158
|
+
};
|
|
159
|
+
};
|
|
182
160
|
/**
|
|
183
161
|
* Creates the `netlify env:set` command
|
|
184
162
|
* @param {import('../base-command.mjs').default} program
|
|
185
163
|
* @returns
|
|
186
164
|
*/
|
|
187
|
-
|
|
188
|
-
|
|
165
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
|
|
166
|
+
export const createEnvSetCommand = (program) => program
|
|
189
167
|
.command('env:set')
|
|
190
168
|
.argument('<key>', 'Environment variable key')
|
|
191
169
|
.argument('[value]', 'Value to set to', '')
|
|
192
|
-
.option(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
'post-processing',
|
|
203
|
-
'runtime',
|
|
204
|
-
]),
|
|
205
|
-
)
|
|
170
|
+
.option('-c, --context <context...>', 'Specify a deploy context or branch (contexts: "production", "deploy-preview", "branch-deploy", "dev") (default: all contexts)',
|
|
171
|
+
// spread over an array for variadic options
|
|
172
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'context' implicitly has an 'any' type.
|
|
173
|
+
(context, previous = []) => [...previous, normalizeContext(context)])
|
|
174
|
+
.addOption(new Option('-s, --scope <scope...>', 'Specify a scope (default: all scopes)').choices([
|
|
175
|
+
'builds',
|
|
176
|
+
'functions',
|
|
177
|
+
'post-processing',
|
|
178
|
+
'runtime',
|
|
179
|
+
]))
|
|
206
180
|
.option('--secret', 'Indicate whether the environment variable value can be read again.')
|
|
207
181
|
.description('Set value of environment variable')
|
|
208
182
|
.addExamples([
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
183
|
+
'netlify env:set VAR_NAME value # set in all contexts and scopes',
|
|
184
|
+
'netlify env:set VAR_NAME value --context production',
|
|
185
|
+
'netlify env:set VAR_NAME value --context production deploy-preview',
|
|
186
|
+
'netlify env:set VAR_NAME value --context production --secret',
|
|
187
|
+
'netlify env:set VAR_NAME value --scope builds',
|
|
188
|
+
'netlify env:set VAR_NAME value --scope builds functions',
|
|
189
|
+
'netlify env:set VAR_NAME --secret # convert existing variable to secret',
|
|
190
|
+
])
|
|
191
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'key' implicitly has an 'any' type.
|
|
217
192
|
.action(async (key, value, options, command) => {
|
|
218
|
-
|
|
219
|
-
|
|
193
|
+
await envSet(key, value, options, command);
|
|
194
|
+
});
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { AVAILABLE_CONTEXTS, normalizeContext, translateFromEnvelopeToMongo } from '../../utils/env/index.mjs'
|
|
4
|
-
|
|
1
|
+
import { chalk, error, log, logJson } from '../../utils/command-helpers.mjs';
|
|
2
|
+
import { AVAILABLE_CONTEXTS, normalizeContext, translateFromEnvelopeToMongo } from '../../utils/env/index.mjs';
|
|
5
3
|
/**
|
|
6
4
|
* The env:unset command
|
|
7
5
|
* @param {string} key Environment variable key
|
|
@@ -9,145 +7,129 @@ import { AVAILABLE_CONTEXTS, normalizeContext, translateFromEnvelopeToMongo } fr
|
|
|
9
7
|
* @param {import('../base-command.mjs').default} command
|
|
10
8
|
* @returns {Promise<boolean>}
|
|
11
9
|
*/
|
|
10
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'key' implicitly has an 'any' type.
|
|
12
11
|
const envUnset = async (key, options, command) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
logJson(finalEnv)
|
|
41
|
-
return false
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const contextType = AVAILABLE_CONTEXTS.includes(context || 'all') ? 'context' : 'branch'
|
|
45
|
-
log(`Unset environment variable ${chalk.yellow(key)} in the ${chalk.magenta(context || 'all')} ${contextType}`)
|
|
46
|
-
}
|
|
47
|
-
|
|
12
|
+
const { context } = options;
|
|
13
|
+
const { api, cachedConfig, site } = command.netlify;
|
|
14
|
+
const siteId = site.id;
|
|
15
|
+
if (!siteId) {
|
|
16
|
+
log('No site id found, please run inside a site folder or `netlify link`');
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const { siteInfo } = cachedConfig;
|
|
20
|
+
let finalEnv;
|
|
21
|
+
if (siteInfo.use_envelope) {
|
|
22
|
+
finalEnv = await unsetInEnvelope({ api, context, siteInfo, key });
|
|
23
|
+
}
|
|
24
|
+
else if (context) {
|
|
25
|
+
error(`To specify a context, please run ${chalk.yellow('netlify open:admin')} to open the Netlify UI and opt in to the new environment variables experience from Site settings`);
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
finalEnv = await unsetInMongo({ api, siteInfo, key });
|
|
30
|
+
}
|
|
31
|
+
// Return new environment variables of site if using json flag
|
|
32
|
+
if (options.json) {
|
|
33
|
+
logJson(finalEnv);
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const contextType = AVAILABLE_CONTEXTS.includes(context || 'all') ? 'context' : 'branch';
|
|
37
|
+
log(`Unset environment variable ${chalk.yellow(key)} in the ${chalk.magenta(context || 'all')} ${contextType}`);
|
|
38
|
+
};
|
|
48
39
|
/**
|
|
49
40
|
* Deletes a given key from the env of a site record
|
|
50
41
|
* @returns {Promise<object>}
|
|
51
42
|
*/
|
|
43
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
52
44
|
const unsetInMongo = async ({ api, key, siteInfo }) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
return newEnv
|
|
74
|
-
}
|
|
75
|
-
|
|
45
|
+
// Get current environment variables set in the UI
|
|
46
|
+
const { build_settings: { env = {} }, } = siteInfo;
|
|
47
|
+
const newEnv = env;
|
|
48
|
+
// Delete environment variable from current variables
|
|
49
|
+
delete newEnv[key];
|
|
50
|
+
// Apply environment variable updates
|
|
51
|
+
await api.updateSite({
|
|
52
|
+
siteId: siteInfo.id,
|
|
53
|
+
body: {
|
|
54
|
+
build_settings: {
|
|
55
|
+
env: newEnv,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
return newEnv;
|
|
60
|
+
};
|
|
76
61
|
/**
|
|
77
62
|
* Deletes a given key from the env of a site configured with Envelope
|
|
78
63
|
* @returns {Promise<object>}
|
|
79
64
|
*/
|
|
65
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
80
66
|
const unsetInEnvelope = async ({ api, context, key, siteInfo }) => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
.map((ctx) => api.setEnvVarValue({ ...params, body: { context: ctx, value: allValue } })),
|
|
113
|
-
)
|
|
67
|
+
const accountId = siteInfo.account_slug;
|
|
68
|
+
const siteId = siteInfo.id;
|
|
69
|
+
// fetch envelope env vars
|
|
70
|
+
const envelopeVariables = await api.getEnvVars({ accountId, siteId });
|
|
71
|
+
const contexts = context || ['all'];
|
|
72
|
+
const env = translateFromEnvelopeToMongo(envelopeVariables, context ? context[0] : 'dev');
|
|
73
|
+
// check if the given key exists
|
|
74
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'envVar' implicitly has an 'any' type.
|
|
75
|
+
const variable = envelopeVariables.find((envVar) => envVar.key === key);
|
|
76
|
+
if (!variable) {
|
|
77
|
+
// if not, no need to call delete; return early
|
|
78
|
+
return env;
|
|
79
|
+
}
|
|
80
|
+
const params = { accountId, siteId, key };
|
|
81
|
+
try {
|
|
82
|
+
if (context) {
|
|
83
|
+
// if context(s) are passed, delete the matching contexts / branches, and the `all` context
|
|
84
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'val' implicitly has an 'any' type.
|
|
85
|
+
const values = variable.values.filter((val) => [...contexts, 'all'].includes(val.context_parameter || val.context));
|
|
86
|
+
if (values) {
|
|
87
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
|
|
88
|
+
await Promise.all(values.map((value) => api.deleteEnvVarValue({ ...params, id: value.id })));
|
|
89
|
+
// if this was the `all` context, we need to create 3 values in the other contexts
|
|
90
|
+
if (values.length === 1 && values[0].context === 'all') {
|
|
91
|
+
const newContexts = AVAILABLE_CONTEXTS.filter((ctx) => !context.includes(ctx));
|
|
92
|
+
const allValue = values[0].value;
|
|
93
|
+
await Promise.all(newContexts
|
|
94
|
+
.filter((ctx) => ctx !== 'all')
|
|
95
|
+
.map((ctx) => api.setEnvVarValue({ ...params, body: { context: ctx, value: allValue } })));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
114
98
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
99
|
+
else {
|
|
100
|
+
// otherwise, if no context passed, delete the whole key
|
|
101
|
+
await api.deleteEnvVar({ accountId, siteId, key });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (error_) {
|
|
105
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
106
|
+
throw error_.json ? error_.json.msg : error_;
|
|
119
107
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
delete env[key]
|
|
125
|
-
|
|
126
|
-
return env
|
|
127
|
-
}
|
|
128
|
-
|
|
108
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
109
|
+
delete env[key];
|
|
110
|
+
return env;
|
|
111
|
+
};
|
|
129
112
|
/**
|
|
130
113
|
* Creates the `netlify env:unset` command
|
|
131
114
|
* @param {import('../base-command.mjs').default} program
|
|
132
115
|
* @returns
|
|
133
116
|
*/
|
|
134
|
-
|
|
135
|
-
|
|
117
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
|
|
118
|
+
export const createEnvUnsetCommand = (program) => program
|
|
136
119
|
.command('env:unset')
|
|
137
120
|
.aliases(['env:delete', 'env:remove'])
|
|
138
121
|
.argument('<key>', 'Environment variable key')
|
|
139
|
-
.option(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
(context, previous = []) => [...previous, normalizeContext(context)],
|
|
144
|
-
)
|
|
122
|
+
.option('-c, --context <context...>', 'Specify a deploy context or branch (contexts: "production", "deploy-preview", "branch-deploy", "dev") (default: all contexts)',
|
|
123
|
+
// spread over an array for variadic options
|
|
124
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'context' implicitly has an 'any' type.
|
|
125
|
+
(context, previous = []) => [...previous, normalizeContext(context)])
|
|
145
126
|
.addExamples([
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
127
|
+
'netlify env:unset VAR_NAME # unset in all contexts',
|
|
128
|
+
'netlify env:unset VAR_NAME --context production',
|
|
129
|
+
'netlify env:unset VAR_NAME --context production deploy-preview',
|
|
130
|
+
])
|
|
150
131
|
.description('Unset an environment variable which removes it from the UI')
|
|
132
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'key' implicitly has an 'any' type.
|
|
151
133
|
.action(async (key, options, command) => {
|
|
152
|
-
|
|
153
|
-
|
|
134
|
+
await envUnset(key, options, command);
|
|
135
|
+
});
|