netlify-cli 15.8.0 → 15.8.1-rc.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.
@@ -36,9 +36,29 @@ import { generateRequestID } from './request-id.mjs'
36
36
  import { createRewriter, onChanges } from './rules-proxy.mjs'
37
37
  import { signRedirect } from './sign-redirect.mjs'
38
38
 
39
- const decompress = util.promisify(zlib.gunzip)
39
+ const gunzip = util.promisify(zlib.gunzip)
40
+ const brotliDecompress = util.promisify(zlib.brotliDecompress)
41
+ const deflate = util.promisify(zlib.deflate)
40
42
  const shouldGenerateETag = Symbol('Internal: response should generate ETag')
41
43
 
44
+ /**
45
+ * @param {Buffer} body
46
+ * @param {string | undefined} contentEncoding
47
+ * @returns {Promise<Buffer>}
48
+ */
49
+ const decompressResponseBody = async function (body, contentEncoding = '') {
50
+ switch (contentEncoding) {
51
+ case 'gzip':
52
+ return await gunzip(body)
53
+ case 'br':
54
+ return await brotliDecompress(body)
55
+ case 'deflate':
56
+ return await deflate(body)
57
+ default:
58
+ return body
59
+ }
60
+ }
61
+
42
62
  const formatEdgeFunctionError = (errorBuffer, acceptsHtml) => {
43
63
  const {
44
64
  error: { message, name, stack },
@@ -479,7 +499,7 @@ const initializeProxy = async function ({ configPath, distDir, env, host, port,
479
499
 
480
500
  if (isEdgeFunctionsRequest(req) && isUncaughtError) {
481
501
  const acceptsHtml = req.headers && req.headers.accept && req.headers.accept.includes('text/html')
482
- const decompressedBody = await decompress(responseBody)
502
+ const decompressedBody = await decompressResponseBody(responseBody, req.headers['content-encoding'])
483
503
  const formattedBody = formatEdgeFunctionError(decompressedBody, acceptsHtml)
484
504
  const errorResponse = acceptsHtml
485
505
  ? await renderErrorTemplate(formattedBody, './templates/function-error.html', 'edge function')
@@ -487,6 +507,7 @@ const initializeProxy = async function ({ configPath, distDir, env, host, port,
487
507
  const contentLength = Buffer.from(errorResponse, 'utf8').byteLength
488
508
 
489
509
  res.setHeader('content-length', contentLength)
510
+ res.statusCode = 500
490
511
  res.write(errorResponse)
491
512
  return res.end()
492
513
  }
@@ -578,12 +599,17 @@ const onRequest = async (
578
599
  proxy.web(req, res, options)
579
600
  }
580
601
 
602
+ /**
603
+ * @param {import('./types.js').ServerSettings} settings
604
+ * @returns
605
+ */
581
606
  export const getProxyUrl = function (settings) {
582
607
  const scheme = settings.https ? 'https' : 'http'
583
608
  return `${scheme}://localhost:${settings.port}`
584
609
  }
585
610
 
586
611
  export const startProxy = async function ({
612
+ accountId,
587
613
  addonsUrls,
588
614
  config,
589
615
  configPath,
@@ -615,6 +641,7 @@ export const startProxy = async function ({
615
641
  passthroughPort: secondaryServerPort || settings.port,
616
642
  projectDir,
617
643
  siteInfo,
644
+ accountId,
618
645
  state,
619
646
  })
620
647
  const proxy = await initializeProxy({
@@ -12,8 +12,13 @@ import { INTERNAL_FUNCTIONS_FOLDER } from './functions/index.mjs'
12
12
 
13
13
  const netlifyBuildPromise = import('@netlify/build')
14
14
 
15
- // Copies `netlify.toml`, if one is defined, into the `.netlify` internal
16
- // directory and returns the path to its new location.
15
+ /**
16
+ * Copies `netlify.toml`, if one is defined, into the `.netlify` internal
17
+ * directory and returns the path to its new location.
18
+ * @param {object} config
19
+ * @param {string} config.configPath
20
+ * @param {string} config.siteRoot
21
+ */
17
22
  const copyConfig = async ({ configPath, siteRoot }) => {
18
23
  const newConfigPath = path.resolve(siteRoot, getPathInProject(['netlify.toml']))
19
24
 
@@ -26,6 +31,9 @@ const copyConfig = async ({ configPath, siteRoot }) => {
26
31
  return newConfigPath
27
32
  }
28
33
 
34
+ /**
35
+ * @param {string} basePath
36
+ */
29
37
  const cleanInternalDirectory = async (basePath) => {
30
38
  const ops = [INTERNAL_FUNCTIONS_FOLDER, INTERNAL_EDGE_FUNCTIONS_FOLDER, 'netlify.toml'].map((name) => {
31
39
  const fullPath = path.resolve(basePath, getPathInProject([name]))
@@ -36,6 +44,21 @@ const cleanInternalDirectory = async (basePath) => {
36
44
  await Promise.all(ops)
37
45
  }
38
46
 
47
+ /**
48
+ *
49
+ * @param {object} config
50
+ * @param {*} config.cachedConfig
51
+ * @param {object} config.options
52
+ * @param {string} config.options.configPath
53
+ * @param {*} config.options.context
54
+ * @param {string=} config.options.cwd
55
+ * @param {boolean} config.options.debug
56
+ * @param {boolean} config.options.dry
57
+ * @param {boolean} config.options.offline
58
+ * @param {boolean} config.options.quiet
59
+ * @param {boolean} config.options.saveConfig
60
+ * @returns
61
+ */
39
62
  const getBuildOptions = ({
40
63
  cachedConfig,
41
64
  options: { configPath, context, cwd = process.cwd(), debug, dry, offline, quiet, saveConfig },
@@ -56,7 +79,18 @@ const getBuildOptions = ({
56
79
  saveConfig,
57
80
  })
58
81
 
59
- const runNetlifyBuild = async ({ cachedConfig, env, options, settings, site, timeline = 'build' }) => {
82
+ /**
83
+ *
84
+ * @param {object} config
85
+ * @param {*} config.cachedConfig
86
+ * @param {NodeJS.ProcessEnv} config.env
87
+ * @param {*} config.options
88
+ * @param {import('./types.js').ServerSettings} config.settings
89
+ * @param {*} config.site
90
+ * @param {'build' | 'dev'} config.timeline
91
+ * @returns
92
+ */
93
+ export const runNetlifyBuild = async ({ cachedConfig, env, options, settings, site, timeline = 'build' }) => {
60
94
  const { default: buildSite, startDev } = await netlifyBuildPromise
61
95
  const sharedOptions = getBuildOptions({
62
96
  cachedConfig,
@@ -118,13 +152,19 @@ const runNetlifyBuild = async ({ cachedConfig, env, options, settings, site, tim
118
152
  // Run Netlify Build using the `startDev` entry point.
119
153
  const { error: startDevError, success } = await startDev(devCommand, startDevOptions)
120
154
 
121
- if (!success) {
155
+ if (!success && startDevError) {
122
156
  error(`Could not start local development server\n\n${startDevError.message}\n\n${startDevError.stack}`)
123
157
  }
124
158
 
125
159
  return {}
126
160
  }
127
161
 
162
+ /**
163
+ * @param {Omit<Parameters<typeof runNetlifyBuild>[0], 'timeline'>} options
164
+ */
128
165
  export const runDevTimeline = (options) => runNetlifyBuild({ ...options, timeline: 'dev' })
129
166
 
167
+ /**
168
+ * @param {Omit<Parameters<typeof runNetlifyBuild>[0], 'timeline'>} options
169
+ */
130
170
  export const runBuildTimeline = (options) => runNetlifyBuild({ ...options, timeline: 'build' })
@@ -48,7 +48,11 @@ export const runCommand = (command, env = {}, spinner = null) => {
48
48
  preferLocal: true,
49
49
  // we use reject=false to avoid rejecting synchronously when the command doesn't exist
50
50
  reject: false,
51
- env,
51
+ env: {
52
+ // we want always colorful terminal outputs
53
+ FORCE_COLOR: 'true',
54
+ ...env,
55
+ },
52
56
  // windowsHide needs to be false for child process to terminate properly on Windows
53
57
  windowsHide: false,
54
58
  })
@@ -100,6 +104,13 @@ export const runCommand = (command, env = {}, spinner = null) => {
100
104
  return commandProcess
101
105
  }
102
106
 
107
+ /**
108
+ *
109
+ * @param {object} config
110
+ * @param {string} config.command
111
+ * @param {*} config.error
112
+ * @returns
113
+ */
103
114
  const isNonExistingCommandError = ({ command, error: commandError }) => {
104
115
  // `ENOENT` is only returned for non Windows systems
105
116
  // See https://github.com/sindresorhus/execa/pull/447
@@ -108,7 +119,7 @@ const isNonExistingCommandError = ({ command, error: commandError }) => {
108
119
  }
109
120
 
110
121
  // if the command is a package manager we let it report the error
111
- if (['yarn', 'npm'].includes(command)) {
122
+ if (['yarn', 'npm', 'pnpm'].includes(command)) {
112
123
  return false
113
124
  }
114
125
 
@@ -6,6 +6,10 @@ import Fastify from 'fastify'
6
6
 
7
7
  import { log, NETLIFYDEVLOG } from './command-helpers.mjs'
8
8
 
9
+ /**
10
+ * @param {object} config
11
+ * @param {import('./types.js').ServerSettings} config.settings
12
+ */
9
13
  export const startStaticServer = async ({ settings }) => {
10
14
  const server = Fastify()
11
15
  const rootPath = path.resolve(settings.dist)