@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 +16 -0
- package/dist/build/content/prerendered.js +1 -1
- package/dist/build/content/server.js +5 -1
- package/dist/build/content/static.js +1 -1
- package/dist/build/functions/edge.js +2 -2
- package/dist/build/functions/server.js +5 -3
- package/dist/build/plugin-context.js +1 -1
- package/dist/build/verification.js +18 -0
- package/dist/esm-chunks/{chunk-MPZEWLBG.js → chunk-3IGTKVSS.js} +4 -2
- package/dist/esm-chunks/{chunk-655Y7ISI.js → chunk-3NYX5FXN.js} +30 -33
- package/dist/esm-chunks/{chunk-UTCWWUFW.js → chunk-637Y3P2U.js} +99 -65
- package/dist/esm-chunks/chunk-7CY6B4WT.js +61 -0
- package/dist/esm-chunks/{chunk-E3NFUTWC.js → chunk-7HI65MAI.js} +7 -5
- package/dist/esm-chunks/{chunk-52WMBYKL.js → chunk-BKDCZVBK.js} +56 -8
- package/dist/esm-chunks/chunk-GQ6KIYPX.js +1658 -0
- package/dist/esm-chunks/{chunk-ZZOGIP2V.js → chunk-OBKVBMAL.js} +27 -34
- package/dist/esm-chunks/chunk-PJG75HGC.js +2454 -0
- package/dist/esm-chunks/{chunk-67EWAGDQ.js → chunk-VSH4JS2L.js} +18 -6
- package/dist/esm-chunks/{package-V53S3A76.js → package-K6MJITES.js} +10 -5
- package/dist/index.js +13 -7
- package/dist/run/handlers/cache.cjs +878 -1722
- package/dist/run/handlers/server.js +25 -9
- package/dist/run/handlers/tracing.js +5249 -6840
- package/dist/run/headers.js +1 -1
- package/dist/run/next.cjs +863 -1717
- package/package.json +2 -10
- package/dist/esm-chunks/chunk-VDDK7MXY.js +0 -1661
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-
|
|
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-
|
|
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-
|
|
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-
|
|
9
|
+
} from "../../esm-chunks/chunk-OBKVBMAL.js";
|
|
10
10
|
import "../../esm-chunks/chunk-VZNKO4OO.js";
|
|
11
|
-
import "../../esm-chunks/chunk-
|
|
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-
|
|
10
|
-
import "../../esm-chunks/chunk-
|
|
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-
|
|
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 {
|
|
@@ -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.
|
|
47
|
-
await cp(ctx.
|
|
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 {
|
|
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.
|
|
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.
|
|
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
|
|
44
|
-
return this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
154
|
-
/** Get
|
|
155
|
-
get
|
|
156
|
-
if (!this.
|
|
157
|
-
this.
|
|
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
|
-
)
|
|
164
|
+
);
|
|
160
165
|
}
|
|
161
|
-
return this.
|
|
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/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
var collectIterator = async (iterator) => {
|
|
19
|
+
const result = [];
|
|
20
|
+
for await (const item of iterator) {
|
|
21
|
+
result.push(item);
|
|
30
22
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
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
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
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((
|
|
114
|
-
setTimeout(
|
|
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
|
|
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/
|
|
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
|
-
|
|
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(), {
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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 =
|
|
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 (
|
|
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 (
|
|
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
|
+
};
|