netlify-cli 11.5.1 → 11.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
3
  "description": "Netlify command line tool",
4
- "version": "11.5.1",
4
+ "version": "11.7.1",
5
5
  "author": "Netlify Inc.",
6
6
  "contributors": [
7
7
  "@whitep4nth3r (https://twitter.com/whitep4nth3r)",
@@ -223,13 +223,13 @@
223
223
  "prettier": "--ignore-path .gitignore --loglevel=warn \"{src,tools,scripts,site,tests,.github}/**/*.{mjs,cjs,js,md,yml,json,html}\" \"*.{mjs,cjs,js,yml,json,html}\" \".*.{mjs,cjs,js,yml,json,html}\" \"!CHANGELOG.md\" \"!npm-shrinkwrap.json\" \"!**/*/package-lock.json\" \"!.github/**/*.md\""
224
224
  },
225
225
  "dependencies": {
226
- "@netlify/build": "^27.16.1",
226
+ "@netlify/build": "^27.17.2",
227
227
  "@netlify/config": "^18.2.3",
228
228
  "@netlify/edge-bundler": "^1.14.1",
229
229
  "@netlify/framework-info": "^9.2.0",
230
230
  "@netlify/local-functions-proxy": "^1.1.1",
231
- "@netlify/plugins-list": "^6.41.0",
232
- "@netlify/zip-it-and-ship-it": "^6.0.0",
231
+ "@netlify/plugins-list": "^6.42.0",
232
+ "@netlify/zip-it-and-ship-it": "^7.1.1",
233
233
  "@octokit/rest": "^18.0.0",
234
234
  "@sindresorhus/slugify": "^1.1.0",
235
235
  "ansi-escapes": "^5.0.0",
@@ -7,11 +7,7 @@ const { error, exit, generateNetlifyGraphJWT, getEnvelopeEnv, getToken, normaliz
7
7
  /**
8
8
  * @param {import('../../lib/build').BuildConfig} options
9
9
  */
10
- const checkOptions = ({ cachedConfig: { siteInfo = {} }, token }) => {
11
- if (!siteInfo.id) {
12
- error('Could not find the site ID. Please run netlify link.')
13
- }
14
-
10
+ const checkOptions = ({ token }) => {
15
11
  if (!token) {
16
12
  error('Could not find the access token. Please run netlify login.')
17
13
  }
@@ -72,7 +68,7 @@ const build = async (options, command) => {
72
68
  await injectEnv(command, { api, buildOptions, context, site, siteInfo })
73
69
  }
74
70
 
75
- const { exitCode } = await runBuild(buildOptions)
71
+ const { exitCode } = await runBuild(buildOptions, command, options)
76
72
  exit(exitCode)
77
73
  }
78
74
 
@@ -375,10 +375,11 @@ const runDeploy = async ({
375
375
  *
376
376
  * @param {object} config
377
377
  * @param {*} config.cachedConfig
378
+ * @param {*} config.command
378
379
  * @param {import('commander').OptionValues} config.options The options of the command
379
380
  * @returns
380
381
  */
381
- const handleBuild = async ({ cachedConfig, options }) => {
382
+ const handleBuild = async ({ cachedConfig, command, options }) => {
382
383
  if (!options.build) {
383
384
  return {}
384
385
  }
@@ -388,7 +389,7 @@ const handleBuild = async ({ cachedConfig, options }) => {
388
389
  token,
389
390
  options,
390
391
  })
391
- const { configMutations, exitCode, newConfig } = await runBuild(resolvedOptions)
392
+ const { configMutations, exitCode, newConfig } = await runBuild(resolvedOptions, command, options)
392
393
  if (exitCode !== 0) {
393
394
  exit(exitCode)
394
395
  }
@@ -573,6 +574,7 @@ const deploy = async (options, command) => {
573
574
 
574
575
  const { newConfig, configMutations = [] } = await handleBuild({
575
576
  cachedConfig: command.netlify.cachedConfig,
577
+ command,
576
578
  options,
577
579
  })
578
580
  const config = newConfig || command.netlify.config
@@ -9,7 +9,7 @@
9
9
  "version": "1.0.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "stripe": "^9.0.0"
12
+ "stripe": "^10.0.0"
13
13
  }
14
14
  },
15
15
  "node_modules/@types/node": {
@@ -105,9 +105,9 @@
105
105
  }
106
106
  },
107
107
  "node_modules/stripe": {
108
- "version": "9.16.0",
109
- "resolved": "https://registry.npmjs.org/stripe/-/stripe-9.16.0.tgz",
110
- "integrity": "sha512-Dn8K+jSoQcXjxCobRI4HXUdHjOXsiF/KszK49fJnkbeCFjZ3EZxLG2JiM/CX+Hcq27NBDtv/Sxhvy+HhTmvyaQ==",
108
+ "version": "10.8.0",
109
+ "resolved": "https://registry.npmjs.org/stripe/-/stripe-10.8.0.tgz",
110
+ "integrity": "sha512-/cQiJ7puqVMDrGDRGqtHn6zPB+nRNA97qyQU59msLQ1OWaQOmwW1IQR7PpRqeqkSv9SgPU7BVBlMKNwWtn1qNA==",
111
111
  "dependencies": {
112
112
  "@types/node": ">=8.1.0",
113
113
  "qs": "^6.10.3"
@@ -184,9 +184,9 @@
184
184
  }
185
185
  },
186
186
  "stripe": {
187
- "version": "9.16.0",
188
- "resolved": "https://registry.npmjs.org/stripe/-/stripe-9.16.0.tgz",
189
- "integrity": "sha512-Dn8K+jSoQcXjxCobRI4HXUdHjOXsiF/KszK49fJnkbeCFjZ3EZxLG2JiM/CX+Hcq27NBDtv/Sxhvy+HhTmvyaQ==",
187
+ "version": "10.8.0",
188
+ "resolved": "https://registry.npmjs.org/stripe/-/stripe-10.8.0.tgz",
189
+ "integrity": "sha512-/cQiJ7puqVMDrGDRGqtHn6zPB+nRNA97qyQU59msLQ1OWaQOmwW1IQR7PpRqeqkSv9SgPU7BVBlMKNwWtn1qNA==",
190
190
  "requires": {
191
191
  "@types/node": ">=8.1.0",
192
192
  "qs": "^6.10.3"
@@ -16,6 +16,6 @@
16
16
  "author": "Netlify",
17
17
  "license": "MIT",
18
18
  "dependencies": {
19
- "stripe": "^9.0.0"
19
+ "stripe": "^10.0.0"
20
20
  }
21
21
  }
@@ -9,7 +9,7 @@
9
9
  "version": "1.0.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "stripe": "^9.0.0"
12
+ "stripe": "^10.0.0"
13
13
  }
14
14
  },
15
15
  "node_modules/@types/node": {
@@ -105,9 +105,9 @@
105
105
  }
106
106
  },
107
107
  "node_modules/stripe": {
108
- "version": "9.16.0",
109
- "resolved": "https://registry.npmjs.org/stripe/-/stripe-9.16.0.tgz",
110
- "integrity": "sha512-Dn8K+jSoQcXjxCobRI4HXUdHjOXsiF/KszK49fJnkbeCFjZ3EZxLG2JiM/CX+Hcq27NBDtv/Sxhvy+HhTmvyaQ==",
108
+ "version": "10.8.0",
109
+ "resolved": "https://registry.npmjs.org/stripe/-/stripe-10.8.0.tgz",
110
+ "integrity": "sha512-/cQiJ7puqVMDrGDRGqtHn6zPB+nRNA97qyQU59msLQ1OWaQOmwW1IQR7PpRqeqkSv9SgPU7BVBlMKNwWtn1qNA==",
111
111
  "dependencies": {
112
112
  "@types/node": ">=8.1.0",
113
113
  "qs": "^6.10.3"
@@ -184,9 +184,9 @@
184
184
  }
185
185
  },
186
186
  "stripe": {
187
- "version": "9.16.0",
188
- "resolved": "https://registry.npmjs.org/stripe/-/stripe-9.16.0.tgz",
189
- "integrity": "sha512-Dn8K+jSoQcXjxCobRI4HXUdHjOXsiF/KszK49fJnkbeCFjZ3EZxLG2JiM/CX+Hcq27NBDtv/Sxhvy+HhTmvyaQ==",
187
+ "version": "10.8.0",
188
+ "resolved": "https://registry.npmjs.org/stripe/-/stripe-10.8.0.tgz",
189
+ "integrity": "sha512-/cQiJ7puqVMDrGDRGqtHn6zPB+nRNA97qyQU59msLQ1OWaQOmwW1IQR7PpRqeqkSv9SgPU7BVBlMKNwWtn1qNA==",
190
190
  "requires": {
191
191
  "@types/node": ">=8.1.0",
192
192
  "qs": "^6.10.3"
@@ -16,6 +16,6 @@
16
16
  "author": "Netlify",
17
17
  "license": "MIT",
18
18
  "dependencies": {
19
- "stripe": "^9.0.0"
19
+ "stripe": "^10.0.0"
20
20
  }
21
21
  }
@@ -11,4 +11,4 @@ http = "0.2.8"
11
11
  lambda_runtime = "0.6.0"
12
12
  log = "0.4.17"
13
13
  simple_logger = "1.16.0"
14
- tokio = "1.20.1"
14
+ tokio = "1.21.0"
package/src/lib/build.js CHANGED
@@ -3,6 +3,8 @@ const process = require('process')
3
3
 
4
4
  const netlifyBuildPromise = import('@netlify/build')
5
5
 
6
+ const { NETLIFYDEVERR, detectServerSettings, error, log } = require('../utils')
7
+
6
8
  /**
7
9
  * The buildConfig + a missing cachedConfig
8
10
  * @typedef BuildConfig
@@ -36,16 +38,26 @@ const getBuildOptions = ({ cachedConfig, options: { context, cwd, debug, dry, js
36
38
  featureFlags: {
37
39
  functionsBundlingManifest: true,
38
40
  edge_functions_produce_eszip: true,
41
+ project_deploy_configuration_api_use_per_function_configuration_files: true,
39
42
  },
40
43
  })
41
44
 
42
45
  /**
43
46
  * run the build command
44
- * @param {BuildConfig} options
47
+ * @param {BuildConfig} buildOptions
48
+ * @param {import('../commands/base-command').BaseCommand} command
49
+ * @param {import('commander').OptionValues} commandOptions
45
50
  * @returns
46
51
  */
47
- const runBuild = async (options) => {
52
+ const runBuild = async (buildOptions, command, commandOptions) => {
48
53
  const { default: build } = await netlifyBuildPromise
54
+ const { cachedConfig, config, site } = command.netlify
55
+ const devConfig = {
56
+ framework: '#auto',
57
+ ...(config.functionsDirectory && { functions: config.functionsDirectory }),
58
+ ...config.dev,
59
+ ...commandOptions,
60
+ }
49
61
 
50
62
  // If netlify NETLIFY_API_URL is set we need to pass this information to @netlify/build
51
63
  // TODO don't use testOpts, but add real properties to do this.
@@ -55,10 +67,52 @@ const runBuild = async (options) => {
55
67
  scheme: apiUrl.protocol.slice(0, -1),
56
68
  host: apiUrl.host,
57
69
  }
58
- options = { ...options, testOpts }
70
+ buildOptions = { ...buildOptions, testOpts }
71
+ }
72
+
73
+ /** @type {Partial<import('../../utils/types').ServerSettings>} */
74
+ let settings = {}
75
+ try {
76
+ settings = await detectServerSettings(devConfig, commandOptions, site.root)
77
+
78
+ const defaultConfig = { build: {} }
79
+
80
+ if (settings.buildCommand && settings.dist) {
81
+ buildOptions.cachedConfig.config.build.command = settings.buildCommand
82
+ defaultConfig.build.command = settings.buildCommand
83
+ buildOptions.cachedConfig.config.build.publish = settings.buildCommand
84
+ defaultConfig.build.publish = settings.dist
85
+ }
86
+
87
+ if (defaultConfig.build.command && defaultConfig.build.publish) {
88
+ buildOptions.defaultConfig = defaultConfig
89
+ }
90
+
91
+ // If there are plugins that we should be running for this site, add them
92
+ // to the config as if they were declared in netlify.toml. We must check
93
+ // whether the plugin has already been added by another source (like the
94
+ // TOML file or the UI), as we don't want to run the same plugin twice.
95
+ if (settings.plugins) {
96
+ const { plugins: existingPlugins = [] } = cachedConfig.config
97
+ const existingPluginNames = new Set(existingPlugins.map((plugin) => plugin.package))
98
+ const newPlugins = settings.plugins
99
+ .map((pluginName) => {
100
+ if (existingPluginNames.has(pluginName)) {
101
+ return
102
+ }
103
+
104
+ return { package: pluginName, origin: 'config', inputs: {} }
105
+ })
106
+ .filter(Boolean)
107
+
108
+ buildOptions.cachedConfig.config.plugins = [...newPlugins, ...cachedConfig.config.plugins]
109
+ }
110
+ } catch (detectServerSettingsError) {
111
+ log(NETLIFYDEVERR, detectServerSettingsError.message)
112
+ error(detectServerSettingsError)
59
113
  }
60
114
 
61
- const { configMutations, netlifyConfig: newConfig, severityCode: exitCode } = await build(options)
115
+ const { configMutations, netlifyConfig: newConfig, severityCode: exitCode } = await build(buildOptions)
62
116
  return { exitCode, newConfig, configMutations }
63
117
  }
64
118
 
@@ -176,6 +176,7 @@ class FunctionsRegistry {
176
176
  const functions = await this.listFunctions(directories, {
177
177
  featureFlags: {
178
178
  buildRustSource: env.NETLIFY_EXPERIMENTAL_BUILD_RUST_SOURCE === 'true',
179
+ project_deploy_configuration_api_use_per_function_configuration_files: true,
179
180
  },
180
181
  config: this.config.functions,
181
182
  })
@@ -158,7 +158,10 @@ const handleStaticServer = async ({ devConfig, options, projectDir }) => {
158
158
  */
159
159
  const getSettingsFromFramework = (framework) => {
160
160
  const {
161
- build: { directory: dist },
161
+ build: {
162
+ directory: dist,
163
+ commands: [buildCommand],
164
+ },
162
165
  dev: {
163
166
  commands: [command],
164
167
  port: frameworkPort,
@@ -172,6 +175,7 @@ const getSettingsFromFramework = (framework) => {
172
175
 
173
176
  return {
174
177
  command,
178
+ buildCommand,
175
179
  frameworkPort,
176
180
  dist: staticDir || dist,
177
181
  framework: frameworkName,
@@ -250,6 +254,7 @@ const handleCustomFramework = ({ devConfig }) => {
250
254
  const mergeSettings = async ({ devConfig, frameworkSettings = {} }) => {
251
255
  const {
252
256
  command: frameworkCommand,
257
+ buildCommand,
253
258
  frameworkPort: frameworkDetectedPort,
254
259
  dist,
255
260
  framework,
@@ -263,6 +268,7 @@ const mergeSettings = async ({ devConfig, frameworkSettings = {} }) => {
263
268
  const useStaticServer = !(command && frameworkPort)
264
269
  return {
265
270
  command,
271
+ buildCommand,
266
272
  frameworkPort: useStaticServer ? await getStaticServerPort({ devConfig }) : frameworkPort,
267
273
  dist: devConfig.publish || dist || getDefaultDist(),
268
274
  framework,
@@ -70,7 +70,7 @@ const proxyToExternalUrl = function ({ dest, destURL, req, res }) {
70
70
  pathRewrite: () => destURL,
71
71
  ...(Buffer.isBuffer(req.originalBody) && { buffer: toReadableStream(req.originalBody) }),
72
72
  })
73
- return handler(req, res, {})
73
+ return handler(req, res, () => {})
74
74
  }
75
75
 
76
76
  const handleAddonUrl = function ({ addonUrl, req, res }) {
@@ -185,7 +185,7 @@ const serveRedirect = async function ({ match, options, proxy, req, res }) {
185
185
 
186
186
  const staticFile = await getStatic(decodeURIComponent(reqUrl.pathname), options.publicFolder)
187
187
  if (staticFile) {
188
- req.url = encodeURIComponent(staticFile) + reqUrl.search
188
+ req.url = encodeURI(staticFile) + reqUrl.search
189
189
  // if there is an existing static file and it is not a forced redirect, return the file
190
190
  if (!match.force) {
191
191
  return proxy.web(req, res, { ...options, staticFile })
@@ -214,18 +214,25 @@ const serveRedirect = async function ({ match, options, proxy, req, res }) {
214
214
  })
215
215
  }
216
216
 
217
- const destURL = stripOrigin(dest)
217
+ let destURL = stripOrigin(dest)
218
218
 
219
219
  if (isExternal(match)) {
220
- return proxyToExternalUrl({ req, res, dest, destURL })
220
+ if (isRedirect(match)) {
221
+ // This is a redirect, so we set the complete external URL as destination
222
+ destURL = `${dest}`
223
+ } else {
224
+ return proxyToExternalUrl({ req, res, dest, destURL })
225
+ }
221
226
  }
222
227
 
223
228
  if (isRedirect(match)) {
229
+ console.log(`${NETLIFYDEVLOG} Redirecting ${req.url} to ${destURL}`)
224
230
  res.writeHead(match.status, {
225
231
  Location: destURL,
226
232
  'Cache-Control': 'no-cache',
227
233
  })
228
234
  res.end(`Redirecting to ${destURL}`)
235
+
229
236
  return
230
237
  }
231
238