@edgeone/opennextjs-pages 0.1.5 → 0.1.6-beta.2
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 +258 -100
- package/dist/run/handlers/tags-handler.cjs +1 -1
- package/package.json +1 -1
package/dist/build/routes.js
CHANGED
|
@@ -9,18 +9,130 @@ 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;
|
|
91
|
+
}
|
|
92
|
+
function getServerRoutes(staticRoutes, prerenderManifest, basePath = "") {
|
|
93
|
+
const routes = [];
|
|
94
|
+
const prerenderRoutes = prerenderManifest?.routes || {};
|
|
95
|
+
for (const route of staticRoutes) {
|
|
96
|
+
if (route.page.startsWith("/_")) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const prerenderInfo = prerenderRoutes[route.page];
|
|
100
|
+
if (prerenderInfo && prerenderInfo.initialRevalidateSeconds === false) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (route.namedRegex) {
|
|
104
|
+
let src = convertNamedRegexToSrc(route.namedRegex, basePath);
|
|
105
|
+
if (src) {
|
|
106
|
+
src = src.replace(/\(\?:\/\)\?\$$/, "$");
|
|
107
|
+
routes.push({ src });
|
|
108
|
+
}
|
|
109
|
+
} else if (route.regex) {
|
|
110
|
+
if (isRE2Compatible(route.regex)) {
|
|
111
|
+
let src = route.regex;
|
|
112
|
+
if (basePath && !src.startsWith(`^${basePath}`)) {
|
|
113
|
+
src = src.replace(/^\^/, `^${basePath}`);
|
|
114
|
+
}
|
|
115
|
+
src = src.replace(/\(\?:\/\)\?\$$/, "$");
|
|
116
|
+
routes.push({ src });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return routes;
|
|
121
|
+
}
|
|
122
|
+
function getApiRoutes(appPathsManifest, basePath = "") {
|
|
123
|
+
if (!appPathsManifest) {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
const routes = [];
|
|
127
|
+
for (const routePath of Object.keys(appPathsManifest)) {
|
|
128
|
+
if (routePath.includes("/api/") && routePath.endsWith("/route")) {
|
|
129
|
+
const apiPath = routePath.replace(/\/route$/, "");
|
|
130
|
+
const escapedPath = apiPath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
131
|
+
const src = `^${basePath}${escapedPath}$`;
|
|
132
|
+
routes.push({ src });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return routes;
|
|
24
136
|
}
|
|
25
137
|
async function getMiddlewareConfig(ctx) {
|
|
26
138
|
try {
|
|
@@ -46,9 +158,14 @@ async function getMiddlewareConfig(ctx) {
|
|
|
46
158
|
matcher: normalizedMatchers.map((item) => ({ source: item.source }))
|
|
47
159
|
};
|
|
48
160
|
}
|
|
161
|
+
const nextDistDir = ctx.nextDistDir || ".next";
|
|
49
162
|
const possibleFunctionsConfigPaths = [
|
|
50
|
-
|
|
51
|
-
path.join(ctx.distDir, "server/functions-config-manifest.json")
|
|
163
|
+
// 1. 使用配置的 distDir
|
|
164
|
+
path.join(ctx.distDir, "server/functions-config-manifest.json"),
|
|
165
|
+
// 2. 相对于当前工作目录(使用配置的 nextDistDir)
|
|
166
|
+
path.join(process.cwd(), nextDistDir, "server/functions-config-manifest.json"),
|
|
167
|
+
// 3. 兼容默认 .next 目录
|
|
168
|
+
path.join(process.cwd(), ".next/server/functions-config-manifest.json")
|
|
52
169
|
];
|
|
53
170
|
let functionsConfigPath = "";
|
|
54
171
|
for (const p of possibleFunctionsConfigPaths) {
|
|
@@ -86,8 +203,8 @@ async function getMiddlewareConfig(ctx) {
|
|
|
86
203
|
return null;
|
|
87
204
|
}
|
|
88
205
|
}
|
|
89
|
-
function
|
|
90
|
-
const metaJsonPath = path.join(process.cwd(), ".edgeone/edge-functions/
|
|
206
|
+
function updateEdgeFunctionsConfigJson(middlewareConfig) {
|
|
207
|
+
const metaJsonPath = path.join(process.cwd(), ".edgeone/edge-functions/config.json");
|
|
91
208
|
let meta = { routes: [] };
|
|
92
209
|
if (fs.existsSync(metaJsonPath)) {
|
|
93
210
|
try {
|
|
@@ -105,101 +222,139 @@ function updateEdgeFunctionsMetaJson(middlewareConfig) {
|
|
|
105
222
|
}
|
|
106
223
|
fs.writeFileSync(metaJsonPath, JSON.stringify(meta, null, 2), "utf-8");
|
|
107
224
|
}
|
|
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
225
|
var createRouteMeta = async (ctx) => {
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
226
|
+
const routes = [];
|
|
227
|
+
const routesManifest = await ctx.getRoutesManifest();
|
|
228
|
+
const appPathRoutesManifest = await ctx.getAppPathRoutesManifest();
|
|
229
|
+
const isAppRouter = hasAppRouter(appPathRoutesManifest);
|
|
230
|
+
const basePath = routesManifest?.basePath || "";
|
|
231
|
+
const trailingSlash = ctx.requiredServerFiles?.config?.trailingSlash ?? false;
|
|
232
|
+
const redirects = routesManifest?.redirects || [];
|
|
233
|
+
const headers = routesManifest?.headers || [];
|
|
234
|
+
const rewrites = routesManifest?.rewrites || { beforeFiles: [], afterFiles: [], fallback: [] };
|
|
235
|
+
let beforeFilesRewrites = [];
|
|
236
|
+
let afterFilesRewrites = [];
|
|
237
|
+
let fallbackRewrites = [];
|
|
238
|
+
if (Array.isArray(rewrites)) {
|
|
239
|
+
afterFilesRewrites = rewrites;
|
|
240
|
+
} else {
|
|
241
|
+
beforeFilesRewrites = rewrites.beforeFiles || [];
|
|
242
|
+
afterFilesRewrites = rewrites.afterFiles || [];
|
|
243
|
+
fallbackRewrites = rewrites.fallback || [];
|
|
143
244
|
}
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
245
|
+
const dynamicRoutes = routesManifest?.dynamicRoutes || [];
|
|
246
|
+
const dataRoutes = routesManifest?.dataRoutes || [];
|
|
247
|
+
const staticRoutes = routesManifest?.staticRoutes || [];
|
|
248
|
+
const appPathsManifest = await ctx.getAppPathsManifest?.() || null;
|
|
249
|
+
const prerenderManifest = await ctx.getPrerenderManifest?.() || null;
|
|
250
|
+
const buildId = getBuildId(ctx);
|
|
251
|
+
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)/.+`;
|
|
252
|
+
routes.push({
|
|
253
|
+
src: staticCacheRegex,
|
|
254
|
+
headers: {
|
|
255
|
+
"cache-control": "public,max-age=31536000,immutable"
|
|
256
|
+
},
|
|
257
|
+
continue: true
|
|
258
|
+
});
|
|
259
|
+
if (trailingSlash) {
|
|
260
|
+
routes.push(...convertTrailingSlash(true));
|
|
261
|
+
} else {
|
|
262
|
+
routes.push(...convertTrailingSlash(false));
|
|
263
|
+
}
|
|
264
|
+
if (headers.length > 0) {
|
|
265
|
+
try {
|
|
266
|
+
routes.push(...convertHeaders(headers));
|
|
267
|
+
} catch (e) {
|
|
268
|
+
console.warn("[opennext] Warning: Failed to convert some headers:", e);
|
|
153
269
|
}
|
|
154
270
|
}
|
|
155
|
-
const
|
|
156
|
-
if (
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
271
|
+
const userRedirects = redirects.filter((r) => !r.internal);
|
|
272
|
+
if (userRedirects.length > 0) {
|
|
273
|
+
try {
|
|
274
|
+
routes.push(...convertRedirects(userRedirects));
|
|
275
|
+
} catch (e) {
|
|
276
|
+
console.warn("[opennext] Warning: Failed to convert some redirects:", e);
|
|
161
277
|
}
|
|
162
278
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
routeMap[dataRouteRegex] = {
|
|
169
|
-
isStatic: routeMap[page]?.isStatic || false
|
|
170
|
-
};
|
|
171
|
-
}
|
|
279
|
+
if (beforeFilesRewrites.length > 0) {
|
|
280
|
+
try {
|
|
281
|
+
routes.push(...convertRewrites(beforeFilesRewrites));
|
|
282
|
+
} catch (e) {
|
|
283
|
+
console.warn("[opennext] Warning: Failed to convert beforeFiles rewrites:", e);
|
|
172
284
|
}
|
|
173
285
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
286
|
+
if (isAppRouter) {
|
|
287
|
+
const rscVary = "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch";
|
|
288
|
+
const rscContentType = "text/x-component";
|
|
289
|
+
routes.push({
|
|
290
|
+
src: `^${basePath}/?$`,
|
|
291
|
+
has: [{ type: "header", key: "rsc", value: "1" }],
|
|
292
|
+
dest: `${basePath}/index.rsc`,
|
|
293
|
+
headers: { vary: rscVary, "content-type": rscContentType },
|
|
294
|
+
continue: true
|
|
295
|
+
});
|
|
296
|
+
routes.push({
|
|
297
|
+
src: `^${basePath}/(.+?)(?:/)?$`,
|
|
298
|
+
exclude: "\\.rsc/?$",
|
|
299
|
+
has: [{ type: "header", key: "rsc", value: "1" }],
|
|
300
|
+
dest: `${basePath}/$1.rsc`,
|
|
301
|
+
headers: { vary: rscVary, "content-type": rscContentType },
|
|
302
|
+
continue: true
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
routes.push({
|
|
306
|
+
src: `^${basePath}/404/?$`,
|
|
307
|
+
status: 404,
|
|
308
|
+
continue: true,
|
|
309
|
+
missing: [{ type: "header", key: "x-prerender-revalidate" }]
|
|
310
|
+
});
|
|
311
|
+
routes.push({
|
|
312
|
+
src: `^${basePath}/500$`,
|
|
313
|
+
status: 500,
|
|
314
|
+
continue: true
|
|
315
|
+
});
|
|
316
|
+
routes.push({
|
|
317
|
+
src: `^${basePath}/((?:[^/]+/)*[^/.]+)/$`,
|
|
318
|
+
dest: `${basePath}/$1`,
|
|
319
|
+
continue: true
|
|
320
|
+
});
|
|
321
|
+
routes.push({ handle: "filesystem" });
|
|
322
|
+
if (afterFilesRewrites.length > 0) {
|
|
323
|
+
try {
|
|
324
|
+
routes.push(...convertRewrites(afterFilesRewrites));
|
|
325
|
+
} catch (e) {
|
|
326
|
+
console.warn("[opennext] Warning: Failed to convert afterFiles rewrites:", e);
|
|
179
327
|
}
|
|
180
328
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
pathsToDelete.push(routePath);
|
|
187
|
-
convertedRouteMap[convertedPath] = routeConfig;
|
|
329
|
+
if (fallbackRewrites.length > 0) {
|
|
330
|
+
try {
|
|
331
|
+
routes.push(...convertRewrites(fallbackRewrites));
|
|
332
|
+
} catch (e) {
|
|
333
|
+
console.warn("[opennext] Warning: Failed to convert fallback rewrites:", e);
|
|
188
334
|
}
|
|
189
335
|
}
|
|
190
|
-
|
|
191
|
-
|
|
336
|
+
if (staticRoutes.length > 0) {
|
|
337
|
+
routes.push(...getServerRoutes(staticRoutes, prerenderManifest, basePath));
|
|
338
|
+
}
|
|
339
|
+
if (dynamicRoutes.length > 0) {
|
|
340
|
+
routes.push(...getDynamicRoutes(dynamicRoutes, basePath));
|
|
192
341
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
342
|
+
if (dataRoutes.length > 0) {
|
|
343
|
+
routes.push(...getDataRoutes(dataRoutes, basePath));
|
|
344
|
+
}
|
|
345
|
+
const apiRoutes = getApiRoutes(appPathsManifest, basePath);
|
|
346
|
+
if (apiRoutes.length > 0) {
|
|
347
|
+
routes.push(...apiRoutes);
|
|
348
|
+
}
|
|
349
|
+
routes.push({
|
|
350
|
+
src: `^${basePath}/.*$`
|
|
351
|
+
});
|
|
198
352
|
const serverHandlerDir = ctx.serverHandlerRootDir;
|
|
199
353
|
if (!fs.existsSync(serverHandlerDir)) {
|
|
200
354
|
fs.mkdirSync(serverHandlerDir, { recursive: true });
|
|
201
355
|
}
|
|
202
|
-
const
|
|
356
|
+
const nextVersion = ctx.nextVersion || null;
|
|
357
|
+
const imagesManifest = await ctx.getImagesManifest();
|
|
203
358
|
const updatedRedirects = [];
|
|
204
359
|
if (imagesManifest?.images?.path) {
|
|
205
360
|
const imagePath = imagesManifest.images.path;
|
|
@@ -210,21 +365,24 @@ var createRouteMeta = async (ctx) => {
|
|
|
210
365
|
};
|
|
211
366
|
updatedRedirects.push(nextImageRedirect);
|
|
212
367
|
}
|
|
213
|
-
const
|
|
368
|
+
const config = {
|
|
369
|
+
version: 3,
|
|
370
|
+
routes,
|
|
214
371
|
conf: {
|
|
215
372
|
redirects: updatedRedirects
|
|
216
373
|
},
|
|
217
|
-
|
|
374
|
+
...nextVersion ? { framework: { version: nextVersion } } : {}
|
|
218
375
|
};
|
|
376
|
+
const configFilePath = path.join(serverHandlerDir, "config.json");
|
|
219
377
|
fs.writeFileSync(
|
|
220
|
-
|
|
221
|
-
JSON.stringify(
|
|
378
|
+
configFilePath,
|
|
379
|
+
JSON.stringify(config, null, 2),
|
|
222
380
|
"utf-8"
|
|
223
381
|
);
|
|
382
|
+
console.log(`[opennext] Generated ${configFilePath} with ${routes.length} routes`);
|
|
224
383
|
const middlewareConfig = await getMiddlewareConfig(ctx);
|
|
225
|
-
|
|
384
|
+
updateEdgeFunctionsConfigJson(middlewareConfig);
|
|
226
385
|
};
|
|
227
386
|
export {
|
|
228
|
-
convertNextRoutePattern,
|
|
229
387
|
createRouteMeta
|
|
230
388
|
};
|
|
@@ -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.2";
|
|
32
32
|
|
|
33
33
|
// src/run/handlers/tags-handler.cts
|
|
34
34
|
var import_request_context = require("./request-context.cjs");
|