@edgeone/opennextjs-pages 0.1.5 → 0.1.6-beta.1
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/middleware/compiler.js +65 -18
- package/dist/build/functions/middleware/middleware.js +12 -7
- package/dist/build/functions/middleware/polyfills/index.js +24 -0
- package/dist/build/functions/middleware/wrapper.js +51 -32
- package/dist/build/plugin-context.js +44 -13
- package/dist/build/route-utils.js +698 -0
- package/dist/build/routes.js +203 -100
- package/dist/run/handlers/tags-handler.cjs +1 -1
- package/package.json +1 -1
package/dist/build/routes.js
CHANGED
|
@@ -9,18 +9,85 @@ import "../esm-chunks/chunk-6BT4RYQJ.js";
|
|
|
9
9
|
// src/build/routes.ts
|
|
10
10
|
import * as fs from "fs";
|
|
11
11
|
import * as path from "path";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
import {
|
|
13
|
+
convertRedirects,
|
|
14
|
+
convertRewrites,
|
|
15
|
+
convertHeaders,
|
|
16
|
+
convertTrailingSlash
|
|
17
|
+
} from "./route-utils.js";
|
|
18
|
+
function hasAppRouter(appPathRoutesManifest) {
|
|
19
|
+
return appPathRoutesManifest && Object.keys(appPathRoutesManifest).length > 0;
|
|
20
|
+
}
|
|
21
|
+
function getBuildId(ctx) {
|
|
22
|
+
try {
|
|
23
|
+
const buildIdPath = path.join(ctx.publishDir, "BUILD_ID");
|
|
24
|
+
if (fs.existsSync(buildIdPath)) {
|
|
25
|
+
return fs.readFileSync(buildIdPath, "utf-8").trim();
|
|
26
|
+
}
|
|
27
|
+
} catch {
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
function isRE2Compatible(regex) {
|
|
32
|
+
if (/\(\?[=!<]/.test(regex)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (/\\[1-9]/.test(regex)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
function convertNamedRegexToSrc(namedRegex, basePath = "") {
|
|
41
|
+
const regexWithoutNamedGroups = namedRegex.replace(/\(\?<[a-zA-Z][a-zA-Z0-9_]*>/g, "(");
|
|
42
|
+
if (!isRE2Compatible(regexWithoutNamedGroups)) {
|
|
43
|
+
console.warn(`[opennext] Warning: Regex not RE2 compatible, skipping: ${namedRegex}`);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
let src = namedRegex.replace(/\(\?<[a-zA-Z][a-zA-Z0-9_]*>/g, "(");
|
|
47
|
+
if (basePath && !src.startsWith(`^${basePath}`)) {
|
|
48
|
+
src = src.replace(/^\^/, `^${basePath}`);
|
|
49
|
+
}
|
|
50
|
+
return src;
|
|
51
|
+
}
|
|
52
|
+
function getDynamicRoutes(dynamicRoutes, basePath = "") {
|
|
53
|
+
const routes = [];
|
|
54
|
+
for (const route of dynamicRoutes) {
|
|
55
|
+
if (route.namedRegex) {
|
|
56
|
+
const src = convertNamedRegexToSrc(route.namedRegex, basePath);
|
|
57
|
+
if (src) {
|
|
58
|
+
routes.push({ src });
|
|
59
|
+
}
|
|
60
|
+
} else if (route.regex) {
|
|
61
|
+
if (isRE2Compatible(route.regex)) {
|
|
62
|
+
let src = route.regex;
|
|
63
|
+
if (basePath && !src.startsWith(`^${basePath}`)) {
|
|
64
|
+
src = src.replace(/^\^/, `^${basePath}`);
|
|
65
|
+
}
|
|
66
|
+
routes.push({ src });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return routes;
|
|
71
|
+
}
|
|
72
|
+
function getDataRoutes(dataRoutes, basePath = "") {
|
|
73
|
+
const routes = [];
|
|
74
|
+
for (const route of dataRoutes) {
|
|
75
|
+
if (route.namedDataRouteRegex) {
|
|
76
|
+
const src = convertNamedRegexToSrc(route.namedDataRouteRegex, basePath);
|
|
77
|
+
if (src) {
|
|
78
|
+
routes.push({ src });
|
|
79
|
+
}
|
|
80
|
+
} else if (route.dataRouteRegex) {
|
|
81
|
+
if (isRE2Compatible(route.dataRouteRegex)) {
|
|
82
|
+
let src = route.dataRouteRegex;
|
|
83
|
+
if (basePath && !src.startsWith(`^${basePath}`)) {
|
|
84
|
+
src = src.replace(/^\^/, `^${basePath}`);
|
|
85
|
+
}
|
|
86
|
+
routes.push({ src });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return routes;
|
|
24
91
|
}
|
|
25
92
|
async function getMiddlewareConfig(ctx) {
|
|
26
93
|
try {
|
|
@@ -46,9 +113,14 @@ async function getMiddlewareConfig(ctx) {
|
|
|
46
113
|
matcher: normalizedMatchers.map((item) => ({ source: item.source }))
|
|
47
114
|
};
|
|
48
115
|
}
|
|
116
|
+
const nextDistDir = ctx.nextDistDir || ".next";
|
|
49
117
|
const possibleFunctionsConfigPaths = [
|
|
50
|
-
|
|
51
|
-
path.join(ctx.distDir, "server/functions-config-manifest.json")
|
|
118
|
+
// 1. 使用配置的 distDir
|
|
119
|
+
path.join(ctx.distDir, "server/functions-config-manifest.json"),
|
|
120
|
+
// 2. 相对于当前工作目录(使用配置的 nextDistDir)
|
|
121
|
+
path.join(process.cwd(), nextDistDir, "server/functions-config-manifest.json"),
|
|
122
|
+
// 3. 兼容默认 .next 目录
|
|
123
|
+
path.join(process.cwd(), ".next/server/functions-config-manifest.json")
|
|
52
124
|
];
|
|
53
125
|
let functionsConfigPath = "";
|
|
54
126
|
for (const p of possibleFunctionsConfigPaths) {
|
|
@@ -86,8 +158,8 @@ async function getMiddlewareConfig(ctx) {
|
|
|
86
158
|
return null;
|
|
87
159
|
}
|
|
88
160
|
}
|
|
89
|
-
function
|
|
90
|
-
const metaJsonPath = path.join(process.cwd(), ".edgeone/edge-functions/
|
|
161
|
+
function updateEdgeFunctionsConfigJson(middlewareConfig) {
|
|
162
|
+
const metaJsonPath = path.join(process.cwd(), ".edgeone/edge-functions/config.json");
|
|
91
163
|
let meta = { routes: [] };
|
|
92
164
|
if (fs.existsSync(metaJsonPath)) {
|
|
93
165
|
try {
|
|
@@ -105,101 +177,129 @@ function updateEdgeFunctionsMetaJson(middlewareConfig) {
|
|
|
105
177
|
}
|
|
106
178
|
fs.writeFileSync(metaJsonPath, JSON.stringify(meta, null, 2), "utf-8");
|
|
107
179
|
}
|
|
108
|
-
var convertNextRoutePattern = (path2) => {
|
|
109
|
-
if (!path2.includes("[")) {
|
|
110
|
-
return path2;
|
|
111
|
-
}
|
|
112
|
-
let convertedPath = path2;
|
|
113
|
-
const optionalCatchAllMatch = path2.match(/\[\[\.\.\.([^\]]+)\]\]/);
|
|
114
|
-
if (optionalCatchAllMatch) {
|
|
115
|
-
const paramName = optionalCatchAllMatch[1];
|
|
116
|
-
convertedPath = convertedPath.replace(/\[\[\.\.\.([^\]]+)\]\]/g, `:${paramName}*`);
|
|
117
|
-
}
|
|
118
|
-
const catchAllMatch = path2.match(/\[\.\.\.([^\]]+)\]/);
|
|
119
|
-
if (catchAllMatch) {
|
|
120
|
-
const paramName = catchAllMatch[1];
|
|
121
|
-
convertedPath = convertedPath.replace(/\[\.\.\.([^\]]+)\]/g, `:${paramName}*`);
|
|
122
|
-
}
|
|
123
|
-
const dynamicMatch = path2.match(/\[([^\]]+)\]/);
|
|
124
|
-
if (dynamicMatch) {
|
|
125
|
-
const paramName = dynamicMatch[1];
|
|
126
|
-
convertedPath = convertedPath.replace(/\[([^\]]+)\]/g, `:${paramName}`);
|
|
127
|
-
}
|
|
128
|
-
return convertedPath;
|
|
129
|
-
};
|
|
130
180
|
var createRouteMeta = async (ctx) => {
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
181
|
+
const routes = [];
|
|
182
|
+
const routesManifest = await ctx.getRoutesManifest();
|
|
183
|
+
const appPathRoutesManifest = await ctx.getAppPathRoutesManifest();
|
|
184
|
+
const isAppRouter = hasAppRouter(appPathRoutesManifest);
|
|
185
|
+
const basePath = routesManifest?.basePath || "";
|
|
186
|
+
const trailingSlash = ctx.requiredServerFiles?.config?.trailingSlash ?? false;
|
|
187
|
+
const redirects = routesManifest?.redirects || [];
|
|
188
|
+
const headers = routesManifest?.headers || [];
|
|
189
|
+
const rewrites = routesManifest?.rewrites || { beforeFiles: [], afterFiles: [], fallback: [] };
|
|
190
|
+
let beforeFilesRewrites = [];
|
|
191
|
+
let afterFilesRewrites = [];
|
|
192
|
+
let fallbackRewrites = [];
|
|
193
|
+
if (Array.isArray(rewrites)) {
|
|
194
|
+
afterFilesRewrites = rewrites;
|
|
195
|
+
} else {
|
|
196
|
+
beforeFilesRewrites = rewrites.beforeFiles || [];
|
|
197
|
+
afterFilesRewrites = rewrites.afterFiles || [];
|
|
198
|
+
fallbackRewrites = rewrites.fallback || [];
|
|
143
199
|
}
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
200
|
+
const dynamicRoutes = routesManifest?.dynamicRoutes || [];
|
|
201
|
+
const dataRoutes = routesManifest?.dataRoutes || [];
|
|
202
|
+
const buildId = getBuildId(ctx);
|
|
203
|
+
const staticCacheRegex = buildId ? `^${basePath}/_next/static/(?:[^/]+/pages|pages|chunks|runtime|css|image|media|${buildId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})/.+` : `^${basePath}/_next/static/(?:[^/]+/pages|pages|chunks|runtime|css|image|media)/.+`;
|
|
204
|
+
routes.push({
|
|
205
|
+
src: staticCacheRegex,
|
|
206
|
+
headers: {
|
|
207
|
+
"cache-control": "public,max-age=31536000,immutable"
|
|
208
|
+
},
|
|
209
|
+
continue: true
|
|
210
|
+
});
|
|
211
|
+
if (trailingSlash) {
|
|
212
|
+
routes.push(...convertTrailingSlash(true));
|
|
213
|
+
} else {
|
|
214
|
+
routes.push(...convertTrailingSlash(false));
|
|
215
|
+
}
|
|
216
|
+
if (headers.length > 0) {
|
|
217
|
+
try {
|
|
218
|
+
routes.push(...convertHeaders(headers));
|
|
219
|
+
} catch (e) {
|
|
220
|
+
console.warn("[opennext] Warning: Failed to convert some headers:", e);
|
|
153
221
|
}
|
|
154
222
|
}
|
|
155
|
-
const
|
|
156
|
-
if (
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
223
|
+
const userRedirects = redirects.filter((r) => !r.internal);
|
|
224
|
+
if (userRedirects.length > 0) {
|
|
225
|
+
try {
|
|
226
|
+
routes.push(...convertRedirects(userRedirects));
|
|
227
|
+
} catch (e) {
|
|
228
|
+
console.warn("[opennext] Warning: Failed to convert some redirects:", e);
|
|
161
229
|
}
|
|
162
230
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
routeMap[dataRouteRegex] = {
|
|
169
|
-
isStatic: routeMap[page]?.isStatic || false
|
|
170
|
-
};
|
|
171
|
-
}
|
|
231
|
+
if (beforeFilesRewrites.length > 0) {
|
|
232
|
+
try {
|
|
233
|
+
routes.push(...convertRewrites(beforeFilesRewrites));
|
|
234
|
+
} catch (e) {
|
|
235
|
+
console.warn("[opennext] Warning: Failed to convert beforeFiles rewrites:", e);
|
|
172
236
|
}
|
|
173
237
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
238
|
+
if (isAppRouter) {
|
|
239
|
+
const rscVary = "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch";
|
|
240
|
+
const rscContentType = "text/x-component";
|
|
241
|
+
routes.push({
|
|
242
|
+
src: `^${basePath}/?$`,
|
|
243
|
+
has: [{ type: "header", key: "rsc", value: "1" }],
|
|
244
|
+
dest: `${basePath}/index.rsc`,
|
|
245
|
+
headers: { vary: rscVary, "content-type": rscContentType },
|
|
246
|
+
continue: true
|
|
247
|
+
});
|
|
248
|
+
routes.push({
|
|
249
|
+
src: `^${basePath}/(.+?)(?:/)?$`,
|
|
250
|
+
exclude: "\\.rsc/?$",
|
|
251
|
+
has: [{ type: "header", key: "rsc", value: "1" }],
|
|
252
|
+
dest: `${basePath}/$1.rsc`,
|
|
253
|
+
headers: { vary: rscVary, "content-type": rscContentType },
|
|
254
|
+
continue: true
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
routes.push({
|
|
258
|
+
src: `^${basePath}/404/?$`,
|
|
259
|
+
status: 404,
|
|
260
|
+
continue: true,
|
|
261
|
+
missing: [{ type: "header", key: "x-prerender-revalidate" }]
|
|
262
|
+
});
|
|
263
|
+
routes.push({
|
|
264
|
+
src: `^${basePath}/500$`,
|
|
265
|
+
status: 500,
|
|
266
|
+
continue: true
|
|
267
|
+
});
|
|
268
|
+
routes.push({
|
|
269
|
+
src: `^${basePath}/((?:[^/]+/)*[^/.]+)/$`,
|
|
270
|
+
dest: `${basePath}/$1`,
|
|
271
|
+
continue: true
|
|
272
|
+
});
|
|
273
|
+
routes.push({ handle: "filesystem" });
|
|
274
|
+
if (afterFilesRewrites.length > 0) {
|
|
275
|
+
try {
|
|
276
|
+
routes.push(...convertRewrites(afterFilesRewrites));
|
|
277
|
+
} catch (e) {
|
|
278
|
+
console.warn("[opennext] Warning: Failed to convert afterFiles rewrites:", e);
|
|
179
279
|
}
|
|
180
280
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
pathsToDelete.push(routePath);
|
|
187
|
-
convertedRouteMap[convertedPath] = routeConfig;
|
|
281
|
+
if (fallbackRewrites.length > 0) {
|
|
282
|
+
try {
|
|
283
|
+
routes.push(...convertRewrites(fallbackRewrites));
|
|
284
|
+
} catch (e) {
|
|
285
|
+
console.warn("[opennext] Warning: Failed to convert fallback rewrites:", e);
|
|
188
286
|
}
|
|
189
287
|
}
|
|
190
|
-
|
|
191
|
-
|
|
288
|
+
if (dynamicRoutes.length > 0) {
|
|
289
|
+
routes.push(...getDynamicRoutes(dynamicRoutes, basePath));
|
|
192
290
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
291
|
+
if (dataRoutes.length > 0) {
|
|
292
|
+
routes.push(...getDataRoutes(dataRoutes, basePath));
|
|
293
|
+
}
|
|
294
|
+
routes.push({
|
|
295
|
+
src: `^${basePath}/.*$`
|
|
296
|
+
});
|
|
198
297
|
const serverHandlerDir = ctx.serverHandlerRootDir;
|
|
199
298
|
if (!fs.existsSync(serverHandlerDir)) {
|
|
200
299
|
fs.mkdirSync(serverHandlerDir, { recursive: true });
|
|
201
300
|
}
|
|
202
|
-
const
|
|
301
|
+
const nextVersion = ctx.nextVersion || null;
|
|
302
|
+
const imagesManifest = await ctx.getImagesManifest();
|
|
203
303
|
const updatedRedirects = [];
|
|
204
304
|
if (imagesManifest?.images?.path) {
|
|
205
305
|
const imagePath = imagesManifest.images.path;
|
|
@@ -210,21 +310,24 @@ var createRouteMeta = async (ctx) => {
|
|
|
210
310
|
};
|
|
211
311
|
updatedRedirects.push(nextImageRedirect);
|
|
212
312
|
}
|
|
213
|
-
const
|
|
313
|
+
const config = {
|
|
314
|
+
version: 3,
|
|
315
|
+
routes,
|
|
214
316
|
conf: {
|
|
215
317
|
redirects: updatedRedirects
|
|
216
318
|
},
|
|
217
|
-
|
|
319
|
+
...nextVersion ? { framework: { version: nextVersion } } : {}
|
|
218
320
|
};
|
|
321
|
+
const configFilePath = path.join(serverHandlerDir, "config.json");
|
|
219
322
|
fs.writeFileSync(
|
|
220
|
-
|
|
221
|
-
JSON.stringify(
|
|
323
|
+
configFilePath,
|
|
324
|
+
JSON.stringify(config, null, 2),
|
|
222
325
|
"utf-8"
|
|
223
326
|
);
|
|
327
|
+
console.log(`[opennext] Generated ${configFilePath} with ${routes.length} routes`);
|
|
224
328
|
const middlewareConfig = await getMiddlewareConfig(ctx);
|
|
225
|
-
|
|
329
|
+
updateEdgeFunctionsConfigJson(middlewareConfig);
|
|
226
330
|
};
|
|
227
331
|
export {
|
|
228
|
-
convertNextRoutePattern,
|
|
229
332
|
createRouteMeta
|
|
230
333
|
};
|
|
@@ -28,7 +28,7 @@ module.exports = __toCommonJS(tags_handler_exports);
|
|
|
28
28
|
|
|
29
29
|
// package.json
|
|
30
30
|
var name = "@edgeone/opennextjs-pages";
|
|
31
|
-
var version = "0.1.
|
|
31
|
+
var version = "0.1.6-beta.1";
|
|
32
32
|
|
|
33
33
|
// src/run/handlers/tags-handler.cts
|
|
34
34
|
var import_request_context = require("./request-context.cjs");
|