netlify-cli 17.24.0 → 17.26.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.
@@ -1 +1 @@
1
- {"version":3,"file":"hash-fns.d.ts","sourceRoot":"","sources":["../../../src/utils/deploy/hash-fns.ts"],"names":[],"mappings":"AAYA,OAAO,WAAW,MAAM,gCAAgC,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAoGlD,QAAA,MAAM,OAAO,YACF,WAAW,eACP,MAAM,EAAE,UACb;IACN,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,QAAQ,CAAA;IACzB,wBAAwB;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,QAAQ,CAAA;IACtB,OAAO,EAAE,QAAQ,CAAA;IACjB,kBAAkB,EAAE,QAAQ,CAAA;IAC5B,QAAQ,EAAE,QAAQ,CAAA;IAClB,MAAM,EAAE,QAAQ,CAAA;CACjB;;;;;;;;;;;;;;;;;;;oBAvFyC,OAAO;;;;;EA4LlD,CAAA;AAED,eAAe,OAAO,CAAA"}
1
+ {"version":3,"file":"hash-fns.d.ts","sourceRoot":"","sources":["../../../src/utils/deploy/hash-fns.ts"],"names":[],"mappings":"AAYA,OAAO,WAAW,MAAM,gCAAgC,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAoGlD,QAAA,MAAM,OAAO,YACF,WAAW,eACP,MAAM,EAAE,UACb;IACN,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,QAAQ,CAAA;IACzB,wBAAwB;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,QAAQ,CAAA;IACtB,OAAO,EAAE,QAAQ,CAAA;IACjB,kBAAkB,EAAE,QAAQ,CAAA;IAC5B,QAAQ,EAAE,QAAQ,CAAA;IAClB,MAAM,EAAE,QAAQ,CAAA;CACjB;;;;;;;;;;;;;;;;;;;oBAvFyC,OAAO;;;;;EA8LlD,CAAA;AAED,eAAe,OAAO,CAAA"}
@@ -95,7 +95,7 @@ const hashFns = async (command, directories, config) => {
95
95
  statusCb,
96
96
  tmpDir,
97
97
  });
98
- const fileObjs = functionZips.map(({ buildData, displayName, generator, invocationMode, path: functionPath, priority, runtime, runtimeVersion, trafficRules, }) => ({
98
+ const fileObjs = functionZips.map(({ buildData, displayName, generator, invocationMode, path: functionPath, priority, runtime, runtimeVersion, trafficRules, timeout, }) => ({
99
99
  filepath: functionPath,
100
100
  root: tmpDir,
101
101
  relname: path.relative(tmpDir, functionPath),
@@ -108,6 +108,7 @@ const hashFns = async (command, directories, config) => {
108
108
  displayName,
109
109
  generator,
110
110
  invocationMode,
111
+ timeout,
111
112
  buildData,
112
113
  priority,
113
114
  trafficRules,
@@ -1 +1 @@
1
- {"version":3,"file":"upload-files.d.ts","sourceRoot":"","sources":["../../../src/utils/deploy/upload-files.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,WAAW;;;;wBAuEhB,CAAA;AAuDD,eAAe,WAAW,CAAA"}
1
+ {"version":3,"file":"upload-files.d.ts","sourceRoot":"","sources":["../../../src/utils/deploy/upload-files.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,WAAW;;;;wBAwEhB,CAAA;AAuDD,eAAe,WAAW,CAAA"}
@@ -14,7 +14,7 @@ const uploadFiles = async (api, deployId, uploadList, { concurrentUpload, maxRet
14
14
  });
15
15
  // @ts-expect-error TS(7006) FIXME: Parameter 'fileObj' implicitly has an 'any' type.
16
16
  const uploadFile = async (fileObj, index) => {
17
- const { assetType, body, filepath, invocationMode, normalizedPath, runtime } = fileObj;
17
+ const { assetType, body, filepath, invocationMode, normalizedPath, runtime, timeout } = fileObj;
18
18
  const readStreamCtor = () => body ?? fs.createReadStream(filepath);
19
19
  statusCb({
20
20
  type: 'upload',
@@ -38,6 +38,7 @@ const uploadFiles = async (api, deployId, uploadList, { concurrentUpload, maxRet
38
38
  body: readStreamCtor,
39
39
  deployId,
40
40
  invocationMode,
41
+ timeout,
41
42
  name: encodeURI(normalizedPath),
42
43
  runtime,
43
44
  };
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/utils/proxy.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAkB/C,OAAO,EAAqB,cAAc,EAAE,MAAM,YAAY,CAAA;AAytB9D,eAAO,MAAM,WAAW,aAAuB,KAAK,cAAc,EAAE,OAAO,GAAG,MAAM,CAAC,WAGpF,CAAA;AAID,eAAO,MAAM,UAAU;aAqBT,WAAW;cAAY,cAAc;0BAAwB,OAAO;2CAoGjF,CAAA"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/utils/proxy.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAkB,MAAM,sBAAsB,CAAA;AAkB/D,OAAO,EAAqB,cAAc,EAAE,MAAM,YAAY,CAAA;AAywB9D,eAAO,MAAM,WAAW,aAAuB,KAAK,cAAc,EAAE,OAAO,GAAG,MAAM,CAAC,WAGpF,CAAA;AAID,eAAO,MAAM,UAAU;aAqBT,WAAW;cAAY,cAAc;0BAAwB,OAAO;2CA2GjF,CAAA"}
@@ -34,8 +34,11 @@ import { generateRequestID } from './request-id.js';
34
34
  import { createRewriter, onChanges } from './rules-proxy.js';
35
35
  import { signRedirect } from './sign-redirect.js';
36
36
  const gunzip = util.promisify(zlib.gunzip);
37
+ const gzip = util.promisify(zlib.gzip);
37
38
  const brotliDecompress = util.promisify(zlib.brotliDecompress);
39
+ const brotliCompress = util.promisify(zlib.brotliCompress);
38
40
  const deflate = util.promisify(zlib.deflate);
41
+ const inflate = util.promisify(zlib.inflate);
39
42
  const shouldGenerateETag = Symbol('Internal: response should generate ETag');
40
43
  const decompressResponseBody = async function (body, contentEncoding = '') {
41
44
  switch (contentEncoding) {
@@ -44,11 +47,40 @@ const decompressResponseBody = async function (body, contentEncoding = '') {
44
47
  case 'br':
45
48
  return await brotliDecompress(body);
46
49
  case 'deflate':
47
- return await deflate(body);
50
+ return await inflate(body);
48
51
  default:
49
52
  return body;
50
53
  }
51
54
  };
55
+ const compressResponseBody = async function (body, contentEncoding = '') {
56
+ switch (contentEncoding) {
57
+ case 'gzip':
58
+ return await gzip(body);
59
+ case 'br':
60
+ return await brotliCompress(body);
61
+ case 'deflate':
62
+ return await deflate(body);
63
+ default:
64
+ return Buffer.from(body, 'utf8');
65
+ }
66
+ };
67
+ const injectHtml = async function (responseBody, proxyRes, htmlInjections) {
68
+ const decompressedBody = await decompressResponseBody(responseBody, proxyRes.headers['content-encoding']);
69
+ const bodyWithInjections = (htmlInjections ?? []).reduce((accum, htmlInjection) => {
70
+ if (!htmlInjection.html || typeof htmlInjection.html !== 'string') {
71
+ return accum;
72
+ }
73
+ const location = htmlInjection.location ?? 'before_closing_head_tag';
74
+ if (location === 'before_closing_head_tag') {
75
+ accum = accum.replace('</head>', `${htmlInjection.html}</head>`);
76
+ }
77
+ else if (location === 'before_closing_body_tag') {
78
+ accum = accum.replace('</body>', `${htmlInjection.html}</body>`);
79
+ }
80
+ return accum;
81
+ }, decompressedBody.toString());
82
+ return await compressResponseBody(bodyWithInjections, proxyRes.headers['content-encoding']);
83
+ };
52
84
  // @ts-expect-error TS(7006) FIXME: Parameter 'errorBuffer' implicitly has an 'any' ty... Remove this comment to see the full error message
53
85
  const formatEdgeFunctionError = (errorBuffer, acceptsHtml) => {
54
86
  const { error: { message, name, stack }, } = JSON.parse(errorBuffer.toString());
@@ -312,25 +344,7 @@ const reqToURL = function (req, pathname) {
312
344
  return new URL(pathname, `${req.protocol || (req.headers.scheme && `${req.headers.scheme}:`) || 'http:'}//${req.headers.host || req.hostname}`);
313
345
  };
314
346
  const MILLISEC_TO_SEC = 1e3;
315
- const initializeProxy = async function ({
316
- // @ts-expect-error TS(7031) FIXME: Binding element 'configPath' implicitly has an 'any... Remove this comment to see the full error message
317
- config,
318
- // @ts-expect-error TS(7031) FIXME: Binding element 'distDir' implicitly has an 'any... Remove this comment to see the full error message
319
- configPath,
320
- // @ts-expect-error TS(7031) FIXME: Binding element 'env' implicitly has an 'any... Remove this comment to see the full error message
321
- distDir,
322
- // @ts-expect-error TS(7031) FIXME: Binding element 'host' implicitly has an 'any... Remove this comment to see the full error message
323
- env,
324
- // @ts-expect-error TS(7031) FIXME: Binding element 'imageProxy' implicitly has an 'any... Remove this comment to see the full error message
325
- host,
326
- // @ts-expect-error TS(7031) FIXME: Binding element 'port' implicitly has an 'any... Remove this comment to see the full error message
327
- imageProxy,
328
- // @ts-expect-error TS(7031) FIXME: Binding element 'projectDir' implicitly has an 'any... Remove this comment to see the full error message
329
- port,
330
- // @ts-expect-error TS(7031) FIXME: Binding element 'siteInfo' implicitly has an 'any... Remove this comment to see the full error message
331
- projectDir,
332
- // @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any... Remove this comment to see the full error message
333
- siteInfo, }) {
347
+ const initializeProxy = async function ({ config, configPath, distDir, env, host, imageProxy, port, projectDir, siteInfo, }) {
334
348
  const proxy = httpProxy.createProxyServer({
335
349
  selfHandleResponse: true,
336
350
  target: {
@@ -445,10 +459,16 @@ siteInfo, }) {
445
459
  // @ts-expect-error TS(2345) FIXME: Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message
446
460
  const requestURL = new URL(req.url, `http://${req.headers.host || '127.0.0.1'}`);
447
461
  const headersRules = headersForPath(headers, requestURL.pathname);
462
+ const htmlInjections = config.dev?.processing?.html?.injections &&
463
+ config.dev.processing.html.injections.length !== 0 &&
464
+ proxyRes.headers?.['content-type']?.startsWith('text/html')
465
+ ? config.dev.processing.html.injections
466
+ : undefined;
448
467
  // for streamed responses, we can't do etag generation nor error templates.
449
468
  // we'll just stream them through!
469
+ // when html_injections are present in dev config, we can't use streamed response
450
470
  const isStreamedResponse = proxyRes.headers['content-length'] === undefined;
451
- if (isStreamedResponse) {
471
+ if (isStreamedResponse && !htmlInjections) {
452
472
  Object.entries(headersRules).forEach(([key, val]) => {
453
473
  // @ts-expect-error TS(2345) FIXME: Argument of type 'unknown' is not assignable to pa... Remove this comment to see the full error message
454
474
  res.setHeader(key, val);
@@ -468,7 +488,7 @@ siteInfo, }) {
468
488
  });
469
489
  proxyRes.on('end', async function onEnd() {
470
490
  // @ts-expect-error TS(7005) FIXME: Variable 'responseData' implicitly has an 'any[]' ... Remove this comment to see the full error message
471
- const responseBody = Buffer.concat(responseData);
491
+ let responseBody = Buffer.concat(responseData);
472
492
  // @ts-expect-error TS(2339) FIXME: Property 'proxyOptions' does not exist on type 'In... Remove this comment to see the full error message
473
493
  let responseStatus = req.proxyOptions.status || proxyRes.statusCode;
474
494
  // `req[shouldGenerateETag]` may contain a function that determines
@@ -502,7 +522,15 @@ siteInfo, }) {
502
522
  res.write(errorResponse);
503
523
  return res.end();
504
524
  }
505
- res.writeHead(responseStatus, proxyRes.headers);
525
+ let proxyResHeaders = proxyRes.headers;
526
+ if (htmlInjections) {
527
+ responseBody = await injectHtml(responseBody, proxyRes, htmlInjections);
528
+ proxyResHeaders = {
529
+ ...proxyResHeaders,
530
+ 'content-length': String(responseBody.byteLength),
531
+ };
532
+ }
533
+ res.writeHead(responseStatus, proxyResHeaders);
506
534
  if (responseStatus !== 304) {
507
535
  res.write(responseBody);
508
536
  }
@@ -520,7 +548,7 @@ siteInfo, }) {
520
548
  return proxy.web(req, res, options);
521
549
  },
522
550
  // @ts-expect-error TS(7006) FIXME: Parameter 'req' implicitly has an 'any' type.
523
- ws: (req, socket, head) => proxy.ws(req, socket, head),
551
+ ws: (req, socket, head, options) => proxy.ws(req, socket, head, options),
524
552
  };
525
553
  return handlers;
526
554
  };
@@ -661,8 +689,15 @@ export const startProxy = async function ({ accountId, addonsUrls, blobsContext,
661
689
  const primaryServer = settings.https
662
690
  ? https.createServer({ cert: settings.https.cert, key: settings.https.key }, onRequestWithOptions)
663
691
  : http.createServer(onRequestWithOptions);
664
- const onUpgrade = function onUpgrade(req, socket, head) {
665
- proxy.ws(req, socket, head);
692
+ const onUpgrade = async function onUpgrade(req, socket, head) {
693
+ const match = await rewriter(req);
694
+ if (match && !match.force404 && isExternal(match)) {
695
+ const reqUrl = reqToURL(req, req.url);
696
+ const dest = new URL(match.to, `${reqUrl.protocol}//${reqUrl.host}`);
697
+ const destURL = stripOrigin(dest);
698
+ return proxy.ws(req, socket, head, { target: dest.origin, changeOrigin: true, pathRewrite: () => destURL });
699
+ }
700
+ return proxy.ws(req, socket, head, {});
666
701
  };
667
702
  primaryServer.on('upgrade', onUpgrade);
668
703
  primaryServer.listen({ port: settings.port });