@netlify/plugin-nextjs 5.0.0-rc.2 → 5.0.0-rc.4

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
@@ -28,6 +28,16 @@ For a simple next.js app
28
28
 
29
29
  ## Testing
30
30
 
31
+ The repo includes two types of tests: e2e tests in the repo that use Playwright, integration tests
32
+ that use Vitest.
33
+
34
+ By default the e2e and integration tests run against the latest version of Next.js. To run tests
35
+ against a specific version, set the `NEXT_VERSION` environment variable to the desired version.
36
+
37
+ By default, PRs will run the integration tests against the latest version of Next.js. To run tests
38
+ against `latest`, `canary` and `13.5.1`, apply the `test all versions` label to the PR when you
39
+ create it. These also run nightly and on release PRs.
40
+
31
41
  ### Integration testing
32
42
 
33
43
  How to add new integration test scenarios to the application:
@@ -75,6 +85,12 @@ following:
75
85
  > [!TIP] If you'd like to always keep the deployment and the local fixture around for
76
86
  > troubleshooting, run `E2E_PERSIST=1 npm run e2e`.
77
87
 
88
+ ### Next.js tests
89
+
90
+ There is a script `run-local-test.sh` and GitHub workflow that runs the e2e tests from the Next.js
91
+ repo against this repo. It requires that `next.js` is checked out in the same parent directory as
92
+ this repo, and is run from this repo with `./run-local-test.sh your-test-pattern-here`.
93
+
78
94
  #### cleanup old deploys
79
95
 
80
96
  To cleanup old and dangling deploys from failed builds you can run the following script:
@@ -7,7 +7,7 @@
7
7
  import {
8
8
  copyFetchContent,
9
9
  copyPrerenderedContent
10
- } from "../../esm-chunks/chunk-67EWAGDQ.js";
10
+ } from "../../esm-chunks/chunk-VSH4JS2L.js";
11
11
  import "../../esm-chunks/chunk-VZNKO4OO.js";
12
12
  import "../../esm-chunks/chunk-TYCYFZ22.js";
13
13
  import "../../esm-chunks/chunk-5JVNISGM.js";
@@ -7,13 +7,17 @@
7
7
  import {
8
8
  copyNextDependencies,
9
9
  copyNextServerCode,
10
+ verifyHandlerDirStructure,
10
11
  writeTagsManifest
11
- } from "../../esm-chunks/chunk-52WMBYKL.js";
12
+ } from "../../esm-chunks/chunk-BKDCZVBK.js";
12
13
  import "../../esm-chunks/chunk-VZNKO4OO.js";
14
+ import "../../esm-chunks/chunk-7CY6B4WT.js";
15
+ import "../../esm-chunks/chunk-PJG75HGC.js";
13
16
  import "../../esm-chunks/chunk-UYKENJEU.js";
14
17
  import "../../esm-chunks/chunk-5JVNISGM.js";
15
18
  export {
16
19
  copyNextDependencies,
17
20
  copyNextServerCode,
21
+ verifyHandlerDirStructure,
18
22
  writeTagsManifest
19
23
  };
@@ -9,7 +9,7 @@ import {
9
9
  copyStaticContent,
10
10
  publishStaticDir,
11
11
  unpublishStaticDir
12
- } from "../../esm-chunks/chunk-MPZEWLBG.js";
12
+ } from "../../esm-chunks/chunk-3IGTKVSS.js";
13
13
  import "../../esm-chunks/chunk-VZNKO4OO.js";
14
14
  import "../../esm-chunks/chunk-TYCYFZ22.js";
15
15
  import "../../esm-chunks/chunk-5JVNISGM.js";
@@ -6,9 +6,9 @@
6
6
 
7
7
  import {
8
8
  createEdgeHandlers
9
- } from "../../esm-chunks/chunk-ZZOGIP2V.js";
9
+ } from "../../esm-chunks/chunk-OBKVBMAL.js";
10
10
  import "../../esm-chunks/chunk-VZNKO4OO.js";
11
- import "../../esm-chunks/chunk-655Y7ISI.js";
11
+ import "../../esm-chunks/chunk-3NYX5FXN.js";
12
12
  import "../../esm-chunks/chunk-5JVNISGM.js";
13
13
  export {
14
14
  createEdgeHandlers
@@ -6,10 +6,12 @@
6
6
 
7
7
  import {
8
8
  createServerHandler
9
- } from "../../esm-chunks/chunk-E3NFUTWC.js";
10
- import "../../esm-chunks/chunk-52WMBYKL.js";
9
+ } from "../../esm-chunks/chunk-7HI65MAI.js";
10
+ import "../../esm-chunks/chunk-BKDCZVBK.js";
11
11
  import "../../esm-chunks/chunk-VZNKO4OO.js";
12
- import "../../esm-chunks/chunk-655Y7ISI.js";
12
+ import "../../esm-chunks/chunk-3NYX5FXN.js";
13
+ import "../../esm-chunks/chunk-7CY6B4WT.js";
14
+ import "../../esm-chunks/chunk-PJG75HGC.js";
13
15
  import "../../esm-chunks/chunk-UYKENJEU.js";
14
16
  import "../../esm-chunks/chunk-5JVNISGM.js";
15
17
  export {
@@ -8,7 +8,7 @@ import {
8
8
  EDGE_HANDLER_NAME,
9
9
  PluginContext,
10
10
  SERVER_HANDLER_NAME
11
- } from "../esm-chunks/chunk-655Y7ISI.js";
11
+ } from "../esm-chunks/chunk-3NYX5FXN.js";
12
12
  import "../esm-chunks/chunk-5JVNISGM.js";
13
13
  export {
14
14
  EDGE_HANDLER_NAME,
@@ -0,0 +1,18 @@
1
+
2
+ var require = await (async () => {
3
+ var { createRequire } = await import("node:module");
4
+ return createRequire(import.meta.url);
5
+ })();
6
+
7
+ import {
8
+ verifyBuildConfig,
9
+ verifyNextVersion,
10
+ verifyPublishDir
11
+ } from "../esm-chunks/chunk-7CY6B4WT.js";
12
+ import "../esm-chunks/chunk-PJG75HGC.js";
13
+ import "../esm-chunks/chunk-5JVNISGM.js";
14
+ export {
15
+ verifyBuildConfig,
16
+ verifyNextVersion,
17
+ verifyPublishDir
18
+ };
@@ -43,8 +43,10 @@ var copyStaticAssets = async (ctx) => {
43
43
  try {
44
44
  await rm(ctx.staticDir, { recursive: true, force: true });
45
45
  const { basePath } = await ctx.getRoutesManifest();
46
- if (existsSync(ctx.resolve("public"))) {
47
- await cp(ctx.resolve("public"), join(ctx.staticDir, basePath), { recursive: true });
46
+ if (existsSync(ctx.resolveFromSiteDir("public"))) {
47
+ await cp(ctx.resolveFromSiteDir("public"), join(ctx.staticDir, basePath), {
48
+ recursive: true
49
+ });
48
50
  }
49
51
  if (existsSync(join(ctx.publishDir, "static"))) {
50
52
  await cp(join(ctx.publishDir, "static"), join(ctx.staticDir, basePath, "_next/static"), {
@@ -6,7 +6,7 @@
6
6
 
7
7
 
8
8
  // src/build/plugin-context.ts
9
- import { existsSync, readFileSync } from "node:fs";
9
+ import { readFileSync } from "node:fs";
10
10
  import { readFile } from "node:fs/promises";
11
11
  import { join, relative, resolve } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
@@ -25,11 +25,11 @@ var PluginContext = class {
25
25
  /** Absolute path of the next runtime plugin directory */
26
26
  pluginDir = PLUGIN_DIR;
27
27
  get relPublishDir() {
28
- return this.constants.PUBLISH_DIR ?? join(this.packagePath, DEFAULT_PUBLISH_DIR);
28
+ return this.constants.PUBLISH_DIR ?? join(this.constants.PACKAGE_PATH || "", DEFAULT_PUBLISH_DIR);
29
29
  }
30
30
  /** Temporary directory for stashing the build output */
31
31
  get tempPublishDir() {
32
- return this.resolve(".netlify/.next");
32
+ return this.resolveFromPackagePath(".netlify/.next");
33
33
  }
34
34
  /** Absolute path of the publish directory */
35
35
  get publishDir() {
@@ -37,11 +37,12 @@ var PluginContext = class {
37
37
  }
38
38
  /**
39
39
  * Relative package path in non monorepo setups this is an empty string
40
+ * This path is provided by Next.js RequiredServerFiles manifest
40
41
  * @example ''
41
42
  * @example 'apps/my-app'
42
43
  */
43
- get packagePath() {
44
- return this.constants.PACKAGE_PATH || "";
44
+ get relativeAppDir() {
45
+ return this.requiredServerFiles.relativeAppDir ?? "";
45
46
  }
46
47
  /**
47
48
  * The working directory inside the lambda that is used for monorepos to execute the serverless function
@@ -62,7 +63,7 @@ var PluginContext = class {
62
63
  */
63
64
  get distDir() {
64
65
  const dir = this.buildConfig.distDir ?? DEFAULT_PUBLISH_DIR;
65
- return relative(process.cwd(), resolve(this.packagePath, dir));
66
+ return relative(process.cwd(), resolve(this.relativeAppDir, dir));
66
67
  }
67
68
  /** Represents the parent directory of the .next folder or custom distDir */
68
69
  get distDirParent() {
@@ -82,34 +83,34 @@ var PluginContext = class {
82
83
  * `.netlify/static`
83
84
  */
84
85
  get staticDir() {
85
- return this.resolve(".netlify/static");
86
+ return this.resolveFromPackagePath(".netlify/static");
86
87
  }
87
88
  /**
88
89
  * Absolute path of the directory that will be deployed to the blob store
89
90
  * `.netlify/blobs/deploy`
90
91
  */
91
92
  get blobDir() {
92
- return this.resolve(".netlify/blobs/deploy");
93
+ return this.resolveFromPackagePath(".netlify/blobs/deploy");
93
94
  }
94
95
  /**
95
96
  * Absolute path of the directory containing the files for the serverless lambda function
96
97
  * `.netlify/functions-internal`
97
98
  */
98
99
  get serverFunctionsDir() {
99
- return this.resolve(".netlify/functions-internal");
100
+ return this.resolveFromPackagePath(".netlify/functions-internal");
100
101
  }
101
102
  /** Absolute path of the server handler */
102
103
  get serverHandlerRootDir() {
103
104
  return join(this.serverFunctionsDir, SERVER_HANDLER_NAME);
104
105
  }
105
106
  get serverHandlerDir() {
106
- if (this.packagePath.length === 0) {
107
+ if (this.relativeAppDir.length === 0) {
107
108
  return this.serverHandlerRootDir;
108
109
  }
109
110
  return join(this.serverHandlerRootDir, this.distDirParent);
110
111
  }
111
112
  get nextServerHandler() {
112
- if (this.packagePath.length !== 0) {
113
+ if (this.relativeAppDir.length !== 0) {
113
114
  return join(this.lambdaWorkingDirectory, ".netlify/dist/run/handlers/server.js");
114
115
  }
115
116
  return "./.netlify/dist/run/handlers/server.js";
@@ -119,7 +120,7 @@ var PluginContext = class {
119
120
  * `.netlify/edge-functions`
120
121
  */
121
122
  get edgeFunctionsDir() {
122
- return this.resolve(".netlify/edge-functions");
123
+ return this.resolveFromPackagePath(".netlify/edge-functions");
123
124
  }
124
125
  /** Absolute path of the edge handler */
125
126
  get edgeHandlerDir() {
@@ -133,10 +134,14 @@ var PluginContext = class {
133
134
  this.utils = options.utils;
134
135
  this.netlifyConfig = options.netlifyConfig;
135
136
  }
136
- /** Resolves a path correctly with mono repository awareness */
137
- resolve(...args) {
137
+ /** Resolves a path correctly with mono repository awareness for .netlify directories mainly */
138
+ resolveFromPackagePath(...args) {
138
139
  return resolve(this.constants.PACKAGE_PATH || "", ...args);
139
140
  }
141
+ /** Resolves a path correctly from site directory */
142
+ resolveFromSiteDir(...args) {
143
+ return resolve(this.requiredServerFiles.appDir, ...args);
144
+ }
140
145
  /** Get the next prerender-manifest.json */
141
146
  async getPrerenderManifest() {
142
147
  return JSON.parse(await readFile(join(this.publishDir, "prerender-manifest.json"), "utf-8"));
@@ -150,15 +155,19 @@ var PluginContext = class {
150
155
  );
151
156
  }
152
157
  // don't make private as it is handy inside testing to override the config
153
- _buildConfig = null;
154
- /** Get Next Config from build output **/
155
- get buildConfig() {
156
- if (!this._buildConfig) {
157
- this._buildConfig = JSON.parse(
158
+ _requiredServerFiles = null;
159
+ /** Get RequiredServerFiles manifest from build output **/
160
+ get requiredServerFiles() {
161
+ if (!this._requiredServerFiles) {
162
+ this._requiredServerFiles = JSON.parse(
158
163
  readFileSync(join(this.publishDir, "required-server-files.json"), "utf-8")
159
- ).config;
164
+ );
160
165
  }
161
- return this._buildConfig;
166
+ return this._requiredServerFiles;
167
+ }
168
+ /** Get Next Config from build output **/
169
+ get buildConfig() {
170
+ return this.requiredServerFiles.config;
162
171
  }
163
172
  /**
164
173
  * Get Next.js routes manifest from the build output
@@ -170,18 +179,6 @@ var PluginContext = class {
170
179
  failBuild(message, error) {
171
180
  return this.utils.build.failBuild(message, error instanceof Error ? { error } : void 0);
172
181
  }
173
- verifyPublishDir() {
174
- if (!existsSync(this.publishDir)) {
175
- this.failBuild(
176
- `Your publish directory was not found at: ${this.publishDir}, please check your build settings`
177
- );
178
- }
179
- if (this.publishDir === this.resolve(this.packagePath)) {
180
- this.failBuild(
181
- `Your publish directory cannot be the same as the base directory of your site, please check your build settings`
182
- );
183
- }
184
- }
185
182
  };
186
183
 
187
184
  export {
@@ -8,42 +8,33 @@ import {
8
8
  encodeBlobKey
9
9
  } from "./chunk-TYCYFZ22.js";
10
10
 
11
- // node_modules/@netlify/blobs/dist/main.js
12
- import { Buffer } from "buffer";
13
- import { env } from "process";
14
- import { Buffer as Buffer2 } from "buffer";
15
- import { Buffer as Buffer3 } from "buffer";
16
- import stream from "stream";
17
- import { promisify } from "util";
18
- var BlobsConsistencyError = class extends Error {
19
- constructor() {
20
- super(
21
- `Netlify Blobs has failed to perform a read using strong consistency because the environment has not been configured with a 'uncachedEdgeURL' property`
22
- );
23
- this.name = "BlobsConsistencyError";
11
+ // node_modules/@netlify/blobs/dist/chunk-6TGYNZGH.js
12
+ var BlobsInternalError = class extends Error {
13
+ constructor(statusCode) {
14
+ super(`Netlify Blobs has generated an internal error: ${statusCode} response`);
15
+ this.name = "BlobsInternalError";
24
16
  }
25
17
  };
26
- var getEnvironmentContext = () => {
27
- const context = globalThis.netlifyBlobsContext || env.NETLIFY_BLOBS_CONTEXT;
28
- if (typeof context !== "string" || !context) {
29
- return {};
18
+ var collectIterator = async (iterator) => {
19
+ const result = [];
20
+ for await (const item of iterator) {
21
+ result.push(item);
30
22
  }
31
- const data = Buffer.from(context, "base64").toString();
32
- try {
33
- return JSON.parse(data);
34
- } catch {
23
+ return result;
24
+ };
25
+ var base64Decode = (input) => {
26
+ const { Buffer } = globalThis;
27
+ if (Buffer) {
28
+ return Buffer.from(input, "base64").toString();
35
29
  }
36
- return {};
30
+ return atob(input);
37
31
  };
38
- var MissingBlobsEnvironmentError = class extends Error {
39
- constructor(requiredProperties) {
40
- super(
41
- `The environment has not been configured to use Netlify Blobs. To use it manually, supply the following properties when creating a store: ${requiredProperties.join(
42
- ", "
43
- )}`
44
- );
45
- this.name = "MissingBlobsEnvironmentError";
32
+ var base64Encode = (input) => {
33
+ const { Buffer } = globalThis;
34
+ if (Buffer) {
35
+ return Buffer.from(input).toString("base64");
46
36
  }
37
+ return btoa(input);
47
38
  };
48
39
  var BASE64_PREFIX = "b64;";
49
40
  var METADATA_HEADER_INTERNAL = "x-amz-meta-user";
@@ -53,7 +44,7 @@ var encodeMetadata = (metadata) => {
53
44
  if (!metadata) {
54
45
  return null;
55
46
  }
56
- const encodedObject = Buffer2.from(JSON.stringify(metadata)).toString("base64");
47
+ const encodedObject = base64Encode(JSON.stringify(metadata));
57
48
  const payload = `b64;${encodedObject}`;
58
49
  if (METADATA_HEADER_EXTERNAL.length + payload.length > METADATA_MAX_SIZE) {
59
50
  throw new Error("Metadata object exceeds the maximum size");
@@ -65,7 +56,7 @@ var decodeMetadata = (header) => {
65
56
  return {};
66
57
  }
67
58
  const encodedData = header.slice(BASE64_PREFIX.length);
68
- const decodedData = Buffer2.from(encodedData, "base64").toString();
59
+ const decodedData = base64Decode(encodedData);
69
60
  const metadata = JSON.parse(decodedData);
70
61
  return metadata;
71
62
  };
@@ -82,7 +73,51 @@ var getMetadataFromResponse = (response) => {
82
73
  );
83
74
  }
84
75
  };
85
- var DEFAULT_RETRY_DELAY = 5e3;
76
+ var BlobsConsistencyError = class extends Error {
77
+ constructor() {
78
+ super(
79
+ `Netlify Blobs has failed to perform a read using strong consistency because the environment has not been configured with a 'uncachedEdgeURL' property`
80
+ );
81
+ this.name = "BlobsConsistencyError";
82
+ }
83
+ };
84
+ var getEnvironment = () => {
85
+ const { Deno, Netlify, process } = globalThis;
86
+ return Netlify?.env ?? Deno?.env ?? {
87
+ delete: (key) => delete process?.env[key],
88
+ get: (key) => process?.env[key],
89
+ has: (key) => Boolean(process?.env[key]),
90
+ set: (key, value) => {
91
+ if (process?.env) {
92
+ process.env[key] = value;
93
+ }
94
+ },
95
+ toObject: () => process?.env ?? {}
96
+ };
97
+ };
98
+ var getEnvironmentContext = () => {
99
+ const context = globalThis.netlifyBlobsContext || getEnvironment().get("NETLIFY_BLOBS_CONTEXT");
100
+ if (typeof context !== "string" || !context) {
101
+ return {};
102
+ }
103
+ const data = base64Decode(context);
104
+ try {
105
+ return JSON.parse(data);
106
+ } catch {
107
+ }
108
+ return {};
109
+ };
110
+ var MissingBlobsEnvironmentError = class extends Error {
111
+ constructor(requiredProperties) {
112
+ super(
113
+ `The environment has not been configured to use Netlify Blobs. To use it manually, supply the following properties when creating a store: ${requiredProperties.join(
114
+ ", "
115
+ )}`
116
+ );
117
+ this.name = "MissingBlobsEnvironmentError";
118
+ }
119
+ };
120
+ var DEFAULT_RETRY_DELAY = getEnvironment().get("NODE_ENV") === "test" ? 1 : 5e3;
86
121
  var MIN_RETRY_DELAY = 1e3;
87
122
  var MAX_RETRY = 5;
88
123
  var RATE_LIMIT_HEADER = "X-RateLimit-Reset";
@@ -110,9 +145,10 @@ var getDelay = (rateLimitReset) => {
110
145
  }
111
146
  return Math.max(Number(rateLimitReset) * 1e3 - Date.now(), MIN_RETRY_DELAY);
112
147
  };
113
- var sleep = (ms) => new Promise((resolve2) => {
114
- setTimeout(resolve2, ms);
148
+ var sleep = (ms) => new Promise((resolve) => {
149
+ setTimeout(resolve, ms);
115
150
  });
151
+ var SIGNED_URL_ACCEPT_HEADER = "application/json;type=signed-url";
116
152
  var Client = class {
117
153
  constructor({ apiURL, consistency, edgeURL, fetch, siteID, token, uncachedEdgeURL }) {
118
154
  this.apiURL = apiURL;
@@ -138,6 +174,13 @@ var Client = class {
138
174
  }) {
139
175
  const encodedMetadata = encodeMetadata(metadata);
140
176
  const consistency = opConsistency ?? this.consistency;
177
+ let urlPath = `/${this.siteID}`;
178
+ if (storeName) {
179
+ urlPath += `/${storeName}`;
180
+ }
181
+ if (key) {
182
+ urlPath += `/${key}`;
183
+ }
141
184
  if (this.edgeURL) {
142
185
  if (consistency === "strong" && !this.uncachedEdgeURL) {
143
186
  throw new BlobsConsistencyError();
@@ -148,8 +191,7 @@ var Client = class {
148
191
  if (encodedMetadata) {
149
192
  headers[METADATA_HEADER_INTERNAL] = encodedMetadata;
150
193
  }
151
- const path = key ? `/${this.siteID}/${storeName}/${key}` : `/${this.siteID}/${storeName}`;
152
- const url2 = new URL(path, consistency === "strong" ? this.uncachedEdgeURL : this.edgeURL);
194
+ const url2 = new URL(urlPath, consistency === "strong" ? this.uncachedEdgeURL : this.edgeURL);
153
195
  for (const key2 in parameters) {
154
196
  url2.searchParams.set(key2, parameters[key2]);
155
197
  }
@@ -159,28 +201,29 @@ var Client = class {
159
201
  };
160
202
  }
161
203
  const apiHeaders = { authorization: `Bearer ${this.token}` };
162
- const url = new URL(`/api/v1/sites/${this.siteID}/blobs`, this.apiURL ?? "https://api.netlify.com");
204
+ const url = new URL(`/api/v1/blobs${urlPath}`, this.apiURL ?? "https://api.netlify.com");
163
205
  for (const key2 in parameters) {
164
206
  url.searchParams.set(key2, parameters[key2]);
165
207
  }
166
- url.searchParams.set("context", storeName);
167
- if (key === void 0) {
208
+ if (storeName === void 0 || key === void 0) {
168
209
  return {
169
210
  headers: apiHeaders,
170
211
  url: url.toString()
171
212
  };
172
213
  }
173
- url.pathname += `/${key}`;
174
214
  if (encodedMetadata) {
175
215
  apiHeaders[METADATA_HEADER_EXTERNAL] = encodedMetadata;
176
216
  }
177
- if (method === "head") {
217
+ if (method === "head" || method === "delete") {
178
218
  return {
179
219
  headers: apiHeaders,
180
220
  url: url.toString()
181
221
  };
182
222
  }
183
- const res = await this.fetch(url.toString(), { headers: apiHeaders, method });
223
+ const res = await this.fetch(url.toString(), {
224
+ headers: { ...apiHeaders, accept: SIGNED_URL_ACCEPT_HEADER },
225
+ method
226
+ });
184
227
  if (res.status !== 200) {
185
228
  throw new Error(`Netlify Blobs has generated an internal error: ${res.status} response`);
186
229
  }
@@ -245,29 +288,24 @@ var getClientOptions = (options, contextOverride) => {
245
288
  };
246
289
  return clientOptions;
247
290
  };
248
- var BlobsInternalError = class extends Error {
249
- constructor(statusCode) {
250
- super(`Netlify Blobs has generated an internal error: ${statusCode} response`);
251
- this.name = "BlobsInternalError";
252
- }
253
- };
254
- var collectIterator = async (iterator) => {
255
- const result = [];
256
- for await (const item of iterator) {
257
- result.push(item);
258
- }
259
- return result;
260
- };
291
+
292
+ // node_modules/@netlify/blobs/dist/main.js
293
+ var DEPLOY_STORE_PREFIX = "deploy:";
294
+ var LEGACY_STORE_INTERNAL_PREFIX = "netlify-internal/legacy-namespace/";
295
+ var SITE_STORE_PREFIX = "site:";
261
296
  var Store = class _Store {
262
297
  constructor(options) {
263
298
  this.client = options.client;
264
- this.consistency = options.consistency ?? "eventual";
265
299
  if ("deployID" in options) {
266
300
  _Store.validateDeployID(options.deployID);
267
- this.name = `deploy:${options.deployID}`;
301
+ this.name = DEPLOY_STORE_PREFIX + options.deployID;
302
+ } else if (options.name.startsWith(LEGACY_STORE_INTERNAL_PREFIX)) {
303
+ const storeName = options.name.slice(LEGACY_STORE_INTERNAL_PREFIX.length);
304
+ _Store.validateStoreName(storeName);
305
+ this.name = storeName;
268
306
  } else {
269
307
  _Store.validateStoreName(options.name);
270
- this.name = options.name;
308
+ this.name = SITE_STORE_PREFIX + options.name;
271
309
  }
272
310
  }
273
311
  async delete(key) {
@@ -422,7 +460,7 @@ var Store = class _Store {
422
460
  if (key.startsWith("/") || key.startsWith("%2F")) {
423
461
  throw new Error("Blob key must not start with forward slash (/).");
424
462
  }
425
- if (Buffer3.byteLength(key, "utf8") > 600) {
463
+ if (new TextEncoder().encode(key).length > 600) {
426
464
  throw new Error(
427
465
  "Blob key must be a sequence of Unicode characters whose UTF-8 encoding is at most 600 bytes long."
428
466
  );
@@ -434,13 +472,10 @@ var Store = class _Store {
434
472
  }
435
473
  }
436
474
  static validateStoreName(name) {
437
- if (name.startsWith("deploy:") || name.startsWith("deploy%3A1")) {
438
- throw new Error("Store name must not start with the `deploy:` reserved keyword.");
439
- }
440
475
  if (name.includes("/") || name.includes("%2F")) {
441
476
  throw new Error("Store name must not contain forward slashes (/).");
442
477
  }
443
- if (Buffer3.byteLength(name, "utf8") > 64) {
478
+ if (new TextEncoder().encode(name).length > 64) {
444
479
  throw new Error(
445
480
  "Store name must be a sequence of Unicode characters whose UTF-8 encoding is at most 64 bytes long."
446
481
  );
@@ -503,7 +538,6 @@ var getDeployStore = (options = {}) => {
503
538
  const client = new Client(clientOptions);
504
539
  return new Store({ client, deployID });
505
540
  };
506
- var pipeline = promisify(stream.pipeline);
507
541
 
508
542
  // src/run/headers.ts
509
543
  var generateNetlifyVaryValues = ({ headers, languages, cookies }) => {
@@ -0,0 +1,61 @@
1
+
2
+ var require = await (async () => {
3
+ var { createRequire } = await import("node:module");
4
+ return createRequire(import.meta.url);
5
+ })();
6
+
7
+ import {
8
+ require_semver
9
+ } from "./chunk-PJG75HGC.js";
10
+ import {
11
+ __toESM
12
+ } from "./chunk-5JVNISGM.js";
13
+
14
+ // src/build/verification.ts
15
+ var import_semver = __toESM(require_semver(), 1);
16
+ import { existsSync } from "node:fs";
17
+ var SUPPORTED_NEXT_VERSIONS = ">=13.5.0";
18
+ function verifyPublishDir(ctx) {
19
+ if (!existsSync(ctx.publishDir)) {
20
+ ctx.failBuild(
21
+ `Your publish directory was not found at: ${ctx.publishDir}, please check your build settings`
22
+ );
23
+ }
24
+ if (ctx.publishDir === ctx.resolveFromPackagePath("")) {
25
+ ctx.failBuild(
26
+ `Your publish directory cannot be the same as the base directory of your site, please check your build settings`
27
+ );
28
+ }
29
+ try {
30
+ ctx.buildConfig;
31
+ } catch {
32
+ ctx.failBuild(
33
+ "Your publish directory does not contain expected Next.js build output, please check your build settings"
34
+ );
35
+ }
36
+ if (!existsSync(ctx.standaloneRootDir)) {
37
+ ctx.failBuild(
38
+ `Your publish directory does not contain expected Next.js build output, please make sure you are using Next.js version (${SUPPORTED_NEXT_VERSIONS})`
39
+ );
40
+ }
41
+ }
42
+ function verifyNextVersion(ctx, nextVersion) {
43
+ if (!(0, import_semver.satisfies)(nextVersion, SUPPORTED_NEXT_VERSIONS, { includePrerelease: true })) {
44
+ ctx.failBuild(
45
+ `@netlify/plugin-next@5 requires Next.js version ${SUPPORTED_NEXT_VERSIONS}, but found ${nextVersion}. Please upgrade your project's Next.js version.`
46
+ );
47
+ }
48
+ }
49
+ function verifyBuildConfig(ctx) {
50
+ if (ctx.buildConfig.experimental.ppr) {
51
+ console.log(
52
+ `Partial prerendering is not yet fully supported on Netlify, see https://ntl.fyi/nextjs-ppr for details`
53
+ );
54
+ }
55
+ }
56
+
57
+ export {
58
+ verifyPublishDir,
59
+ verifyNextVersion,
60
+ verifyBuildConfig
61
+ };