@netlify/plugin-nextjs 5.6.0 → 5.7.0-ipx.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/functions/edge.js +4 -0
- package/dist/build/functions/ipx.js +83 -0
- package/dist/build/image-cdn.js +64 -59
- package/dist/build/plugin-context.js +13 -0
- package/dist/build/templates/ipx-edge-accept-handler.ts +13 -0
- package/dist/build/templates/ipx.ts +11 -0
- package/dist/esm-chunks/{package-OHGYB5OD.js → package-O63J727E.js} +6 -2
- package/dist/index.js +1 -1
- package/dist/run/handlers/tracing.js +1 -1
- package/package.json +5 -2
|
@@ -392,6 +392,7 @@ var import_path_to_regexp = __toESM(require_dist(), 1);
|
|
|
392
392
|
import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
393
393
|
import { dirname, join } from "node:path";
|
|
394
394
|
import { EDGE_HANDLER_NAME } from "../plugin-context.js";
|
|
395
|
+
import { createIpxEdgeAcceptHandler } from "./ipx.js";
|
|
395
396
|
var writeEdgeManifest = async (ctx, manifest) => {
|
|
396
397
|
await mkdir(ctx.edgeFunctionsDir, { recursive: true });
|
|
397
398
|
await writeFile(join(ctx.edgeFunctionsDir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
@@ -513,6 +514,9 @@ var createEdgeHandlers = async (ctx) => {
|
|
|
513
514
|
version: 1,
|
|
514
515
|
functions: netlifyDefinitions
|
|
515
516
|
};
|
|
517
|
+
if (ctx.imageService === "ipx") {
|
|
518
|
+
await createIpxEdgeAcceptHandler(ctx, netlifyManifest);
|
|
519
|
+
}
|
|
516
520
|
await writeEdgeManifest(ctx, netlifyManifest);
|
|
517
521
|
};
|
|
518
522
|
export {
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
|
|
2
|
+
var require = await (async () => {
|
|
3
|
+
var { createRequire } = await import("node:module");
|
|
4
|
+
return createRequire(import.meta.url);
|
|
5
|
+
})();
|
|
6
|
+
|
|
7
|
+
import "../../esm-chunks/chunk-OEQOKJGE.js";
|
|
8
|
+
|
|
9
|
+
// src/build/functions/ipx.ts
|
|
10
|
+
import { cp, mkdir, writeFile } from "fs/promises";
|
|
11
|
+
import { join } from "path";
|
|
12
|
+
import { IPX_HANDLER_NAME } from "../plugin-context.js";
|
|
13
|
+
var sanitizeEdgePath = (imagesPath) => new URL(imagesPath, process.env.URL || "http://n").pathname;
|
|
14
|
+
var getAdjustedImageConfig = (ctx) => {
|
|
15
|
+
return {
|
|
16
|
+
...ctx.buildConfig.images,
|
|
17
|
+
basePath: [ctx.buildConfig.basePath, IPX_HANDLER_NAME].join("/")
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
var createIpxHandler = async (ctx) => {
|
|
21
|
+
await mkdir(ctx.ipxHandlerRootDir, { recursive: true });
|
|
22
|
+
await cp(
|
|
23
|
+
join(ctx.pluginDir, "dist/build/templates/ipx.ts"),
|
|
24
|
+
join(ctx.ipxHandlerRootDir, "_ipx.ts")
|
|
25
|
+
);
|
|
26
|
+
await writeFile(
|
|
27
|
+
join(ctx.ipxHandlerRootDir, "imageconfig.json"),
|
|
28
|
+
JSON.stringify(getAdjustedImageConfig(ctx))
|
|
29
|
+
);
|
|
30
|
+
await writeFile(
|
|
31
|
+
join(ctx.ipxHandlerRootDir, "_ipx.json"),
|
|
32
|
+
JSON.stringify({
|
|
33
|
+
version: 1,
|
|
34
|
+
config: {
|
|
35
|
+
name: "next/image handler",
|
|
36
|
+
generator: `${ctx.pluginName}@${ctx.pluginVersion}`,
|
|
37
|
+
timeout: 120
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
ctx.netlifyConfig.redirects.push(
|
|
42
|
+
{
|
|
43
|
+
from: ctx.buildConfig.images.path,
|
|
44
|
+
// eslint-disable-next-line id-length
|
|
45
|
+
query: { url: ":url", w: ":width", q: ":quality" },
|
|
46
|
+
to: `${ctx.buildConfig.basePath}/${IPX_HANDLER_NAME}/w_:width,q_:quality/:url`,
|
|
47
|
+
status: 301
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
from: `${ctx.buildConfig.basePath}/${IPX_HANDLER_NAME}/*`,
|
|
51
|
+
to: `/.netlify/builders/${IPX_HANDLER_NAME}`,
|
|
52
|
+
status: 200
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
var createIpxEdgeAcceptHandler = async (ctx, netlifyManifest) => {
|
|
57
|
+
await mkdir(ctx.ipxEdgeHandlerRootDir, { recursive: true });
|
|
58
|
+
await cp(
|
|
59
|
+
join(ctx.pluginDir, "dist/build/templates/ipx-edge-accept-handler.ts"),
|
|
60
|
+
join(ctx.ipxEdgeHandlerRootDir, "index.ts")
|
|
61
|
+
);
|
|
62
|
+
await writeFile(
|
|
63
|
+
join(ctx.ipxEdgeHandlerRootDir, "imageconfig.json"),
|
|
64
|
+
JSON.stringify(getAdjustedImageConfig(ctx))
|
|
65
|
+
);
|
|
66
|
+
netlifyManifest.functions.push({
|
|
67
|
+
function: IPX_HANDLER_NAME,
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
name: "next/image handler",
|
|
71
|
+
path: ctx.buildConfig.images.path ? sanitizeEdgePath(ctx.buildConfig.images.path) : "/_next/image",
|
|
72
|
+
generator: `${ctx.pluginName}@${ctx.pluginVersion}`
|
|
73
|
+
});
|
|
74
|
+
netlifyManifest.layers ??= [];
|
|
75
|
+
netlifyManifest.layers.push({
|
|
76
|
+
name: `https://ipx-edge-function-layer.netlify.app/mod.ts`,
|
|
77
|
+
flag: "ipx-edge-function-layer-url"
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
export {
|
|
81
|
+
createIpxEdgeAcceptHandler,
|
|
82
|
+
createIpxHandler
|
|
83
|
+
};
|
package/dist/build/image-cdn.js
CHANGED
|
@@ -1528,6 +1528,7 @@ var require_picomatch2 = __commonJS({
|
|
|
1528
1528
|
|
|
1529
1529
|
// src/build/image-cdn.ts
|
|
1530
1530
|
var import_picomatch = __toESM(require_picomatch2(), 1);
|
|
1531
|
+
import { createIpxHandler } from "./functions/ipx.js";
|
|
1531
1532
|
function generateRegexFromPattern(pattern) {
|
|
1532
1533
|
return (0, import_picomatch.makeRe)(pattern).source;
|
|
1533
1534
|
}
|
|
@@ -1538,67 +1539,71 @@ var setImageConfig = async (ctx) => {
|
|
|
1538
1539
|
if (imageLoader !== "default") {
|
|
1539
1540
|
return;
|
|
1540
1541
|
}
|
|
1541
|
-
ctx.
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
//
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
if (remotePatterns
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1542
|
+
if (ctx.imageService === "ipx") {
|
|
1543
|
+
await createIpxHandler(ctx);
|
|
1544
|
+
} else {
|
|
1545
|
+
ctx.netlifyConfig.redirects.push(
|
|
1546
|
+
{
|
|
1547
|
+
from: imageEndpointPath,
|
|
1548
|
+
// w and q are too short to be used as params with id-length rule
|
|
1549
|
+
// but we are forced to do so because of the next/image loader decides on their names
|
|
1550
|
+
// eslint-disable-next-line id-length
|
|
1551
|
+
query: { url: ":url", w: ":width", q: ":quality" },
|
|
1552
|
+
to: "/.netlify/images?url=:url&w=:width&q=:quality",
|
|
1553
|
+
status: 200
|
|
1554
|
+
},
|
|
1555
|
+
// when migrating from @netlify/plugin-nextjs@4 image redirect to ipx might be cached in the browser
|
|
1556
|
+
{
|
|
1557
|
+
from: "/_ipx/*",
|
|
1558
|
+
// w and q are too short to be used as params with id-length rule
|
|
1559
|
+
// but we are forced to do so because of the next/image loader decides on their names
|
|
1560
|
+
// eslint-disable-next-line id-length
|
|
1561
|
+
query: { url: ":url", w: ":width", q: ":quality" },
|
|
1562
|
+
to: "/.netlify/images?url=:url&w=:width&q=:quality",
|
|
1563
|
+
status: 200
|
|
1564
|
+
}
|
|
1565
|
+
);
|
|
1566
|
+
if (remotePatterns?.length !== 0 || domains?.length !== 0) {
|
|
1567
|
+
ctx.netlifyConfig.images ||= { remote_images: [] };
|
|
1568
|
+
ctx.netlifyConfig.images.remote_images ||= [];
|
|
1569
|
+
if (remotePatterns && remotePatterns.length !== 0) {
|
|
1570
|
+
for (const remotePattern of remotePatterns) {
|
|
1571
|
+
let { protocol, hostname, port, pathname } = remotePattern;
|
|
1572
|
+
if (pathname) {
|
|
1573
|
+
pathname = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
1574
|
+
}
|
|
1575
|
+
const combinedRemotePattern = `${protocol ?? "http?(s)"}://${hostname}${port ? `:${port}` : ""}${pathname ?? "/**"}`;
|
|
1576
|
+
try {
|
|
1577
|
+
ctx.netlifyConfig.images.remote_images.push(
|
|
1578
|
+
generateRegexFromPattern(combinedRemotePattern)
|
|
1579
|
+
);
|
|
1580
|
+
} catch (error) {
|
|
1581
|
+
ctx.failBuild(
|
|
1582
|
+
`Failed to generate Image CDN remote image regex from Next.js remote pattern: ${JSON.stringify(
|
|
1583
|
+
{ remotePattern, combinedRemotePattern },
|
|
1584
|
+
null,
|
|
1585
|
+
2
|
|
1586
|
+
)}`,
|
|
1587
|
+
error
|
|
1588
|
+
);
|
|
1589
|
+
}
|
|
1585
1590
|
}
|
|
1586
1591
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1592
|
+
if (domains && domains.length !== 0) {
|
|
1593
|
+
for (const domain of domains) {
|
|
1594
|
+
const patternFromDomain = `http?(s)://${domain}/**`;
|
|
1595
|
+
try {
|
|
1596
|
+
ctx.netlifyConfig.images.remote_images.push(generateRegexFromPattern(patternFromDomain));
|
|
1597
|
+
} catch (error) {
|
|
1598
|
+
ctx.failBuild(
|
|
1599
|
+
`Failed to generate Image CDN remote image regex from Next.js domain: ${JSON.stringify(
|
|
1600
|
+
{ domain, patternFromDomain },
|
|
1601
|
+
null,
|
|
1602
|
+
2
|
|
1603
|
+
)}`,
|
|
1604
|
+
error
|
|
1605
|
+
);
|
|
1606
|
+
}
|
|
1602
1607
|
}
|
|
1603
1608
|
}
|
|
1604
1609
|
}
|
|
@@ -23,6 +23,7 @@ var MODULE_DIR = fileURLToPath(new URL(".", import.meta.url));
|
|
|
23
23
|
var PLUGIN_DIR = join(MODULE_DIR, "../..");
|
|
24
24
|
var DEFAULT_PUBLISH_DIR = ".next";
|
|
25
25
|
var SERVER_HANDLER_NAME = "___netlify-server-handler";
|
|
26
|
+
var IPX_HANDLER_NAME = "_ipx";
|
|
26
27
|
var EDGE_HANDLER_NAME = "___netlify-edge-handler";
|
|
27
28
|
var PluginContext = class {
|
|
28
29
|
featureFlags;
|
|
@@ -116,6 +117,9 @@ var PluginContext = class {
|
|
|
116
117
|
const REQUIRED_BUILD_VERSION = ">=29.41.5";
|
|
117
118
|
return (0, import_semver.satisfies)(this.buildVersion, REQUIRED_BUILD_VERSION, { includePrerelease: true });
|
|
118
119
|
}
|
|
120
|
+
get imageService() {
|
|
121
|
+
return "ipx";
|
|
122
|
+
}
|
|
119
123
|
/**
|
|
120
124
|
* Absolute path of the directory containing the files for the serverless lambda function
|
|
121
125
|
* `.netlify/functions-internal`
|
|
@@ -127,6 +131,10 @@ var PluginContext = class {
|
|
|
127
131
|
get serverHandlerRootDir() {
|
|
128
132
|
return join(this.serverFunctionsDir, SERVER_HANDLER_NAME);
|
|
129
133
|
}
|
|
134
|
+
/** Absolute path of the ipx handler */
|
|
135
|
+
get ipxHandlerRootDir() {
|
|
136
|
+
return join(this.serverFunctionsDir, IPX_HANDLER_NAME);
|
|
137
|
+
}
|
|
130
138
|
get serverHandlerDir() {
|
|
131
139
|
if (this.relativeAppDir.length === 0) {
|
|
132
140
|
return this.serverHandlerRootDir;
|
|
@@ -153,6 +161,10 @@ var PluginContext = class {
|
|
|
153
161
|
get edgeHandlerDir() {
|
|
154
162
|
return join(this.edgeFunctionsDir, EDGE_HANDLER_NAME);
|
|
155
163
|
}
|
|
164
|
+
/** Absolute path of the ipx edge handler */
|
|
165
|
+
get ipxEdgeHandlerRootDir() {
|
|
166
|
+
return join(this.edgeFunctionsDir, IPX_HANDLER_NAME);
|
|
167
|
+
}
|
|
156
168
|
constructor(options) {
|
|
157
169
|
this.constants = options.constants;
|
|
158
170
|
this.featureFlags = options.featureFlags;
|
|
@@ -276,6 +288,7 @@ var PluginContext = class {
|
|
|
276
288
|
};
|
|
277
289
|
export {
|
|
278
290
|
EDGE_HANDLER_NAME,
|
|
291
|
+
IPX_HANDLER_NAME,
|
|
279
292
|
PluginContext,
|
|
280
293
|
SERVER_HANDLER_NAME
|
|
281
294
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
import { getHandler } from 'https://ipx-edge-function-layer.netlify.app/mod.ts'
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
6
|
+
// @ts-ignore Injected at build time
|
|
7
|
+
import imageconfig from './imageconfig.json' assert { type: 'json' }
|
|
8
|
+
|
|
9
|
+
export default getHandler({
|
|
10
|
+
formats: imageconfig?.formats,
|
|
11
|
+
basePath: imageconfig?.basePath,
|
|
12
|
+
imageCDNCompat: true,
|
|
13
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createIPXHandler } from '@netlify/ipx'
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
4
|
+
// @ts-ignore Injected at build time
|
|
5
|
+
import { basePath, domains, remotePatterns } from './imageconfig.json'
|
|
6
|
+
|
|
7
|
+
export const handler = createIPXHandler({
|
|
8
|
+
basePath,
|
|
9
|
+
domains,
|
|
10
|
+
remotePatterns,
|
|
11
|
+
})
|
|
@@ -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.
|
|
11
|
+
var version = "5.7.0-ipx.0";
|
|
12
12
|
var description = "Run Next.js seamlessly on Netlify";
|
|
13
13
|
var main = "./dist/index.js";
|
|
14
14
|
var type = "module";
|
|
@@ -55,6 +55,9 @@ var bugs = {
|
|
|
55
55
|
url: "https://github.com/netlify/next-runtime/issues"
|
|
56
56
|
};
|
|
57
57
|
var homepage = "https://github.com/netlify/next-runtime#readme";
|
|
58
|
+
var dependencies = {
|
|
59
|
+
"@netlify/ipx": "^1.4.6"
|
|
60
|
+
};
|
|
58
61
|
var devDependencies = {
|
|
59
62
|
"@fastly/http-compute-js": "1.1.4",
|
|
60
63
|
"@netlify/blobs": "^7.3.0",
|
|
@@ -104,7 +107,6 @@ var clean_package = {
|
|
|
104
107
|
indent: 2,
|
|
105
108
|
remove: [
|
|
106
109
|
"clean-package",
|
|
107
|
-
"dependencies",
|
|
108
110
|
"devDependencies",
|
|
109
111
|
"scripts"
|
|
110
112
|
]
|
|
@@ -123,6 +125,7 @@ var package_default = {
|
|
|
123
125
|
license,
|
|
124
126
|
bugs,
|
|
125
127
|
homepage,
|
|
128
|
+
dependencies,
|
|
126
129
|
devDependencies,
|
|
127
130
|
"clean-package": clean_package
|
|
128
131
|
};
|
|
@@ -130,6 +133,7 @@ export {
|
|
|
130
133
|
bugs,
|
|
131
134
|
clean_package as "clean-package",
|
|
132
135
|
package_default as default,
|
|
136
|
+
dependencies,
|
|
133
137
|
description,
|
|
134
138
|
devDependencies,
|
|
135
139
|
engines,
|
package/dist/index.js
CHANGED
|
@@ -62,7 +62,7 @@ var onBuild = async (options) => {
|
|
|
62
62
|
await saveBuildCache(ctx);
|
|
63
63
|
}
|
|
64
64
|
if (ctx.buildConfig.output === "export") {
|
|
65
|
-
return copyStaticExport(ctx);
|
|
65
|
+
return Promise.all([copyStaticExport(ctx), setImageConfig(ctx)]);
|
|
66
66
|
}
|
|
67
67
|
await verifyAdvancedAPIRoutes(ctx);
|
|
68
68
|
await verifyNetlifyFormsWorkaround(ctx);
|
|
@@ -67385,7 +67385,7 @@ var import_semantic_conventions = __toESM(require_src(), 1);
|
|
|
67385
67385
|
import { getLogger } from "./request-context.cjs";
|
|
67386
67386
|
var {
|
|
67387
67387
|
default: { version, name }
|
|
67388
|
-
} = await import("../../esm-chunks/package-
|
|
67388
|
+
} = await import("../../esm-chunks/package-O63J727E.js");
|
|
67389
67389
|
var sdk = new import_sdk_node.NodeSDK({
|
|
67390
67390
|
resource: new import_resources.Resource({
|
|
67391
67391
|
[import_semantic_conventions.SEMRESATTRS_SERVICE_NAME]: name,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/plugin-nextjs",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.7.0-ipx.0",
|
|
4
4
|
"description": "Run Next.js seamlessly on Netlify",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,5 +26,8 @@
|
|
|
26
26
|
"bugs": {
|
|
27
27
|
"url": "https://github.com/netlify/next-runtime/issues"
|
|
28
28
|
},
|
|
29
|
-
"homepage": "https://github.com/netlify/next-runtime#readme"
|
|
29
|
+
"homepage": "https://github.com/netlify/next-runtime#readme",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@netlify/ipx": "^1.4.6"
|
|
32
|
+
}
|
|
30
33
|
}
|