@netlify/plugin-nextjs 5.3.2 → 5.3.3

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
- ![Next.js Runtime](https://github.com/netlify/next-runtime/raw/main/next-js-runtime.png)
1
+ ![Next.js Runtime](next-js-runtime.png)
2
2
 
3
- # `@netlify/plugin-nextjs`
3
+ # Next.js Runtime
4
4
 
5
5
  <p align="center">
6
6
  <a aria-label="npm version" href="https://www.npmjs.com/package/@netlify/plugin-nextjs">
@@ -16,3 +16,63 @@ Netlify. You should not normally need to install it yourself, as it is used auto
16
16
  builds of Next.js sites. See
17
17
  [the docs for using Next.js on Netlify](https://docs.netlify.com/frameworks/next-js/overview/) for
18
18
  more details.
19
+
20
+ Next.js is supported natively on Netlify, and in most cases you will not need to install or
21
+ configure anything. This repo includes the packages used to support Next.js on Netlify.
22
+
23
+ ## Prerequisites
24
+
25
+ - Next.js 13.5 or later
26
+ - Node.js 18 or later
27
+ - The latest version of the [Netlify CLI](https://docs.netlify.com/cli/get-started/)
28
+
29
+ ## Deploying
30
+
31
+ If you build on Netlify, the Next.js Runtime will work with no additional configuration.
32
+
33
+ ## Manually installing the Next.js Runtime
34
+
35
+ The Next.js Runtime installs automatically for new Next.js sites on Netlify. You can also install it
36
+ manually in the following ways:
37
+
38
+ ### From the UI (Recommended)
39
+
40
+ You can go to the [UI](https://app.netlify.com/plugins/@netlify/plugin-nextjs/install) and choose
41
+ the site to install the Next.js Runtime on. This method is recommended because you will benefit from
42
+ auto-upgrades to important fixes and feature updates.
43
+
44
+ ### From `npm`
45
+
46
+ ```shell
47
+ npm install -D @netlify/plugin-nextjs
48
+ ```
49
+
50
+ ...then add the following to your `netlify.toml` file:
51
+
52
+ ```toml
53
+ [[plugins]]
54
+ package = "@netlify/plugin-nextjs"
55
+ ```
56
+
57
+ This method is recommended if you wish to pin the Next.js Runtime to a specific version.
58
+
59
+ ## v4
60
+
61
+ If you are using Next.js 10-13.4 or Node.js < 18, you must use v4 of the Next.js Runtime.
62
+
63
+ If you are still using v4, you can find
64
+ [its README here](https://github.com/netlify/next-runtime/blob/v4/README.md) and the
65
+ [v4 Runtime docs here](https://docs.netlify.com/frameworks/next-js/runtime-v4/overview/).
66
+
67
+ ### Upgrading from v4 to v5
68
+
69
+ To upgrade from v4 to v5, please visit
70
+ [the v5 documentation](https://docs.netlify.com/frameworks/next-js/overview/).
71
+
72
+ ## Feedback
73
+
74
+ If you think you have found a bug in Next.js on Netlify,
75
+ [please open an issue](https://github.com/netlify/next-runtime/issues). If you have comments or
76
+ feature requests, [see the discussion board](https://github.com/netlify/next-runtime/discussions)
77
+
78
+ Please note that v4 will only receive security fixes and critical bug fixes.
@@ -14,6 +14,9 @@ import {
14
14
  init_esm,
15
15
  trace
16
16
  } from "../../esm-chunks/chunk-GNGHTHMQ.js";
17
+ import {
18
+ require_semver
19
+ } from "../../esm-chunks/chunk-EFGWM7RS.js";
17
20
  import {
18
21
  __toESM
19
22
  } from "../../esm-chunks/chunk-OEQOKJGE.js";
@@ -132,6 +135,7 @@ function pLimit(concurrency) {
132
135
  }
133
136
 
134
137
  // src/build/content/prerendered.ts
138
+ var import_semver = __toESM(require_semver(), 1);
135
139
  import { encodeBlobKey } from "../../shared/blobkey.js";
136
140
  var tracer = wrapTracer(trace.getTracer("Next runtime"));
137
141
  var writeCacheEntry = async (route, value, lastModified, ctx) => {
@@ -147,12 +151,22 @@ var buildPagesCacheValue = async (path) => ({
147
151
  kind: "PAGE",
148
152
  html: await readFile(`${path}.html`, "utf-8"),
149
153
  pageData: JSON.parse(await readFile(`${path}.json`, "utf-8")),
150
- postponed: void 0,
151
154
  headers: void 0,
152
155
  status: void 0
153
156
  });
154
- var buildAppCacheValue = async (path) => {
157
+ var buildAppCacheValue = async (path, shouldUseAppPageKind) => {
155
158
  const meta = JSON.parse(await readFile(`${path}.meta`, "utf-8"));
159
+ const html = await readFile(`${path}.html`, "utf-8");
160
+ if (shouldUseAppPageKind) {
161
+ return {
162
+ kind: "APP_PAGE",
163
+ html,
164
+ rscData: await readFile(`${path}.rsc`, "base64").catch(
165
+ () => readFile(`${path}.prefetch.rsc`, "base64")
166
+ ),
167
+ ...meta
168
+ };
169
+ }
156
170
  const rsc = await readFile(`${path}.rsc`, "utf-8").catch(
157
171
  () => readFile(`${path}.prefetch.rsc`, "utf-8")
158
172
  );
@@ -161,7 +175,7 @@ var buildAppCacheValue = async (path) => {
161
175
  }
162
176
  return {
163
177
  kind: "PAGE",
164
- html: await readFile(`${path}.html`, "utf-8"),
178
+ html,
165
179
  pageData: rsc,
166
180
  ...meta
167
181
  };
@@ -182,6 +196,9 @@ var copyPrerenderedContent = async (ctx) => {
182
196
  await mkdir(ctx.blobDir, { recursive: true });
183
197
  const manifest = await ctx.getPrerenderManifest();
184
198
  const limitConcurrentPrerenderContentHandling = pLimit(10);
199
+ const shouldUseAppPageKind = ctx.nextVersion ? (0, import_semver.satisfies)(ctx.nextVersion, ">=15.0.0-canary.13 <15.0.0-d || >15.0.0-rc.0", {
200
+ includePrerelease: true
201
+ }) : false;
185
202
  await Promise.all(
186
203
  Object.entries(manifest.routes).map(
187
204
  ([route, meta]) => limitConcurrentPrerenderContentHandling(async () => {
@@ -198,7 +215,10 @@ var copyPrerenderedContent = async (ctx) => {
198
215
  value = await buildPagesCacheValue(join(ctx.publishDir, "server/pages", key));
199
216
  break;
200
217
  case meta.dataRoute?.endsWith(".rsc"):
201
- value = await buildAppCacheValue(join(ctx.publishDir, "server/app", key));
218
+ value = await buildAppCacheValue(
219
+ join(ctx.publishDir, "server/app", key),
220
+ shouldUseAppPageKind
221
+ );
202
222
  break;
203
223
  case meta.dataRoute === null:
204
224
  value = await buildRouteCacheValue(
@@ -216,7 +236,10 @@ var copyPrerenderedContent = async (ctx) => {
216
236
  if (existsSync(join(ctx.publishDir, `server/app/_not-found.html`))) {
217
237
  const lastModified = Date.now();
218
238
  const key = "/404";
219
- const value = await buildAppCacheValue(join(ctx.publishDir, "server/app/_not-found"));
239
+ const value = await buildAppCacheValue(
240
+ join(ctx.publishDir, "server/app/_not-found"),
241
+ shouldUseAppPageKind
242
+ );
220
243
  await writeCacheEntry(key, value, lastModified, ctx);
221
244
  }
222
245
  } catch (error) {
@@ -28,8 +28,8 @@ import {
28
28
  access,
29
29
  cp,
30
30
  mkdir,
31
- readFile,
32
31
  readdir,
32
+ readFile,
33
33
  readlink,
34
34
  symlink,
35
35
  writeFile
@@ -40,8 +40,6 @@ import { join as posixJoin, sep as posixSep } from "node:path/posix";
40
40
  var import_fast_glob = __toESM(require_out(), 1);
41
41
  var import_semver = __toESM(require_semver(), 1);
42
42
  import { RUN_CONFIG } from "../../run/constants.js";
43
- import { logger } from "../../run/systemlog.cjs";
44
- import { verifyNextVersion } from "../verification.js";
45
43
  var tracer = wrapTracer(trace.getTracer("Next runtime"));
46
44
  var toPosixPath = (path) => path.split(sep).join(posixSep);
47
45
  function isError(error) {
@@ -192,17 +190,8 @@ var copyNextDependencies = async (ctx) => {
192
190
  }
193
191
  await Promise.all(promises);
194
192
  const serverHandlerRequire = createRequire(posixJoin(ctx.serverHandlerDir, ":internal:"));
195
- let nextVersion;
196
- try {
197
- const { version } = serverHandlerRequire("next/package.json");
198
- if (version) {
199
- nextVersion = version;
200
- }
201
- } catch {
202
- }
203
- if (nextVersion) {
204
- verifyNextVersion(ctx, nextVersion);
205
- await patchNextModules(ctx, nextVersion, serverHandlerRequire.resolve);
193
+ if (ctx.nextVersion) {
194
+ await patchNextModules(ctx, ctx.nextVersion, serverHandlerRequire.resolve);
206
195
  }
207
196
  try {
208
197
  const nextEntryAbsolutePath = serverHandlerRequire.resolve("next");
@@ -227,7 +216,7 @@ var writeTagsManifest = async (ctx) => {
227
216
  tags = meta.headers["x-next-cache-tags"];
228
217
  } catch {
229
218
  if (!definition.dataRoute?.endsWith("/default.rsc")) {
230
- logger.log(`Unable to read cache tags for: ${path}`);
219
+ console.log(`Unable to read cache tags for: ${path}`);
231
220
  }
232
221
  }
233
222
  }
@@ -15,7 +15,9 @@ import {
15
15
  var import_semver = __toESM(require_semver(), 1);
16
16
  import { existsSync, readFileSync } from "node:fs";
17
17
  import { readFile } from "node:fs/promises";
18
+ import { createRequire } from "node:module";
18
19
  import { join, relative, resolve } from "node:path";
20
+ import { join as posixJoin } from "node:path/posix";
19
21
  import { fileURLToPath } from "node:url";
20
22
  var MODULE_DIR = fileURLToPath(new URL(".", import.meta.url));
21
23
  var PLUGIN_DIR = join(MODULE_DIR, "../..");
@@ -248,6 +250,22 @@ var PluginContext = class {
248
250
  async getRoutesManifest() {
249
251
  return JSON.parse(await readFile(join(this.publishDir, "routes-manifest.json"), "utf-8"));
250
252
  }
253
+ #nextVersion = void 0;
254
+ /**
255
+ * Get Next.js version that was used to build the site
256
+ */
257
+ get nextVersion() {
258
+ if (this.#nextVersion === void 0) {
259
+ try {
260
+ const serverHandlerRequire = createRequire(posixJoin(this.standaloneRootDir, ":internal:"));
261
+ const { version } = serverHandlerRequire("next/package.json");
262
+ this.#nextVersion = version;
263
+ } catch {
264
+ this.#nextVersion = null;
265
+ }
266
+ }
267
+ return this.#nextVersion;
268
+ }
251
269
  /** Fails a build with a message and an optional error */
252
270
  failBuild(message, error) {
253
271
  return this.utils.build.failBuild(message, error instanceof Error ? { error } : void 0);
@@ -16,7 +16,7 @@ export default async function (req, context) {
16
16
  tracing.start()
17
17
  }
18
18
 
19
- const requestContext = createRequestContext(req.headers.get('x-next-debug-logging'))
19
+ const requestContext = createRequestContext(req)
20
20
  const tracer = getTracer()
21
21
 
22
22
  const handlerResponse = await runWithRequestContext(requestContext, () => {
@@ -13,7 +13,7 @@ export default async function handler(req, context) {
13
13
  if (process.env.NETLIFY_OTLP_TRACE_EXPORTER_URL) {
14
14
  tracing.start()
15
15
  }
16
- const requestContext = createRequestContext(req.headers.get('x-next-debug-logging'))
16
+ const requestContext = createRequestContext(req)
17
17
  const tracer = getTracer()
18
18
 
19
19
  const handlerResponse = await runWithRequestContext(requestContext, () => {
@@ -46,6 +46,11 @@ function verifyPublishDir(ctx) {
46
46
  `Your publish directory does not contain expected Next.js build output. Please make sure you are using Next.js version (${SUPPORTED_NEXT_VERSIONS})`
47
47
  );
48
48
  }
49
+ if (ctx.nextVersion && !(0, import_semver.satisfies)(ctx.nextVersion, SUPPORTED_NEXT_VERSIONS, { includePrerelease: true })) {
50
+ ctx.failBuild(
51
+ `@netlify/plugin-next@5 requires Next.js version ${SUPPORTED_NEXT_VERSIONS}, but found ${ctx.nextVersion}. Please upgrade your project's Next.js version.`
52
+ );
53
+ }
49
54
  }
50
55
  if (ctx.buildConfig.output === "export") {
51
56
  if (!ctx.exportDetail?.success) {
@@ -58,13 +63,6 @@ function verifyPublishDir(ctx) {
58
63
  }
59
64
  }
60
65
  }
61
- function verifyNextVersion(ctx, nextVersion) {
62
- if (!(0, import_semver.satisfies)(nextVersion, SUPPORTED_NEXT_VERSIONS, { includePrerelease: true })) {
63
- ctx.failBuild(
64
- `@netlify/plugin-next@5 requires Next.js version ${SUPPORTED_NEXT_VERSIONS}, but found ${nextVersion}. Please upgrade your project's Next.js version.`
65
- );
66
- }
67
- }
68
66
  async function verifyNoAdvancedAPIRoutes(ctx) {
69
67
  const apiRoutesConfigs = await getAPIRoutesConfigs(ctx);
70
68
  const unsupportedAPIRoutes = apiRoutesConfigs.filter((apiRouteConfig) => {
@@ -80,7 +78,6 @@ Refer to https://ntl.fyi/next-scheduled-bg-function-migration as migration examp
80
78
  }
81
79
  }
82
80
  export {
83
- verifyNextVersion,
84
81
  verifyNoAdvancedAPIRoutes,
85
82
  verifyPublishDir
86
83
  };
@@ -8,7 +8,7 @@ import "./chunk-OEQOKJGE.js";
8
8
 
9
9
  // package.json
10
10
  var name = "@netlify/plugin-nextjs";
11
- var version = "5.3.2";
11
+ var version = "5.3.3";
12
12
  var description = "Run Next.js seamlessly on Netlify";
13
13
  var main = "./dist/index.js";
14
14
  var type = "module";
@@ -42,7 +42,7 @@ var scripts = {
42
42
  };
43
43
  var repository = {
44
44
  type: "git",
45
- url: "git+https://github.com/netlify/next-runtime-minimal.git"
45
+ url: "git+https://github.com/netlify/next-runtime.git"
46
46
  };
47
47
  var keywords = [
48
48
  "nextjs",
@@ -52,19 +52,19 @@ var keywords = [
52
52
  ];
53
53
  var license = "MIT";
54
54
  var bugs = {
55
- url: "https://github.com/netlify/next-runtime-minimal/issues"
55
+ url: "https://github.com/netlify/next-runtime/issues"
56
56
  };
57
- var homepage = "https://github.com/netlify/next-runtime-minimal#readme";
57
+ var homepage = "https://github.com/netlify/next-runtime#readme";
58
58
  var devDependencies = {
59
59
  "@fastly/http-compute-js": "1.1.4",
60
60
  "@netlify/blobs": "^7.3.0",
61
- "@netlify/build": "^29.43.0",
61
+ "@netlify/build": "^29.48.1",
62
62
  "@netlify/edge-bundler": "^12.0.1",
63
63
  "@netlify/edge-functions": "^2.8.1",
64
64
  "@netlify/eslint-config-node": "^7.0.1",
65
65
  "@netlify/functions": "^2.7.0",
66
- "@netlify/serverless-functions-api": "^1.18.2",
67
- "@netlify/zip-it-and-ship-it": "^9.33.2",
66
+ "@netlify/serverless-functions-api": "^1.18.4",
67
+ "@netlify/zip-it-and-ship-it": "^9.37.0",
68
68
  "@opentelemetry/api": "^1.8.0",
69
69
  "@opentelemetry/exporter-trace-otlp-http": "^0.51.0",
70
70
  "@opentelemetry/resources": "^1.24.0",
@@ -87,7 +87,7 @@ var devDependencies = {
87
87
  memfs: "^4.9.2",
88
88
  "mock-require": "^3.0.3",
89
89
  msw: "^2.0.7",
90
- next: "^14.0.4",
90
+ next: "^15.0.0-canary.28",
91
91
  os: "^0.1.2",
92
92
  outdent: "^0.8.0",
93
93
  "p-limit": "^5.0.0",
@@ -21,6 +21,8 @@ var setRunConfig = (config) => {
21
21
  }
22
22
  config.experimental = {
23
23
  ...config.experimental,
24
+ // @ts-expect-error incrementalCacheHandlerPath was removed from config type
25
+ // but we still need to set it for older Next.js versions
24
26
  incrementalCacheHandlerPath: cacheHandler
25
27
  };
26
28
  config.cacheHandler = cacheHandler;
@@ -35,6 +35,8 @@ __export(cache_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(cache_exports);
37
37
  var import_node_buffer = require("node:buffer");
38
+ var import_node_path = require("node:path");
39
+ var import_posix = require("node:path/posix");
38
40
 
39
41
  // node_modules/@netlify/functions/dist/chunk-COIAWFHF.mjs
40
42
  var import_process = require("process");
@@ -94,7 +96,6 @@ var pipeline = (0, import_util.promisify)(import_stream.pipeline);
94
96
  // src/run/handlers/cache.cts
95
97
  var import_constants = require("next/dist/lib/constants.js");
96
98
  var import_regional_blob_store = require("../regional-blob-store.cjs");
97
- var import_systemlog = require("../systemlog.cjs");
98
99
  var import_request_context = require("./request-context.cjs");
99
100
  var import_tracer = require("./tracer.cjs");
100
101
  var NetlifyCacheHandler = class {
@@ -154,10 +155,37 @@ var NetlifyCacheHandler = class {
154
155
  }
155
156
  return restOfRouteValue;
156
157
  }
158
+ async injectEntryToPrerenderManifest(key, revalidate) {
159
+ if (this.options.serverDistDir && (typeof revalidate === "number" || revalidate === false)) {
160
+ try {
161
+ const { loadManifest } = await import("next/dist/server/load-manifest.js");
162
+ const prerenderManifest = loadManifest(
163
+ (0, import_node_path.join)(this.options.serverDistDir, "..", "prerender-manifest.json")
164
+ );
165
+ try {
166
+ const { normalizePagePath } = await import("next/dist/shared/lib/page-path/normalize-page-path.js");
167
+ prerenderManifest.routes[key] = {
168
+ experimentalPPR: void 0,
169
+ dataRoute: (0, import_posix.join)("/_next/data", `${normalizePagePath(key)}.json`),
170
+ srcRoute: null,
171
+ // FIXME: provide actual source route, however, when dynamically appending it doesn't really matter
172
+ initialRevalidateSeconds: revalidate,
173
+ // Pages routes do not have a prefetch data route.
174
+ prefetchDataRoute: void 0
175
+ };
176
+ } catch {
177
+ const { SharedRevalidateTimings } = await import("next/dist/server/lib/incremental-cache/shared-revalidate-timings.js");
178
+ const sharedRevalidateTimings = new SharedRevalidateTimings(prerenderManifest);
179
+ sharedRevalidateTimings.set(key, revalidate);
180
+ }
181
+ } catch {
182
+ }
183
+ }
184
+ }
157
185
  async get(...args) {
158
186
  return this.tracer.withActiveSpan("get cache key", async (span) => {
159
187
  const [key, ctx = {}] = args;
160
- import_systemlog.logger.debug(`[NetlifyCacheHandler.get]: ${key}`);
188
+ (0, import_request_context.getLogger)().debug(`[NetlifyCacheHandler.get]: ${key}`);
161
189
  const blobKey = await this.encodeBlobKey(key);
162
190
  span.setAttributes({ key, blobKey });
163
191
  const blob = await this.tracer.withActiveSpan("blobStore.get", async (blobGetSpan) => {
@@ -194,33 +222,64 @@ var NetlifyCacheHandler = class {
194
222
  }
195
223
  };
196
224
  }
197
- case "PAGE":
225
+ case "PAGE": {
198
226
  span.addEvent("PAGE", { lastModified: blob.lastModified });
227
+ const { revalidate, ...restOfPageValue } = blob.value;
228
+ await this.injectEntryToPrerenderManifest(key, revalidate);
199
229
  return {
200
230
  lastModified: blob.lastModified,
201
- value: blob.value
231
+ value: restOfPageValue
232
+ };
233
+ }
234
+ case "APP_PAGE": {
235
+ span.addEvent("APP_PAGE", { lastModified: blob.lastModified });
236
+ const { revalidate, rscData, ...restOfPageValue } = blob.value;
237
+ await this.injectEntryToPrerenderManifest(key, revalidate);
238
+ return {
239
+ lastModified: blob.lastModified,
240
+ value: {
241
+ ...restOfPageValue,
242
+ rscData: rscData ? import_node_buffer.Buffer.from(rscData, "base64") : void 0
243
+ }
202
244
  };
245
+ }
203
246
  default:
204
247
  span.recordException(new Error(`Unknown cache entry kind: ${blob.value?.kind}`));
205
248
  }
206
249
  return null;
207
250
  });
208
251
  }
252
+ transformToStorableObject(data, context) {
253
+ if (data?.kind === "ROUTE") {
254
+ return {
255
+ ...data,
256
+ revalidate: context.revalidate,
257
+ body: data.body.toString("base64")
258
+ };
259
+ }
260
+ if (data?.kind === "PAGE") {
261
+ return {
262
+ ...data,
263
+ revalidate: context.revalidate
264
+ };
265
+ }
266
+ if (data?.kind === "APP_PAGE") {
267
+ return {
268
+ ...data,
269
+ revalidate: context.revalidate,
270
+ rscData: data.rscData?.toString("base64")
271
+ };
272
+ }
273
+ return data;
274
+ }
209
275
  async set(...args) {
210
276
  return this.tracer.withActiveSpan("set cache key", async (span) => {
211
277
  const [key, data, context] = args;
212
278
  const blobKey = await this.encodeBlobKey(key);
213
279
  const lastModified = Date.now();
214
280
  span.setAttributes({ key, lastModified, blobKey });
215
- import_systemlog.logger.debug(`[NetlifyCacheHandler.set]: ${key}`);
216
- const value = data?.kind === "ROUTE" ? (
217
- // don't mutate data, as it's used for the initial response - instead create a new object
218
- {
219
- ...data,
220
- revalidate: context.revalidate,
221
- body: data.body.toString("base64")
222
- }
223
- ) : data;
281
+ (0, import_request_context.getLogger)().debug(`[NetlifyCacheHandler.set]: ${key}`);
282
+ const value = this.transformToStorableObject(data, context);
224
283
  await this.blobStore.setJSON(blobKey, {
225
284
  lastModified,
226
285
  value
@@ -229,9 +288,9 @@ var NetlifyCacheHandler = class {
229
288
  const requestContext = (0, import_request_context.getRequestContext)();
230
289
  if (requestContext?.didPagesRouterOnDemandRevalidate) {
231
290
  const tag = `_N_T_${key === "/index" ? "/" : key}`;
232
- import_systemlog.logger.debug(`Purging CDN cache for: [${tag}]`);
291
+ (0, import_request_context.getLogger)().debug(`Purging CDN cache for: [${tag}]`);
233
292
  purgeCache({ tags: [tag] }).catch((error) => {
234
- import_systemlog.logger.withError(error).error(`[NetlifyCacheHandler]: Purging the cache for tag ${tag} failed`);
293
+ (0, import_request_context.getLogger)().withError(error).error(`[NetlifyCacheHandler]: Purging the cache for tag ${tag} failed`);
235
294
  });
236
295
  }
237
296
  }
@@ -239,7 +298,7 @@ var NetlifyCacheHandler = class {
239
298
  }
240
299
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
241
300
  async revalidateTag(tagOrTags, ...args) {
242
- import_systemlog.logger.withFields({ tagOrTags, args }).debug("NetlifyCacheHandler.revalidateTag");
301
+ (0, import_request_context.getLogger)().withFields({ tagOrTags, args }).debug("NetlifyCacheHandler.revalidateTag");
243
302
  const tags = Array.isArray(tagOrTags) ? tagOrTags : [tagOrTags];
244
303
  const data = {
245
304
  revalidatedAt: Date.now()
@@ -249,12 +308,12 @@ var NetlifyCacheHandler = class {
249
308
  try {
250
309
  await this.blobStore.setJSON(await this.encodeBlobKey(tag), data);
251
310
  } catch (error) {
252
- import_systemlog.logger.withError(error).log(`Failed to update tag manifest for ${tag}`);
311
+ (0, import_request_context.getLogger)().withError(error).log(`Failed to update tag manifest for ${tag}`);
253
312
  }
254
313
  })
255
314
  );
256
315
  purgeCache({ tags }).catch((error) => {
257
- import_systemlog.logger.withError(error).error(`[NetlifyCacheHandler]: Purging the cache for tags ${tags.join(", ")} failed`);
316
+ (0, import_request_context.getLogger)().withError(error).error(`[NetlifyCacheHandler]: Purging the cache for tags ${tags.join(", ")} failed`);
258
317
  });
259
318
  }
260
319
  resetRequestCache() {
@@ -267,7 +326,7 @@ var NetlifyCacheHandler = class {
267
326
  let cacheTags = [];
268
327
  if (cacheEntry.value?.kind === "FETCH") {
269
328
  cacheTags = [...tags, ...softTags];
270
- } else if (cacheEntry.value?.kind === "PAGE" || cacheEntry.value?.kind === "ROUTE") {
329
+ } else if (cacheEntry.value?.kind === "PAGE" || cacheEntry.value?.kind === "APP_PAGE" || cacheEntry.value?.kind === "ROUTE") {
271
330
  cacheTags = cacheEntry.value.headers?.[import_constants.NEXT_CACHE_TAGS_HEADER]?.split(",") || [];
272
331
  } else {
273
332
  return false;
@@ -21,21 +21,94 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var request_context_exports = {};
22
22
  __export(request_context_exports, {
23
23
  createRequestContext: () => createRequestContext,
24
+ getLogger: () => getLogger,
24
25
  getRequestContext: () => getRequestContext,
25
26
  runWithRequestContext: () => runWithRequestContext
26
27
  });
27
28
  module.exports = __toCommonJS(request_context_exports);
28
29
  var import_node_async_hooks = require("node:async_hooks");
29
- function createRequestContext(debug = false) {
30
+
31
+ // node_modules/@netlify/functions/dist/chunk-HYMERDCV.mjs
32
+ var import_process = require("process");
33
+ var systemLogTag = "__nfSystemLog";
34
+ var serializeError = (error) => {
35
+ const cause = error?.cause instanceof Error ? serializeError(error.cause) : error.cause;
36
+ return {
37
+ error: error.message,
38
+ error_cause: cause,
39
+ error_stack: error.stack
40
+ };
41
+ };
42
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
43
+ LogLevel2[LogLevel2["Debug"] = 1] = "Debug";
44
+ LogLevel2[LogLevel2["Log"] = 2] = "Log";
45
+ LogLevel2[LogLevel2["Error"] = 3] = "Error";
46
+ return LogLevel2;
47
+ })(LogLevel || {});
48
+ var SystemLogger = class _SystemLogger {
49
+ fields;
50
+ logLevel;
51
+ constructor(fields = {}, logLevel = 2) {
52
+ this.fields = fields;
53
+ this.logLevel = logLevel;
54
+ }
55
+ doLog(logger, message) {
56
+ if (import_process.env.NETLIFY_DEV && !import_process.env.NETLIFY_ENABLE_SYSTEM_LOGGING) {
57
+ return;
58
+ }
59
+ logger(systemLogTag, JSON.stringify({ msg: message, fields: this.fields }));
60
+ }
61
+ log(message) {
62
+ if (this.logLevel > 2) {
63
+ return;
64
+ }
65
+ this.doLog(console.log, message);
66
+ }
67
+ debug(message) {
68
+ if (this.logLevel > 1) {
69
+ return;
70
+ }
71
+ this.doLog(console.debug, message);
72
+ }
73
+ error(message) {
74
+ if (this.logLevel > 3) {
75
+ return;
76
+ }
77
+ this.doLog(console.error, message);
78
+ }
79
+ withLogLevel(level) {
80
+ return new _SystemLogger(this.fields, level);
81
+ }
82
+ withFields(fields) {
83
+ return new _SystemLogger(
84
+ {
85
+ ...this.fields,
86
+ ...fields
87
+ },
88
+ this.logLevel
89
+ );
90
+ }
91
+ withError(error) {
92
+ const fields = error instanceof Error ? serializeError(error) : { error };
93
+ return this.withFields(fields);
94
+ }
95
+ };
96
+ var systemLogger = new SystemLogger();
97
+
98
+ // src/run/handlers/request-context.cts
99
+ function createRequestContext(request) {
30
100
  const backgroundWorkPromises = [];
31
101
  return {
32
- debug,
102
+ captureServerTiming: request?.headers.has("x-next-debug-logging") ?? false,
33
103
  trackBackgroundWork: (promise) => {
34
104
  backgroundWorkPromises.push(promise);
35
105
  },
36
106
  get backgroundWorkPromise() {
37
107
  return Promise.allSettled(backgroundWorkPromises);
38
- }
108
+ },
109
+ logger: systemLogger.withLogLevel(
110
+ request?.headers.has("x-nf-debug-logging") || request?.headers.has("x-next-debug-logging") ? LogLevel.Debug : LogLevel.Log
111
+ )
39
112
  };
40
113
  }
41
114
  var REQUEST_CONTEXT_GLOBAL_KEY = Symbol.for("nf-request-context-async-local-storage");
@@ -57,9 +130,13 @@ var getRequestContext = () => getRequestContextAsyncLocalStorage().getStore();
57
130
  function runWithRequestContext(requestContext, fn) {
58
131
  return getRequestContextAsyncLocalStorage().run(requestContext, fn);
59
132
  }
133
+ function getLogger() {
134
+ return getRequestContext()?.logger ?? systemLogger;
135
+ }
60
136
  // Annotate the CommonJS export names for ESM import in node:
61
137
  0 && (module.exports = {
62
138
  createRequestContext,
139
+ getLogger,
63
140
  getRequestContext,
64
141
  runWithRequestContext
65
142
  });
@@ -3100,8 +3100,7 @@ import {
3100
3100
  setVaryHeaders
3101
3101
  } from "../headers.js";
3102
3102
  import { nextResponseProxy } from "../revalidate.js";
3103
- import { logger } from "../systemlog.cjs";
3104
- import { createRequestContext, getRequestContext } from "./request-context.cjs";
3103
+ import { createRequestContext, getLogger, getRequestContext } from "./request-context.cjs";
3105
3104
  import { getTracer } from "./tracer.cjs";
3106
3105
  var nextImportPromise = import("../next.cjs");
3107
3106
  var nextHandler;
@@ -3163,7 +3162,7 @@ var server_default = async (request, context) => {
3163
3162
  const requestContext = getRequestContext() ?? createRequestContext();
3164
3163
  const resProxy = nextResponseProxy(res, requestContext);
3165
3164
  const nextHandlerPromise = nextHandler(req, resProxy).catch((error) => {
3166
- logger.withError(error).error("next handler error");
3165
+ getLogger().withError(error).error("next handler error");
3167
3166
  console.error(error);
3168
3167
  resProxy.statusCode = 500;
3169
3168
  span.setAttribute("http.status_code", 500);
@@ -856,7 +856,7 @@ function spanHook(span) {
856
856
  const meta = spanMeta.get(span);
857
857
  if (meta) {
858
858
  const requestContext = (0, import_request_context.getRequestContext)();
859
- if (requestContext?.debug) {
859
+ if (requestContext?.captureServerTiming) {
860
860
  const duration = (typeof endTime === "number" ? endTime : performance.now()) - meta.start;
861
861
  const serverTiming = requestContext.serverTiming ?? "";
862
862
  const currentRequestSpanCounter = spanCounter.get(requestContext) ?? 1;
@@ -25421,7 +25421,7 @@ var require_shimmer = __commonJS({
25421
25421
  function isFunction(funktion) {
25422
25422
  return typeof funktion === "function";
25423
25423
  }
25424
- var logger2 = console.error.bind(console);
25424
+ var logger = console.error.bind(console);
25425
25425
  function defineProperty(obj, name2, value) {
25426
25426
  var enumerable = !!obj[name2] && obj.propertyIsEnumerable(name2);
25427
25427
  Object.defineProperty(obj, name2, {
@@ -25433,22 +25433,22 @@ var require_shimmer = __commonJS({
25433
25433
  }
25434
25434
  function shimmer(options) {
25435
25435
  if (options && options.logger) {
25436
- if (!isFunction(options.logger)) logger2("new logger isn't a function, not replacing");
25437
- else logger2 = options.logger;
25436
+ if (!isFunction(options.logger)) logger("new logger isn't a function, not replacing");
25437
+ else logger = options.logger;
25438
25438
  }
25439
25439
  }
25440
25440
  function wrap(nodule, name2, wrapper) {
25441
25441
  if (!nodule || !nodule[name2]) {
25442
- logger2("no original function " + name2 + " to wrap");
25442
+ logger("no original function " + name2 + " to wrap");
25443
25443
  return;
25444
25444
  }
25445
25445
  if (!wrapper) {
25446
- logger2("no wrapper function");
25447
- logger2(new Error().stack);
25446
+ logger("no wrapper function");
25447
+ logger(new Error().stack);
25448
25448
  return;
25449
25449
  }
25450
25450
  if (!isFunction(nodule[name2]) || !isFunction(wrapper)) {
25451
- logger2("original object and wrapper must be functions");
25451
+ logger("original object and wrapper must be functions");
25452
25452
  return;
25453
25453
  }
25454
25454
  var original = nodule[name2];
@@ -25463,14 +25463,14 @@ var require_shimmer = __commonJS({
25463
25463
  }
25464
25464
  function massWrap(nodules, names, wrapper) {
25465
25465
  if (!nodules) {
25466
- logger2("must provide one or more modules to patch");
25467
- logger2(new Error().stack);
25466
+ logger("must provide one or more modules to patch");
25467
+ logger(new Error().stack);
25468
25468
  return;
25469
25469
  } else if (!Array.isArray(nodules)) {
25470
25470
  nodules = [nodules];
25471
25471
  }
25472
25472
  if (!(names && Array.isArray(names))) {
25473
- logger2("must provide one or more functions to wrap on modules");
25473
+ logger("must provide one or more functions to wrap on modules");
25474
25474
  return;
25475
25475
  }
25476
25476
  nodules.forEach(function(nodule) {
@@ -25481,26 +25481,26 @@ var require_shimmer = __commonJS({
25481
25481
  }
25482
25482
  function unwrap(nodule, name2) {
25483
25483
  if (!nodule || !nodule[name2]) {
25484
- logger2("no function to unwrap.");
25485
- logger2(new Error().stack);
25484
+ logger("no function to unwrap.");
25485
+ logger(new Error().stack);
25486
25486
  return;
25487
25487
  }
25488
25488
  if (!nodule[name2].__unwrap) {
25489
- logger2("no original to unwrap to -- has " + name2 + " already been unwrapped?");
25489
+ logger("no original to unwrap to -- has " + name2 + " already been unwrapped?");
25490
25490
  } else {
25491
25491
  return nodule[name2].__unwrap();
25492
25492
  }
25493
25493
  }
25494
25494
  function massUnwrap(nodules, names) {
25495
25495
  if (!nodules) {
25496
- logger2("must provide one or more modules to patch");
25497
- logger2(new Error().stack);
25496
+ logger("must provide one or more modules to patch");
25497
+ logger(new Error().stack);
25498
25498
  return;
25499
25499
  } else if (!Array.isArray(nodules)) {
25500
25500
  nodules = [nodules];
25501
25501
  }
25502
25502
  if (!(names && Array.isArray(names))) {
25503
- logger2("must provide one or more functions to unwrap on modules");
25503
+ logger("must provide one or more functions to unwrap on modules");
25504
25504
  return;
25505
25505
  }
25506
25506
  nodules.forEach(function(nodule) {
@@ -39342,12 +39342,12 @@ var require_logging = __commonJS({
39342
39342
  break;
39343
39343
  default:
39344
39344
  }
39345
- var getLogger = () => {
39345
+ var getLogger2 = () => {
39346
39346
  return _logger;
39347
39347
  };
39348
- exports2.getLogger = getLogger;
39349
- var setLogger = (logger2) => {
39350
- _logger = logger2;
39348
+ exports2.getLogger = getLogger2;
39349
+ var setLogger = (logger) => {
39350
+ _logger = logger;
39351
39351
  };
39352
39352
  exports2.setLogger = setLogger;
39353
39353
  var setLoggerVerbosity = (verbosity) => {
@@ -45546,7 +45546,24 @@ var require_parse = __commonJS({
45546
45546
  else
45547
45547
  target.push([start = parseId(next()), skip("to", true) ? parseId(next()) : start]);
45548
45548
  } while (skip(",", true));
45549
- skip(";");
45549
+ var dummy = { options: void 0 };
45550
+ dummy.setOption = function(name2, value) {
45551
+ if (this.options === void 0) this.options = {};
45552
+ this.options[name2] = value;
45553
+ };
45554
+ ifBlock(
45555
+ dummy,
45556
+ function parseRange_block(token3) {
45557
+ if (token3 === "option") {
45558
+ parseOption(dummy, token3);
45559
+ skip(";");
45560
+ } else
45561
+ throw illegal(token3);
45562
+ },
45563
+ function parseRange_line() {
45564
+ parseInlineOptions(dummy);
45565
+ }
45566
+ );
45550
45567
  }
45551
45568
  function parseNumber(token2, insideTryCatch) {
45552
45569
  var sign = 1;
@@ -56753,8 +56770,8 @@ var require_src31 = __commonJS({
56753
56770
  throw new Error("Not available in this library. Use @grpc/proto-loader and loadPackageDefinition instead");
56754
56771
  };
56755
56772
  exports2.load = load;
56756
- var setLogger = (logger2) => {
56757
- logging.setLogger(logger2);
56773
+ var setLogger = (logger) => {
56774
+ logging.setLogger(logger);
56758
56775
  };
56759
56776
  exports2.setLogger = setLogger;
56760
56777
  var setLogVerbosity = (verbosity) => {
@@ -67365,10 +67382,10 @@ var import_resources = __toESM(require_src5(), 1);
67365
67382
  var import_sdk_node = __toESM(require_src36(), 1);
67366
67383
  var import_sdk_trace_node = __toESM(require_src20(), 1);
67367
67384
  var import_semantic_conventions = __toESM(require_src(), 1);
67368
- import { logger } from "../systemlog.cjs";
67385
+ import { getLogger } from "./request-context.cjs";
67369
67386
  var {
67370
67387
  default: { version, name }
67371
- } = await import("../../esm-chunks/package-NUPTPA44.js");
67388
+ } = await import("../../esm-chunks/package-7AUBRXLQ.js");
67372
67389
  var sdk = new import_sdk_node.NodeSDK({
67373
67390
  resource: new import_resources.Resource({
67374
67391
  [import_semantic_conventions.SEMRESATTRS_SERVICE_NAME]: name,
@@ -67386,7 +67403,7 @@ process.on("SIGTERM", () => {
67386
67403
  // eslint-disable-next-line @typescript-eslint/no-empty-function
67387
67404
  () => {
67388
67405
  },
67389
- (error) => logger.withError(error).log("Error shutting down OpenTelemetry NodeSDK")
67406
+ (error) => getLogger().withError(error).log("Error shutting down OpenTelemetry NodeSDK")
67390
67407
  ).finally(() => process.exit(0));
67391
67408
  });
67392
67409
  export {
@@ -1,6 +1,12 @@
1
1
  import type { Context } from '@netlify/edge-functions'
2
2
 
3
- import { addBasePath, normalizeDataUrl, normalizeLocalePath, removeBasePath } 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,43 +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
- }
76
-
77
- // keep the locale in the url for request.nextUrl object
78
- if (detectedLocale) {
79
- url.pathname = `/${detectedLocale}${url.pathname}`
80
- }
68
+ url.pathname = addBasePath(pathname, nextConfig?.basePath)
81
69
 
82
70
  return {
83
71
  url: url.toString(),
@@ -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,7 +1,7 @@
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'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/plugin-nextjs",
3
- "version": "5.3.2",
3
+ "version": "5.3.3",
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,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
- });