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,58 +1,45 @@
1
- // @ts-check
2
- import { writeFile } from 'fs/promises'
3
- import path from 'path'
4
-
5
- import cleanDeep from 'clean-deep'
6
- import inquirer from 'inquirer'
7
-
8
- import { fileExistsAsync } from '../../lib/fs.mjs'
9
- import { normalizeBackslash } from '../../lib/path.mjs'
10
- import { detectBuildSettings } from '../build-info.mjs'
11
- import { chalk, error as failAndExit, log, warn } from '../command-helpers.mjs'
12
-
13
- import { getRecommendPlugins, getUIPlugins } from './plugins.mjs'
14
-
1
+ import { writeFile } from 'fs/promises';
2
+ import path from 'path';
3
+ import cleanDeep from 'clean-deep';
4
+ import inquirer from 'inquirer';
5
+ import { fileExistsAsync } from '../../lib/fs.mjs';
6
+ import { normalizeBackslash } from '../../lib/path.mjs';
7
+ import { detectBuildSettings } from '../build-info.mjs';
8
+ import { chalk, error as failAndExit, log, warn } from '../command-helpers.mjs';
9
+ import { getRecommendPlugins, getUIPlugins } from './plugins.mjs';
15
10
  // these plugins represent runtimes that are
16
11
  // expected to be "automatically" installed. Even though
17
12
  // they can be installed on package/toml, we always
18
13
  // want them installed in the site settings. When installed
19
14
  // there our build will automatically install the latest without
20
15
  // user management of the versioning.
21
- const pluginsToAlwaysInstall = new Set(['@netlify/plugin-nextjs'])
22
-
16
+ const pluginsToAlwaysInstall = new Set(['@netlify/plugin-nextjs']);
23
17
  /**
24
18
  * Retrieve a list of plugins to auto install
25
19
  * @param {string[]=} pluginsInstalled
26
20
  * @param {string[]=} pluginsRecommended
27
21
  * @returns
28
22
  */
29
- export const getPluginsToAutoInstall = (pluginsInstalled = [], pluginsRecommended = []) =>
30
- pluginsRecommended.reduce(
31
- (acc, plugin) =>
32
- pluginsInstalled.includes(plugin) && !pluginsToAlwaysInstall.has(plugin) ? acc : [...acc, plugin],
33
-
34
- /** @type {string[]} */ ([]),
35
- )
36
-
23
+ export const getPluginsToAutoInstall = (pluginsInstalled = [], pluginsRecommended = []) => pluginsRecommended.reduce((acc, plugin) => pluginsInstalled.includes(plugin) && !pluginsToAlwaysInstall.has(plugin) ? acc : [...acc, plugin],
24
+ /** @type {string[]} */ ([]));
37
25
  /**
38
26
  *
39
27
  * @param {Partial<import('@netlify/build-info').Settings>} settings
40
28
  * @param {*} config
41
29
  * @param {import('../../commands/base-command.mjs').default} command
42
30
  */
31
+ // @ts-expect-error TS(7006) FIXME: Parameter 'settings' implicitly has an 'any' type.
43
32
  const normalizeSettings = (settings, config, command) => {
44
- const plugins = getPluginsToAutoInstall(settings.plugins_from_config_file, settings.plugins_recommended)
45
- const recommendedPlugins = getRecommendPlugins(plugins, config)
46
-
47
- return {
48
- defaultBaseDir: settings.baseDirectory ?? command.project.relativeBaseDirectory ?? '',
49
- defaultBuildCmd: config.build.command || settings.buildCommand,
50
- defaultBuildDir: settings.dist,
51
- defaultFunctionsDir: config.build.functions || 'netlify/functions',
52
- recommendedPlugins,
53
- }
54
- }
55
-
33
+ const plugins = getPluginsToAutoInstall(settings.plugins_from_config_file, settings.plugins_recommended);
34
+ const recommendedPlugins = getRecommendPlugins(plugins, config);
35
+ return {
36
+ defaultBaseDir: settings.baseDirectory ?? command.project.relativeBaseDirectory ?? '',
37
+ defaultBuildCmd: config.build.command || settings.buildCommand,
38
+ defaultBuildDir: settings.dist,
39
+ defaultFunctionsDir: config.build.functions || 'netlify/functions',
40
+ recommendedPlugins,
41
+ };
42
+ };
56
43
  /**
57
44
  *
58
45
  * @param {object} param0
@@ -61,71 +48,61 @@ const normalizeSettings = (settings, config, command) => {
61
48
  * @param {string=} param0.defaultBuildDir
62
49
  * @returns
63
50
  */
51
+ // @ts-expect-error TS(7031) FIXME: Binding element 'defaultBaseDir' implicitly has an... Remove this comment to see the full error message
64
52
  const getPromptInputs = ({ defaultBaseDir, defaultBuildCmd, defaultBuildDir }) => {
65
- const inputs = [
66
- defaultBaseDir !== undefined &&
67
- defaultBaseDir !== '' && {
68
- type: 'input',
69
- name: 'baseDir',
70
- message: 'Base directory `(blank for current dir):',
71
- default: defaultBaseDir,
72
- },
73
- {
74
- type: 'input',
75
- name: 'buildCmd',
76
- message: 'Your build command (hugo build/yarn run build/etc):',
77
- filter: (val) => (val === '' ? '# no build command' : val),
78
- default: defaultBuildCmd,
79
- },
80
- {
81
- type: 'input',
82
- name: 'buildDir',
83
- message: 'Directory to deploy (blank for current dir):',
84
- default: defaultBuildDir,
85
- },
86
- ].filter(Boolean)
87
-
88
- return inputs.filter(Boolean)
89
- }
90
-
53
+ const inputs = [
54
+ defaultBaseDir !== undefined &&
55
+ defaultBaseDir !== '' && {
56
+ type: 'input',
57
+ name: 'baseDir',
58
+ message: 'Base directory `(blank for current dir):',
59
+ default: defaultBaseDir,
60
+ },
61
+ {
62
+ type: 'input',
63
+ name: 'buildCmd',
64
+ message: 'Your build command (hugo build/yarn run build/etc):',
65
+ // @ts-expect-error TS(7006) FIXME: Parameter 'val' implicitly has an 'any' type.
66
+ filter: (val) => (val === '' ? '# no build command' : val),
67
+ default: defaultBuildCmd,
68
+ },
69
+ {
70
+ type: 'input',
71
+ name: 'buildDir',
72
+ message: 'Directory to deploy (blank for current dir):',
73
+ default: defaultBuildDir,
74
+ },
75
+ ].filter(Boolean);
76
+ return inputs.filter(Boolean);
77
+ };
91
78
  /**
92
79
  * @param {object} param0
93
80
  * @param {*} param0.config
94
81
  * @param {import('../../commands/base-command.mjs').default} param0.command
95
82
  */
83
+ // @ts-expect-error TS(7031) FIXME: Binding element 'command' implicitly has an 'any' ... Remove this comment to see the full error message
96
84
  export const getBuildSettings = async ({ command, config }) => {
97
- const settings = await detectBuildSettings(command)
98
- // TODO: add prompt for asking to choose the build command
99
- /** @type {Partial<import('@netlify/build-info').Settings>} */
100
- // eslint-disable-next-line unicorn/explicit-length-check
101
- const setting = settings.length > 0 ? settings[0] : {}
102
- const { defaultBaseDir, defaultBuildCmd, defaultBuildDir, defaultFunctionsDir, recommendedPlugins } =
103
- await normalizeSettings(setting, config, command)
104
-
105
- if (recommendedPlugins.length !== 0 && setting.framework?.name) {
106
- log(`Configuring ${formatTitle(setting.framework?.name)} runtime...`)
107
- log()
108
- }
109
-
110
- const { baseDir, buildCmd, buildDir } = await inquirer.prompt(
111
- getPromptInputs({
112
- defaultBaseDir,
113
- defaultBuildCmd,
114
- defaultBuildDir,
115
- }),
116
- )
117
-
118
- const pluginsToInstall = recommendedPlugins.map((plugin) => ({ package: plugin }))
119
- const normalizedBaseDir = baseDir ? normalizeBackslash(baseDir) : undefined
120
-
121
- return { baseDir: normalizedBaseDir, buildCmd, buildDir, functionsDir: defaultFunctionsDir, pluginsToInstall }
122
- }
123
-
124
- const getNetlifyToml = ({
125
- command = '# no build command',
126
- functions = 'functions',
127
- publish = '.',
128
- }) => `# example netlify.toml
85
+ const settings = await detectBuildSettings(command);
86
+ // TODO: add prompt for asking to choose the build command
87
+ /** @type {Partial<import('@netlify/build-info').Settings>} */
88
+ // eslint-disable-next-line unicorn/explicit-length-check
89
+ const setting = settings.length > 0 ? settings[0] : {};
90
+ const { defaultBaseDir, defaultBuildCmd, defaultBuildDir, defaultFunctionsDir, recommendedPlugins } = await normalizeSettings(setting, config, command);
91
+ if (recommendedPlugins.length !== 0 && setting.framework?.name) {
92
+ log(`Configuring ${formatTitle(setting.framework?.name)} runtime...`);
93
+ log();
94
+ }
95
+ const { baseDir, buildCmd, buildDir } = await inquirer.prompt(getPromptInputs({
96
+ defaultBaseDir,
97
+ defaultBuildCmd,
98
+ defaultBuildDir,
99
+ }));
100
+ // @ts-expect-error TS(7006) FIXME: Parameter 'plugin' implicitly has an 'any' type.
101
+ const pluginsToInstall = recommendedPlugins.map((plugin) => ({ package: plugin }));
102
+ const normalizedBaseDir = baseDir ? normalizeBackslash(baseDir) : undefined;
103
+ return { baseDir: normalizedBaseDir, buildCmd, buildDir, functionsDir: defaultFunctionsDir, pluginsToInstall };
104
+ };
105
+ const getNetlifyToml = ({ command = '# no build command', functions = 'functions', publish = '.', }) => `# example netlify.toml
129
106
  [build]
130
107
  command = "${command}"
131
108
  functions = "${functions}"
@@ -145,89 +122,92 @@ const getNetlifyToml = ({
145
122
  # port = 3000 # Port that the dev server will be listening on
146
123
  # publish = "dist" # Folder with the static content for _redirect file
147
124
 
148
- ## more info on configuring this file: https://docs.netlify.com/configure-builds/file-based-configuration/
149
- `
150
-
151
- export const saveNetlifyToml = async ({
152
- baseDir,
153
- buildCmd,
154
- buildDir,
155
- config,
156
- configPath,
157
- functionsDir,
158
- repositoryRoot,
159
- }) => {
160
- const tomlPathParts = [repositoryRoot, baseDir, 'netlify.toml'].filter(Boolean)
161
- const tomlPath = path.join(...tomlPathParts)
162
- if (await fileExistsAsync(tomlPath)) {
163
- return
164
- }
165
-
166
- // We don't want to create a `netlify.toml` file that overrides existing configuration
167
- // In a monorepo the configuration can come from a repo level netlify.toml
168
- // so we make sure it doesn't by checking `configPath === undefined`
169
- if (configPath === undefined && Object.keys(cleanDeep(config)).length !== 0) {
170
- return
171
- }
172
-
173
- const { makeNetlifyTOML } = await inquirer.prompt([
174
- {
175
- type: 'confirm',
176
- name: 'makeNetlifyTOML',
177
- message: 'No netlify.toml detected. Would you like to create one with these build settings?',
178
- default: true,
179
- },
180
- ])
181
- if (makeNetlifyTOML) {
182
- try {
183
- await writeFile(
184
- tomlPath,
185
- getNetlifyToml({ command: buildCmd, publish: buildDir, functions: functionsDir }),
186
- 'utf-8',
187
- )
188
- } catch (error) {
189
- warn(`Failed saving Netlify toml file: ${error.message}`)
125
+ ## more info on configuring this file: https://ntl.fyi/file-based-build-config
126
+ `;
127
+ export const saveNetlifyToml = async ({
128
+ // @ts-expect-error TS(7031) FIXME: Binding element 'baseDir' implicitly has an 'any' ... Remove this comment to see the full error message
129
+ baseDir,
130
+ // @ts-expect-error TS(7031) FIXME: Binding element 'buildCmd' implicitly has an 'any'... Remove this comment to see the full error message
131
+ buildCmd,
132
+ // @ts-expect-error TS(7031) FIXME: Binding element 'buildDir' implicitly has an 'any'... Remove this comment to see the full error message
133
+ buildDir,
134
+ // @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any' t... Remove this comment to see the full error message
135
+ config,
136
+ // @ts-expect-error TS(7031) FIXME: Binding element 'configPath' implicitly has an 'an... Remove this comment to see the full error message
137
+ configPath,
138
+ // @ts-expect-error TS(7031) FIXME: Binding element 'functionsDir' implicitly has an '... Remove this comment to see the full error message
139
+ functionsDir,
140
+ // @ts-expect-error TS(7031) FIXME: Binding element 'repositoryRoot' implicitly has an... Remove this comment to see the full error message
141
+ repositoryRoot, }) => {
142
+ const tomlPathParts = [repositoryRoot, baseDir, 'netlify.toml'].filter(Boolean);
143
+ const tomlPath = path.join(...tomlPathParts);
144
+ if (await fileExistsAsync(tomlPath)) {
145
+ return;
190
146
  }
191
- }
192
- }
193
-
147
+ // We don't want to create a `netlify.toml` file that overrides existing configuration
148
+ // In a monorepo the configuration can come from a repo level netlify.toml
149
+ // so we make sure it doesn't by checking `configPath === undefined`
150
+ // @ts-expect-error TS(2349)
151
+ if (configPath === undefined && Object.keys(cleanDeep(config)).length !== 0) {
152
+ return;
153
+ }
154
+ const { makeNetlifyTOML } = await inquirer.prompt([
155
+ {
156
+ type: 'confirm',
157
+ name: 'makeNetlifyTOML',
158
+ message: 'No netlify.toml detected. Would you like to create one with these build settings?',
159
+ default: true,
160
+ },
161
+ ]);
162
+ if (makeNetlifyTOML) {
163
+ try {
164
+ await writeFile(tomlPath, getNetlifyToml({ command: buildCmd, publish: buildDir, functions: functionsDir }), 'utf-8');
165
+ }
166
+ catch (error) {
167
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
168
+ warn(`Failed saving Netlify toml file: ${error.message}`);
169
+ }
170
+ }
171
+ };
172
+ // @ts-expect-error TS(7031) FIXME: Binding element 'error' implicitly has an 'any' ty... Remove this comment to see the full error message
194
173
  export const formatErrorMessage = ({ error, message }) => {
195
- const errorMessage = error.json ? `${error.message} - ${JSON.stringify(error.json)}` : error.message
196
- return `${message} with error: ${chalk.red(errorMessage)}`
197
- }
198
-
174
+ const errorMessage = error.json ? `${error.message} - ${JSON.stringify(error.json)}` : error.message;
175
+ return `${message} with error: ${chalk.red(errorMessage)}`;
176
+ };
199
177
  /**
200
178
  * @param {string} title
201
179
  */
202
- const formatTitle = (title) => chalk.cyan(title)
203
-
180
+ // @ts-expect-error TS(7006) FIXME: Parameter 'title' implicitly has an 'any' type.
181
+ const formatTitle = (title) => chalk.cyan(title);
182
+ // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
204
183
  export const createDeployKey = async ({ api }) => {
205
- try {
206
- const deployKey = await api.createDeployKey()
207
- return deployKey
208
- } catch (error) {
209
- const message = formatErrorMessage({ message: 'Failed creating deploy key', error })
210
- failAndExit(message)
211
- }
212
- }
213
-
184
+ try {
185
+ const deployKey = await api.createDeployKey();
186
+ return deployKey;
187
+ }
188
+ catch (error) {
189
+ const message = formatErrorMessage({ message: 'Failed creating deploy key', error });
190
+ failAndExit(message);
191
+ }
192
+ };
193
+ // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
214
194
  export const updateSite = async ({ api, options, siteId }) => {
215
- try {
216
- const updatedSite = await api.updateSite({ siteId, body: options })
217
- return updatedSite
218
- } catch (error) {
219
- const message = formatErrorMessage({ message: 'Failed updating site with repo information', error })
220
- failAndExit(message)
221
- }
222
- }
223
-
195
+ try {
196
+ const updatedSite = await api.updateSite({ siteId, body: options });
197
+ return updatedSite;
198
+ }
199
+ catch (error) {
200
+ const message = formatErrorMessage({ message: 'Failed updating site with repo information', error });
201
+ failAndExit(message);
202
+ }
203
+ };
204
+ // @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
224
205
  export const setupSite = async ({ api, configPlugins, pluginsToInstall, repo, siteId }) => {
225
- const updatedSite = await updateSite({
226
- siteId,
227
- api,
228
- // merge existing plugins with new ones
229
- options: { repo, plugins: [...getUIPlugins(configPlugins), ...pluginsToInstall] },
230
- })
231
-
232
- return updatedSite
233
- }
206
+ const updatedSite = await updateSite({
207
+ siteId,
208
+ api,
209
+ // merge existing plugins with new ones
210
+ options: { repo, plugins: [...getUIPlugins(configPlugins), ...pluginsToInstall] },
211
+ });
212
+ return updatedSite;
213
+ };
@@ -1,149 +1,126 @@
1
- // @ts-check
2
- import process from 'process'
3
-
4
- import fetch from 'node-fetch'
5
- import pWaitFor from 'p-wait-for'
6
- import { v4 as uuidv4 } from 'uuid'
7
-
8
- import { fetchLatestVersion, shouldFetchLatestVersion } from '../lib/exec-fetcher.mjs'
9
- import { getPathInHome } from '../lib/settings.mjs'
10
-
11
- import { NETLIFYDEVERR, NETLIFYDEVLOG, chalk, log } from './command-helpers.mjs'
12
- import execa from './execa.mjs'
13
-
14
- const PACKAGE_NAME = 'live-tunnel-client'
15
- const EXEC_NAME = PACKAGE_NAME
16
- const SLUG_LOCAL_STATE_KEY = 'liveTunnelSlug'
17
-
1
+ import process from 'process';
2
+ // @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'node... Remove this comment to see the full error message
3
+ import fetch from 'node-fetch';
4
+ import pWaitFor from 'p-wait-for';
5
+ import { v4 as uuidv4 } from 'uuid';
6
+ import { fetchLatestVersion, shouldFetchLatestVersion } from '../lib/exec-fetcher.mjs';
7
+ import { getPathInHome } from '../lib/settings.mjs';
8
+ import { NETLIFYDEVERR, NETLIFYDEVLOG, chalk, log } from './command-helpers.mjs';
9
+ // @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
10
+ import execa from './execa.mjs';
11
+ const PACKAGE_NAME = 'live-tunnel-client';
12
+ const EXEC_NAME = PACKAGE_NAME;
13
+ const SLUG_LOCAL_STATE_KEY = 'liveTunnelSlug';
18
14
  // 1 second
19
- const TUNNEL_POLL_INTERVAL = 1e3
15
+ const TUNNEL_POLL_INTERVAL = 1e3;
20
16
  // 5 minutes
21
- const TUNNEL_POLL_TIMEOUT = 3e5
22
-
17
+ const TUNNEL_POLL_TIMEOUT = 3e5;
18
+ // @ts-expect-error TS(7031) FIXME: Binding element 'netlifyApiToken' implicitly has a... Remove this comment to see the full error message
23
19
  const createTunnel = async function ({ netlifyApiToken, siteId, slug }) {
24
- await installTunnelClient()
25
-
26
- if (!siteId) {
27
- console.error(
28
- `${NETLIFYDEVERR} Error: no siteId defined, did you forget to run ${chalk.yellow(
29
- 'netlify init',
30
- )} or ${chalk.yellow('netlify link')}?`,
31
- )
32
- process.exit(1)
33
- }
34
-
35
- const url = `https://api.netlify.com/api/v1/live_sessions?site_id=${siteId}&slug=${slug}`
36
- const response = await fetch(url, {
37
- method: 'POST',
38
- headers: {
39
- 'Content-Type': 'application/json',
40
- Authorization: `Bearer ${netlifyApiToken}`,
41
- },
42
- body: JSON.stringify({}),
43
- })
44
-
45
- const data = await response.json()
46
-
47
- if (response.status !== 201) {
48
- throw new Error(data.message)
49
- }
50
-
51
- return data
52
- }
53
-
20
+ await installTunnelClient();
21
+ if (!siteId) {
22
+ console.error(`${NETLIFYDEVERR} Error: no siteId defined, did you forget to run ${chalk.yellow('netlify init')} or ${chalk.yellow('netlify link')}?`);
23
+ process.exit(1);
24
+ }
25
+ const url = `https://api.netlify.com/api/v1/live_sessions?site_id=${siteId}&slug=${slug}`;
26
+ const response = await fetch(url, {
27
+ method: 'POST',
28
+ headers: {
29
+ 'Content-Type': 'application/json',
30
+ Authorization: `Bearer ${netlifyApiToken}`,
31
+ },
32
+ body: JSON.stringify({}),
33
+ });
34
+ const data = await response.json();
35
+ if (response.status !== 201) {
36
+ throw new Error(data.message);
37
+ }
38
+ return data;
39
+ };
40
+ // @ts-expect-error TS(7031) FIXME: Binding element 'localPort' implicitly has an 'any... Remove this comment to see the full error message
54
41
  const connectTunnel = function ({ localPort, netlifyApiToken, session }) {
55
- const execPath = getPathInHome(['tunnel', 'bin', EXEC_NAME])
56
- const args = ['connect', '-s', session.id, '-t', netlifyApiToken, '-l', localPort]
57
- if (process.env.DEBUG) {
58
- args.push('-v')
59
- log(execPath, args)
60
- }
61
-
62
- const ps = execa(execPath, args, { stdio: 'inherit' })
63
- ps.on('close', (code) => process.exit(code))
64
- ps.on('SIGINT', process.exit)
65
- ps.on('SIGTERM', process.exit)
66
- }
67
-
42
+ const execPath = getPathInHome(['tunnel', 'bin', EXEC_NAME]);
43
+ const args = ['connect', '-s', session.id, '-t', netlifyApiToken, '-l', localPort];
44
+ if (process.env.DEBUG) {
45
+ args.push('-v');
46
+ log(execPath, args);
47
+ }
48
+ // @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
49
+ const ps = execa(execPath, args, { stdio: 'inherit' });
50
+ // @ts-expect-error TS(7006) FIXME: Parameter 'code' implicitly has an 'any' type.
51
+ ps.on('close', (code) => process.exit(code));
52
+ ps.on('SIGINT', process.exit);
53
+ ps.on('SIGTERM', process.exit);
54
+ };
68
55
  const installTunnelClient = async function () {
69
- const binPath = getPathInHome(['tunnel', 'bin'])
70
- const shouldFetch = await shouldFetchLatestVersion({
71
- binPath,
72
- packageName: PACKAGE_NAME,
73
- execArgs: ['version'],
74
- pattern: `${PACKAGE_NAME}\\/v?([^\\s]+)`,
75
- execName: EXEC_NAME,
76
- })
77
- if (!shouldFetch) {
78
- return
79
- }
80
-
81
- log(`${NETLIFYDEVLOG} Installing Live Tunnel Client`)
82
-
83
- await fetchLatestVersion({
84
- packageName: PACKAGE_NAME,
85
- execName: EXEC_NAME,
86
- destination: binPath,
87
- extension: process.platform === 'win32' ? 'zip' : 'tar.gz',
88
- })
89
- }
90
-
91
- export const startLiveTunnel = async ({ localPort, netlifyApiToken, siteId, slug }) => {
92
- const session = await createTunnel({
93
- siteId,
94
- netlifyApiToken,
95
- slug,
96
- })
97
-
98
- const isLiveTunnelReady = async function () {
99
- const url = `https://api.netlify.com/api/v1/live_sessions/${session.id}`
100
- const response = await fetch(url, {
101
- method: 'GET',
102
- headers: {
103
- 'Content-Type': 'application/json',
104
- Authorization: `Bearer ${netlifyApiToken}`,
105
- },
106
- })
107
- const data = await response.json()
108
-
109
- if (response.status !== 200) {
110
- throw new Error(data.message)
56
+ const binPath = getPathInHome(['tunnel', 'bin']);
57
+ // @ts-expect-error TS(2345) FIXME: Argument of type '{ binPath: string; packageName: ... Remove this comment to see the full error message
58
+ const shouldFetch = await shouldFetchLatestVersion({
59
+ binPath,
60
+ packageName: PACKAGE_NAME,
61
+ execArgs: ['version'],
62
+ pattern: `${PACKAGE_NAME}\\/v?([^\\s]+)`,
63
+ execName: EXEC_NAME,
64
+ });
65
+ if (!shouldFetch) {
66
+ return;
111
67
  }
112
-
113
- return data.state === 'online'
114
- }
115
-
116
- connectTunnel({ session, netlifyApiToken, localPort })
117
-
118
- // Waiting for the live session to have a state of `online`.
119
- await pWaitFor(isLiveTunnelReady, {
120
- interval: TUNNEL_POLL_INTERVAL,
121
- timeout: TUNNEL_POLL_TIMEOUT,
122
- })
123
-
124
- return session.session_url
125
- }
126
-
68
+ log(`${NETLIFYDEVLOG} Installing Live Tunnel Client`);
69
+ // @ts-expect-error TS(2345) FIXME: Argument of type '{ packageName: string; execName:... Remove this comment to see the full error message
70
+ await fetchLatestVersion({
71
+ packageName: PACKAGE_NAME,
72
+ execName: EXEC_NAME,
73
+ destination: binPath,
74
+ extension: process.platform === 'win32' ? 'zip' : 'tar.gz',
75
+ });
76
+ };
77
+ // @ts-expect-error TS(7031) FIXME: Binding element 'localPort' implicitly has an 'any... Remove this comment to see the full error message
78
+ export const startLiveTunnel = async ({ localPort, netlifyApiToken, siteId, slug }) => {
79
+ const session = await createTunnel({
80
+ siteId,
81
+ netlifyApiToken,
82
+ slug,
83
+ });
84
+ const isLiveTunnelReady = async function () {
85
+ const url = `https://api.netlify.com/api/v1/live_sessions/${session.id}`;
86
+ const response = await fetch(url, {
87
+ method: 'GET',
88
+ headers: {
89
+ 'Content-Type': 'application/json',
90
+ Authorization: `Bearer ${netlifyApiToken}`,
91
+ },
92
+ });
93
+ const data = await response.json();
94
+ if (response.status !== 200) {
95
+ throw new Error(data.message);
96
+ }
97
+ return data.state === 'online';
98
+ };
99
+ connectTunnel({ session, netlifyApiToken, localPort });
100
+ // Waiting for the live session to have a state of `online`.
101
+ await pWaitFor(isLiveTunnelReady, {
102
+ interval: TUNNEL_POLL_INTERVAL,
103
+ timeout: TUNNEL_POLL_TIMEOUT,
104
+ });
105
+ return session.session_url;
106
+ };
107
+ // @ts-expect-error TS(7006) FIXME: Parameter 'state' implicitly has an 'any' type.
127
108
  export const getLiveTunnelSlug = (state, override) => {
128
- if (override !== undefined) {
129
- return override
130
- }
131
-
132
- const newSlug = generateRandomSlug()
133
-
134
- try {
135
- const existingSlug = state.get(SLUG_LOCAL_STATE_KEY)
136
-
137
- if (existingSlug !== undefined) {
138
- return existingSlug
109
+ if (override !== undefined) {
110
+ return override;
111
+ }
112
+ const newSlug = generateRandomSlug();
113
+ try {
114
+ const existingSlug = state.get(SLUG_LOCAL_STATE_KEY);
115
+ if (existingSlug !== undefined) {
116
+ return existingSlug;
117
+ }
118
+ state.set(SLUG_LOCAL_STATE_KEY, newSlug);
119
+ }
120
+ catch (error) {
121
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
122
+ log(`${NETLIFYDEVERR} Could not read or write local state file: ${error.message}`);
139
123
  }
140
-
141
- state.set(SLUG_LOCAL_STATE_KEY, newSlug)
142
- } catch (error) {
143
- log(`${NETLIFYDEVERR} Could not read or write local state file: ${error.message}`)
144
- }
145
-
146
- return newSlug
147
- }
148
-
149
- const generateRandomSlug = () => uuidv4().slice(0, 8)
124
+ return newSlug;
125
+ };
126
+ const generateRandomSlug = () => uuidv4().slice(0, 8);