netlify-cli 12.8.0 → 12.9.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/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.9.1",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "netlify-cli",
|
|
9
|
-
"version": "12.
|
|
9
|
+
"version": "12.9.1",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"netlify-headers-parser": "^7.1.1",
|
|
83
83
|
"netlify-onegraph-internal": "0.10.1",
|
|
84
84
|
"netlify-redirect-parser": "^14.1.1",
|
|
85
|
-
"netlify-redirector": "^0.
|
|
85
|
+
"netlify-redirector": "^0.4.0",
|
|
86
86
|
"node-fetch": "^2.6.0",
|
|
87
87
|
"node-version-alias": "^1.0.1",
|
|
88
88
|
"ora": "^5.0.0",
|
|
@@ -17610,9 +17610,9 @@
|
|
|
17610
17610
|
}
|
|
17611
17611
|
},
|
|
17612
17612
|
"node_modules/netlify-redirector": {
|
|
17613
|
-
"version": "0.
|
|
17614
|
-
"resolved": "https://registry.npmjs.org/netlify-redirector/-/netlify-redirector-0.
|
|
17615
|
-
"integrity": "sha512
|
|
17613
|
+
"version": "0.4.0",
|
|
17614
|
+
"resolved": "https://registry.npmjs.org/netlify-redirector/-/netlify-redirector-0.4.0.tgz",
|
|
17615
|
+
"integrity": "sha512-ssD+V9o2DD9VnilOYC+34i07IrlY8XDsh5mN+qLYA4MxCpdALKXFICcz1KzsHZabuIS5XsF1VP/HzDyx5ubJ2g=="
|
|
17616
17616
|
},
|
|
17617
17617
|
"node_modules/netlify/node_modules/node-fetch": {
|
|
17618
17618
|
"version": "3.3.0",
|
|
@@ -37423,9 +37423,9 @@
|
|
|
37423
37423
|
}
|
|
37424
37424
|
},
|
|
37425
37425
|
"netlify-redirector": {
|
|
37426
|
-
"version": "0.
|
|
37427
|
-
"resolved": "https://registry.npmjs.org/netlify-redirector/-/netlify-redirector-0.
|
|
37428
|
-
"integrity": "sha512
|
|
37426
|
+
"version": "0.4.0",
|
|
37427
|
+
"resolved": "https://registry.npmjs.org/netlify-redirector/-/netlify-redirector-0.4.0.tgz",
|
|
37428
|
+
"integrity": "sha512-ssD+V9o2DD9VnilOYC+34i07IrlY8XDsh5mN+qLYA4MxCpdALKXFICcz1KzsHZabuIS5XsF1VP/HzDyx5ubJ2g=="
|
|
37429
37429
|
},
|
|
37430
37430
|
"next-tick": {
|
|
37431
37431
|
"version": "1.1.0",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
3
|
"description": "Netlify command line tool",
|
|
4
|
-
"version": "12.
|
|
4
|
+
"version": "12.9.1",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
"netlify-headers-parser": "^7.1.1",
|
|
148
148
|
"netlify-onegraph-internal": "0.10.1",
|
|
149
149
|
"netlify-redirect-parser": "^14.1.1",
|
|
150
|
-
"netlify-redirector": "^0.
|
|
150
|
+
"netlify-redirector": "^0.4.0",
|
|
151
151
|
"node-fetch": "^2.6.0",
|
|
152
152
|
"node-version-alias": "^1.0.1",
|
|
153
153
|
"ora": "^5.0.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { Buffer } from 'buffer'
|
|
3
3
|
|
|
4
|
-
import { NETLIFYDEVERR } from '../../utils/command-helpers.mjs'
|
|
4
|
+
import { chalk, log, NETLIFYDEVERR } from '../../utils/command-helpers.mjs'
|
|
5
5
|
import renderErrorTemplate from '../render-error-template.mjs'
|
|
6
6
|
|
|
7
7
|
import { detectAwsSdkError } from './utils.mjs'
|
|
@@ -16,20 +16,35 @@ const addHeaders = (headers, response) => {
|
|
|
16
16
|
})
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export const handleSynchronousFunction = function (
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
export const handleSynchronousFunction = function ({
|
|
20
|
+
error: invocationError,
|
|
21
|
+
functionName,
|
|
22
|
+
request,
|
|
23
|
+
response,
|
|
24
|
+
result,
|
|
25
|
+
}) {
|
|
26
|
+
if (invocationError) {
|
|
27
|
+
return handleErr(invocationError, request, response)
|
|
22
28
|
}
|
|
23
29
|
|
|
24
30
|
const { error } = validateLambdaResponse(result)
|
|
25
31
|
if (error) {
|
|
26
|
-
|
|
32
|
+
log(`${NETLIFYDEVERR} ${error}`)
|
|
27
33
|
return handleErr(error, request, response)
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
response.statusCode = result.statusCode
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
addHeaders(result.headers, response)
|
|
40
|
+
addHeaders(result.multiValueHeaders, response)
|
|
41
|
+
} catch (headersError) {
|
|
42
|
+
formatError(headersError)
|
|
43
|
+
|
|
44
|
+
log(`${NETLIFYDEVERR} Failed to set header in function ${chalk.yellow(functionName)}: ${headersError.message}`)
|
|
45
|
+
|
|
46
|
+
return handleErr(headersError, request, response)
|
|
47
|
+
}
|
|
33
48
|
|
|
34
49
|
if (result.body) {
|
|
35
50
|
response.write(result.isBase64Encoded ? Buffer.from(result.body, 'base64') : result.body)
|
|
@@ -37,6 +52,12 @@ export const handleSynchronousFunction = function (err, result, request, respons
|
|
|
37
52
|
response.end()
|
|
38
53
|
}
|
|
39
54
|
|
|
55
|
+
const formatError = (err) => {
|
|
56
|
+
err.errorType = err.code
|
|
57
|
+
err.errorMessage = err.message
|
|
58
|
+
err.stackTrace = err.trace
|
|
59
|
+
}
|
|
60
|
+
|
|
40
61
|
const formatLambdaLocalError = (err, acceptsHtml) =>
|
|
41
62
|
acceptsHtml
|
|
42
63
|
? JSON.stringify({
|
package/src/utils/proxy.mjs
CHANGED
|
@@ -29,10 +29,11 @@ import {
|
|
|
29
29
|
import { fileExistsAsync, isFileAsync } from '../lib/fs.mjs'
|
|
30
30
|
import renderErrorTemplate from '../lib/render-error-template.mjs'
|
|
31
31
|
|
|
32
|
-
import { NETLIFYDEVLOG, NETLIFYDEVWARN } from './command-helpers.mjs'
|
|
32
|
+
import { NETLIFYDEVLOG, NETLIFYDEVWARN, log, chalk } from './command-helpers.mjs'
|
|
33
33
|
import createStreamPromise from './create-stream-promise.mjs'
|
|
34
34
|
import { headersForPath, parseHeaders } from './headers.mjs'
|
|
35
35
|
import { createRewriter, onChanges } from './rules-proxy.mjs'
|
|
36
|
+
import { signRedirect } from './sign-redirect.mjs'
|
|
36
37
|
|
|
37
38
|
const decompress = util.promisify(zlib.gunzip)
|
|
38
39
|
const shouldGenerateETag = Symbol('Internal: response should generate ETag')
|
|
@@ -143,7 +144,7 @@ const alternativePathsFor = function (url) {
|
|
|
143
144
|
return paths
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
const serveRedirect = async function ({ match, options, proxy, req, res }) {
|
|
147
|
+
const serveRedirect = async function ({ env, match, options, proxy, req, res, siteInfo }) {
|
|
147
148
|
if (!match) return proxy.web(req, res, options)
|
|
148
149
|
|
|
149
150
|
options = options || req.proxyOptions || {}
|
|
@@ -155,6 +156,24 @@ const serveRedirect = async function ({ match, options, proxy, req, res }) {
|
|
|
155
156
|
})
|
|
156
157
|
}
|
|
157
158
|
|
|
159
|
+
if (match.signingSecret) {
|
|
160
|
+
const signingSecretVar = env[match.signingSecret]
|
|
161
|
+
|
|
162
|
+
if (signingSecretVar) {
|
|
163
|
+
req.headers['x-nf-sign'] = signRedirect({
|
|
164
|
+
deployContext: 'dev',
|
|
165
|
+
secret: signingSecretVar.value,
|
|
166
|
+
siteID: siteInfo.id,
|
|
167
|
+
siteURL: siteInfo.url,
|
|
168
|
+
})
|
|
169
|
+
} else {
|
|
170
|
+
log(
|
|
171
|
+
NETLIFYDEVWARN,
|
|
172
|
+
`Could not sign redirect because environment variable ${chalk.yellow(match.signingSecret)} is not set`,
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
158
177
|
if (isFunction(options.functionsPort, req.url)) {
|
|
159
178
|
return proxy.web(req, res, { target: options.functionsServer })
|
|
160
179
|
}
|
|
@@ -306,7 +325,7 @@ const reqToURL = function (req, pathname) {
|
|
|
306
325
|
|
|
307
326
|
const MILLISEC_TO_SEC = 1e3
|
|
308
327
|
|
|
309
|
-
const initializeProxy = async function ({ configPath, distDir, host, port, projectDir }) {
|
|
328
|
+
const initializeProxy = async function ({ configPath, distDir, env, host, port, projectDir, siteInfo }) {
|
|
310
329
|
const proxy = httpProxy.createProxyServer({
|
|
311
330
|
selfHandleResponse: true,
|
|
312
331
|
target: {
|
|
@@ -370,13 +389,21 @@ const initializeProxy = async function ({ configPath, distDir, host, port, proje
|
|
|
370
389
|
return proxy.web(req, res, req.proxyOptions)
|
|
371
390
|
}
|
|
372
391
|
if (req.proxyOptions && req.proxyOptions.match) {
|
|
373
|
-
return serveRedirect({
|
|
392
|
+
return serveRedirect({
|
|
393
|
+
req,
|
|
394
|
+
res,
|
|
395
|
+
proxy: handlers,
|
|
396
|
+
match: req.proxyOptions.match,
|
|
397
|
+
options: req.proxyOptions,
|
|
398
|
+
siteInfo,
|
|
399
|
+
env,
|
|
400
|
+
})
|
|
374
401
|
}
|
|
375
402
|
}
|
|
376
403
|
|
|
377
404
|
if (req.proxyOptions.staticFile && isRedirect({ status: proxyRes.statusCode }) && proxyRes.headers.location) {
|
|
378
405
|
req.url = proxyRes.headers.location
|
|
379
|
-
return serveRedirect({ req, res, proxy: handlers, match: null, options: req.proxyOptions })
|
|
406
|
+
return serveRedirect({ req, res, proxy: handlers, match: null, options: req.proxyOptions, siteInfo, env })
|
|
380
407
|
}
|
|
381
408
|
|
|
382
409
|
const responseData = []
|
|
@@ -472,7 +499,11 @@ const initializeProxy = async function ({ configPath, distDir, host, port, proje
|
|
|
472
499
|
return handlers
|
|
473
500
|
}
|
|
474
501
|
|
|
475
|
-
const onRequest = async (
|
|
502
|
+
const onRequest = async (
|
|
503
|
+
{ addonsUrls, edgeFunctionsProxy, env, functionsServer, proxy, rewriter, settings, siteInfo },
|
|
504
|
+
req,
|
|
505
|
+
res,
|
|
506
|
+
) => {
|
|
476
507
|
req.originalBody = ['GET', 'OPTIONS', 'HEAD'].includes(req.method)
|
|
477
508
|
? null
|
|
478
509
|
: await createStreamPromise(req, BYTES_LIMIT)
|
|
@@ -509,7 +540,7 @@ const onRequest = async ({ addonsUrls, edgeFunctionsProxy, functionsServer, prox
|
|
|
509
540
|
// We don't want to generate an ETag for 3xx redirects.
|
|
510
541
|
req[shouldGenerateETag] = ({ statusCode }) => statusCode < 300 || statusCode >= 400
|
|
511
542
|
|
|
512
|
-
return serveRedirect({ req, res, proxy, match, options })
|
|
543
|
+
return serveRedirect({ req, res, proxy, match, options, siteInfo, env })
|
|
513
544
|
}
|
|
514
545
|
|
|
515
546
|
// The request will be served by the framework server, which means we want to
|
|
@@ -565,11 +596,13 @@ export const startProxy = async function ({
|
|
|
565
596
|
state,
|
|
566
597
|
})
|
|
567
598
|
const proxy = await initializeProxy({
|
|
599
|
+
env,
|
|
568
600
|
host: settings.frameworkHost,
|
|
569
601
|
port: settings.frameworkPort,
|
|
570
602
|
distDir: settings.dist,
|
|
571
603
|
projectDir,
|
|
572
604
|
configPath,
|
|
605
|
+
siteInfo,
|
|
573
606
|
})
|
|
574
607
|
|
|
575
608
|
const rewriter = await createRewriter({
|
|
@@ -588,6 +621,8 @@ export const startProxy = async function ({
|
|
|
588
621
|
addonsUrls,
|
|
589
622
|
functionsServer,
|
|
590
623
|
edgeFunctionsProxy,
|
|
624
|
+
siteInfo,
|
|
625
|
+
env,
|
|
591
626
|
})
|
|
592
627
|
const primaryServer = settings.https
|
|
593
628
|
? https.createServer({ cert: settings.https.cert, key: settings.https.key }, onRequestWithOptions)
|
package/src/utils/redirects.mjs
CHANGED
|
@@ -36,6 +36,7 @@ const normalizeRedirect = function ({
|
|
|
36
36
|
conditions: { country, language, role, ...conditions },
|
|
37
37
|
from,
|
|
38
38
|
query,
|
|
39
|
+
signed,
|
|
39
40
|
...redirect
|
|
40
41
|
}) {
|
|
41
42
|
return {
|
|
@@ -48,5 +49,10 @@ const normalizeRedirect = function ({
|
|
|
48
49
|
...(country && { Country: country }),
|
|
49
50
|
...(language && { Language: language }),
|
|
50
51
|
},
|
|
52
|
+
...(signed && {
|
|
53
|
+
sign: {
|
|
54
|
+
jwt_secret: signed,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
51
57
|
}
|
|
52
58
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import jwt from 'jsonwebtoken'
|
|
2
|
+
|
|
3
|
+
// https://docs.netlify.com/routing/redirects/rewrites-proxies/#signed-proxy-redirects
|
|
4
|
+
export const signRedirect = ({ deployContext, secret, siteID, siteURL }) => {
|
|
5
|
+
const claims = {
|
|
6
|
+
deploy_context: deployContext,
|
|
7
|
+
netlify_id: siteID,
|
|
8
|
+
site_url: siteURL,
|
|
9
|
+
}
|
|
10
|
+
const options = {
|
|
11
|
+
expiresIn: '5 minutes',
|
|
12
|
+
issuer: 'netlify',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return jwt.sign(claims, secret, options)
|
|
16
|
+
}
|