netlify-cli 17.6.0 → 17.8.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 (295) hide show
  1. package/bin/{run.mjs → run.js} +3 -3
  2. package/npm-shrinkwrap.json +4 -4
  3. package/package.json +8 -9
  4. package/scripts/{postinstall.mjs → postinstall.js} +3 -4
  5. package/src/commands/addons/addons-auth.js +22 -0
  6. package/src/commands/addons/{addons-config.mjs → addons-config.js} +9 -34
  7. package/src/commands/addons/{addons-create.mjs → addons-create.js} +7 -33
  8. package/src/commands/addons/addons-delete.js +33 -0
  9. package/src/commands/addons/{addons-list.mjs → addons-list.js} +3 -25
  10. package/src/commands/addons/addons.js +68 -0
  11. package/src/commands/addons/index.js +1 -0
  12. package/src/commands/api/{api.mjs → api.js} +2 -24
  13. package/src/commands/api/index.js +13 -0
  14. package/src/commands/{base-command.mjs → base-command.js} +7 -7
  15. package/src/commands/blobs/blobs-delete.js +20 -0
  16. package/src/commands/blobs/{blobs-get.mjs → blobs-get.js} +2 -15
  17. package/src/commands/blobs/{blobs-list.mjs → blobs-list.js} +2 -16
  18. package/src/commands/blobs/{blobs-set.mjs → blobs-set.js} +2 -17
  19. package/src/commands/blobs/blobs.js +74 -0
  20. package/src/commands/blobs/index.js +1 -0
  21. package/src/commands/build/{build.mjs → build.js} +7 -28
  22. package/src/commands/build/index.js +13 -0
  23. package/src/commands/completion/completion.js +29 -0
  24. package/src/commands/completion/index.js +26 -0
  25. package/src/commands/deploy/{deploy.mjs → deploy.js} +17 -133
  26. package/src/commands/deploy/index.js +106 -0
  27. package/src/commands/dev/{dev-exec.mjs → dev-exec.js} +3 -15
  28. package/src/commands/dev/{dev.mjs → dev.js} +19 -38
  29. package/src/commands/dev/index.js +1 -0
  30. package/src/commands/env/{env-clone.mjs → env-clone.js} +71 -94
  31. package/src/commands/env/env-get.js +34 -0
  32. package/src/commands/env/{env-import.mjs → env-import.js} +38 -65
  33. package/src/commands/env/{env-list.mjs → env-list.js} +3 -37
  34. package/src/commands/env/{env-set.mjs → env-set.js} +36 -81
  35. package/src/commands/env/{env-unset.mjs → env-unset.js} +30 -62
  36. package/src/commands/env/env.js +127 -0
  37. package/src/commands/env/index.js +1 -0
  38. package/src/commands/functions/{functions-build.mjs → functions-build.js} +3 -22
  39. package/src/commands/functions/{functions-create.mjs → functions-create.js} +20 -47
  40. package/src/commands/functions/{functions-invoke.mjs → functions-invoke.js} +3 -41
  41. package/src/commands/functions/{functions-list.mjs → functions-list.js} +3 -27
  42. package/src/commands/functions/{functions-serve.mjs → functions-serve.js} +6 -28
  43. package/src/commands/functions/functions.js +98 -0
  44. package/src/commands/functions/index.js +1 -0
  45. package/src/commands/index.js +2 -0
  46. package/src/commands/init/index.js +12 -0
  47. package/src/commands/init/{init.mjs → init.js} +10 -31
  48. package/src/commands/integration/{deploy.mjs → deploy.js} +7 -28
  49. package/src/commands/integration/index.js +26 -0
  50. package/src/commands/link/index.js +13 -0
  51. package/src/commands/link/{link.mjs → link.js} +6 -28
  52. package/src/commands/lm/index.js +1 -0
  53. package/src/commands/lm/{lm-info.mjs → lm-info.js} +2 -9
  54. package/src/commands/lm/lm-install.js +8 -0
  55. package/src/commands/lm/{lm-setup.mjs → lm-setup.js} +6 -25
  56. package/src/commands/lm/lm-uninstall.js +7 -0
  57. package/src/commands/lm/lm.js +46 -0
  58. package/src/commands/login/index.js +9 -0
  59. package/src/commands/login/{login.mjs → login.js} +1 -19
  60. package/src/commands/logout/index.js +7 -0
  61. package/src/commands/logout/{logout.mjs → logout.js} +3 -16
  62. package/src/commands/logs/{build.mjs → build.js} +3 -8
  63. package/src/commands/logs/{functions.mjs → functions.js} +4 -27
  64. package/src/commands/logs/index.js +39 -0
  65. package/src/commands/logs/log-levels.js +11 -0
  66. package/src/commands/{main.mjs → main.js} +32 -32
  67. package/src/commands/open/index.js +31 -0
  68. package/src/commands/open/open-admin.js +11 -0
  69. package/src/commands/open/open-site.js +12 -0
  70. package/src/commands/open/open.js +13 -0
  71. package/src/commands/recipes/{common.mjs → common.js} +2 -2
  72. package/src/commands/recipes/index.js +20 -0
  73. package/src/commands/recipes/recipes-list.js +14 -0
  74. package/src/commands/recipes/{recipes.mjs → recipes.js} +8 -32
  75. package/src/commands/serve/index.js +27 -0
  76. package/src/commands/serve/{serve.mjs → serve.js} +14 -51
  77. package/src/commands/sites/index.js +1 -0
  78. package/src/commands/sites/{sites-create-template.mjs → sites-create-template.js} +9 -38
  79. package/src/commands/sites/{sites-create.mjs → sites-create.js} +5 -38
  80. package/src/commands/sites/{sites-delete.mjs → sites-delete.js} +2 -22
  81. package/src/commands/sites/{sites-list.mjs → sites-list.js} +4 -24
  82. package/src/commands/sites/sites.js +77 -0
  83. package/src/commands/status/index.js +19 -0
  84. package/src/commands/status/{status-hooks.mjs → status-hooks.js} +2 -20
  85. package/src/commands/status/{status.mjs → status.js} +2 -23
  86. package/src/commands/switch/index.js +7 -0
  87. package/src/commands/switch/{switch.mjs → switch.js} +3 -16
  88. package/src/commands/unlink/index.js +7 -0
  89. package/src/commands/unlink/unlink.js +21 -0
  90. package/src/commands/watch/index.js +8 -0
  91. package/src/commands/watch/{watch.mjs → watch.js} +4 -21
  92. package/src/lib/{api.mjs → api.js} +1 -1
  93. package/src/lib/blobs/{blobs.mjs → blobs.js} +2 -2
  94. package/src/lib/{build.mjs → build.js} +3 -3
  95. package/src/lib/completion/{constants.mjs → constants.js} +1 -1
  96. package/src/lib/completion/{generate-autocompletion.mjs → generate-autocompletion.js} +3 -3
  97. package/src/lib/completion/{index.mjs → index.js} +1 -1
  98. package/src/lib/completion/{script.mjs → script.js} +3 -3
  99. package/src/lib/edge-functions/{deploy.mjs → deploy.js} +2 -2
  100. package/src/lib/edge-functions/{editor-helper.mjs → editor-helper.js} +1 -1
  101. package/src/lib/edge-functions/{internal.mjs → internal.js} +2 -2
  102. package/src/lib/edge-functions/{proxy.mjs → proxy.js} +10 -11
  103. package/src/lib/edge-functions/{registry.mjs → registry.js} +4 -2
  104. package/src/lib/{exec-fetcher.mjs → exec-fetcher.js} +2 -2
  105. package/src/lib/functions/{background.mjs → background.js} +2 -2
  106. package/src/lib/functions/{form-submissions-handler.mjs → form-submissions-handler.js} +3 -3
  107. package/src/lib/functions/{local-proxy.mjs → local-proxy.js} +1 -1
  108. package/src/lib/functions/{netlify-function.mjs → netlify-function.js} +18 -63
  109. package/src/lib/functions/{registry.mjs → registry.js} +33 -96
  110. package/src/lib/functions/runtimes/go/{index.mjs → index.js} +2 -2
  111. package/src/lib/functions/runtimes/{index.mjs → index.js} +3 -4
  112. package/src/lib/functions/runtimes/js/builders/{netlify-lambda.mjs → netlify-lambda.js} +3 -3
  113. package/src/lib/functions/runtimes/js/builders/{zisi.mjs → zisi.js} +6 -6
  114. package/src/lib/functions/runtimes/js/{index.mjs → index.js} +4 -4
  115. package/src/lib/functions/runtimes/rust/{index.mjs → index.js} +4 -4
  116. package/src/lib/functions/{scheduled.mjs → scheduled.js} +2 -2
  117. package/src/lib/functions/{server.mjs → server.js} +16 -15
  118. package/src/lib/functions/{synchronous.mjs → synchronous.js} +3 -3
  119. package/src/lib/functions/{utils.mjs → utils.js} +2 -2
  120. package/src/lib/{geo-location.mjs → geo-location.js} +1 -1
  121. package/src/lib/{http-agent.mjs → http-agent.js} +1 -1
  122. package/src/lib/images/{proxy.mjs → proxy.js} +3 -3
  123. package/src/lib/{log.mjs → log.js} +1 -1
  124. package/src/recipes/vscode/{index.mjs → index.js} +2 -2
  125. package/src/recipes/vscode/{settings.mjs → settings.js} +0 -1
  126. package/src/utils/addons/diffs/{index.mjs → index.js} +1 -1
  127. package/src/utils/addons/diffs/{options.mjs → options.js} +0 -1
  128. package/src/utils/addons/{prepare.mjs → prepare.js} +2 -2
  129. package/src/utils/addons/{prompts.mjs → prompts.js} +1 -1
  130. package/src/utils/addons/{render.mjs → render.js} +1 -1
  131. package/src/utils/{banner.mjs → banner.js} +1 -1
  132. package/src/utils/{build-info.mjs → build-info.js} +3 -3
  133. package/src/utils/{command-helpers.mjs → command-helpers.js} +4 -9
  134. package/src/utils/deploy/{deploy-site.mjs → deploy-site.js} +8 -8
  135. package/src/utils/deploy/{hash-files.mjs → hash-files.js} +1 -1
  136. package/src/utils/deploy/{hash-fns.mjs → hash-fns.js} +3 -3
  137. package/src/utils/deploy/{hasher-segments.mjs → hasher-segments.js} +1 -1
  138. package/src/utils/deploy/{upload-files.mjs → upload-files.js} +1 -1
  139. package/src/utils/deploy/{util.mjs → util.js} +1 -1
  140. package/src/utils/{detect-server-settings.mjs → detect-server-settings.js} +6 -7
  141. package/src/utils/{dev.mjs → dev.js} +3 -3
  142. package/src/utils/{dot-env.mjs → dot-env.js} +2 -2
  143. package/src/utils/env/{index.mjs → index.js} +1 -1
  144. package/src/utils/{framework-server.mjs → framework-server.js} +4 -4
  145. package/src/utils/functions/{functions.mjs → functions.js} +2 -2
  146. package/src/utils/functions/{get-functions.mjs → get-functions.js} +1 -1
  147. package/src/utils/functions/index.js +3 -0
  148. package/src/utils/{get-global-config.mjs → get-global-config.js} +1 -1
  149. package/src/utils/{get-repo-data.mjs → get-repo-data.js} +1 -1
  150. package/src/utils/{get-site.mjs → get-site.js} +1 -1
  151. package/src/utils/{gh-auth.mjs → gh-auth.js} +3 -3
  152. package/src/utils/{gitignore.mjs → gitignore.js} +2 -2
  153. package/src/utils/{headers.mjs → headers.js} +1 -1
  154. package/src/utils/hooks/{requires-site-info.mjs → requires-site-info.js} +1 -1
  155. package/src/utils/init/{config-github.mjs → config-github.js} +4 -4
  156. package/src/utils/init/{config-manual.mjs → config-manual.js} +5 -5
  157. package/src/utils/init/{config.mjs → config.js} +4 -4
  158. package/src/utils/init/{node-version.mjs → node-version.js} +1 -1
  159. package/src/utils/init/{utils.mjs → utils.js} +7 -7
  160. package/src/utils/{live-tunnel.mjs → live-tunnel.js} +4 -4
  161. package/src/utils/lm/{install.mjs → install.js} +6 -6
  162. package/src/utils/lm/{requirements.mjs → requirements.js} +1 -1
  163. package/src/utils/lm/{steps.mjs → steps.js} +2 -2
  164. package/src/utils/lm/{ui.mjs → ui.js} +2 -2
  165. package/src/utils/{open-browser.mjs → open-browser.js} +1 -1
  166. package/src/utils/{proxy-server.mjs → proxy-server.js} +5 -5
  167. package/src/utils/{proxy.mjs → proxy.js} +18 -16
  168. package/src/utils/{redirects.mjs → redirects.js} +1 -1
  169. package/src/utils/{rules-proxy.mjs → rules-proxy.js} +3 -3
  170. package/src/utils/{run-build.mjs → run-build.js} +8 -8
  171. package/src/utils/{shell.mjs → shell.js} +2 -2
  172. package/src/utils/{state-config.mjs → state-config.js} +1 -1
  173. package/src/utils/{static-server.mjs → static-server.js} +1 -1
  174. package/src/utils/telemetry/index.js +2 -0
  175. package/src/utils/telemetry/{report-error.mjs → report-error.js} +4 -4
  176. package/src/utils/telemetry/{request.mjs → request.js} +1 -1
  177. package/src/utils/telemetry/{telemetry.mjs → telemetry.js} +5 -5
  178. package/src/utils/telemetry/{utils.mjs → utils.js} +1 -1
  179. package/src/utils/telemetry/{validation.mjs → validation.js} +1 -1
  180. package/src/utils/{validation.mjs → validation.js} +1 -1
  181. package/src/commands/addons/addons-auth.mjs +0 -45
  182. package/src/commands/addons/addons-delete.mjs +0 -53
  183. package/src/commands/addons/addons.mjs +0 -39
  184. package/src/commands/addons/index.mjs +0 -1
  185. package/src/commands/api/index.mjs +0 -1
  186. package/src/commands/blobs/blobs-delete.mjs +0 -35
  187. package/src/commands/blobs/blobs.mjs +0 -32
  188. package/src/commands/blobs/index.mjs +0 -1
  189. package/src/commands/build/index.mjs +0 -1
  190. package/src/commands/completion/completion.mjs +0 -53
  191. package/src/commands/completion/index.mjs +0 -1
  192. package/src/commands/deploy/index.mjs +0 -1
  193. package/src/commands/dev/index.mjs +0 -1
  194. package/src/commands/dev/types.d.ts +0 -30
  195. package/src/commands/env/env-get.mjs +0 -66
  196. package/src/commands/env/env.mjs +0 -41
  197. package/src/commands/env/index.mjs +0 -1
  198. package/src/commands/functions/functions.mjs +0 -39
  199. package/src/commands/functions/index.mjs +0 -1
  200. package/src/commands/index.mjs +0 -2
  201. package/src/commands/init/index.mjs +0 -1
  202. package/src/commands/integration/index.mjs +0 -24
  203. package/src/commands/link/index.mjs +0 -1
  204. package/src/commands/lm/index.mjs +0 -1
  205. package/src/commands/lm/lm-install.mjs +0 -27
  206. package/src/commands/lm/lm-uninstall.mjs +0 -18
  207. package/src/commands/lm/lm.mjs +0 -30
  208. package/src/commands/login/index.mjs +0 -1
  209. package/src/commands/logout/index.mjs +0 -1
  210. package/src/commands/logs/index.mjs +0 -12
  211. package/src/commands/open/index.mjs +0 -1
  212. package/src/commands/open/open-admin.mjs +0 -30
  213. package/src/commands/open/open-site.mjs +0 -31
  214. package/src/commands/open/open.mjs +0 -36
  215. package/src/commands/recipes/index.mjs +0 -1
  216. package/src/commands/recipes/recipes-list.mjs +0 -25
  217. package/src/commands/serve/index.mjs +0 -1
  218. package/src/commands/sites/index.mjs +0 -2
  219. package/src/commands/sites/sites.mjs +0 -30
  220. package/src/commands/status/index.mjs +0 -1
  221. package/src/commands/switch/index.mjs +0 -1
  222. package/src/commands/types.d.ts +0 -31
  223. package/src/commands/unlink/index.mjs +0 -1
  224. package/src/commands/unlink/unlink.mjs +0 -34
  225. package/src/commands/watch/index.mjs +0 -1
  226. package/src/functions-templates/typescript/abtest/{{name}}.ts +0 -31
  227. package/src/functions-templates/typescript/geolocation/{{name}}.ts +0 -24
  228. package/src/functions-templates/typescript/hello-world/{{name}}.ts +0 -12
  229. package/src/functions-templates/typescript/json/{{name}}.ts +0 -5
  230. package/src/functions-templates/typescript/log/{{name}}.ts +0 -9
  231. package/src/functions-templates/typescript/scheduled-function/{{name}}.ts +0 -12
  232. package/src/functions-templates/typescript/set-cookies/{{name}}.ts +0 -29
  233. package/src/functions-templates/typescript/set-req-header/{{name}}.ts +0 -5
  234. package/src/functions-templates/typescript/set-res-header/{{name}}.ts +0 -7
  235. package/src/functions-templates/typescript/transform-response/{{name}}.ts +0 -13
  236. package/src/utils/functions/index.mjs +0 -3
  237. package/src/utils/telemetry/index.mjs +0 -2
  238. package/src/utils/types.d.ts +0 -46
  239. /package/src/functions-templates/go/hello-world/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  240. /package/src/functions-templates/javascript/hello/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  241. /package/src/functions-templates/javascript/hello-world/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  242. /package/src/functions-templates/javascript/identity-signup/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  243. /package/src/functions-templates/javascript/image-external/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  244. /package/src/functions-templates/javascript/localized-content/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  245. /package/src/functions-templates/javascript/sanity-create/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  246. /package/src/functions-templates/javascript/sanity-groq/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  247. /package/src/functions-templates/javascript/scheduled-function/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  248. /package/src/functions-templates/javascript/set-cookies/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  249. /package/src/functions-templates/javascript/set-req-header/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  250. /package/src/functions-templates/javascript/set-res-header/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  251. /package/src/functions-templates/javascript/submission-created/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  252. /package/src/functions-templates/javascript/transform-response/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  253. /package/src/functions-templates/rust/hello-world/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  254. /package/src/functions-templates/typescript/abtest/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  255. /package/src/functions-templates/typescript/geolocation/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  256. /package/src/functions-templates/typescript/hello-world/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  257. /package/src/functions-templates/typescript/json/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  258. /package/src/functions-templates/typescript/log/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  259. /package/src/functions-templates/typescript/scheduled-function/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  260. /package/src/functions-templates/typescript/set-cookies/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  261. /package/src/functions-templates/typescript/set-req-header/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  262. /package/src/functions-templates/typescript/set-res-header/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  263. /package/src/functions-templates/typescript/transform-response/{.netlify-function-template.mjs → .netlify-function-template.js} +0 -0
  264. /package/src/lib/{account.mjs → account.js} +0 -0
  265. /package/src/lib/completion/{get-autocompletion.mjs → get-autocompletion.js} +0 -0
  266. /package/src/lib/edge-functions/{bootstrap.mjs → bootstrap.js} +0 -0
  267. /package/src/lib/edge-functions/{consts.mjs → consts.js} +0 -0
  268. /package/src/lib/edge-functions/{headers.mjs → headers.js} +0 -0
  269. /package/src/lib/{fs.mjs → fs.js} +0 -0
  270. /package/src/lib/functions/{config.mjs → config.js} +0 -0
  271. /package/src/lib/functions/{memoized-build.mjs → memoized-build.js} +0 -0
  272. /package/src/lib/functions/runtimes/js/{constants.mjs → constants.js} +0 -0
  273. /package/src/lib/functions/runtimes/js/{worker.mjs → worker.js} +0 -0
  274. /package/src/lib/{path.mjs → path.js} +0 -0
  275. /package/src/lib/{render-error-template.mjs → render-error-template.js} +0 -0
  276. /package/src/lib/{settings.mjs → settings.js} +0 -0
  277. /package/src/lib/{spinner.mjs → spinner.js} +0 -0
  278. /package/src/lib/{string.mjs → string.js} +0 -0
  279. /package/src/utils/addons/{compare.mjs → compare.js} +0 -0
  280. /package/src/utils/addons/{validation.mjs → validation.js} +0 -0
  281. /package/src/utils/{create-deferred.mjs → create-deferred.js} +0 -0
  282. /package/src/utils/{create-stream-promise.mjs → create-stream-promise.js} +0 -0
  283. /package/src/utils/deploy/{constants.mjs → constants.js} +0 -0
  284. /package/src/utils/deploy/{hash-config.mjs → hash-config.js} +0 -0
  285. /package/src/utils/{execa.mjs → execa.js} +0 -0
  286. /package/src/utils/{feature-flags.mjs → feature-flags.js} +0 -0
  287. /package/src/utils/functions/{constants.mjs → constants.js} +0 -0
  288. /package/src/utils/{get-package-json.mjs → get-package-json.js} +0 -0
  289. /package/src/utils/init/{plugins.mjs → plugins.js} +0 -0
  290. /package/src/utils/{parse-raw-flags.mjs → parse-raw-flags.js} +0 -0
  291. /package/src/utils/{read-repo-url.mjs → read-repo-url.js} +0 -0
  292. /package/src/utils/{request-id.mjs → request-id.js} +0 -0
  293. /package/src/utils/{sign-redirect.mjs → sign-redirect.js} +0 -0
  294. /package/src/utils/sites/{utils.mjs → utils.js} +0 -0
  295. /package/src/utils/websockets/{index.mjs → index.js} +0 -0
@@ -1,5 +1,5 @@
1
- import { chalk, error as logError, log } from '../../utils/command-helpers.mjs';
2
- import { translateFromEnvelopeToMongo, translateFromMongoToEnvelope } from '../../utils/env/index.mjs';
1
+ import { chalk, error as logError, log } from '../../utils/command-helpers.js';
2
+ import { translateFromEnvelopeToMongo, translateFromMongoToEnvelope } from '../../utils/env/index.js';
3
3
  // @ts-expect-error TS(7006) FIXME: Parameter 'api' implicitly has an 'any' type.
4
4
  const safeGetSite = async (api, siteId) => {
5
5
  try {
@@ -11,68 +11,18 @@ const safeGetSite = async (api, siteId) => {
11
11
  }
12
12
  };
13
13
  /**
14
- * The env:clone command
15
- * @param {string} siteIdA Site (From)
16
- * @param {string} siteIdB Site (To)
17
- * @param {import('commander').OptionValues} options
18
- * @param {import('../base-command.mjs').default} command
19
- * @returns {Promise<boolean>}
20
- */
21
- // @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
22
- const envClone = async (options, command) => {
23
- const { api, site } = command.netlify;
24
- if (!site.id && !options.from) {
25
- log('Please include the source site Id as the `--from` option, or run `netlify link` to link this folder to a Netlify site');
26
- return false;
27
- }
28
- const siteId = {
29
- from: options.from || site.id,
30
- to: options.to,
31
- };
32
- const [{ data: siteFrom, error: errorFrom }, { data: siteTo, error: errorTo }] = await Promise.all([
33
- safeGetSite(api, siteId.from),
34
- safeGetSite(api, siteId.to),
35
- ]);
36
- if (errorFrom) {
37
- logError(`Can't find site with id ${chalk.bold(siteId.from)}. Please make sure the site exists.`);
38
- return false;
39
- }
40
- if (errorTo) {
41
- logError(`Can't find site with id ${chalk.bold(siteId.to)}. Please make sure the site exists.`);
42
- return false;
43
- }
44
- // determine if siteFrom and/or siteTo is on Envelope
45
- let method;
46
- if (!siteFrom.use_envelope && !siteTo.use_envelope) {
47
- method = mongoToMongo;
48
- }
49
- else if (!siteFrom.use_envelope && siteTo.use_envelope) {
50
- method = mongoToEnvelope;
51
- }
52
- else if (siteFrom.use_envelope && !siteTo.use_envelope) {
53
- method = envelopeToMongo;
54
- }
55
- else {
56
- method = envelopeToEnvelope;
57
- }
58
- const success = await method({ api, siteFrom, siteTo });
59
- if (!success) {
60
- return false;
61
- }
62
- log(`Successfully cloned environment variables from ${chalk.green(siteFrom.name)} to ${chalk.green(siteTo.name)}`);
63
- return true;
64
- };
65
- /**
66
- * Copies the env from a site not configured with Envelope to a different site not configured with Envelope
14
+ * Copies the env from a site configured with Envelope to a site not configured with Envelope
67
15
  * @returns {Promise<boolean>}
68
16
  */
69
17
  // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
70
- const mongoToMongo = async ({ api, siteFrom, siteTo }) => {
71
- const [{ build_settings: { env: envFrom = {} }, }, { build_settings: { env: envTo = {} }, },] = [siteFrom, siteTo];
18
+ const envelopeToMongo = async ({ api, siteFrom, siteTo }) => {
19
+ const envelopeVariables = await api.getEnvVars({ accountId: siteFrom.account_slug, siteId: siteFrom.id });
20
+ const envFrom = translateFromEnvelopeToMongo(envelopeVariables);
72
21
  if (Object.keys(envFrom).length === 0) {
73
22
  log(`${chalk.green(siteFrom.name)} has no environment variables, nothing to clone`);
74
23
  return false;
75
24
  }
25
+ const envTo = siteTo.build_settings.env || {};
76
26
  // Merge from site A to site B
77
27
  const mergedEnv = {
78
28
  ...envTo,
@@ -90,29 +40,31 @@ const mongoToMongo = async ({ api, siteFrom, siteTo }) => {
90
40
  return true;
91
41
  };
92
42
  /**
93
- * Copies the env from a site not configured with Envelope to a site configured with Envelope
43
+ * Copies the env from a site configured with Envelope to a different site configured with Envelope
94
44
  * @returns {Promise<boolean>}
95
45
  */
96
46
  // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
97
- const mongoToEnvelope = async ({ api, siteFrom, siteTo }) => {
98
- const envFrom = siteFrom.build_settings.env || {};
99
- const keysFrom = Object.keys(envFrom);
100
- if (Object.keys(envFrom).length === 0) {
47
+ const envelopeToEnvelope = async ({ api, siteFrom, siteTo }) => {
48
+ const [envelopeFrom, envelopeTo] = await Promise.all([
49
+ api.getEnvVars({ accountId: siteFrom.account_slug, siteId: siteFrom.id }),
50
+ api.getEnvVars({ accountId: siteTo.account_slug, siteId: siteTo.id }),
51
+ ]);
52
+ // @ts-expect-error TS(7031) FIXME: Binding element 'key' implicitly has an 'any' type... Remove this comment to see the full error message
53
+ const keysFrom = envelopeFrom.map(({ key }) => key);
54
+ if (keysFrom.length === 0) {
101
55
  log(`${chalk.green(siteFrom.name)} has no environment variables, nothing to clone`);
102
56
  return false;
103
57
  }
104
58
  const accountId = siteTo.account_slug;
105
59
  const siteId = siteTo.id;
106
- const envelopeTo = await api.getEnvVars({ accountId, siteId });
107
60
  // @ts-expect-error TS(7031) FIXME: Binding element 'key' implicitly has an 'any' type... Remove this comment to see the full error message
108
61
  const envVarsToDelete = envelopeTo.filter(({ key }) => keysFrom.includes(key));
109
62
  // delete marked env vars in parallel
110
63
  // @ts-expect-error TS(7031) FIXME: Binding element 'key' implicitly has an 'any' type... Remove this comment to see the full error message
111
64
  await Promise.all(envVarsToDelete.map(({ key }) => api.deleteEnvVar({ accountId, siteId, key })));
112
65
  // hit create endpoint
113
- const body = translateFromMongoToEnvelope(envFrom);
114
66
  try {
115
- await api.createEnvVars({ accountId, siteId, body });
67
+ await api.createEnvVars({ accountId, siteId, body: envelopeFrom });
116
68
  }
117
69
  catch (error) {
118
70
  // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
@@ -121,18 +73,16 @@ const mongoToEnvelope = async ({ api, siteFrom, siteTo }) => {
121
73
  return true;
122
74
  };
123
75
  /**
124
- * Copies the env from a site configured with Envelope to a site not configured with Envelope
76
+ * Copies the env from a site not configured with Envelope to a different site not configured with Envelope
125
77
  * @returns {Promise<boolean>}
126
78
  */
127
79
  // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
128
- const envelopeToMongo = async ({ api, siteFrom, siteTo }) => {
129
- const envelopeVariables = await api.getEnvVars({ accountId: siteFrom.account_slug, siteId: siteFrom.id });
130
- const envFrom = translateFromEnvelopeToMongo(envelopeVariables);
80
+ const mongoToMongo = async ({ api, siteFrom, siteTo }) => {
81
+ const [{ build_settings: { env: envFrom = {} }, }, { build_settings: { env: envTo = {} }, },] = [siteFrom, siteTo];
131
82
  if (Object.keys(envFrom).length === 0) {
132
83
  log(`${chalk.green(siteFrom.name)} has no environment variables, nothing to clone`);
133
84
  return false;
134
85
  }
135
- const envTo = siteTo.build_settings.env || {};
136
86
  // Merge from site A to site B
137
87
  const mergedEnv = {
138
88
  ...envTo,
@@ -150,31 +100,29 @@ const envelopeToMongo = async ({ api, siteFrom, siteTo }) => {
150
100
  return true;
151
101
  };
152
102
  /**
153
- * Copies the env from a site configured with Envelope to a different site configured with Envelope
103
+ * Copies the env from a site not configured with Envelope to a site configured with Envelope
154
104
  * @returns {Promise<boolean>}
155
105
  */
156
106
  // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
157
- const envelopeToEnvelope = async ({ api, siteFrom, siteTo }) => {
158
- const [envelopeFrom, envelopeTo] = await Promise.all([
159
- api.getEnvVars({ accountId: siteFrom.account_slug, siteId: siteFrom.id }),
160
- api.getEnvVars({ accountId: siteTo.account_slug, siteId: siteTo.id }),
161
- ]);
162
- // @ts-expect-error TS(7031) FIXME: Binding element 'key' implicitly has an 'any' type... Remove this comment to see the full error message
163
- const keysFrom = envelopeFrom.map(({ key }) => key);
164
- if (keysFrom.length === 0) {
107
+ const mongoToEnvelope = async ({ api, siteFrom, siteTo }) => {
108
+ const envFrom = siteFrom.build_settings.env || {};
109
+ const keysFrom = Object.keys(envFrom);
110
+ if (Object.keys(envFrom).length === 0) {
165
111
  log(`${chalk.green(siteFrom.name)} has no environment variables, nothing to clone`);
166
112
  return false;
167
113
  }
168
114
  const accountId = siteTo.account_slug;
169
115
  const siteId = siteTo.id;
116
+ const envelopeTo = await api.getEnvVars({ accountId, siteId });
170
117
  // @ts-expect-error TS(7031) FIXME: Binding element 'key' implicitly has an 'any' type... Remove this comment to see the full error message
171
118
  const envVarsToDelete = envelopeTo.filter(({ key }) => keysFrom.includes(key));
172
119
  // delete marked env vars in parallel
173
120
  // @ts-expect-error TS(7031) FIXME: Binding element 'key' implicitly has an 'any' type... Remove this comment to see the full error message
174
121
  await Promise.all(envVarsToDelete.map(({ key }) => api.deleteEnvVar({ accountId, siteId, key })));
175
122
  // hit create endpoint
123
+ const body = translateFromMongoToEnvelope(envFrom);
176
124
  try {
177
- await api.createEnvVars({ accountId, siteId, body: envelopeFrom });
125
+ await api.createEnvVars({ accountId, siteId, body });
178
126
  }
179
127
  catch (error) {
180
128
  // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
@@ -182,17 +130,46 @@ const envelopeToEnvelope = async ({ api, siteFrom, siteTo }) => {
182
130
  }
183
131
  return true;
184
132
  };
185
- /**
186
- * Creates the `netlify env:clone` command
187
- * @param {import('../base-command.mjs').default} program
188
- * @returns
189
- */
190
- // @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
191
- export const createEnvCloneCommand = (program) => program
192
- .command('env:clone')
193
- .alias('env:migrate')
194
- .option('-f, --from <from>', 'Site ID (From)')
195
- .requiredOption('-t, --to <to>', 'Site ID (To)')
196
- .description(`Clone environment variables from one site to another`)
197
- .addExamples(['netlify env:clone --to <to-site-id>', 'netlify env:clone --to <to-site-id> --from <from-site-id>'])
198
- .action(envClone);
133
+ export const envClone = async (options, command) => {
134
+ const { api, site } = command.netlify;
135
+ if (!site.id && !options.from) {
136
+ log('Please include the source site Id as the `--from` option, or run `netlify link` to link this folder to a Netlify site');
137
+ return false;
138
+ }
139
+ const siteId = {
140
+ from: options.from || site.id,
141
+ to: options.to,
142
+ };
143
+ const [{ data: siteFrom, error: errorFrom }, { data: siteTo, error: errorTo }] = await Promise.all([
144
+ safeGetSite(api, siteId.from),
145
+ safeGetSite(api, siteId.to),
146
+ ]);
147
+ if (errorFrom) {
148
+ logError(`Can't find site with id ${chalk.bold(siteId.from)}. Please make sure the site exists.`);
149
+ return false;
150
+ }
151
+ if (errorTo) {
152
+ logError(`Can't find site with id ${chalk.bold(siteId.to)}. Please make sure the site exists.`);
153
+ return false;
154
+ }
155
+ // determine if siteFrom and/or siteTo is on Envelope
156
+ let method;
157
+ if (!siteFrom.use_envelope && !siteTo.use_envelope) {
158
+ method = mongoToMongo;
159
+ }
160
+ else if (!siteFrom.use_envelope && siteTo.use_envelope) {
161
+ method = mongoToEnvelope;
162
+ }
163
+ else if (siteFrom.use_envelope && !siteTo.use_envelope) {
164
+ method = envelopeToMongo;
165
+ }
166
+ else {
167
+ method = envelopeToEnvelope;
168
+ }
169
+ const success = await method({ api, siteFrom, siteTo });
170
+ if (!success) {
171
+ return false;
172
+ }
173
+ log(`Successfully cloned environment variables from ${chalk.green(siteFrom.name)} to ${chalk.green(siteTo.name)}`);
174
+ return true;
175
+ };
@@ -0,0 +1,34 @@
1
+ import { chalk, error, log, logJson } from '../../utils/command-helpers.js';
2
+ import { AVAILABLE_CONTEXTS, getEnvelopeEnv } from '../../utils/env/index.js';
3
+ export const envGet = async (name, options, command) => {
4
+ const { context, scope } = options;
5
+ const { api, cachedConfig, site } = command.netlify;
6
+ const siteId = site.id;
7
+ if (!siteId) {
8
+ log('No site id found, please run inside a site folder or `netlify link`');
9
+ return false;
10
+ }
11
+ const { siteInfo } = cachedConfig;
12
+ let { env } = cachedConfig;
13
+ if (siteInfo.use_envelope) {
14
+ env = await getEnvelopeEnv({ api, context, env, key: name, scope, siteInfo });
15
+ }
16
+ else if (context !== 'dev' || scope !== 'any') {
17
+ 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`);
18
+ return false;
19
+ }
20
+ const { value } = env[name] || {};
21
+ // Return json response for piping commands
22
+ if (options.json) {
23
+ logJson(value ? { [name]: value } : {});
24
+ return false;
25
+ }
26
+ if (!value) {
27
+ const contextType = AVAILABLE_CONTEXTS.includes(context) ? 'context' : 'branch';
28
+ const withContext = `in the ${chalk.magenta(context)} ${contextType}`;
29
+ const withScope = scope === 'any' ? '' : ` and the ${chalk.magenta(scope)} scope`;
30
+ log(`No value set ${withContext}${withScope} for environment variable ${chalk.yellow(name)}`);
31
+ return false;
32
+ }
33
+ log(value);
34
+ };
@@ -1,53 +1,8 @@
1
1
  import { readFile } from 'fs/promises';
2
2
  import AsciiTable from 'ascii-table';
3
- import { Option } from 'commander';
4
3
  import dotenv from 'dotenv';
5
- import { exit, log, logJson } from '../../utils/command-helpers.mjs';
6
- import { translateFromEnvelopeToMongo, translateFromMongoToEnvelope } from '../../utils/env/index.mjs';
7
- /**
8
- * The env:import command
9
- * @param {string} fileName .env file to import
10
- * @param {import('commander').OptionValues} options
11
- * @param {import('../base-command.mjs').default} command
12
- * @returns {Promise<boolean>}
13
- */
14
- // @ts-expect-error TS(7006) FIXME: Parameter 'fileName' implicitly has an 'any' type.
15
- const envImport = async (fileName, options, command) => {
16
- const { api, cachedConfig, site } = command.netlify;
17
- const siteId = site.id;
18
- if (!siteId) {
19
- log('No site id found, please run inside a site folder or `netlify link`');
20
- return false;
21
- }
22
- let importedEnv = {};
23
- try {
24
- const envFileContents = await readFile(fileName, 'utf-8');
25
- importedEnv = dotenv.parse(envFileContents);
26
- }
27
- catch (error) {
28
- // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
29
- log(error.message);
30
- exit(1);
31
- }
32
- if (Object.keys(importedEnv).length === 0) {
33
- log(`No environment variables found in file ${fileName} to import`);
34
- return false;
35
- }
36
- const { siteInfo } = cachedConfig;
37
- const importIntoService = siteInfo.use_envelope ? importIntoEnvelope : importIntoMongo;
38
- const finalEnv = await importIntoService({ api, importedEnv, options, siteInfo });
39
- // Return new environment variables of site if using json flag
40
- if (options.json) {
41
- logJson(finalEnv);
42
- return false;
43
- }
44
- // List newly imported environment variables in a table
45
- log(`site: ${siteInfo.name}`);
46
- const table = new AsciiTable(`Imported environment variables`);
47
- table.setHeading('Key', 'Value');
48
- table.addRowMatrix(Object.entries(importedEnv));
49
- log(table.toString());
50
- };
4
+ import { exit, log, logJson } from '../../utils/command-helpers.js';
5
+ import { translateFromEnvelopeToMongo, translateFromMongoToEnvelope } from '../../utils/env/index.js';
51
6
  /**
52
7
  * Updates the imported env in the site record
53
8
  * @returns {Promise<object>}
@@ -107,21 +62,39 @@ const importIntoEnvelope = async ({ api, importedEnv, options, siteInfo }) => {
107
62
  ...importedEnv,
108
63
  };
109
64
  };
110
- /**
111
- * Creates the `netlify env:import` command
112
- * @param {import('../base-command.mjs').default} program
113
- * @returns
114
- */
115
- // @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
116
- export const createEnvImportCommand = (program) => program
117
- .command('env:import')
118
- .argument('<fileName>', '.env file to import')
119
- .addOption(new Option('-r --replaceExisting', 'Old, prefer --replace-existing. Replace all existing variables instead of merging them with the current ones')
120
- .default(false)
121
- .hideHelp(true))
122
- .option('-r, --replace-existing', 'Replace all existing variables instead of merging them with the current ones', false)
123
- .description('Import and set environment variables from .env file')
124
- // @ts-expect-error TS(7006) FIXME: Parameter 'fileName' implicitly has an 'any' type.
125
- .action(async (fileName, options, command) => {
126
- await envImport(fileName, options, command);
127
- });
65
+ export const envImport = async (fileName, options, command) => {
66
+ const { api, cachedConfig, site } = command.netlify;
67
+ const siteId = site.id;
68
+ if (!siteId) {
69
+ log('No site id found, please run inside a site folder or `netlify link`');
70
+ return false;
71
+ }
72
+ let importedEnv = {};
73
+ try {
74
+ const envFileContents = await readFile(fileName, 'utf-8');
75
+ importedEnv = dotenv.parse(envFileContents);
76
+ }
77
+ catch (error) {
78
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
79
+ log(error.message);
80
+ exit(1);
81
+ }
82
+ if (Object.keys(importedEnv).length === 0) {
83
+ log(`No environment variables found in file ${fileName} to import`);
84
+ return false;
85
+ }
86
+ const { siteInfo } = cachedConfig;
87
+ const importIntoService = siteInfo.use_envelope ? importIntoEnvelope : importIntoMongo;
88
+ const finalEnv = await importIntoService({ api, importedEnv, options, siteInfo });
89
+ // Return new environment variables of site if using json flag
90
+ if (options.json) {
91
+ logJson(finalEnv);
92
+ return false;
93
+ }
94
+ // List newly imported environment variables in a table
95
+ log(`site: ${siteInfo.name}`);
96
+ const table = new AsciiTable(`Imported environment variables`);
97
+ table.setHeading('Key', 'Value');
98
+ table.addRowMatrix(Object.entries(importedEnv));
99
+ log(table.toString());
100
+ };
@@ -1,11 +1,10 @@
1
1
  import ansiEscapes from 'ansi-escapes';
2
2
  import AsciiTable from 'ascii-table';
3
3
  import { isCI } from 'ci-info';
4
- import { Option } from 'commander';
5
4
  import inquirer from 'inquirer';
6
5
  import logUpdate from 'log-update';
7
- import { chalk, error, log, logJson } from '../../utils/command-helpers.mjs';
8
- import { AVAILABLE_CONTEXTS, getEnvelopeEnv, getHumanReadableScopes, normalizeContext } from '../../utils/env/index.mjs';
6
+ import { chalk, error, log, logJson } from '../../utils/command-helpers.js';
7
+ import { AVAILABLE_CONTEXTS, getEnvelopeEnv, getHumanReadableScopes } from '../../utils/env/index.js';
9
8
  const MASK_LENGTH = 50;
10
9
  const MASK = '*'.repeat(MASK_LENGTH);
11
10
  // @ts-expect-error TS(7031) FIXME: Binding element 'environment' implicitly has an 'a... Remove this comment to see the full error message
@@ -25,14 +24,7 @@ const getTable = ({ environment, hideValues, scopesColumn }) => {
25
24
  ].filter(Boolean)));
26
25
  return table.toString();
27
26
  };
28
- /**
29
- * The env:list command
30
- * @param {import('commander').OptionValues} options
31
- * @param {import('../base-command.mjs').default} command
32
- * @returns {Promise<boolean>}
33
- */
34
- // @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
35
- const envList = async (options, command) => {
27
+ export const envList = async (options, command) => {
36
28
  const { context, scope } = options;
37
29
  const { api, cachedConfig, site } = command.netlify;
38
30
  const siteId = site.id;
@@ -101,29 +93,3 @@ const envList = async (options, command) => {
101
93
  log(`${chalk.cyan('?')} Show values? ${chalk.cyan('Yes')}`);
102
94
  }
103
95
  };
104
- /**
105
- * Creates the `netlify env:list` command
106
- * @param {import('../base-command.mjs').default} program
107
- * @returns
108
- */
109
- // @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
110
- export const createEnvListCommand = (program) => program
111
- .command('env:list')
112
- .option('-c, --context <context>', 'Specify a deploy context or branch (contexts: "production", "deploy-preview", "branch-deploy", "dev")', normalizeContext, 'dev')
113
- .option('--json', 'Output environment variables as JSON')
114
- .addOption(new Option('--plain', 'Output environment variables as plaintext').conflicts('json'))
115
- .addOption(new Option('-s, --scope <scope>', 'Specify a scope')
116
- .choices(['builds', 'functions', 'post-processing', 'runtime', 'any'])
117
- .default('any'))
118
- .addExamples([
119
- 'netlify env:list # list variables with values in the dev context and with any scope',
120
- 'netlify env:list --context production',
121
- 'netlify env:list --context branch:staging',
122
- 'netlify env:list --scope functions',
123
- 'netlify env:list --plain',
124
- ])
125
- .description('Lists resolved environment variables for site (includes netlify.toml)')
126
- // @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
127
- .action(async (options, command) => {
128
- await envList(options, command);
129
- });
@@ -1,49 +1,5 @@
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';
4
- /**
5
- * The env:set command
6
- * @param {string} key Environment variable key
7
- * @param {string} value Value to set to
8
- * @param {import('commander').OptionValues} options
9
- * @param {import('../base-command.mjs').default} command
10
- * @returns {Promise<boolean>}
11
- */
12
- // @ts-expect-error TS(7006) FIXME: Parameter 'key' implicitly has an 'any' type.
13
- const envSet = async (key, value, options, command) => {
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
- };
1
+ import { chalk, error, log, logJson } from '../../utils/command-helpers.js';
2
+ import { AVAILABLE_CONTEXTS, AVAILABLE_SCOPES, translateFromEnvelopeToMongo } from '../../utils/env/index.js';
47
3
  /**
48
4
  * Updates the env for a site record with a new key/value pair
49
5
  * @returns {Promise<object>}
@@ -157,38 +113,37 @@ const setInEnvelope = async ({ api, context, key, scope, secret, siteInfo, value
157
113
  [key]: value || env[key],
158
114
  };
159
115
  };
160
- /**
161
- * Creates the `netlify env:set` command
162
- * @param {import('../base-command.mjs').default} program
163
- * @returns
164
- */
165
- // @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
166
- export const createEnvSetCommand = (program) => program
167
- .command('env:set')
168
- .argument('<key>', 'Environment variable key')
169
- .argument('[value]', 'Value to set to', '')
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
- ]))
180
- .option('--secret', 'Indicate whether the environment variable value can be read again.')
181
- .description('Set value of environment variable')
182
- .addExamples([
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.
192
- .action(async (key, value, options, command) => {
193
- await envSet(key, value, options, command);
194
- });
116
+ export const envSet = async (key, value, options, command) => {
117
+ const { context, scope, secret } = options;
118
+ const { api, cachedConfig, site } = command.netlify;
119
+ const siteId = site.id;
120
+ if (!siteId) {
121
+ log('No site id found, please run inside a site folder or `netlify link`');
122
+ return false;
123
+ }
124
+ const { siteInfo } = cachedConfig;
125
+ let finalEnv;
126
+ // Get current environment variables set in the UI
127
+ if (siteInfo.use_envelope) {
128
+ finalEnv = await setInEnvelope({ api, siteInfo, key, value, context, scope, secret });
129
+ }
130
+ else if (context || scope) {
131
+ 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`);
132
+ return false;
133
+ }
134
+ else {
135
+ finalEnv = await setInMongo({ api, siteInfo, key, value });
136
+ }
137
+ if (!finalEnv) {
138
+ return false;
139
+ }
140
+ // Return new environment variables of site if using json flag
141
+ if (options.json) {
142
+ logJson(finalEnv);
143
+ return false;
144
+ }
145
+ const withScope = scope ? ` scoped to ${chalk.white(scope)}` : '';
146
+ const withSecret = secret ? ` as a ${chalk.blue('secret')}` : '';
147
+ const contextType = AVAILABLE_CONTEXTS.includes(context || 'all') ? 'context' : 'branch';
148
+ log(`Set environment variable ${chalk.yellow(`${key}${value && !secret ? `=${value}` : ''}`)}${withScope}${withSecret} in the ${chalk.magenta(context || 'all')} ${contextType}`);
149
+ };