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