@netlify/plugin-nextjs 5.4.0-canary-perf-debug.0 → 5.5.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.
@@ -51,11 +51,6 @@ var omitHeaderValues = (header, values) => {
51
51
  );
52
52
  return filteredValues.join(", ");
53
53
  };
54
- var mapHeaderValues = (header, callback) => {
55
- const headerValues = getHeaderValueArray(header);
56
- const mappedValues = headerValues.map(callback);
57
- return mappedValues.join(", ");
58
- };
59
54
  var setVaryHeaders = (headers, request, { basePath, i18n }) => {
60
55
  const netlifyVaryValues = {
61
56
  header: ["x-nextjs-data", "x-next-debug-logging"],
@@ -147,11 +142,12 @@ var adjustDateHeader = async ({
147
142
  headers.set("x-nextjs-date", headers.get("date") ?? lastModifiedDate.toUTCString());
148
143
  headers.set("date", lastModifiedDate.toUTCString());
149
144
  };
150
- var setCacheControlHeaders = (headers, request, requestContext) => {
145
+ var setCacheControlHeaders = (headers, request, requestContext, useDurableCache) => {
146
+ const durableCacheDirective = useDurableCache ? ", durable" : "";
151
147
  if (typeof requestContext.routeHandlerRevalidate !== "undefined" && ["GET", "HEAD"].includes(request.method) && !headers.has("cdn-cache-control") && !headers.has("netlify-cdn-cache-control")) {
152
148
  const cdnCacheControl = (
153
149
  // if we are serving already stale response, instruct edge to not attempt to cache that response
154
- headers.get("x-nextjs-cache") === "STALE" ? "public, max-age=0, must-revalidate" : `s-maxage=${requestContext.routeHandlerRevalidate === false ? 31536e3 : requestContext.routeHandlerRevalidate}, stale-while-revalidate=31536000`
150
+ headers.get("x-nextjs-cache") === "STALE" ? "public, max-age=0, must-revalidate" : `s-maxage=${requestContext.routeHandlerRevalidate === false ? 31536e3 : requestContext.routeHandlerRevalidate}, stale-while-revalidate=31536000${durableCacheDirective}`
155
151
  );
156
152
  headers.set("netlify-cdn-cache-control", cdnCacheControl);
157
153
  return;
@@ -164,10 +160,12 @@ var setCacheControlHeaders = (headers, request, requestContext) => {
164
160
  ]);
165
161
  const cdnCacheControl = (
166
162
  // if we are serving already stale response, instruct edge to not attempt to cache that response
167
- headers.get("x-nextjs-cache") === "STALE" ? "public, max-age=0, must-revalidate" : mapHeaderValues(
168
- cacheControl,
169
- (value) => value === "stale-while-revalidate" ? "stale-while-revalidate=31536000" : value
170
- )
163
+ headers.get("x-nextjs-cache") === "STALE" ? "public, max-age=0, must-revalidate" : [
164
+ ...getHeaderValueArray(cacheControl).map(
165
+ (value) => value === "stale-while-revalidate" ? "stale-while-revalidate=31536000" : value
166
+ ),
167
+ ...useDurableCache ? ["durable"] : []
168
+ ].join(", ")
171
169
  );
172
170
  headers.set("cache-control", browserCacheControl || "public, max-age=0, must-revalidate");
173
171
  headers.set("netlify-cdn-cache-control", cdnCacheControl);
@@ -175,17 +173,12 @@ var setCacheControlHeaders = (headers, request, requestContext) => {
175
173
  }
176
174
  if (cacheControl === null && !headers.has("cdn-cache-control") && !headers.has("netlify-cdn-cache-control") && requestContext.usedFsRead) {
177
175
  headers.set("cache-control", "public, max-age=0, must-revalidate");
178
- headers.set("netlify-cdn-cache-control", `max-age=31536000`);
176
+ headers.set("netlify-cdn-cache-control", `max-age=31536000${durableCacheDirective}`);
179
177
  }
180
178
  };
181
- function getCanonicalPathFromCacheKey(cacheKey) {
182
- return cacheKey === "/index" ? "/" : cacheKey;
183
- }
184
- var setCacheTagsHeaders = (headers, request, manifest, requestContext) => {
185
- const path = getCanonicalPathFromCacheKey(requestContext.responseCacheKey) ?? new URL(request.url).pathname;
186
- const tags = manifest[path];
187
- if (tags !== void 0) {
188
- headers.set("netlify-cache-tag", tags);
179
+ var setCacheTagsHeaders = (headers, requestContext) => {
180
+ if (requestContext.responseCacheTags) {
181
+ headers.set("netlify-cache-tag", requestContext.responseCacheTags.join(","));
189
182
  }
190
183
  };
191
184
  var NEXT_CACHE_TO_CACHE_STATUS = {
package/dist/run/next.cjs CHANGED
@@ -553,9 +553,7 @@ async function getMockedRequestHandlers(...args) {
553
553
  if (typeof path === "string" && path.endsWith(".html")) {
554
554
  const store = (0, import_regional_blob_store.getRegionalBlobStore)();
555
555
  const relPath = (0, import_path.relative)((0, import_path.resolve)(".next/server/pages"), path);
556
- const file = await (0, import_tracer.getTracer)().withActiveSpan(`blob readFile ${relPath}`, async () => {
557
- return await store.get(await encodeBlobKey(relPath));
558
- });
556
+ const file = await store.get(await encodeBlobKey(relPath));
559
557
  if (file !== null) {
560
558
  const requestContext = (0, import_request_context.getRequestContext)();
561
559
  if (requestContext) {
@@ -7,15 +7,22 @@
7
7
  import "../esm-chunks/chunk-OEQOKJGE.js";
8
8
 
9
9
  // src/run/revalidate.ts
10
+ import { isPromise } from "node:util/types";
11
+ function isRevalidateMethod(key, nextResponseField) {
12
+ return key === "revalidate" && typeof nextResponseField === "function";
13
+ }
10
14
  var nextResponseProxy = (res, requestContext) => {
11
15
  return new Proxy(res, {
12
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
16
  get(target, key) {
14
- const originalValue = target[key];
15
- if (key === "revalidate") {
16
- return async function newRevalidate(...args) {
17
+ const originalValue = Reflect.get(target, key);
18
+ if (isRevalidateMethod(key, originalValue)) {
19
+ return function newRevalidate(...args) {
17
20
  requestContext.didPagesRouterOnDemandRevalidate = true;
18
- return originalValue?.apply(target, args);
21
+ const result = originalValue.apply(target, args);
22
+ if (result && isPromise(result)) {
23
+ requestContext.trackBackgroundWork(result);
24
+ }
25
+ return result;
19
26
  };
20
27
  }
21
28
  return originalValue;
@@ -1,6 +1,12 @@
1
1
  import type { Context } from '@netlify/edge-functions'
2
2
 
3
- import { normalizeDataUrl, removeBasePath, normalizeLocalePath, addBasePath } from './util.ts'
3
+ import {
4
+ addBasePath,
5
+ addTrailingSlash,
6
+ normalizeDataUrl,
7
+ normalizeLocalePath,
8
+ removeBasePath,
9
+ } from './util.ts'
4
10
 
5
11
  interface I18NConfig {
6
12
  defaultLocale: string
@@ -41,38 +47,25 @@ const normalizeRequestURL = (
41
47
  ): { url: string; detectedLocale?: string } => {
42
48
  const url = new URL(originalURL)
43
49
 
44
- url.pathname = removeBasePath(url.pathname, nextConfig?.basePath)
45
- const didRemoveBasePath = url.toString() !== originalURL
50
+ let pathname = removeBasePath(url.pathname, nextConfig?.basePath)
46
51
 
47
- let detectedLocale: string | undefined
48
-
49
- if (nextConfig?.i18n) {
50
- const { pathname, detectedLocale: detected } = normalizeLocalePath(
51
- url.pathname,
52
- nextConfig?.i18n?.locales,
53
- )
54
- if (!nextConfig?.skipMiddlewareUrlNormalize) {
55
- url.pathname = pathname || '/'
56
- }
57
- detectedLocale = detected
58
- }
52
+ // If it exists, remove the locale from the URL and store it
53
+ const { detectedLocale } = normalizeLocalePath(pathname, nextConfig?.i18n?.locales)
59
54
 
60
55
  if (!nextConfig?.skipMiddlewareUrlNormalize) {
61
56
  // We want to run middleware for data requests and expose the URL of the
62
57
  // corresponding pages, so we have to normalize the URLs before running
63
58
  // the handler.
64
- url.pathname = normalizeDataUrl(url.pathname)
59
+ pathname = normalizeDataUrl(pathname)
65
60
 
66
61
  // Normalizing the trailing slash based on the `trailingSlash` configuration
67
62
  // property from the Next.js config.
68
- if (nextConfig?.trailingSlash && url.pathname !== '/' && !url.pathname.endsWith('/')) {
69
- url.pathname = `${url.pathname}/`
63
+ if (nextConfig?.trailingSlash) {
64
+ pathname = addTrailingSlash(pathname)
70
65
  }
71
66
  }
72
67
 
73
- if (didRemoveBasePath) {
74
- url.pathname = addBasePath(url.pathname, nextConfig?.basePath)
75
- }
68
+ url.pathname = addBasePath(pathname, nextConfig?.basePath)
76
69
 
77
70
  return {
78
71
  url: url.toString(),
@@ -88,9 +81,9 @@ export const buildNextRequest = (
88
81
  const { url, method, body, headers } = request
89
82
  const { country, subdivision, city, latitude, longitude, timezone } = context.geo
90
83
  const geo: RequestData['geo'] = {
84
+ city,
91
85
  country: country?.code,
92
86
  region: subdivision?.code,
93
- city,
94
87
  latitude: latitude?.toString(),
95
88
  longitude: longitude?.toString(),
96
89
  timezone,
@@ -10,7 +10,7 @@ import type { Key } from '../vendor/deno.land/x/path_to_regexp@v6.2.1/index.ts'
10
10
  import { compile, pathToRegexp } from '../vendor/deno.land/x/path_to_regexp@v6.2.1/index.ts'
11
11
  import { getCookies } from '../vendor/deno.land/std@0.175.0/http/cookie.ts'
12
12
 
13
- /*
13
+ /*
14
14
  ┌─────────────────────────────────────────────────────────────────────────┐
15
15
  │ Inlined/re-implemented types │
16
16
  └─────────────────────────────────────────────────────────────────────────┘
@@ -86,7 +86,7 @@ export type RoutesManifest = {
86
86
  dynamicRoutes: DynamicRoute[]
87
87
  }
88
88
 
89
- /*
89
+ /*
90
90
  ┌─────────────────────────────────────────────────────────────────────────┐
91
91
  │ packages/next/src/shared/lib/escape-regexp.ts │
92
92
  └─────────────────────────────────────────────────────────────────────────┘
@@ -104,7 +104,7 @@ export function escapeStringRegexp(str: string) {
104
104
  return str
105
105
  }
106
106
 
107
- /*
107
+ /*
108
108
  ┌─────────────────────────────────────────────────────────────────────────┐
109
109
  │ packages/next/src/shared/lib/router/utils/querystring.ts │
110
110
  └─────────────────────────────────────────────────────────────────────────┘
@@ -125,7 +125,7 @@ export function searchParamsToUrlQuery(searchParams: URLSearchParams): ParsedUrl
125
125
  return query
126
126
  }
127
127
 
128
- /*
128
+ /*
129
129
  ┌─────────────────────────────────────────────────────────────────────────┐
130
130
  │ packages/next/src/shared/lib/router/utils/parse-url.ts │
131
131
  └─────────────────────────────────────────────────────────────────────────┘
@@ -156,7 +156,7 @@ export function parseUrl(url: string): ParsedUrl {
156
156
  }
157
157
  }
158
158
 
159
- /*
159
+ /*
160
160
  ┌─────────────────────────────────────────────────────────────────────────┐
161
161
  │ packages/next/src/shared/lib/router/utils/prepare-destination.ts │
162
162
  │ — Changed to use WHATWG Fetch `Request` instead of │
@@ -392,7 +392,7 @@ function unescapeSegments(str: string) {
392
392
  return str.replace(/__ESC_COLON_/gi, ':')
393
393
  }
394
394
 
395
- /*
395
+ /*
396
396
  ┌─────────────────────────────────────────────────────────────────────────┐
397
397
  │ packages/next/src/shared/lib/router/utils/is-dynamic.ts │
398
398
  └─────────────────────────────────────────────────────────────────────────┘
@@ -404,7 +404,7 @@ export function isDynamicRoute(route: string): boolean {
404
404
  return TEST_ROUTE.test(route)
405
405
  }
406
406
 
407
- /*
407
+ /*
408
408
  ┌─────────────────────────────────────────────────────────────────────────┐
409
409
  │ packages/next/shared/lib/router/utils/middleware-route-matcher.ts │
410
410
  └─────────────────────────────────────────────────────────────────────────┘
@@ -1,5 +1,3 @@
1
- import type { RequestData } from './next-request.ts'
2
-
3
1
  /**
4
2
  * Normalize a data URL into a route path.
5
3
  * @see https://github.com/vercel/next.js/blob/25e0988e7c9033cb1503cbe0c62ba5de2e97849c/packages/next/src/shared/lib/router/utils/get-next-pathname-info.ts#L69-L76
@@ -1,17 +1,16 @@
1
1
  import type { Context } from '@netlify/edge-functions'
2
2
 
3
- import matchers from './matchers.json' assert { type: 'json' }
4
- import nextConfig from './next.config.json' assert { type: 'json' }
3
+ import matchers from './matchers.json' with { type: 'json' }
4
+ import nextConfig from './next.config.json' with { type: 'json' }
5
5
 
6
6
  import { InternalHeaders } from './lib/headers.ts'
7
7
  import { logger, LogLevel } from './lib/logging.ts'
8
8
  import { buildNextRequest, RequestData } from './lib/next-request.ts'
9
- import { buildResponse } from './lib/response.ts'
10
- import { FetchEventResult } from './lib/response.ts'
9
+ import { buildResponse, FetchEventResult } from './lib/response.ts'
11
10
  import {
12
- type MiddlewareRouteMatch,
13
11
  getMiddlewareRouteMatcher,
14
12
  searchParamsToUrlQuery,
13
+ type MiddlewareRouteMatch,
15
14
  } from './lib/routing.ts'
16
15
 
17
16
  type NextHandler = (params: { request: RequestData }) => Promise<FetchEventResult>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/plugin-nextjs",
3
- "version": "5.4.0-canary-perf-debug.0",
3
+ "version": "5.5.0",
4
4
  "description": "Run Next.js seamlessly on Netlify",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "repository": {
16
16
  "type": "git",
17
- "url": "git+https://github.com/netlify/next-runtime-minimal.git"
17
+ "url": "git+https://github.com/netlify/next-runtime.git"
18
18
  },
19
19
  "keywords": [
20
20
  "nextjs",
@@ -24,7 +24,7 @@
24
24
  ],
25
25
  "license": "MIT",
26
26
  "bugs": {
27
- "url": "https://github.com/netlify/next-runtime-minimal/issues"
27
+ "url": "https://github.com/netlify/next-runtime/issues"
28
28
  },
29
- "homepage": "https://github.com/netlify/next-runtime-minimal#readme"
29
+ "homepage": "https://github.com/netlify/next-runtime#readme"
30
30
  }
@@ -1,53 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/run/handlers/import-time-debug.cts
21
- var import_time_debug_exports = {};
22
- __export(import_time_debug_exports, {
23
- enableModuleImportTracing: () => enableModuleImportTracing
24
- });
25
- module.exports = __toCommonJS(import_time_debug_exports);
26
- var import_path = require("path");
27
- var import_tracer = require("./tracer.cjs");
28
- function enableModuleImportTracing() {
29
- const cwd = process.cwd();
30
- const extension = ".js";
31
- const original = require.extensions[extension];
32
- if (!original) {
33
- return;
34
- }
35
- require.extensions[extension] = function patchedExtensions(module2, filename) {
36
- const startTime = Date.now();
37
- const ret = original(module2, filename);
38
- const durationMS = Date.now() - startTime;
39
- if (durationMS > 50) {
40
- (0, import_tracer.getTracer)().withActiveSpan(
41
- `module import ${(0, import_path.relative)(cwd, module2.filename)}`,
42
- { startTime },
43
- () => {
44
- }
45
- );
46
- }
47
- return ret;
48
- };
49
- }
50
- // Annotate the CommonJS export names for ESM import in node:
51
- 0 && (module.exports = {
52
- enableModuleImportTracing
53
- });
@@ -1,98 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/run/systemlog.cts
21
- var systemlog_exports = {};
22
- __export(systemlog_exports, {
23
- LogLevel: () => LogLevel,
24
- logger: () => systemLogger
25
- });
26
- module.exports = __toCommonJS(systemlog_exports);
27
-
28
- // node_modules/@netlify/functions/dist/chunk-HYMERDCV.mjs
29
- var import_process = require("process");
30
- var systemLogTag = "__nfSystemLog";
31
- var serializeError = (error) => {
32
- const cause = error?.cause instanceof Error ? serializeError(error.cause) : error.cause;
33
- return {
34
- error: error.message,
35
- error_cause: cause,
36
- error_stack: error.stack
37
- };
38
- };
39
- var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
40
- LogLevel2[LogLevel2["Debug"] = 1] = "Debug";
41
- LogLevel2[LogLevel2["Log"] = 2] = "Log";
42
- LogLevel2[LogLevel2["Error"] = 3] = "Error";
43
- return LogLevel2;
44
- })(LogLevel || {});
45
- var SystemLogger = class _SystemLogger {
46
- fields;
47
- logLevel;
48
- constructor(fields = {}, logLevel = 2) {
49
- this.fields = fields;
50
- this.logLevel = logLevel;
51
- }
52
- doLog(logger, message) {
53
- if (import_process.env.NETLIFY_DEV && !import_process.env.NETLIFY_ENABLE_SYSTEM_LOGGING) {
54
- return;
55
- }
56
- logger(systemLogTag, JSON.stringify({ msg: message, fields: this.fields }));
57
- }
58
- log(message) {
59
- if (this.logLevel > 2) {
60
- return;
61
- }
62
- this.doLog(console.log, message);
63
- }
64
- debug(message) {
65
- if (this.logLevel > 1) {
66
- return;
67
- }
68
- this.doLog(console.debug, message);
69
- }
70
- error(message) {
71
- if (this.logLevel > 3) {
72
- return;
73
- }
74
- this.doLog(console.error, message);
75
- }
76
- withLogLevel(level) {
77
- return new _SystemLogger(this.fields, level);
78
- }
79
- withFields(fields) {
80
- return new _SystemLogger(
81
- {
82
- ...this.fields,
83
- ...fields
84
- },
85
- this.logLevel
86
- );
87
- }
88
- withError(error) {
89
- const fields = error instanceof Error ? serializeError(error) : { error };
90
- return this.withFields(fields);
91
- }
92
- };
93
- var systemLogger = new SystemLogger();
94
- // Annotate the CommonJS export names for ESM import in node:
95
- 0 && (module.exports = {
96
- LogLevel,
97
- logger
98
- });