netlify-cli 17.3.2 → 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 +2 -138
  2. package/npm-shrinkwrap.json +76 -76
  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 -99
  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,68 +1,56 @@
1
- // @ts-check
2
- import { stat } from 'fs/promises'
3
- import { basename, resolve } from 'path'
4
- import { env } from 'process'
5
-
6
- import { runCoreSteps } from '@netlify/build'
7
- import { Option } from 'commander'
8
- import inquirer from 'inquirer'
9
- import isEmpty from 'lodash/isEmpty.js'
10
- import isObject from 'lodash/isObject.js'
11
- import { parseAllHeaders } from 'netlify-headers-parser'
12
- import { parseAllRedirects } from 'netlify-redirect-parser'
13
- import prettyjson from 'prettyjson'
14
-
15
- import { cancelDeploy } from '../../lib/api.mjs'
16
- import { getBuildOptions, runBuild } from '../../lib/build.mjs'
17
- import { getBootstrapURL } from '../../lib/edge-functions/bootstrap.mjs'
18
- import { featureFlags as edgeFunctionsFeatureFlags } from '../../lib/edge-functions/consts.mjs'
19
- import { normalizeFunctionsConfig } from '../../lib/functions/config.mjs'
20
- import { BACKGROUND_FUNCTIONS_WARNING } from '../../lib/log.mjs'
21
- import { startSpinner, stopSpinner } from '../../lib/spinner.mjs'
22
- import {
23
- chalk,
24
- error,
25
- exit,
26
- getToken,
27
- log,
28
- logJson,
29
- NETLIFYDEV,
30
- NETLIFYDEVERR,
31
- NETLIFYDEVLOG,
32
- warn,
33
- } from '../../utils/command-helpers.mjs'
34
- import { DEFAULT_DEPLOY_TIMEOUT } from '../../utils/deploy/constants.mjs'
35
- import { deploySite } from '../../utils/deploy/deploy-site.mjs'
36
- import { getEnvelopeEnv } from '../../utils/env/index.mjs'
37
- import { getFunctionsManifestPath, getInternalFunctionsDir } from '../../utils/functions/index.mjs'
38
- import openBrowser from '../../utils/open-browser.mjs'
39
- import { link } from '../link/index.mjs'
40
- import { sitesCreate } from '../sites/index.mjs'
41
-
1
+ import { stat } from 'fs/promises';
2
+ import { basename, resolve } from 'path';
3
+ import { env } from 'process';
4
+ import { runCoreSteps } from '@netlify/build';
5
+ import { Option } from 'commander';
6
+ import inquirer from 'inquirer';
7
+ import isEmpty from 'lodash/isEmpty.js';
8
+ import isObject from 'lodash/isObject.js';
9
+ import { parseAllHeaders } from 'netlify-headers-parser';
10
+ import { parseAllRedirects } from 'netlify-redirect-parser';
11
+ import prettyjson from 'prettyjson';
12
+ import { cancelDeploy } from '../../lib/api.mjs';
13
+ import { getBuildOptions, runBuild } from '../../lib/build.mjs';
14
+ import { getBootstrapURL } from '../../lib/edge-functions/bootstrap.mjs';
15
+ import { featureFlags as edgeFunctionsFeatureFlags } from '../../lib/edge-functions/consts.mjs';
16
+ import { normalizeFunctionsConfig } from '../../lib/functions/config.mjs';
17
+ import { BACKGROUND_FUNCTIONS_WARNING } from '../../lib/log.mjs';
18
+ import { startSpinner, stopSpinner } from '../../lib/spinner.mjs';
19
+ import { chalk, error, exit, getToken, log, logJson, NETLIFYDEV, NETLIFYDEVERR, NETLIFYDEVLOG, warn, } from '../../utils/command-helpers.mjs';
20
+ import { DEFAULT_DEPLOY_TIMEOUT } from '../../utils/deploy/constants.mjs';
21
+ import { deploySite } from '../../utils/deploy/deploy-site.mjs';
22
+ import { getEnvelopeEnv } from '../../utils/env/index.mjs';
23
+ import { getFunctionsManifestPath, getInternalFunctionsDir } from '../../utils/functions/index.mjs';
24
+ import openBrowser from '../../utils/open-browser.mjs';
25
+ import { link } from '../link/index.mjs';
26
+ import { sitesCreate } from '../sites/index.mjs';
27
+ // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
42
28
  const triggerDeploy = async ({ api, options, siteData, siteId }) => {
43
- try {
44
- const siteBuild = await api.createSiteBuild({ siteId })
45
- if (options.json) {
46
- logJson({
47
- site_id: siteId,
48
- site_name: siteData.name,
49
- deploy_id: `${siteBuild.deploy_id}`,
50
- logs: `https://app.netlify.com/sites/${siteData.name}/deploys/${siteBuild.deploy_id}`,
51
- })
52
- } else {
53
- log(
54
- `${NETLIFYDEV} A new deployment was triggered successfully. Visit https://app.netlify.com/sites/${siteData.name}/deploys/${siteBuild.deploy_id} to see the logs.`,
55
- )
56
- }
57
- } catch (error_) {
58
- if (error_.status === 404) {
59
- error('Site not found. Please rerun "netlify link" and make sure that your site has CI configured.')
60
- } else {
61
- error(error_.message)
62
- }
63
- }
64
- }
65
-
29
+ try {
30
+ const siteBuild = await api.createSiteBuild({ siteId });
31
+ if (options.json) {
32
+ logJson({
33
+ site_id: siteId,
34
+ site_name: siteData.name,
35
+ deploy_id: `${siteBuild.deploy_id}`,
36
+ logs: `https://app.netlify.com/sites/${siteData.name}/deploys/${siteBuild.deploy_id}`,
37
+ });
38
+ }
39
+ else {
40
+ log(`${NETLIFYDEV} A new deployment was triggered successfully. Visit https://app.netlify.com/sites/${siteData.name}/deploys/${siteBuild.deploy_id} to see the logs.`);
41
+ }
42
+ }
43
+ catch (error_) {
44
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
45
+ if (error_.status === 404) {
46
+ error('Site not found. Please rerun "netlify link" and make sure that your site has CI configured.');
47
+ }
48
+ else {
49
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
50
+ error(error_.message);
51
+ }
52
+ }
53
+ };
66
54
  /**
67
55
  * Retrieves the folder containing the static files that need to be deployed
68
56
  * @param {object} config
@@ -73,64 +61,65 @@ const triggerDeploy = async ({ api, options, siteData, siteId }) => {
73
61
  * @param {object} config.siteData
74
62
  * @returns {Promise<string>}
75
63
  */
64
+ // @ts-expect-error TS(7031) FIXME: Binding element 'command' implicitly has an 'any' ... Remove this comment to see the full error message
76
65
  const getDeployFolder = async ({ command, config, options, site, siteData }) => {
77
- let deployFolder
78
- // if the `--dir .` flag is provided we should resolve it to the working directory.
79
- // - in regular sites this is the `process.cwd`
80
- // - in mono repositories this will be the root of the jsWorkspace
81
- if (options.dir) {
82
- deployFolder = command.workspacePackage
83
- ? resolve(command.jsWorkspaceRoot || site.root, options.dir)
84
- : resolve(command.workingDir, options.dir)
85
- } else if (config?.build?.publish) {
86
- deployFolder = resolve(site.root, config.build.publish)
87
- } else if (siteData?.build_settings?.dir) {
88
- deployFolder = resolve(site.root, siteData.build_settings.dir)
89
- }
90
-
91
- if (!deployFolder) {
92
- log('Please provide a publish directory (e.g. "public" or "dist" or "."):')
93
- const { promptPath } = await inquirer.prompt([
94
- {
95
- type: 'input',
96
- name: 'promptPath',
97
- message: 'Publish directory',
98
- default: '.',
99
- filter: (input) => resolve(command.workingDir, input),
100
- },
101
- ])
102
- deployFolder = promptPath
103
- }
104
-
105
- return deployFolder
106
- }
107
-
66
+ let deployFolder;
67
+ // if the `--dir .` flag is provided we should resolve it to the working directory.
68
+ // - in regular sites this is the `process.cwd`
69
+ // - in mono repositories this will be the root of the jsWorkspace
70
+ if (options.dir) {
71
+ deployFolder = command.workspacePackage
72
+ ? resolve(command.jsWorkspaceRoot || site.root, options.dir)
73
+ : resolve(command.workingDir, options.dir);
74
+ }
75
+ else if (config?.build?.publish) {
76
+ deployFolder = resolve(site.root, config.build.publish);
77
+ }
78
+ else if (siteData?.build_settings?.dir) {
79
+ deployFolder = resolve(site.root, siteData.build_settings.dir);
80
+ }
81
+ if (!deployFolder) {
82
+ log('Please provide a publish directory (e.g. "public" or "dist" or "."):');
83
+ const { promptPath } = await inquirer.prompt([
84
+ {
85
+ type: 'input',
86
+ name: 'promptPath',
87
+ message: 'Publish directory',
88
+ default: '.',
89
+ filter: (input) => resolve(command.workingDir, input),
90
+ },
91
+ ]);
92
+ deployFolder = promptPath;
93
+ }
94
+ return deployFolder;
95
+ };
108
96
  /**
109
97
  * @param {string} deployFolder
110
98
  */
99
+ // @ts-expect-error TS(7006) FIXME: Parameter 'deployFolder' implicitly has an 'any' t... Remove this comment to see the full error message
111
100
  const validateDeployFolder = async (deployFolder) => {
112
- /** @type {import('fs').Stats} */
113
- let stats
114
- try {
115
- stats = await stat(deployFolder)
116
- } catch (error_) {
117
- if (error_.code === 'ENOENT') {
118
- return error(`No such directory ${deployFolder}! Did you forget to run a build?`)
101
+ /** @type {import('fs').Stats} */
102
+ let stats;
103
+ try {
104
+ stats = await stat(deployFolder);
119
105
  }
120
-
121
- // Improve the message of permission errors
122
- if (error_.code === 'EACCES') {
123
- return error('Permission error when trying to access deploy folder')
106
+ catch (error_) {
107
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
108
+ if (error_.code === 'ENOENT') {
109
+ return error(`No such directory ${deployFolder}! Did you forget to run a build?`);
110
+ }
111
+ // Improve the message of permission errors
112
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
113
+ if (error_.code === 'EACCES') {
114
+ return error('Permission error when trying to access deploy folder');
115
+ }
116
+ throw error_;
124
117
  }
125
- throw error_
126
- }
127
-
128
- if (!stats.isDirectory()) {
129
- return error('Deploy target must be a path to a directory')
130
- }
131
- return stats
132
- }
133
-
118
+ if (!stats.isDirectory()) {
119
+ return error('Deploy target must be a path to a directory');
120
+ }
121
+ return stats;
122
+ };
134
123
  /**
135
124
  * get the functions directory
136
125
  * @param {object} config
@@ -141,291 +130,299 @@ const validateDeployFolder = async (deployFolder) => {
141
130
  * @param {string} config.workingDir // The process working directory
142
131
  * @returns {string|undefined}
143
132
  */
133
+ // @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any' t... Remove this comment to see the full error message
144
134
  const getFunctionsFolder = ({ config, options, site, siteData, workingDir }) => {
145
- let functionsFolder
146
- // Support "functions" and "Functions"
147
- const funcConfig = config.functionsDirectory
148
- if (options.functions) {
149
- functionsFolder = resolve(workingDir, options.functions)
150
- } else if (funcConfig) {
151
- functionsFolder = resolve(site.root, funcConfig)
152
- } else if (siteData?.build_settings?.functions_dir) {
153
- functionsFolder = resolve(site.root, siteData.build_settings.functions_dir)
154
- }
155
- return functionsFolder
156
- }
157
-
135
+ let functionsFolder;
136
+ // Support "functions" and "Functions"
137
+ const funcConfig = config.functionsDirectory;
138
+ if (options.functions) {
139
+ functionsFolder = resolve(workingDir, options.functions);
140
+ }
141
+ else if (funcConfig) {
142
+ functionsFolder = resolve(site.root, funcConfig);
143
+ }
144
+ else if (siteData?.build_settings?.functions_dir) {
145
+ functionsFolder = resolve(site.root, siteData.build_settings.functions_dir);
146
+ }
147
+ return functionsFolder;
148
+ };
158
149
  /**
159
150
  *
160
151
  * @param {string|undefined} functionsFolder
161
152
  */
153
+ // @ts-expect-error TS(7006) FIXME: Parameter 'functionsFolder' implicitly has an 'any... Remove this comment to see the full error message
162
154
  const validateFunctionsFolder = async (functionsFolder) => {
163
- /** @type {import('fs').Stats|undefined} */
164
- let stats
165
- if (functionsFolder) {
166
- // we used to hard error if functions folder is specified but doesn't exist
167
- // but this was too strict for onboarding. we can just log a warning.
168
- try {
169
- stats = await stat(functionsFolder)
170
- } catch (error_) {
171
- if (error_.code === 'ENOENT') {
172
- log(
173
- `Functions folder "${functionsFolder}" specified but it doesn't exist! Will proceed without deploying functions`,
174
- )
175
- }
176
- // Improve the message of permission errors
177
- if (error_.code === 'EACCES') {
178
- error('Permission error when trying to access functions folder')
179
- }
180
- }
181
- }
182
-
183
- if (stats && !stats.isDirectory()) {
184
- error('Functions folder must be a path to a directory')
185
- }
186
-
187
- return stats
188
- }
189
-
155
+ /** @type {import('fs').Stats|undefined} */
156
+ let stats;
157
+ if (functionsFolder) {
158
+ // we used to hard error if functions folder is specified but doesn't exist
159
+ // but this was too strict for onboarding. we can just log a warning.
160
+ try {
161
+ stats = await stat(functionsFolder);
162
+ }
163
+ catch (error_) {
164
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
165
+ if (error_.code === 'ENOENT') {
166
+ log(`Functions folder "${functionsFolder}" specified but it doesn't exist! Will proceed without deploying functions`);
167
+ }
168
+ // Improve the message of permission errors
169
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
170
+ if (error_.code === 'EACCES') {
171
+ error('Permission error when trying to access functions folder');
172
+ }
173
+ }
174
+ }
175
+ if (stats && !stats.isDirectory()) {
176
+ error('Functions folder must be a path to a directory');
177
+ }
178
+ return stats;
179
+ };
180
+ // @ts-expect-error TS(7031) FIXME: Binding element 'deployFolder' implicitly has an '... Remove this comment to see the full error message
190
181
  const validateFolders = async ({ deployFolder, functionsFolder }) => {
191
- const deployFolderStat = await validateDeployFolder(deployFolder)
192
- const functionsFolderStat = await validateFunctionsFolder(functionsFolder)
193
- return { deployFolderStat, functionsFolderStat }
194
- }
195
-
182
+ const deployFolderStat = await validateDeployFolder(deployFolder);
183
+ const functionsFolderStat = await validateFunctionsFolder(functionsFolder);
184
+ return { deployFolderStat, functionsFolderStat };
185
+ };
196
186
  /**
197
187
  * @param {object} config
198
188
  * @param {string} config.deployFolder
199
189
  * @param {*} config.site
200
190
  * @returns
201
191
  */
192
+ // @ts-expect-error TS(7031) FIXME: Binding element 'deployFolder' implicitly has an '... Remove this comment to see the full error message
202
193
  const getDeployFilesFilter = ({ deployFolder, site }) => {
203
- // site.root === deployFolder can happen when users run `netlify deploy --dir .`
204
- // in that specific case we don't want to publish the repo node_modules
205
- // when site.root !== deployFolder the behaviour matches our buildbot
206
- const skipNodeModules = site.root === deployFolder
207
-
208
- /**
209
- * @param {string} filename
210
- */
211
- return (filename) => {
212
- if (filename == null) {
213
- return false
214
- }
215
- if (filename === deployFolder) {
216
- return true
217
- }
218
-
219
- const base = basename(filename)
220
- const skipFile =
221
- (skipNodeModules && base === 'node_modules') ||
222
- (base.startsWith('.') && base !== '.well-known') ||
223
- base.startsWith('__MACOSX') ||
224
- base.includes('/.') ||
225
- // headers and redirects are bundled in the config
226
- base === '_redirects' ||
227
- base === '_headers'
228
-
229
- return !skipFile
230
- }
231
- }
232
-
233
- const SEC_TO_MILLISEC = 1e3
194
+ // site.root === deployFolder can happen when users run `netlify deploy --dir .`
195
+ // in that specific case we don't want to publish the repo node_modules
196
+ // when site.root !== deployFolder the behaviour matches our buildbot
197
+ const skipNodeModules = site.root === deployFolder;
198
+ /**
199
+ * @param {string} filename
200
+ */
201
+ // @ts-expect-error TS(7006) FIXME: Parameter 'filename' implicitly has an 'any' type.
202
+ return (filename) => {
203
+ if (filename == null) {
204
+ return false;
205
+ }
206
+ if (filename === deployFolder) {
207
+ return true;
208
+ }
209
+ const base = basename(filename);
210
+ const skipFile = (skipNodeModules && base === 'node_modules') ||
211
+ (base.startsWith('.') && base !== '.well-known') ||
212
+ base.startsWith('__MACOSX') ||
213
+ base.includes('/.') ||
214
+ // headers and redirects are bundled in the config
215
+ base === '_redirects' ||
216
+ base === '_headers';
217
+ return !skipFile;
218
+ };
219
+ };
220
+ const SEC_TO_MILLISEC = 1e3;
234
221
  // 100 bytes
235
- const SYNC_FILE_LIMIT = 1e2
236
-
222
+ const SYNC_FILE_LIMIT = 1e2;
223
+ // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
237
224
  const prepareProductionDeploy = async ({ api, siteData }) => {
238
- if (isObject(siteData.published_deploy) && siteData.published_deploy.locked) {
239
- log(`\n${NETLIFYDEVERR} Deployments are "locked" for production context of this site\n`)
240
- const { unlockChoice } = await inquirer.prompt([
241
- {
242
- type: 'confirm',
243
- name: 'unlockChoice',
244
- message: 'Would you like to "unlock" deployments for production context to proceed?',
245
- default: false,
246
- },
247
- ])
248
- if (!unlockChoice) exit(0)
249
- await api.unlockDeploy({ deploy_id: siteData.published_deploy.id })
250
- log(`\n${NETLIFYDEVLOG} "Auto publishing" has been enabled for production context\n`)
251
- }
252
- log('Deploying to main site URL...')
253
- }
254
-
225
+ if (isObject(siteData.published_deploy) && siteData.published_deploy.locked) {
226
+ log(`\n${NETLIFYDEVERR} Deployments are "locked" for production context of this site\n`);
227
+ const { unlockChoice } = await inquirer.prompt([
228
+ {
229
+ type: 'confirm',
230
+ name: 'unlockChoice',
231
+ message: 'Would you like to "unlock" deployments for production context to proceed?',
232
+ default: false,
233
+ },
234
+ ]);
235
+ if (!unlockChoice)
236
+ exit(0);
237
+ await api.unlockDeploy({ deploy_id: siteData.published_deploy.id });
238
+ log(`\n${NETLIFYDEVLOG} "Auto publishing" has been enabled for production context\n`);
239
+ }
240
+ log('Deploying to main site URL...');
241
+ };
242
+ // @ts-expect-error TS(7006) FIXME: Parameter 'actual' implicitly has an 'any' type.
255
243
  const hasErrorMessage = (actual, expected) => {
256
- if (typeof actual === 'string') {
257
- return actual.includes(expected)
258
- }
259
- return false
260
- }
261
-
244
+ if (typeof actual === 'string') {
245
+ return actual.includes(expected);
246
+ }
247
+ return false;
248
+ };
249
+ // @ts-expect-error TS(7031) FIXME: Binding element 'error_' implicitly has an 'any' t... Remove this comment to see the full error message
262
250
  const reportDeployError = ({ error_, failAndExit }) => {
263
- switch (true) {
264
- case error_.name === 'JSONHTTPError': {
265
- const message = error_?.json?.message ?? ''
266
- if (hasErrorMessage(message, 'Background Functions not allowed by team plan')) {
267
- return failAndExit(`\n${BACKGROUND_FUNCTIONS_WARNING}`)
268
- }
269
- warn(`JSONHTTPError: ${message} ${error_.status}`)
270
- warn(`\n${JSON.stringify(error_, null, ' ')}\n`)
271
- failAndExit(error_)
272
- return
273
- }
274
- case error_.name === 'TextHTTPError': {
275
- warn(`TextHTTPError: ${error_.status}`)
276
- warn(`\n${error_}\n`)
277
- failAndExit(error_)
278
- return
279
- }
280
- case hasErrorMessage(error_.message, 'Invalid filename'): {
281
- warn(error_.message)
282
- failAndExit(error_)
283
- return
284
- }
285
- default: {
286
- warn(`\n${JSON.stringify(error_, null, ' ')}\n`)
287
- failAndExit(error_)
288
- }
289
- }
290
- }
291
-
251
+ switch (true) {
252
+ case error_.name === 'JSONHTTPError': {
253
+ const message = error_?.json?.message ?? '';
254
+ if (hasErrorMessage(message, 'Background Functions not allowed by team plan')) {
255
+ return failAndExit(`\n${BACKGROUND_FUNCTIONS_WARNING}`);
256
+ }
257
+ warn(`JSONHTTPError: ${message} ${error_.status}`);
258
+ warn(`\n${JSON.stringify(error_, null, ' ')}\n`);
259
+ failAndExit(error_);
260
+ return;
261
+ }
262
+ case error_.name === 'TextHTTPError': {
263
+ warn(`TextHTTPError: ${error_.status}`);
264
+ warn(`\n${error_}\n`);
265
+ failAndExit(error_);
266
+ return;
267
+ }
268
+ case hasErrorMessage(error_.message, 'Invalid filename'): {
269
+ warn(error_.message);
270
+ failAndExit(error_);
271
+ return;
272
+ }
273
+ default: {
274
+ warn(`\n${JSON.stringify(error_, null, ' ')}\n`);
275
+ failAndExit(error_);
276
+ }
277
+ }
278
+ };
292
279
  const deployProgressCb = function () {
293
- /**
294
- * @type {Record<string, import('ora').Ora>}
295
- */
296
- const events = {}
297
- return (event) => {
298
- switch (event.phase) {
299
- case 'start': {
300
- events[event.type] = startSpinner({
301
- text: event.msg,
302
- })
303
- return
304
- }
305
- case 'progress': {
306
- const spinner = events[event.type]
307
- if (spinner) {
308
- spinner.text = event.msg
280
+ /**
281
+ * @type {Record<string, import('ora').Ora>}
282
+ */
283
+ const events = {};
284
+ // @ts-expect-error TS(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
285
+ return (event) => {
286
+ switch (event.phase) {
287
+ case 'start': {
288
+ // @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
289
+ events[event.type] = startSpinner({
290
+ text: event.msg,
291
+ });
292
+ return;
293
+ }
294
+ case 'progress': {
295
+ // @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
296
+ const spinner = events[event.type];
297
+ if (spinner) {
298
+ spinner.text = event.msg;
299
+ }
300
+ return;
301
+ }
302
+ case 'error':
303
+ // @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
304
+ stopSpinner({ error: true, spinner: events[event.type], text: event.msg });
305
+ // @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
306
+ delete events[event.type];
307
+ return;
308
+ case 'stop':
309
+ default: {
310
+ // @ts-expect-error TS(2345) FIXME: Argument of type '{ spinner: any; text: any; }' is... Remove this comment to see the full error message
311
+ stopSpinner({ spinner: events[event.type], text: event.msg });
312
+ // @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
313
+ delete events[event.type];
314
+ }
309
315
  }
310
- return
311
- }
312
- case 'error':
313
- stopSpinner({ error: true, spinner: events[event.type], text: event.msg })
314
- delete events[event.type]
315
- return
316
- case 'stop':
317
- default: {
318
- stopSpinner({ spinner: events[event.type], text: event.msg })
319
- delete events[event.type]
320
- }
321
- }
322
- }
323
- }
324
-
325
- const runDeploy = async ({
326
- alias,
327
- api,
328
- command,
329
- config,
330
- deployFolder,
331
- deployTimeout,
332
- deployToProduction,
333
- functionsConfig,
334
- functionsFolder,
335
- packagePath,
336
- silent,
337
- site,
338
- siteData,
339
- siteId,
340
- skipFunctionsCache,
341
- title,
342
- }) => {
343
- let results
344
- let deployId
345
-
346
- try {
347
- if (deployToProduction) {
348
- await prepareProductionDeploy({ siteData, api })
349
- } else {
350
- log('Deploying to draft URL...')
316
+ };
317
+ };
318
+ const runDeploy = async ({
319
+ // @ts-expect-error TS(7031) FIXME: Binding element 'alias' implicitly has an 'any' ty... Remove this comment to see the full error message
320
+ alias,
321
+ // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
322
+ api,
323
+ // @ts-expect-error TS(7031) FIXME: Binding element 'command' implicitly has an 'any' ... Remove this comment to see the full error message
324
+ command,
325
+ // @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any' t... Remove this comment to see the full error message
326
+ config,
327
+ // @ts-expect-error TS(7031) FIXME: Binding element 'deployFolder' implicitly has an '... Remove this comment to see the full error message
328
+ deployFolder,
329
+ // @ts-expect-error TS(7031) FIXME: Binding element 'deployTimeout' implicitly has an ... Remove this comment to see the full error message
330
+ deployTimeout,
331
+ // @ts-expect-error TS(7031) FIXME: Binding element 'deployToProduction' implicitly ha... Remove this comment to see the full error message
332
+ deployToProduction,
333
+ // @ts-expect-error TS(7031) FIXME: Binding element 'functionsConfig' implicitly has a... Remove this comment to see the full error message
334
+ functionsConfig,
335
+ // @ts-expect-error TS(7031) FIXME: Binding element 'functionsFolder' implicitly has a... Remove this comment to see the full error message
336
+ functionsFolder,
337
+ // @ts-expect-error TS(7031) FIXME: Binding element 'packagePath' implicitly has an 'a... Remove this comment to see the full error message
338
+ packagePath,
339
+ // @ts-expect-error TS(7031) FIXME: Binding element 'silent' implicitly has an 'any' t... Remove this comment to see the full error message
340
+ silent,
341
+ // @ts-expect-error TS(7031) FIXME: Binding element 'site' implicitly has an 'any' typ... Remove this comment to see the full error message
342
+ site,
343
+ // @ts-expect-error TS(7031) FIXME: Binding element 'siteData' implicitly has an 'any'... Remove this comment to see the full error message
344
+ siteData,
345
+ // @ts-expect-error TS(7031) FIXME: Binding element 'siteId' implicitly has an 'any' t... Remove this comment to see the full error message
346
+ siteId,
347
+ // @ts-expect-error TS(7031) FIXME: Binding element 'skipFunctionsCache' implicitly ha... Remove this comment to see the full error message
348
+ skipFunctionsCache,
349
+ // @ts-expect-error TS(7031) FIXME: Binding element 'title' implicitly has an 'any' ty... Remove this comment to see the full error message
350
+ title, }) => {
351
+ let results;
352
+ let deployId;
353
+ try {
354
+ if (deployToProduction) {
355
+ await prepareProductionDeploy({ siteData, api });
356
+ }
357
+ else {
358
+ log('Deploying to draft URL...');
359
+ }
360
+ const draft = !deployToProduction && !alias;
361
+ results = await api.createSiteDeploy({ siteId, title, body: { draft, branch: alias } });
362
+ deployId = results.id;
363
+ // @ts-expect-error TS(2345) FIXME: Argument of type '{ base: any; packagePath: any; }... Remove this comment to see the full error message
364
+ const internalFunctionsFolder = await getInternalFunctionsDir({ base: site.root, packagePath });
365
+ // The order of the directories matter: zip-it-and-ship-it will prioritize
366
+ // functions from the rightmost directories. In this case, we want user
367
+ // functions to take precedence over internal functions.
368
+ const functionDirectories = [internalFunctionsFolder, functionsFolder].filter(Boolean);
369
+ const manifestPath = skipFunctionsCache ? null : await getFunctionsManifestPath({ base: site.root, packagePath });
370
+ const redirectsPath = `${deployFolder}/_redirects`;
371
+ const headersPath = `${deployFolder}/_headers`;
372
+ const { redirects } = await parseAllRedirects({
373
+ configRedirects: config.redirects,
374
+ redirectsFiles: [redirectsPath],
375
+ minimal: true,
376
+ });
377
+ config.redirects = redirects;
378
+ const { headers } = await parseAllHeaders({
379
+ configHeaders: config.headers,
380
+ // @ts-expect-error TS(2322) FIXME: Type 'string' is not assignable to type 'never'.
381
+ headersFiles: [headersPath],
382
+ minimal: true,
383
+ });
384
+ config.headers = headers;
385
+ results = await deploySite(api, siteId, deployFolder, {
386
+ config,
387
+ // @ts-expect-error TS(2322) FIXME: Type 'any[]' is not assignable to type 'never[]'.
388
+ fnDir: functionDirectories,
389
+ functionsConfig,
390
+ // @ts-expect-error TS(2322) FIXME: Type '(event: any) => void' is not assignable to t... Remove this comment to see the full error message
391
+ statusCb: silent ? () => { } : deployProgressCb(),
392
+ deployTimeout,
393
+ syncFileLimit: SYNC_FILE_LIMIT,
394
+ // pass an existing deployId to update
395
+ deployId,
396
+ filter: getDeployFilesFilter({ site, deployFolder }),
397
+ workingDir: command.workingDir,
398
+ manifestPath,
399
+ skipFunctionsCache,
400
+ siteRoot: site.root,
401
+ });
351
402
  }
352
-
353
- const draft = !deployToProduction && !alias
354
- results = await api.createSiteDeploy({ siteId, title, body: { draft, branch: alias } })
355
- deployId = results.id
356
-
357
- const internalFunctionsFolder = await getInternalFunctionsDir({ base: site.root, packagePath })
358
-
359
- // The order of the directories matter: zip-it-and-ship-it will prioritize
360
- // functions from the rightmost directories. In this case, we want user
361
- // functions to take precedence over internal functions.
362
- const functionDirectories = [internalFunctionsFolder, functionsFolder].filter(Boolean)
363
- const manifestPath = skipFunctionsCache ? null : await getFunctionsManifestPath({ base: site.root, packagePath })
364
-
365
- const redirectsPath = `${deployFolder}/_redirects`
366
- const headersPath = `${deployFolder}/_headers`
367
-
368
- const { redirects } = await parseAllRedirects({
369
- configRedirects: config.redirects,
370
- redirectsFiles: [redirectsPath],
371
- minimal: true,
372
- })
373
-
374
- config.redirects = redirects
375
-
376
- const { headers } = await parseAllHeaders({
377
- configHeaders: config.headers,
378
- // @ts-ignore
379
- headersFiles: [headersPath],
380
- minimal: true,
381
- })
382
-
383
- config.headers = headers
384
-
385
- // @ts-ignore
386
- results = await deploySite(api, siteId, deployFolder, {
387
- config,
388
- fnDir: functionDirectories,
389
- functionsConfig,
390
- statusCb: silent ? () => {} : deployProgressCb(),
391
- deployTimeout,
392
- syncFileLimit: SYNC_FILE_LIMIT,
393
- // pass an existing deployId to update
394
- deployId,
395
- filter: getDeployFilesFilter({ site, deployFolder }),
396
- workingDir: command.workingDir,
397
- manifestPath,
398
- skipFunctionsCache,
399
- siteRoot: site.root,
400
- })
401
- } catch (error_) {
402
- if (deployId) {
403
- await cancelDeploy({ api, deployId })
404
- }
405
- reportDeployError({ error_, failAndExit: error })
406
- }
407
-
408
- const siteUrl = results.deploy.ssl_url || results.deploy.url
409
- const deployUrl = results.deploy.deploy_ssl_url || results.deploy.deploy_url
410
- const logsUrl = `${results.deploy.admin_url}/deploys/${results.deploy.id}`
411
-
412
- let functionLogsUrl = `${results.deploy.admin_url}/functions`
413
-
414
- if (!deployToProduction) {
415
- functionLogsUrl += `?scope=deploy:${deployId}`
416
- }
417
-
418
- return {
419
- siteId: results.deploy.site_id,
420
- siteName: results.deploy.name,
421
- deployId: results.deployId,
422
- siteUrl,
423
- deployUrl,
424
- logsUrl,
425
- functionLogsUrl,
426
- }
427
- }
428
-
403
+ catch (error_) {
404
+ if (deployId) {
405
+ await cancelDeploy({ api, deployId });
406
+ }
407
+ reportDeployError({ error_, failAndExit: error });
408
+ }
409
+ const siteUrl = results.deploy.ssl_url || results.deploy.url;
410
+ const deployUrl = results.deploy.deploy_ssl_url || results.deploy.deploy_url;
411
+ const logsUrl = `${results.deploy.admin_url}/deploys/${results.deploy.id}`;
412
+ let functionLogsUrl = `${results.deploy.admin_url}/functions`;
413
+ if (!deployToProduction) {
414
+ functionLogsUrl += `?scope=deploy:${deployId}`;
415
+ }
416
+ return {
417
+ siteId: results.deploy.site_id,
418
+ siteName: results.deploy.name,
419
+ deployId: results.deployId,
420
+ siteUrl,
421
+ deployUrl,
422
+ logsUrl,
423
+ functionLogsUrl,
424
+ };
425
+ };
429
426
  /**
430
427
  *
431
428
  * @param {object} config
@@ -436,69 +433,64 @@ const runDeploy = async ({
436
433
  * @param {import('commander').OptionValues} config.options The options of the command
437
434
  * @returns
438
435
  */
436
+ // @ts-expect-error TS(7031) FIXME: Binding element 'cachedConfig' implicitly has an '... Remove this comment to see the full error message
439
437
  const handleBuild = async ({ cachedConfig, currentDir, deployHandler, options, packagePath }) => {
440
- if (!options.build) {
441
- return {}
442
- }
443
- const [token] = await getToken()
444
- const resolvedOptions = await getBuildOptions({
445
- cachedConfig,
446
- packagePath,
447
- token,
448
- options,
449
- currentDir,
450
- deployHandler,
451
- })
452
- const { configMutations, exitCode, newConfig } = await runBuild(resolvedOptions)
453
- if (exitCode !== 0) {
454
- exit(exitCode)
455
- }
456
- return { newConfig, configMutations }
457
- }
458
-
438
+ if (!options.build) {
439
+ return {};
440
+ }
441
+ // @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0.
442
+ const [token] = await getToken();
443
+ const resolvedOptions = await getBuildOptions({
444
+ cachedConfig,
445
+ packagePath,
446
+ token,
447
+ options,
448
+ currentDir,
449
+ deployHandler,
450
+ });
451
+ const { configMutations, exitCode, newConfig } = await runBuild(resolvedOptions);
452
+ if (exitCode !== 0) {
453
+ exit(exitCode);
454
+ }
455
+ return { newConfig, configMutations };
456
+ };
459
457
  /**
460
458
  *
461
459
  * @param {*} options Bundling options
462
460
  * @param {import('..//base-command.mjs').default} command
463
461
  * @returns
464
462
  */
463
+ // @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
465
464
  const bundleEdgeFunctions = async (options, command) => {
466
- // eslint-disable-next-line n/prefer-global/process, unicorn/prefer-set-has
467
- const argv = process.argv.slice(2)
468
- const statusCb =
469
- options.silent || argv.includes('--json') || argv.includes('--silent') ? () => {} : deployProgressCb()
470
-
471
- statusCb({
472
- type: 'edge-functions-bundling',
473
- msg: 'Bundling edge functions...\n',
474
- phase: 'start',
475
- })
476
-
477
- const { severityCode, success } = await runCoreSteps(['edge_functions_bundling'], {
478
- ...options,
479
- packagePath: command.workspacePackage,
480
- buffer: true,
481
- featureFlags: edgeFunctionsFeatureFlags,
482
- edgeFunctionsBootstrapURL: getBootstrapURL(),
483
- })
484
-
485
- if (!success) {
465
+ // eslint-disable-next-line n/prefer-global/process, unicorn/prefer-set-has
466
+ const argv = process.argv.slice(2);
467
+ const statusCb = options.silent || argv.includes('--json') || argv.includes('--silent') ? () => { } : deployProgressCb();
486
468
  statusCb({
487
- type: 'edge-functions-bundling',
488
- msg: 'Deploy aborted due to error while bundling edge functions',
489
- phase: 'error',
490
- })
491
-
492
- exit(severityCode)
493
- }
494
-
495
- statusCb({
496
- type: 'edge-functions-bundling',
497
- msg: 'Finished bundling edge functions',
498
- phase: 'stop',
499
- })
500
- }
501
-
469
+ type: 'edge-functions-bundling',
470
+ msg: 'Bundling edge functions...\n',
471
+ phase: 'start',
472
+ });
473
+ const { severityCode, success } = await runCoreSteps(['edge_functions_bundling'], {
474
+ ...options,
475
+ packagePath: command.workspacePackage,
476
+ buffer: true,
477
+ featureFlags: edgeFunctionsFeatureFlags,
478
+ edgeFunctionsBootstrapURL: getBootstrapURL(),
479
+ });
480
+ if (!success) {
481
+ statusCb({
482
+ type: 'edge-functions-bundling',
483
+ msg: 'Deploy aborted due to error while bundling edge functions',
484
+ phase: 'error',
485
+ });
486
+ exit(severityCode);
487
+ }
488
+ statusCb({
489
+ type: 'edge-functions-bundling',
490
+ msg: 'Finished bundling edge functions',
491
+ phase: 'stop',
492
+ });
493
+ };
502
494
  /**
503
495
  *
504
496
  * @param {object} config
@@ -509,266 +501,254 @@ const bundleEdgeFunctions = async (options, command) => {
509
501
  * @param {object} config.results
510
502
  * @returns {void}
511
503
  */
504
+ // @ts-expect-error TS(7031) FIXME: Binding element 'deployToProduction' implicitly ha... Remove this comment to see the full error message
512
505
  const printResults = ({ deployToProduction, isIntegrationDeploy, json, results, runBuildCommand }) => {
513
- const msgData = {
514
- 'Build logs': results.logsUrl,
515
- 'Function logs': results.functionLogsUrl,
516
- }
517
-
518
- if (deployToProduction) {
519
- msgData['Unique deploy URL'] = results.deployUrl
520
- msgData['Website URL'] = results.siteUrl
521
- } else {
522
- msgData['Website draft URL'] = results.deployUrl
523
- }
524
-
525
- // Spacer
526
- log()
527
-
528
- // Json response for piping commands
529
- if (json) {
530
- const jsonData = {
531
- name: results.name,
532
- site_id: results.site_id,
533
- site_name: results.siteName,
534
- deploy_id: results.deployId,
535
- deploy_url: results.deployUrl,
536
- logs: results.logsUrl,
537
- }
506
+ const msgData = {
507
+ 'Build logs': results.logsUrl,
508
+ 'Function logs': results.functionLogsUrl,
509
+ };
538
510
  if (deployToProduction) {
539
- jsonData.url = results.siteUrl
511
+ // @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
512
+ msgData['Unique deploy URL'] = results.deployUrl;
513
+ // @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
514
+ msgData['Website URL'] = results.siteUrl;
540
515
  }
541
-
542
- logJson(jsonData)
543
- exit(0)
544
- } else {
545
- log(prettyjson.render(msgData))
546
-
547
- if (!deployToProduction) {
548
- log()
549
- log('If everything looks good on your draft URL, deploy it to your main site URL with the --prod flag.')
550
- log(
551
- `${chalk.cyanBright.bold(
552
- `netlify ${isIntegrationDeploy ? 'integration:' : ''}deploy${runBuildCommand ? ' --build' : ''} --prod`,
553
- )}`,
554
- )
555
- log()
556
- }
557
- }
558
- }
559
-
560
- const prepAndRunDeploy = async ({
561
- api,
562
- command,
563
- config,
564
- deployToProduction,
565
- options,
566
- site,
567
- siteData,
568
- siteId,
569
- workingDir,
570
- }) => {
571
- const alias = options.alias || options.branch
572
- const isUsingEnvelope = siteData && siteData.use_envelope
573
- // if a context is passed besides dev, we need to pull env vars from that specific context
574
- if (isUsingEnvelope && options.context && options.context !== 'dev') {
575
- command.netlify.cachedConfig.env = await getEnvelopeEnv({
576
- api,
577
- context: options.context,
578
- env: command.netlify.cachedConfig.env,
579
- siteInfo: siteData,
580
- })
581
- }
582
-
583
- const deployFolder = await getDeployFolder({ command, options, config, site, siteData })
584
- const functionsFolder = getFunctionsFolder({ workingDir, options, config, site, siteData })
585
- const { configPath } = site
586
-
587
- const edgeFunctionsConfig = command.netlify.config.edge_functions
588
-
589
- // build flag wasn't used and edge functions exist
590
- if (!options.build && edgeFunctionsConfig && edgeFunctionsConfig.length !== 0) {
591
- await bundleEdgeFunctions(options, command)
592
- }
593
-
594
- log(
595
- prettyjson.render({
596
- 'Deploy path': deployFolder,
597
- 'Functions path': functionsFolder,
598
- 'Configuration path': configPath,
599
- }),
600
- )
601
-
602
- const { functionsFolderStat } = await validateFolders({
603
- deployFolder,
604
- functionsFolder,
605
- })
606
-
607
- const siteEnv = isUsingEnvelope
608
- ? await getEnvelopeEnv({
516
+ else {
517
+ // @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
518
+ msgData['Website draft URL'] = results.deployUrl;
519
+ }
520
+ // Spacer
521
+ log();
522
+ // Json response for piping commands
523
+ if (json) {
524
+ const jsonData = {
525
+ name: results.name,
526
+ site_id: results.site_id,
527
+ site_name: results.siteName,
528
+ deploy_id: results.deployId,
529
+ deploy_url: results.deployUrl,
530
+ logs: results.logsUrl,
531
+ };
532
+ if (deployToProduction) {
533
+ // @ts-expect-error TS(2339) FIXME: Property 'url' does not exist on type '{ name: any... Remove this comment to see the full error message
534
+ jsonData.url = results.siteUrl;
535
+ }
536
+ logJson(jsonData);
537
+ exit(0);
538
+ }
539
+ else {
540
+ log(prettyjson.render(msgData));
541
+ if (!deployToProduction) {
542
+ log();
543
+ log('If everything looks good on your draft URL, deploy it to your main site URL with the --prod flag.');
544
+ log(`${chalk.cyanBright.bold(`netlify ${isIntegrationDeploy ? 'integration:' : ''}deploy${runBuildCommand ? ' --build' : ''} --prod`)}`);
545
+ log();
546
+ }
547
+ }
548
+ };
549
+ const prepAndRunDeploy = async ({
550
+ // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
551
+ api,
552
+ // @ts-expect-error TS(7031) FIXME: Binding element 'command' implicitly has an 'any' ... Remove this comment to see the full error message
553
+ command,
554
+ // @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any' t... Remove this comment to see the full error message
555
+ config,
556
+ // @ts-expect-error TS(7031) FIXME: Binding element 'deployToProduction' implicitly ha... Remove this comment to see the full error message
557
+ deployToProduction,
558
+ // @ts-expect-error TS(7031) FIXME: Binding element 'options' implicitly has an 'any' ... Remove this comment to see the full error message
559
+ options,
560
+ // @ts-expect-error TS(7031) FIXME: Binding element 'site' implicitly has an 'any' typ... Remove this comment to see the full error message
561
+ site,
562
+ // @ts-expect-error TS(7031) FIXME: Binding element 'siteData' implicitly has an 'any'... Remove this comment to see the full error message
563
+ siteData,
564
+ // @ts-expect-error TS(7031) FIXME: Binding element 'siteId' implicitly has an 'any' t... Remove this comment to see the full error message
565
+ siteId,
566
+ // @ts-expect-error TS(7031) FIXME: Binding element 'workingDir' implicitly has an 'an... Remove this comment to see the full error message
567
+ workingDir, }) => {
568
+ const alias = options.alias || options.branch;
569
+ const isUsingEnvelope = siteData && siteData.use_envelope;
570
+ // if a context is passed besides dev, we need to pull env vars from that specific context
571
+ if (isUsingEnvelope && options.context && options.context !== 'dev') {
572
+ command.netlify.cachedConfig.env = await getEnvelopeEnv({
573
+ api,
574
+ context: options.context,
575
+ env: command.netlify.cachedConfig.env,
576
+ siteInfo: siteData,
577
+ });
578
+ }
579
+ const deployFolder = await getDeployFolder({ command, options, config, site, siteData });
580
+ const functionsFolder = getFunctionsFolder({ workingDir, options, config, site, siteData });
581
+ const { configPath } = site;
582
+ const edgeFunctionsConfig = command.netlify.config.edge_functions;
583
+ // build flag wasn't used and edge functions exist
584
+ if (!options.build && edgeFunctionsConfig && edgeFunctionsConfig.length !== 0) {
585
+ await bundleEdgeFunctions(options, command);
586
+ }
587
+ log(prettyjson.render({
588
+ 'Deploy path': deployFolder,
589
+ 'Functions path': functionsFolder,
590
+ 'Configuration path': configPath,
591
+ }));
592
+ const { functionsFolderStat } = await validateFolders({
593
+ deployFolder,
594
+ functionsFolder,
595
+ });
596
+ const siteEnv = isUsingEnvelope
597
+ ? await getEnvelopeEnv({
598
+ api,
599
+ context: options.context,
600
+ env: command.netlify.cachedConfig.env,
601
+ raw: true,
602
+ scope: 'functions',
603
+ siteInfo: siteData,
604
+ })
605
+ : siteData?.build_settings?.env;
606
+ const functionsConfig = normalizeFunctionsConfig({
607
+ functionsConfig: config.functions,
608
+ projectRoot: site.root,
609
+ siteEnv,
610
+ });
611
+ const results = await runDeploy({
612
+ alias,
609
613
  api,
610
- context: options.context,
611
- env: command.netlify.cachedConfig.env,
612
- raw: true,
613
- scope: 'functions',
614
- siteInfo: siteData,
615
- })
616
- : siteData?.build_settings?.env
617
-
618
- const functionsConfig = normalizeFunctionsConfig({
619
- functionsConfig: config.functions,
620
- projectRoot: site.root,
621
- siteEnv,
622
- })
623
-
624
- const results = await runDeploy({
625
- alias,
626
- api,
627
- command,
628
- config,
629
- deployFolder,
630
- deployTimeout: options.timeout * SEC_TO_MILLISEC || DEFAULT_DEPLOY_TIMEOUT,
631
- deployToProduction,
632
- functionsConfig,
633
- // pass undefined functionsFolder if doesn't exist
634
- functionsFolder: functionsFolderStat && functionsFolder,
635
- packagePath: command.workspacePackage,
636
- silent: options.json || options.silent,
637
- site,
638
- siteData,
639
- siteId,
640
- skipFunctionsCache: options.skipFunctionsCache,
641
- title: options.message,
642
- })
643
-
644
- return results
645
- }
646
-
614
+ command,
615
+ config,
616
+ deployFolder,
617
+ deployTimeout: options.timeout * SEC_TO_MILLISEC || DEFAULT_DEPLOY_TIMEOUT,
618
+ deployToProduction,
619
+ functionsConfig,
620
+ // pass undefined functionsFolder if doesn't exist
621
+ functionsFolder: functionsFolderStat && functionsFolder,
622
+ packagePath: command.workspacePackage,
623
+ silent: options.json || options.silent,
624
+ site,
625
+ siteData,
626
+ siteId,
627
+ skipFunctionsCache: options.skipFunctionsCache,
628
+ title: options.message,
629
+ });
630
+ return results;
631
+ };
647
632
  /**
648
633
  * The deploy command
649
634
  * @param {import('commander').OptionValues} options
650
635
  * @param {import('../base-command.mjs').default} command
651
636
  */
637
+ // @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
652
638
  export const deploy = async (options, command) => {
653
- const { workingDir } = command
654
- const { api, site, siteInfo } = command.netlify
655
- const alias = options.alias || options.branch
656
-
657
- command.setAnalyticsPayload({ open: options.open, prod: options.prod, json: options.json, alias: Boolean(alias) })
658
-
659
- if (options.branch) {
660
- warn('--branch flag has been renamed to --alias and will be removed in future versions')
661
- }
662
-
663
- if (options.context && !options.build) {
664
- return error('--context flag is only available when using the --build flag')
665
- }
666
-
667
- await command.authenticate(options.auth)
668
-
669
- let siteId = site.id || options.site
670
-
671
- let siteData = {}
672
- if (siteId && !isEmpty(siteInfo)) {
673
- siteData = siteInfo
674
- siteId = siteData.id
675
- } else {
676
- log("This folder isn't linked to a site yet")
677
- const NEW_SITE = '+ Create & configure a new site'
678
- const EXISTING_SITE = 'Link this directory to an existing site'
679
-
680
- const initializeOpts = [EXISTING_SITE, NEW_SITE]
681
-
682
- const { initChoice } = await inquirer.prompt([
683
- {
684
- type: 'list',
685
- name: 'initChoice',
686
- message: 'What would you like to do?',
687
- choices: initializeOpts,
688
- },
689
- ])
690
- // create site or search for one
691
- if (initChoice === NEW_SITE) {
692
- siteData = await sitesCreate({}, command)
693
- site.id = siteData.id
694
- siteId = site.id
695
- } else if (initChoice === EXISTING_SITE) {
696
- siteData = await link({}, command)
697
- site.id = siteData.id
698
- siteId = site.id
699
- }
700
- }
701
-
702
- if (options.trigger) {
703
- return triggerDeploy({ api, options, siteData, siteId })
704
- }
705
-
706
- const deployToProduction = options.prod || (options.prodIfUnlocked && !siteData.published_deploy.locked)
707
-
708
- let results = {}
709
-
710
- if (options.build) {
711
- await handleBuild({
712
- packagePath: command.workspacePackage,
713
- cachedConfig: command.netlify.cachedConfig,
714
- currentDir: command.workingDir,
715
- options,
716
- deployHandler: async ({ netlifyConfig }) => {
639
+ const { workingDir } = command;
640
+ const { api, site, siteInfo } = command.netlify;
641
+ const alias = options.alias || options.branch;
642
+ command.setAnalyticsPayload({ open: options.open, prod: options.prod, json: options.json, alias: Boolean(alias) });
643
+ if (options.branch) {
644
+ warn('--branch flag has been renamed to --alias and will be removed in future versions');
645
+ }
646
+ if (options.context && !options.build) {
647
+ return error('--context flag is only available when using the --build flag');
648
+ }
649
+ await command.authenticate(options.auth);
650
+ let siteId = site.id || options.site;
651
+ let siteData = {};
652
+ if (siteId && !isEmpty(siteInfo)) {
653
+ siteData = siteInfo;
654
+ // @ts-expect-error TS(2339) FIXME: Property 'id' does not exist on type '{}'.
655
+ siteId = siteData.id;
656
+ }
657
+ else {
658
+ log("This folder isn't linked to a site yet");
659
+ const NEW_SITE = '+ Create & configure a new site';
660
+ const EXISTING_SITE = 'Link this directory to an existing site';
661
+ const initializeOpts = [EXISTING_SITE, NEW_SITE];
662
+ const { initChoice } = await inquirer.prompt([
663
+ {
664
+ type: 'list',
665
+ name: 'initChoice',
666
+ message: 'What would you like to do?',
667
+ choices: initializeOpts,
668
+ },
669
+ ]);
670
+ // create site or search for one
671
+ if (initChoice === NEW_SITE) {
672
+ // @ts-expect-error TS(2322) FIXME: Type 'undefined' is not assignable to type '{}'.
673
+ siteData = await sitesCreate({}, command);
674
+ // @ts-expect-error TS(2339) FIXME: Property 'id' does not exist on type '{}'.
675
+ site.id = siteData.id;
676
+ siteId = site.id;
677
+ }
678
+ else if (initChoice === EXISTING_SITE) {
679
+ siteData = await link({}, command);
680
+ // @ts-expect-error TS(2339) FIXME: Property 'id' does not exist on type '{}'.
681
+ site.id = siteData.id;
682
+ siteId = site.id;
683
+ }
684
+ }
685
+ if (options.trigger) {
686
+ return triggerDeploy({ api, options, siteData, siteId });
687
+ }
688
+ // @ts-expect-error TS(2339) FIXME: Property 'published_deploy' does not exist on type... Remove this comment to see the full error message
689
+ const deployToProduction = options.prod || (options.prodIfUnlocked && !siteData.published_deploy.locked);
690
+ let results = {};
691
+ if (options.build) {
692
+ await handleBuild({
693
+ packagePath: command.workspacePackage,
694
+ cachedConfig: command.netlify.cachedConfig,
695
+ currentDir: command.workingDir,
696
+ options,
697
+ // @ts-expect-error TS(7031) FIXME: Binding element 'netlifyConfig' implicitly has an ... Remove this comment to see the full error message
698
+ deployHandler: async ({ netlifyConfig }) => {
699
+ results = await prepAndRunDeploy({
700
+ command,
701
+ options,
702
+ workingDir,
703
+ api,
704
+ site,
705
+ config: netlifyConfig,
706
+ siteData,
707
+ siteId,
708
+ deployToProduction,
709
+ });
710
+ return {};
711
+ },
712
+ });
713
+ }
714
+ else {
717
715
  results = await prepAndRunDeploy({
718
- command,
719
- options,
720
- workingDir,
721
- api,
722
- site,
723
- config: netlifyConfig,
724
- siteData,
725
- siteId,
726
- deployToProduction,
727
- })
728
-
729
- return {}
730
- },
731
- })
732
- } else {
733
- results = await prepAndRunDeploy({
734
- command,
735
- options,
736
- workingDir,
737
- api,
738
- site,
739
- config: command.netlify.config,
740
- siteData,
741
- siteId,
742
- deployToProduction,
743
- })
744
- }
745
- const isIntegrationDeploy = command.name() === 'integration:deploy'
746
-
747
- printResults({
748
- runBuildCommand: options.build,
749
- isIntegrationDeploy,
750
- json: options.json,
751
- results,
752
- deployToProduction,
753
- })
754
-
755
- if (options.open) {
756
- const urlToOpen = deployToProduction ? results.siteUrl : results.deployUrl
757
- await openBrowser({ url: urlToOpen })
758
- exit()
759
- }
760
- }
761
-
716
+ command,
717
+ options,
718
+ workingDir,
719
+ api,
720
+ site,
721
+ config: command.netlify.config,
722
+ siteData,
723
+ siteId,
724
+ deployToProduction,
725
+ });
726
+ }
727
+ const isIntegrationDeploy = command.name() === 'integration:deploy';
728
+ printResults({
729
+ runBuildCommand: options.build,
730
+ isIntegrationDeploy,
731
+ json: options.json,
732
+ results,
733
+ deployToProduction,
734
+ });
735
+ if (options.open) {
736
+ // @ts-expect-error TS(2339) FIXME: Property 'siteUrl' does not exist on type '{}'.
737
+ const urlToOpen = deployToProduction ? results.siteUrl : results.deployUrl;
738
+ // @ts-expect-error TS(2345) FIXME: Argument of type '{ url: any; }' is not assignable... Remove this comment to see the full error message
739
+ await openBrowser({ url: urlToOpen });
740
+ exit();
741
+ }
742
+ };
762
743
  /**
763
744
  * Creates the `netlify deploy` command
764
745
  * @param {import('../base-command.mjs').default} program
765
746
  * @returns
766
747
  */
767
- export const createDeployCommand = (program) =>
768
- program
748
+ // @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
749
+ export const createDeployCommand = (program) => program
769
750
  .command('deploy')
770
- .description(
771
- `Create a new deploy from the contents of a folder
751
+ .description(`Create a new deploy from the contents of a folder
772
752
  Deploys from the build settings found in the netlify.toml file, or settings from the API.
773
753
 
774
754
  The following environment variables can be used to override configuration file lookups and prompts:
@@ -835,51 +815,36 @@ functions/
835
815
  └── functionName.js
836
816
  \`\`\`
837
817
 
838
- Support for package.json's main field, and intrinsic index.js entrypoints are coming soon.`,
839
- )
818
+ Support for package.json's main field, and intrinsic index.js entrypoints are coming soon.`)
840
819
  .option('-d, --dir <path>', 'Specify a folder to deploy')
841
820
  .option('-f, --functions <folder>', 'Specify a functions folder to deploy')
842
821
  .option('-p, --prod', 'Deploy to production', false)
843
- .addOption(
844
- new Option(
845
- '--prodIfUnlocked',
846
- 'Old, prefer --prod-if-unlocked. Deploy to production if unlocked, create a draft otherwise',
847
- )
848
- .default(false)
849
- .hideHelp(true),
850
- )
822
+ .addOption(new Option('--prodIfUnlocked', 'Old, prefer --prod-if-unlocked. Deploy to production if unlocked, create a draft otherwise')
823
+ .default(false)
824
+ .hideHelp(true))
851
825
  .option('--prod-if-unlocked', 'Deploy to production if unlocked, create a draft otherwise', false)
852
- .option(
853
- '--alias <name>',
854
- 'Specifies the alias for deployment, the string at the beginning of the deploy subdomain. Useful for creating predictable deployment URLs. Avoid setting an alias string to the same value as a deployed branch. `alias` doesn’t create a branch deploy and can’t be used in conjunction with the branch subdomain feature. Maximum 37 characters.',
855
- )
856
- .option(
857
- '-b, --branch <name>',
858
- 'Serves the same functionality as --alias. Deprecated and will be removed in future versions',
859
- )
826
+ .option('--alias <name>', 'Specifies the alias for deployment, the string at the beginning of the deploy subdomain. Useful for creating predictable deployment URLs. Avoid setting an alias string to the same value as a deployed branch. `alias` doesn’t create a branch deploy and can’t be used in conjunction with the branch subdomain feature. Maximum 37 characters.')
827
+ .option('-b, --branch <name>', 'Serves the same functionality as --alias. Deprecated and will be removed in future versions')
860
828
  .option('-o, --open', 'Open site after deploy', false)
861
829
  .option('-m, --message <message>', 'A short message to include in the deploy log')
862
830
  .option('-a, --auth <token>', 'Netlify auth token to deploy with', env.NETLIFY_AUTH_TOKEN)
863
831
  .option('-s, --site <name-or-id>', 'A site name or ID to deploy to', env.NETLIFY_SITE_ID)
864
832
  .option('--json', 'Output deployment data as JSON')
833
+ // @ts-expect-error TS(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
865
834
  .option('--timeout <number>', 'Timeout to wait for deployment to finish', (value) => Number.parseInt(value))
866
835
  .option('--trigger', 'Trigger a new build of your site on Netlify without uploading local files')
867
836
  .option('--build', 'Run build command before deploying')
868
837
  .option('--context <context>', 'Context to use when resolving build configuration')
869
- .option(
870
- '--skip-functions-cache',
871
- 'Ignore any functions created as part of a previous `build` or `deploy` commands, forcing them to be bundled again as part of the deployment',
872
- false,
873
- )
838
+ .option('--skip-functions-cache', 'Ignore any functions created as part of a previous `build` or `deploy` commands, forcing them to be bundled again as part of the deployment', false)
874
839
  .addExamples([
875
- 'netlify deploy',
876
- 'netlify deploy --site my-first-site',
877
- 'netlify deploy --prod',
878
- 'netlify deploy --prod --open',
879
- 'netlify deploy --prod-if-unlocked',
880
- 'netlify deploy --message "A message with an $ENV_VAR"',
881
- 'netlify deploy --auth $NETLIFY_AUTH_TOKEN',
882
- 'netlify deploy --trigger',
883
- 'netlify deploy --build --context deploy-preview',
884
- ])
885
- .action(deploy)
840
+ 'netlify deploy',
841
+ 'netlify deploy --site my-first-site',
842
+ 'netlify deploy --prod',
843
+ 'netlify deploy --prod --open',
844
+ 'netlify deploy --prod-if-unlocked',
845
+ 'netlify deploy --message "A message with an $ENV_VAR"',
846
+ 'netlify deploy --auth $NETLIFY_AUTH_TOKEN',
847
+ 'netlify deploy --trigger',
848
+ 'netlify deploy --build --context deploy-preview',
849
+ ])
850
+ .action(deploy);