@edgeone/nuxt-pages 1.0.15 → 1.0.16
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/content/static.js +2 -2
- package/dist/build/functions/server.js +1 -3
- package/dist/build/plugin-context.js +2 -4
- package/dist/build/routes.js +2 -4
- package/dist/build/templates/nuxt-handler-monorepo.tmpl.js +9 -1
- package/dist/esm-chunks/{chunk-BZJ7SD7E.js → chunk-7X4RPD4I.js} +1 -1
- package/dist/esm-chunks/{chunk-ESOQYHZZ.js → chunk-BZQMVWYQ.js} +37 -129
- package/dist/esm-chunks/{chunk-KYSZO4TW.js → chunk-J25U56II.js} +4 -3
- package/dist/esm-chunks/{chunk-ZG3P7BHA.js → chunk-MONI3XWQ.js} +1 -23
- package/dist/esm-chunks/{chunk-DOOA3WBA.js → chunk-RNEZUAPL.js} +5 -12
- package/dist/index.js +6 -9
- package/dist/utils.js +1 -7
- package/package.json +1 -1
- package/dist/build/templates/nuxt-handler-monorepo.tmpl-ipx_backup.js +0 -511
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
import {
|
|
8
8
|
addNitroBuildOutputConfig,
|
|
9
9
|
resetNitroConfig
|
|
10
|
-
} from "../../esm-chunks/chunk-
|
|
11
|
-
import "../../esm-chunks/chunk-
|
|
10
|
+
} from "../../esm-chunks/chunk-7X4RPD4I.js";
|
|
11
|
+
import "../../esm-chunks/chunk-MONI3XWQ.js";
|
|
12
12
|
import "../../esm-chunks/chunk-V2LFVP3C.js";
|
|
13
13
|
import "../../esm-chunks/chunk-6BT4RYQJ.js";
|
|
14
14
|
export {
|
|
@@ -5,15 +5,13 @@
|
|
|
5
5
|
})();
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
-
clearStaleServerHandlers,
|
|
9
8
|
createServerHandler,
|
|
10
9
|
patchNitroHandler
|
|
11
|
-
} from "../../esm-chunks/chunk-
|
|
10
|
+
} from "../../esm-chunks/chunk-RNEZUAPL.js";
|
|
12
11
|
import "../../esm-chunks/chunk-NJ4SUJNF.js";
|
|
13
12
|
import "../../esm-chunks/chunk-V2LFVP3C.js";
|
|
14
13
|
import "../../esm-chunks/chunk-6BT4RYQJ.js";
|
|
15
14
|
export {
|
|
16
|
-
clearStaleServerHandlers,
|
|
17
15
|
createServerHandler,
|
|
18
16
|
patchNitroHandler
|
|
19
17
|
};
|
|
@@ -5,14 +5,12 @@
|
|
|
5
5
|
})();
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
-
EDGE_HANDLER_NAME,
|
|
9
8
|
PluginContext,
|
|
10
9
|
SERVER_HANDLER_NAME
|
|
11
|
-
} from "../esm-chunks/chunk-
|
|
12
|
-
import "../esm-chunks/chunk-
|
|
10
|
+
} from "../esm-chunks/chunk-BZQMVWYQ.js";
|
|
11
|
+
import "../esm-chunks/chunk-MONI3XWQ.js";
|
|
13
12
|
import "../esm-chunks/chunk-6BT4RYQJ.js";
|
|
14
13
|
export {
|
|
15
|
-
EDGE_HANDLER_NAME,
|
|
16
14
|
PluginContext,
|
|
17
15
|
SERVER_HANDLER_NAME
|
|
18
16
|
};
|
package/dist/build/routes.js
CHANGED
|
@@ -5,14 +5,12 @@
|
|
|
5
5
|
})();
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
-
convertNuxtRoutePattern,
|
|
9
8
|
createNuxtApiRoutesMeta,
|
|
10
9
|
createNuxtPagesRouteMeta
|
|
11
|
-
} from "../esm-chunks/chunk-
|
|
12
|
-
import "../esm-chunks/chunk-
|
|
10
|
+
} from "../esm-chunks/chunk-J25U56II.js";
|
|
11
|
+
import "../esm-chunks/chunk-MONI3XWQ.js";
|
|
13
12
|
import "../esm-chunks/chunk-6BT4RYQJ.js";
|
|
14
13
|
export {
|
|
15
|
-
convertNuxtRoutePattern,
|
|
16
14
|
createNuxtApiRoutesMeta,
|
|
17
15
|
createNuxtPagesRouteMeta
|
|
18
16
|
};
|
|
@@ -136,7 +136,15 @@ async function getNitroApp() {
|
|
|
136
136
|
// Set correct static assets path
|
|
137
137
|
process.env.NITRO_PUBLIC_DIR = ASSET_DIR;
|
|
138
138
|
|
|
139
|
-
const
|
|
139
|
+
const nitroModule = await (async () => {
|
|
140
|
+
try {
|
|
141
|
+
return await import('./chunks/nitro/nitro.mjs')
|
|
142
|
+
} catch {
|
|
143
|
+
return await import('./chunks/_/nitro.mjs')
|
|
144
|
+
}
|
|
145
|
+
})()
|
|
146
|
+
|
|
147
|
+
const { {{USE_NITRO_APP_SYMBOL}}: useNitroApp } = nitroModule
|
|
140
148
|
nitroApp = useNitroApp();
|
|
141
149
|
}
|
|
142
150
|
return nitroApp;
|
|
@@ -9,21 +9,19 @@ import {
|
|
|
9
9
|
getPrerenderRoutesWithAST,
|
|
10
10
|
getRouteRulesWithAST,
|
|
11
11
|
getRoutesArrayWithAST
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MONI3XWQ.js";
|
|
13
13
|
|
|
14
14
|
// src/build/plugin-context.ts
|
|
15
15
|
import { existsSync, readFileSync } from "node:fs";
|
|
16
16
|
import { readFile } from "node:fs/promises";
|
|
17
|
-
import {
|
|
17
|
+
import { createRequire } from "node:module";
|
|
18
18
|
import { join, relative, resolve } from "node:path";
|
|
19
19
|
import { fileURLToPath } from "node:url";
|
|
20
20
|
var MODULE_DIR = fileURLToPath(new URL(".", import.meta.url));
|
|
21
21
|
var PLUGIN_DIR = join(MODULE_DIR, "../..");
|
|
22
22
|
var DEFAULT_BUILD_DIR = ".nuxt";
|
|
23
23
|
var DEFAULT_OUTPUT_DIR = ".edgeone";
|
|
24
|
-
var NUXT_STATIC_DIR = "assets";
|
|
25
24
|
var SERVER_HANDLER_NAME = "server-handler";
|
|
26
|
-
var EDGE_HANDLER_NAME = "edgeone-edge-handler";
|
|
27
25
|
var PluginContext = class {
|
|
28
26
|
edgeoneConfig;
|
|
29
27
|
pluginName;
|
|
@@ -39,10 +37,6 @@ var PluginContext = class {
|
|
|
39
37
|
get relPublishDir() {
|
|
40
38
|
return this.constants.PUBLISH_DIR ?? join(this.constants.PACKAGE_PATH || "", DEFAULT_OUTPUT_DIR);
|
|
41
39
|
}
|
|
42
|
-
/** Temporary directory for stashing the build output */
|
|
43
|
-
get tempPublishDir() {
|
|
44
|
-
return this.resolveFromPackagePath(".edgeone/server-handler");
|
|
45
|
-
}
|
|
46
40
|
/** Absolute path of the publish directory */
|
|
47
41
|
get publishDir() {
|
|
48
42
|
return resolve(this.relPublishDir);
|
|
@@ -62,12 +56,6 @@ var PluginContext = class {
|
|
|
62
56
|
get lambdaWorkingDirectory() {
|
|
63
57
|
return "";
|
|
64
58
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Retrieves the root of the `.output` directory
|
|
67
|
-
*/
|
|
68
|
-
get outputRootDir() {
|
|
69
|
-
return join(this.publishDir, "server-handler");
|
|
70
|
-
}
|
|
71
59
|
/**
|
|
72
60
|
* The resolved relative nuxt build directory defaults to `.nuxt`,
|
|
73
61
|
* but can be configured through the nuxt.config.js. For monorepos this will include the packagePath
|
|
@@ -77,45 +65,10 @@ var PluginContext = class {
|
|
|
77
65
|
const dir = this.buildConfig?.buildDir ?? DEFAULT_BUILD_DIR;
|
|
78
66
|
return relative(process.cwd(), resolve(this.relativeAppDir, dir));
|
|
79
67
|
}
|
|
80
|
-
/** Represents the parent directory of the .nuxt folder or custom buildDir */
|
|
81
|
-
get distDirParent() {
|
|
82
|
-
return join(this.buildDir, "..");
|
|
83
|
-
}
|
|
84
|
-
/** The `.nuxt` folder or what the custom build dir is set to */
|
|
85
|
-
get nuxtBuildDir() {
|
|
86
|
-
return relative(this.distDirParent, this.buildDir);
|
|
87
|
-
}
|
|
88
68
|
/** The directory where the Nuxt output is stored */
|
|
89
69
|
get outputDir() {
|
|
90
70
|
return DEFAULT_OUTPUT_DIR;
|
|
91
71
|
}
|
|
92
|
-
/** Retrieves the `.output/server/` directory monorepo aware */
|
|
93
|
-
get serverDir() {
|
|
94
|
-
return join(this.outputRootDir);
|
|
95
|
-
}
|
|
96
|
-
/** The directory where the Nuxt static files are stored */
|
|
97
|
-
get nuxtStaticDir() {
|
|
98
|
-
return join(this.outputDir, NUXT_STATIC_DIR);
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Absolute path of the directory that is published and deployed to the CDN
|
|
102
|
-
* Will be swapped with the publish directory
|
|
103
|
-
* `.edgeone/static`
|
|
104
|
-
*/
|
|
105
|
-
get staticDir() {
|
|
106
|
-
return this.resolveFromPackagePath(".edgeone/assets");
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Absolute path of the directory that will be deployed to the blob store
|
|
110
|
-
* region aware: `.edgeone/deploy/v1/blobs/deploy`
|
|
111
|
-
* default: `.edgeone/blobs/deploy`
|
|
112
|
-
*/
|
|
113
|
-
get blobDir() {
|
|
114
|
-
if (this.useRegionalBlobs) {
|
|
115
|
-
return this.resolveFromPackagePath(".edgeone/deploy/v1/blobs/deploy");
|
|
116
|
-
}
|
|
117
|
-
return this.resolveFromPackagePath(".edgeone/blobs/deploy");
|
|
118
|
-
}
|
|
119
72
|
get buildVersion() {
|
|
120
73
|
return this.constants.BUILD_VERSION || "v0.0.0";
|
|
121
74
|
}
|
|
@@ -145,17 +98,6 @@ var PluginContext = class {
|
|
|
145
98
|
get nuxtServerHandler() {
|
|
146
99
|
return "./.edgeone/dist/run/handlers/server.js";
|
|
147
100
|
}
|
|
148
|
-
/**
|
|
149
|
-
* Absolute path of the directory containing the files for deno edge functions
|
|
150
|
-
* `.edgeone/edge-functions`
|
|
151
|
-
*/
|
|
152
|
-
get edgeFunctionsDir() {
|
|
153
|
-
return this.resolveFromPackagePath(".edgeone/edge-functions");
|
|
154
|
-
}
|
|
155
|
-
/** Absolute path of the edge handler */
|
|
156
|
-
get edgeHandlerDir() {
|
|
157
|
-
return join(this.edgeFunctionsDir, EDGE_HANDLER_NAME);
|
|
158
|
-
}
|
|
159
101
|
constructor(options) {
|
|
160
102
|
options = {
|
|
161
103
|
...options,
|
|
@@ -196,46 +138,6 @@ var PluginContext = class {
|
|
|
196
138
|
return { routes: [], prerendered: [] };
|
|
197
139
|
}
|
|
198
140
|
}
|
|
199
|
-
/** Get the nuxt build manifest */
|
|
200
|
-
async getBuildManifest() {
|
|
201
|
-
const buildInfoPath = join(this.nuxtBuildDir, "build-info.json");
|
|
202
|
-
const nitroConfigPath = join(this.outputDir, "nitro.json");
|
|
203
|
-
try {
|
|
204
|
-
let manifestData;
|
|
205
|
-
if (existsSync(buildInfoPath)) {
|
|
206
|
-
manifestData = JSON.parse(await readFile(buildInfoPath, "utf-8"));
|
|
207
|
-
} else if (existsSync(nitroConfigPath)) {
|
|
208
|
-
const nitroConfig = JSON.parse(await readFile(nitroConfigPath, "utf-8"));
|
|
209
|
-
manifestData = {
|
|
210
|
-
version: nitroConfig.version || "1.0.0",
|
|
211
|
-
config: nitroConfig.config || {},
|
|
212
|
-
buildDir: this.buildDir,
|
|
213
|
-
outputDir: this.outputDir,
|
|
214
|
-
routes: nitroConfig.routes || {},
|
|
215
|
-
assets: nitroConfig.assets || {}
|
|
216
|
-
};
|
|
217
|
-
} else {
|
|
218
|
-
manifestData = {
|
|
219
|
-
version: "1.0.0",
|
|
220
|
-
config: {},
|
|
221
|
-
buildDir: DEFAULT_BUILD_DIR,
|
|
222
|
-
outputDir: DEFAULT_OUTPUT_DIR,
|
|
223
|
-
routes: {},
|
|
224
|
-
assets: {}
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
return manifestData;
|
|
228
|
-
} catch (error) {
|
|
229
|
-
return {
|
|
230
|
-
version: "1.0.0",
|
|
231
|
-
config: {},
|
|
232
|
-
buildDir: DEFAULT_BUILD_DIR,
|
|
233
|
-
outputDir: DEFAULT_OUTPUT_DIR,
|
|
234
|
-
routes: {},
|
|
235
|
-
assets: {}
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
141
|
/**
|
|
240
142
|
* Uses various heuristics to try to find the .output dir.
|
|
241
143
|
* Works by looking for nitro.json, so requires the site to have been built
|
|
@@ -257,20 +159,6 @@ var PluginContext = class {
|
|
|
257
159
|
}
|
|
258
160
|
return false;
|
|
259
161
|
}
|
|
260
|
-
/**
|
|
261
|
-
* Get Nuxt nitro config from the build output
|
|
262
|
-
*/
|
|
263
|
-
async getNitroConfig() {
|
|
264
|
-
const nitroPath = join(this.publishDir, "nitro.json");
|
|
265
|
-
try {
|
|
266
|
-
if (!existsSync(nitroPath)) {
|
|
267
|
-
return {};
|
|
268
|
-
}
|
|
269
|
-
return JSON.parse(await readFile(nitroPath, "utf-8"));
|
|
270
|
-
} catch (error) {
|
|
271
|
-
return {};
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
162
|
// don't make private as it is handy inside testing to override the config
|
|
275
163
|
_buildManifest = null;
|
|
276
164
|
/** Get Build manifest from build output **/
|
|
@@ -443,32 +331,53 @@ var PluginContext = class {
|
|
|
443
331
|
}
|
|
444
332
|
#nuxtVersion = void 0;
|
|
445
333
|
/**
|
|
446
|
-
* Get Nuxt version
|
|
334
|
+
* Get the exact Nuxt version installed in the project.
|
|
335
|
+
*
|
|
336
|
+
* Prefer resolving `nuxt/package.json` from the app root (works for monorepo and Yarn PnP),
|
|
337
|
+
* then fall back to node_modules.
|
|
447
338
|
*/
|
|
448
339
|
get nuxtVersion() {
|
|
449
|
-
if (this.#nuxtVersion
|
|
340
|
+
if (this.#nuxtVersion !== void 0) return this.#nuxtVersion;
|
|
341
|
+
const roots = [this.constants.PACKAGE_PATH || process.cwd()].filter(Boolean);
|
|
342
|
+
const readJsonVersion = (pkgJsonPath) => {
|
|
450
343
|
try {
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
cwd: process.cwd(),
|
|
454
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
455
|
-
});
|
|
456
|
-
const versionMatch = output.match(/(?:nuxt|version)[:\s]+(\d+\.\d+\.\d+)/i);
|
|
457
|
-
if (versionMatch && versionMatch[1]) {
|
|
458
|
-
this.#nuxtVersion = versionMatch[1];
|
|
459
|
-
} else {
|
|
460
|
-
this.#nuxtVersion = null;
|
|
461
|
-
}
|
|
344
|
+
const pkg = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
|
|
345
|
+
return typeof pkg.version === "string" && pkg.version.trim() ? pkg.version.trim() : null;
|
|
462
346
|
} catch {
|
|
463
|
-
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
try {
|
|
351
|
+
const require2 = createRequire(import.meta.url);
|
|
352
|
+
const resolved = require2.resolve("nuxt/package.json", { paths: roots });
|
|
353
|
+
const v = readJsonVersion(resolved);
|
|
354
|
+
if (v) {
|
|
355
|
+
this.#nuxtVersion = v;
|
|
356
|
+
return this.#nuxtVersion;
|
|
357
|
+
}
|
|
358
|
+
} catch {
|
|
359
|
+
}
|
|
360
|
+
for (const root of roots) {
|
|
361
|
+
const candidate = resolve(root, "node_modules", "nuxt", "package.json");
|
|
362
|
+
if (existsSync(candidate)) {
|
|
363
|
+
const v = readJsonVersion(candidate);
|
|
364
|
+
if (v) {
|
|
365
|
+
this.#nuxtVersion = v;
|
|
366
|
+
return this.#nuxtVersion;
|
|
367
|
+
}
|
|
464
368
|
}
|
|
465
369
|
}
|
|
370
|
+
this.#nuxtVersion = null;
|
|
466
371
|
return this.#nuxtVersion;
|
|
467
372
|
}
|
|
468
373
|
#nuxtModules = null;
|
|
469
374
|
async nuxtModules() {
|
|
470
375
|
if (!this.#nuxtModules) {
|
|
471
376
|
const nuxtConfig = await this.getNuxtConfig();
|
|
377
|
+
if (!nuxtConfig) {
|
|
378
|
+
this.#nuxtModules = null;
|
|
379
|
+
return this.#nuxtModules;
|
|
380
|
+
}
|
|
472
381
|
try {
|
|
473
382
|
const modules = getModulesWithAST(nuxtConfig);
|
|
474
383
|
this.#nuxtModules = modules;
|
|
@@ -526,6 +435,5 @@ var PluginContext = class {
|
|
|
526
435
|
|
|
527
436
|
export {
|
|
528
437
|
SERVER_HANDLER_NAME,
|
|
529
|
-
EDGE_HANDLER_NAME,
|
|
530
438
|
PluginContext
|
|
531
439
|
};
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
getHandlersArrayWithAST
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MONI3XWQ.js";
|
|
10
10
|
|
|
11
11
|
// src/build/routes.ts
|
|
12
12
|
import * as fs from "fs";
|
|
@@ -126,7 +126,9 @@ var createNuxtApiRoutesMeta = async (ctx) => {
|
|
|
126
126
|
}
|
|
127
127
|
const existingContent = await fs.readFileSync(metaFilePath, "utf-8");
|
|
128
128
|
const existingMetaData = JSON.parse(existingContent);
|
|
129
|
-
const
|
|
129
|
+
const defaultNitroPath = path.join(edgeOneDir, "server-handler", "chunks", "nitro", "nitro.mjs");
|
|
130
|
+
const fallbackNitroPath = path.join(edgeOneDir, "server-handler", "chunks", "_", "nitro.mjs");
|
|
131
|
+
const nitroPath = fs.existsSync(defaultNitroPath) ? defaultNitroPath : fallbackNitroPath;
|
|
130
132
|
let apiRoutes = [];
|
|
131
133
|
if (fs.existsSync(nitroPath)) {
|
|
132
134
|
try {
|
|
@@ -206,7 +208,6 @@ var createNuxtApiRoutesMeta = async (ctx) => {
|
|
|
206
208
|
};
|
|
207
209
|
|
|
208
210
|
export {
|
|
209
|
-
convertNuxtRoutePattern,
|
|
210
211
|
createNuxtPagesRouteMeta,
|
|
211
212
|
createNuxtApiRoutesMeta
|
|
212
213
|
};
|
|
@@ -15092,25 +15092,6 @@ function getModulesWithAST(code) {
|
|
|
15092
15092
|
return [];
|
|
15093
15093
|
}
|
|
15094
15094
|
}
|
|
15095
|
-
function checkModules(modules) {
|
|
15096
|
-
const excludeModules = ["@nuxt/image"];
|
|
15097
|
-
const invalidModules = modules.filter((module) => excludeModules.includes(module));
|
|
15098
|
-
if (invalidModules.length > 0) {
|
|
15099
|
-
console.error("\x1B[31mThe following modules are not supported: \x1B[0m", invalidModules.join(", "));
|
|
15100
|
-
console.log("Further optimizations and adaptations are under development...");
|
|
15101
|
-
process.exit(1);
|
|
15102
|
-
}
|
|
15103
|
-
}
|
|
15104
|
-
function checkNuxtVersion(version) {
|
|
15105
|
-
const versionData = version.split(".");
|
|
15106
|
-
if (versionData.length === 3 && Number(versionData[0]) < 3) {
|
|
15107
|
-
console.error("Nuxt version must be greater than 3.16.0. Compatibility for lower versions is under development...");
|
|
15108
|
-
process.exit(1);
|
|
15109
|
-
}
|
|
15110
|
-
}
|
|
15111
|
-
var removeServerHandler = async (ctx) => {
|
|
15112
|
-
await rm(ctx.serverHandlerDir, { recursive: true, force: true });
|
|
15113
|
-
};
|
|
15114
15095
|
|
|
15115
15096
|
export {
|
|
15116
15097
|
useStaticBuild,
|
|
@@ -15121,8 +15102,5 @@ export {
|
|
|
15121
15102
|
getHandlersArrayWithAST,
|
|
15122
15103
|
addCodeToGenerateEdgeoneWithAST,
|
|
15123
15104
|
resetNitroConfigWithAST,
|
|
15124
|
-
getModulesWithAST
|
|
15125
|
-
checkModules,
|
|
15126
|
-
checkNuxtVersion,
|
|
15127
|
-
removeServerHandler
|
|
15105
|
+
getModulesWithAST
|
|
15128
15106
|
};
|
|
@@ -8,21 +8,16 @@ import {
|
|
|
8
8
|
require_out,
|
|
9
9
|
verifyNuxtHandlerDirStructure
|
|
10
10
|
} from "./chunk-NJ4SUJNF.js";
|
|
11
|
-
import {
|
|
12
|
-
trace,
|
|
13
|
-
wrapTracer
|
|
14
|
-
} from "./chunk-V2LFVP3C.js";
|
|
15
11
|
import {
|
|
16
12
|
__require,
|
|
17
13
|
__toESM
|
|
18
14
|
} from "./chunk-6BT4RYQJ.js";
|
|
19
15
|
|
|
20
16
|
// src/build/functions/server.ts
|
|
21
|
-
|
|
17
|
+
var import_fast_glob = __toESM(require_out(), 1);
|
|
18
|
+
import { cp, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
22
19
|
import { join, relative } from "node:path";
|
|
23
20
|
import { join as posixJoin } from "node:path/posix";
|
|
24
|
-
var import_fast_glob = __toESM(require_out(), 1);
|
|
25
|
-
var tracer = wrapTracer(trace.getTracer("Nuxt runtime"));
|
|
26
21
|
var copyHandlerDependencies = async (ctx) => {
|
|
27
22
|
const promises = [];
|
|
28
23
|
const { included_files: includedFiles = [] } = {};
|
|
@@ -98,9 +93,6 @@ var writeHandlerFile = async (ctx) => {
|
|
|
98
93
|
const handler = await getHandlerFile(ctx);
|
|
99
94
|
await writeFile(join(ctx.serverHandlerRootDir, `handler.js`), handler);
|
|
100
95
|
};
|
|
101
|
-
var clearStaleServerHandlers = async (ctx) => {
|
|
102
|
-
await rm(ctx.serverFunctionsDir, { recursive: true, force: true });
|
|
103
|
-
};
|
|
104
96
|
var createServerHandler = async (ctx) => {
|
|
105
97
|
await mkdir(join(ctx.serverHandlerRuntimeModulesDir), { recursive: true });
|
|
106
98
|
await copyHandlerDependencies(ctx);
|
|
@@ -109,7 +101,9 @@ var createServerHandler = async (ctx) => {
|
|
|
109
101
|
};
|
|
110
102
|
async function patchNitroHandler(ctx) {
|
|
111
103
|
const fs = __require("fs");
|
|
112
|
-
const
|
|
104
|
+
const defaultNitroMjsPath = ".edgeone/server-handler/chunks/nitro/nitro.mjs";
|
|
105
|
+
const fallbackNitroMjsPath = ".edgeone/server-handler/chunks/_/nitro.mjs";
|
|
106
|
+
const nitroMjsPath = fs.existsSync(defaultNitroMjsPath) ? defaultNitroMjsPath : fallbackNitroMjsPath;
|
|
113
107
|
const handlerTmplPath = ".edgeone/server-handler/handler.js";
|
|
114
108
|
const nitroCode = fs.readFileSync(nitroMjsPath, "utf-8");
|
|
115
109
|
const match = nitroCode.match(/export\s*\{[^}]*\buseNitroApp\s+as\s+([A-Za-z_$][\w$]*)/) ?? nitroCode.match(/\buseNitroApp\s+as\s+([A-Za-z_$][\w$]*)\b/);
|
|
@@ -121,7 +115,6 @@ async function patchNitroHandler(ctx) {
|
|
|
121
115
|
}
|
|
122
116
|
|
|
123
117
|
export {
|
|
124
|
-
clearStaleServerHandlers,
|
|
125
118
|
createServerHandler,
|
|
126
119
|
patchNitroHandler
|
|
127
120
|
};
|
package/dist/index.js
CHANGED
|
@@ -6,34 +6,31 @@
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
PluginContext
|
|
9
|
-
} from "./esm-chunks/chunk-
|
|
9
|
+
} from "./esm-chunks/chunk-BZQMVWYQ.js";
|
|
10
10
|
import {
|
|
11
11
|
createNuxtApiRoutesMeta,
|
|
12
12
|
createNuxtPagesRouteMeta
|
|
13
|
-
} from "./esm-chunks/chunk-
|
|
13
|
+
} from "./esm-chunks/chunk-J25U56II.js";
|
|
14
14
|
import {
|
|
15
15
|
addNitroBuildOutputConfig,
|
|
16
16
|
resetNitroConfig
|
|
17
|
-
} from "./esm-chunks/chunk-
|
|
17
|
+
} from "./esm-chunks/chunk-7X4RPD4I.js";
|
|
18
18
|
import {
|
|
19
19
|
resetEdgeOneConfig,
|
|
20
20
|
useStaticBuild
|
|
21
|
-
} from "./esm-chunks/chunk-
|
|
21
|
+
} from "./esm-chunks/chunk-MONI3XWQ.js";
|
|
22
22
|
import {
|
|
23
23
|
createServerHandler,
|
|
24
24
|
patchNitroHandler
|
|
25
|
-
} from "./esm-chunks/chunk-
|
|
25
|
+
} from "./esm-chunks/chunk-RNEZUAPL.js";
|
|
26
26
|
import "./esm-chunks/chunk-NJ4SUJNF.js";
|
|
27
27
|
import "./esm-chunks/chunk-V2LFVP3C.js";
|
|
28
28
|
import "./esm-chunks/chunk-6BT4RYQJ.js";
|
|
29
29
|
|
|
30
30
|
// src/index.ts
|
|
31
|
-
import { rm
|
|
31
|
+
import { rm } from "node:fs/promises";
|
|
32
32
|
import { join } from "node:path";
|
|
33
33
|
import { existsSync } from "node:fs";
|
|
34
|
-
import { exec } from "child_process";
|
|
35
|
-
import { promisify } from "util";
|
|
36
|
-
var execAsync = promisify(exec);
|
|
37
34
|
async function checkModules(ctx, targetModules) {
|
|
38
35
|
const modules = await ctx.nuxtModules();
|
|
39
36
|
if (!modules) return false;
|
package/dist/utils.js
CHANGED
|
@@ -6,29 +6,23 @@
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
addCodeToGenerateEdgeoneWithAST,
|
|
9
|
-
checkModules,
|
|
10
|
-
checkNuxtVersion,
|
|
11
9
|
getHandlersArrayWithAST,
|
|
12
10
|
getModulesWithAST,
|
|
13
11
|
getPrerenderRoutesWithAST,
|
|
14
12
|
getRouteRulesWithAST,
|
|
15
13
|
getRoutesArrayWithAST,
|
|
16
|
-
removeServerHandler,
|
|
17
14
|
resetEdgeOneConfig,
|
|
18
15
|
resetNitroConfigWithAST,
|
|
19
16
|
useStaticBuild
|
|
20
|
-
} from "./esm-chunks/chunk-
|
|
17
|
+
} from "./esm-chunks/chunk-MONI3XWQ.js";
|
|
21
18
|
import "./esm-chunks/chunk-6BT4RYQJ.js";
|
|
22
19
|
export {
|
|
23
20
|
addCodeToGenerateEdgeoneWithAST,
|
|
24
|
-
checkModules,
|
|
25
|
-
checkNuxtVersion,
|
|
26
21
|
getHandlersArrayWithAST,
|
|
27
22
|
getModulesWithAST,
|
|
28
23
|
getPrerenderRoutesWithAST,
|
|
29
24
|
getRouteRulesWithAST,
|
|
30
25
|
getRoutesArrayWithAST,
|
|
31
|
-
removeServerHandler,
|
|
32
26
|
resetEdgeOneConfig,
|
|
33
27
|
resetNitroConfigWithAST,
|
|
34
28
|
useStaticBuild
|
package/package.json
CHANGED
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
import { resolve, dirname } from 'path';
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
|
-
import { readFileSync, existsSync, statSync } from 'fs';
|
|
4
|
-
import { extname } from 'path';
|
|
5
|
-
|
|
6
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
-
const __dirname = dirname(__filename);
|
|
8
|
-
|
|
9
|
-
// Static assets directory
|
|
10
|
-
const ASSET_DIR = resolve(__dirname, '../assets');
|
|
11
|
-
|
|
12
|
-
// MIME type mapping
|
|
13
|
-
const MIME_TYPES = {
|
|
14
|
-
'.html': 'text/html; charset=utf-8',
|
|
15
|
-
'.js': 'application/javascript',
|
|
16
|
-
'.css': 'text/css',
|
|
17
|
-
'.json': 'application/json',
|
|
18
|
-
'.png': 'image/png',
|
|
19
|
-
'.jpg': 'image/jpeg',
|
|
20
|
-
'.jpeg': 'image/jpeg',
|
|
21
|
-
'.gif': 'image/gif',
|
|
22
|
-
'.svg': 'image/svg+xml',
|
|
23
|
-
'.ico': 'image/x-icon',
|
|
24
|
-
'.txt': 'text/plain',
|
|
25
|
-
'.xml': 'application/xml'
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Get the MIME type of a file
|
|
30
|
-
*/
|
|
31
|
-
function getMimeType(filePath) {
|
|
32
|
-
const ext = extname(filePath).toLowerCase();
|
|
33
|
-
return MIME_TYPES[ext] || 'application/octet-stream';
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 解析IPX参数
|
|
38
|
-
*/
|
|
39
|
-
function parseIPXParams(paramString) {
|
|
40
|
-
const params = {};
|
|
41
|
-
|
|
42
|
-
if (!paramString || paramString === '_') {
|
|
43
|
-
return params;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// IPX参数格式: w_800&h_600&q_80&f_webp
|
|
47
|
-
const paramPairs = paramString.split('&');
|
|
48
|
-
|
|
49
|
-
for (const pair of paramPairs) {
|
|
50
|
-
if (pair.includes('_')) {
|
|
51
|
-
const [key, value] = pair.split('_', 2);
|
|
52
|
-
|
|
53
|
-
switch (key) {
|
|
54
|
-
case 'w':
|
|
55
|
-
params.width = parseInt(value);
|
|
56
|
-
break;
|
|
57
|
-
case 'h':
|
|
58
|
-
params.height = parseInt(value);
|
|
59
|
-
break;
|
|
60
|
-
case 's':
|
|
61
|
-
// 尺寸格式: s_800x600
|
|
62
|
-
if (value.includes('x')) {
|
|
63
|
-
const [w, h] = value.split('x');
|
|
64
|
-
params.width = parseInt(w);
|
|
65
|
-
params.height = parseInt(h);
|
|
66
|
-
}
|
|
67
|
-
break;
|
|
68
|
-
case 'q':
|
|
69
|
-
params.quality = parseInt(value);
|
|
70
|
-
break;
|
|
71
|
-
case 'f':
|
|
72
|
-
params.format = value;
|
|
73
|
-
break;
|
|
74
|
-
case 'fit':
|
|
75
|
-
params.fit = value;
|
|
76
|
-
break;
|
|
77
|
-
case 'b':
|
|
78
|
-
case 'bg':
|
|
79
|
-
params.background = value;
|
|
80
|
-
break;
|
|
81
|
-
case 'blur':
|
|
82
|
-
params.blur = parseInt(value);
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return params;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* 处理IPX图片请求 - 简化版本,直接调用Nitro的IPX处理器
|
|
93
|
-
*/
|
|
94
|
-
async function processIPXImage(ipxPath) {
|
|
95
|
-
try {
|
|
96
|
-
const app = await getNitroApp();
|
|
97
|
-
const fullPath = `/_ipx/${ipxPath}`;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// 检查本地文件是否存在,如果是本地文件且存在,直接处理
|
|
101
|
-
if (!ipxPath.includes('http')) {
|
|
102
|
-
const pathParts = ipxPath.split('/');
|
|
103
|
-
let filePath = '';
|
|
104
|
-
let params = {};
|
|
105
|
-
|
|
106
|
-
// 找到实际的文件路径(跳过参数)
|
|
107
|
-
for (let i = 0; i < pathParts.length; i++) {
|
|
108
|
-
const part = pathParts[i];
|
|
109
|
-
if (part.includes('.')) {
|
|
110
|
-
// 找到文件扩展名,这是文件路径的开始
|
|
111
|
-
filePath = pathParts.slice(i).join('/');
|
|
112
|
-
// 前面的部分是参数
|
|
113
|
-
if (i > 0) {
|
|
114
|
-
const paramString = pathParts.slice(0, i).join('&');
|
|
115
|
-
params = parseIPXParams(paramString);
|
|
116
|
-
}
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const localFilePath = resolve(ASSET_DIR, filePath);
|
|
122
|
-
// console.log(`Checking local file: ${localFilePath}`);
|
|
123
|
-
// console.log(`File exists: ${existsSync(localFilePath)}`);
|
|
124
|
-
|
|
125
|
-
// 如果是本地文件且存在,直接返回文件内容(暂时跳过IPX处理)
|
|
126
|
-
if (existsSync(localFilePath)) {
|
|
127
|
-
const fileContent = readFileSync(localFilePath);
|
|
128
|
-
const mimeType = getMimeType(localFilePath);
|
|
129
|
-
|
|
130
|
-
return {
|
|
131
|
-
statusCode: 200,
|
|
132
|
-
headers: {
|
|
133
|
-
'Content-Type': mimeType,
|
|
134
|
-
'Content-Length': fileContent.length.toString(),
|
|
135
|
-
'Cache-Control': 'public, max-age=31536000',
|
|
136
|
-
'from-server': 'true'
|
|
137
|
-
},
|
|
138
|
-
body: fileContent
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const response = await app.localCall({
|
|
144
|
-
url: fullPath,
|
|
145
|
-
method: 'GET',
|
|
146
|
-
headers: {
|
|
147
|
-
'accept': 'image/*'
|
|
148
|
-
},
|
|
149
|
-
body: ''
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
if (!response || response.status !== 200) {
|
|
153
|
-
console.log('IPX processing failed, status code:', response?.status);
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// 处理响应体
|
|
158
|
-
let responseBody;
|
|
159
|
-
|
|
160
|
-
if (response.body) {
|
|
161
|
-
if (Buffer.isBuffer(response.body)) {
|
|
162
|
-
responseBody = response.body;
|
|
163
|
-
} else if (typeof response.body === 'string') {
|
|
164
|
-
// 对于图片数据,使用latin1编码保持二进制完整性
|
|
165
|
-
responseBody = Buffer.from(response.body, 'latin1');
|
|
166
|
-
} else if (response.body && typeof response.body.getReader === 'function') {
|
|
167
|
-
// 处理ReadableStream
|
|
168
|
-
const reader = response.body.getReader();
|
|
169
|
-
const chunks = [];
|
|
170
|
-
|
|
171
|
-
while (true) {
|
|
172
|
-
const { done, value } = await reader.read();
|
|
173
|
-
if (done) break;
|
|
174
|
-
chunks.push(Buffer.from(value));
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
responseBody = Buffer.concat(chunks);
|
|
178
|
-
} else if (response.body instanceof Uint8Array) {
|
|
179
|
-
responseBody = Buffer.from(response.body);
|
|
180
|
-
} else {
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
} else if (response._data) {
|
|
184
|
-
if (Buffer.isBuffer(response._data)) {
|
|
185
|
-
responseBody = response._data;
|
|
186
|
-
} else if (response._data instanceof Uint8Array) {
|
|
187
|
-
responseBody = Buffer.from(response._data);
|
|
188
|
-
} else if (typeof response._data === 'string') {
|
|
189
|
-
responseBody = Buffer.from(response._data, 'latin1');
|
|
190
|
-
} else {
|
|
191
|
-
console.log('Unknown _data format:', typeof response._data);
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
} else {
|
|
195
|
-
console.log('No image data found in IPX response');
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (!responseBody || responseBody.length === 0) {
|
|
200
|
-
console.log('Image data is empty after IPX processing');
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// 获取内容类型
|
|
205
|
-
let contentType = 'image/jpeg';
|
|
206
|
-
if (response.headers) {
|
|
207
|
-
const headers = response.headers instanceof Headers ? response.headers : new Headers(response.headers);
|
|
208
|
-
contentType = headers.get('content-type') || contentType;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// 验证图片数据完整性
|
|
212
|
-
const isValidImage = responseBody.length > 0 && (
|
|
213
|
-
responseBody[0] === 0xFF || // JPEG
|
|
214
|
-
(responseBody[0] === 0x89 && responseBody[1] === 0x50) || // PNG
|
|
215
|
-
(responseBody[0] === 0x47 && responseBody[1] === 0x49) // GIF
|
|
216
|
-
);
|
|
217
|
-
|
|
218
|
-
// console.log(`IPX processing successful: size=${responseBody.length}bytes, type=${contentType}, valid image=${isValidImage}`);
|
|
219
|
-
// console.log(`Image header bytes: ${responseBody.slice(0, 10).toString('hex')}`);
|
|
220
|
-
|
|
221
|
-
return {
|
|
222
|
-
statusCode: 200,
|
|
223
|
-
headers: {
|
|
224
|
-
'Content-Type': contentType,
|
|
225
|
-
'Content-Length': responseBody.length.toString(),
|
|
226
|
-
'Cache-Control': 'public, max-age=31536000', // 1年缓存
|
|
227
|
-
'Accept-Ranges': 'bytes',
|
|
228
|
-
'Access-Control-Allow-Origin': '*',
|
|
229
|
-
'from-server': 'true'
|
|
230
|
-
},
|
|
231
|
-
body: responseBody
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
} catch (error) {
|
|
235
|
-
console.error('IPX processing error:', error);
|
|
236
|
-
console.error('Error stack:', error.stack);
|
|
237
|
-
return null;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Handle static file requests
|
|
243
|
-
*/
|
|
244
|
-
async function handleStaticFile(url) {
|
|
245
|
-
try {
|
|
246
|
-
// Remove query parameters
|
|
247
|
-
let cleanUrl = url.split('?')[0];
|
|
248
|
-
|
|
249
|
-
// Handle IPX image processing paths from @nuxt/image
|
|
250
|
-
// 直接使用IPX处理图片,而不是重定向
|
|
251
|
-
if (cleanUrl.startsWith('/_ipx/')) {
|
|
252
|
-
const ipxPath = cleanUrl.slice(6); // Remove '/_ipx/'
|
|
253
|
-
return processIPXImage(ipxPath);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Handle EdgeOne SSR functions IPX paths
|
|
257
|
-
// 直接使用IPX处理图片
|
|
258
|
-
if(cleanUrl.includes('-ssr-functions/_ipx/')) {
|
|
259
|
-
// 提取IPX路径部分
|
|
260
|
-
const ipxIndex = cleanUrl.indexOf('_ipx/');
|
|
261
|
-
if (ipxIndex !== -1) {
|
|
262
|
-
const ipxPath = cleanUrl.slice(ipxIndex + 5); // Remove '_ipx/'
|
|
263
|
-
return processIPXImage(ipxPath);
|
|
264
|
-
}
|
|
265
|
-
return null;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const possiblePaths = [];
|
|
269
|
-
|
|
270
|
-
// Direct file path
|
|
271
|
-
const directPath = resolve(ASSET_DIR, cleanUrl.startsWith('/') ? cleanUrl.slice(1) : cleanUrl);
|
|
272
|
-
possiblePaths.push(directPath);
|
|
273
|
-
|
|
274
|
-
// Try each possible path
|
|
275
|
-
for (const filePath of possiblePaths) {
|
|
276
|
-
// Security check: ensure file is within asset directory
|
|
277
|
-
if (!filePath.startsWith(ASSET_DIR)) {
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
if (existsSync(filePath) && statSync(filePath).isFile()) {
|
|
282
|
-
const content = readFileSync(filePath);
|
|
283
|
-
const mimeType = getMimeType(filePath);
|
|
284
|
-
|
|
285
|
-
return {
|
|
286
|
-
statusCode: 200,
|
|
287
|
-
headers: {
|
|
288
|
-
'Content-Type': mimeType,
|
|
289
|
-
'Content-Length': content.length.toString(),
|
|
290
|
-
'Cache-Control': 'public, max-age=31536000' // 1 year cache
|
|
291
|
-
},
|
|
292
|
-
body: content
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
} catch (error) {
|
|
297
|
-
console.error('Static file error:', error);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
return null;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Lazy load Nitro application
|
|
305
|
-
*/
|
|
306
|
-
let nitroApp = null;
|
|
307
|
-
async function getNitroApp() {
|
|
308
|
-
if (!nitroApp) {
|
|
309
|
-
// Set environment variables to prevent automatic server startup
|
|
310
|
-
process.env.NITRO_PORT = '';
|
|
311
|
-
process.env.PORT = '';
|
|
312
|
-
|
|
313
|
-
// Set correct static assets path
|
|
314
|
-
process.env.NITRO_PUBLIC_DIR = ASSET_DIR;
|
|
315
|
-
|
|
316
|
-
const { j: useNitroApp } = await import('./chunks/nitro/nitro.mjs');
|
|
317
|
-
nitroApp = useNitroApp();
|
|
318
|
-
|
|
319
|
-
// 检查IPX配置
|
|
320
|
-
const runtimeConfig = nitroApp.hooks.callHook ? await nitroApp.hooks.callHook('render:route', { url: '/' }).catch(() => null) : null;
|
|
321
|
-
console.log('Nitro application initialized');
|
|
322
|
-
}
|
|
323
|
-
return nitroApp;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Handle HTTP response
|
|
328
|
-
*/
|
|
329
|
-
function handleResponse(response, event) {
|
|
330
|
-
if (!response) {
|
|
331
|
-
return {
|
|
332
|
-
statusCode: 500,
|
|
333
|
-
headers: { 'Content-Type': 'text/plain' },
|
|
334
|
-
body: 'Internal Server Error'
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
const headers = {};
|
|
339
|
-
|
|
340
|
-
// Ensure response.headers is a Headers object
|
|
341
|
-
if (!(response.headers instanceof Headers)) {
|
|
342
|
-
response.headers = new Headers(response.headers || {});
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Correctly iterate over Headers object (using entries() method)
|
|
346
|
-
for (const [key, value] of response.headers.entries()) {
|
|
347
|
-
headers[key] = value;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// Check if Content-Type already exists (case-insensitive)
|
|
351
|
-
const hasContentType = response.headers.has('content-type');
|
|
352
|
-
|
|
353
|
-
// Only set default value if Content-Type is missing
|
|
354
|
-
if (!hasContentType) {
|
|
355
|
-
headers['Content-Type'] = 'text/html; charset=utf-8';
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
headers['from-server'] = 'true';
|
|
359
|
-
|
|
360
|
-
// Handle set-cookie header (special handling, as there may be multiple values)
|
|
361
|
-
if (response.headers.has('set-cookie')) {
|
|
362
|
-
const cookieArr = response.headers.getSetCookie();
|
|
363
|
-
headers['set-cookie'] = Array.isArray(cookieArr) ? cookieArr : [cookieArr];
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
return {
|
|
367
|
-
statusCode: response.status || response.statusCode || 200,
|
|
368
|
-
headers,
|
|
369
|
-
body: response.body || response._data || ''
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* EdgeOne function handler
|
|
375
|
-
*/
|
|
376
|
-
export async function handler(event, context) {
|
|
377
|
-
try {
|
|
378
|
-
const url = event.path || '/';
|
|
379
|
-
const method = event.httpMethod || event.method || 'GET';
|
|
380
|
-
const headers = event.headers || {};
|
|
381
|
-
const body = event.body || '';
|
|
382
|
-
|
|
383
|
-
// First try to handle static assets
|
|
384
|
-
if (method === 'GET') {
|
|
385
|
-
const staticResponse = await handleStaticFile(url);
|
|
386
|
-
if (staticResponse) {
|
|
387
|
-
return staticResponse;
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// Handle dynamic requests
|
|
392
|
-
const app = await getNitroApp();
|
|
393
|
-
|
|
394
|
-
try {
|
|
395
|
-
const response = await app.localCall({
|
|
396
|
-
url,
|
|
397
|
-
method,
|
|
398
|
-
headers,
|
|
399
|
-
body
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
return handleResponse(response, event);
|
|
403
|
-
} catch (nitroError) {
|
|
404
|
-
// Handle Nitro static file read errors (prerender files not found)
|
|
405
|
-
// Check error and its cause property (H3Error may wrap actual error in cause)
|
|
406
|
-
const actualError = nitroError?.cause || nitroError;
|
|
407
|
-
const errorPath = actualError?.path || nitroError?.path;
|
|
408
|
-
const errorCode = actualError?.code || nitroError?.code;
|
|
409
|
-
|
|
410
|
-
// If error is due to prerender static file not found, try dynamic rendering
|
|
411
|
-
if (errorCode === 'ENOENT' &&
|
|
412
|
-
errorPath &&
|
|
413
|
-
(errorPath.includes('/assets/') || errorPath.includes('assets/')) &&
|
|
414
|
-
(errorPath.includes('/index.html') || errorPath.includes('index.html'))) {
|
|
415
|
-
console.warn(`Prerender file not found: ${errorPath}, falling back to dynamic rendering for ${url}`);
|
|
416
|
-
|
|
417
|
-
// If static file handling has been tried but file not found, should perform dynamic rendering
|
|
418
|
-
// Nitro should be able to handle dynamic routes, but if it still tries to read static files,
|
|
419
|
-
// it may be due to configuration issues. We throw an error directly to let user know to build or check configuration
|
|
420
|
-
throw new Error(`Prerender route ${url} not found. Make sure to run build first or configure routeRules correctly. Original error: ${actualError?.message || nitroError?.message}`);
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// Other errors are thrown directly
|
|
424
|
-
throw nitroError;
|
|
425
|
-
}
|
|
426
|
-
} catch (error) {
|
|
427
|
-
console.error('EdgeOne handler error:', error);
|
|
428
|
-
return {
|
|
429
|
-
statusCode: 500,
|
|
430
|
-
headers: { 'Content-Type': 'text/plain' },
|
|
431
|
-
body: `Internal Server Error: ${error.message}`
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
import('http').then(async (http) => {
|
|
437
|
-
const { createServer } = http;
|
|
438
|
-
// Dynamically import stream module to handle ReadableStream
|
|
439
|
-
await import('stream').then(({ Readable, pipeline }) => {
|
|
440
|
-
const server = createServer(async (req, res) => {
|
|
441
|
-
try {
|
|
442
|
-
const event = {
|
|
443
|
-
path: req.url,
|
|
444
|
-
httpMethod: req.method,
|
|
445
|
-
headers: req.headers,
|
|
446
|
-
body: ''
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
450
|
-
const chunks = [];
|
|
451
|
-
for await (const chunk of req) {
|
|
452
|
-
chunks.push(chunk);
|
|
453
|
-
}
|
|
454
|
-
event.body = Buffer.concat(chunks).toString();
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
const result = await handler(event, {});
|
|
458
|
-
|
|
459
|
-
res.statusCode = result.statusCode;
|
|
460
|
-
Object.entries(result.headers).forEach(([key, value]) => {
|
|
461
|
-
if(key === 'set-cookie') {
|
|
462
|
-
res.setHeader('set-cookie', Array.isArray(value) ? value[0].split(',') : value);
|
|
463
|
-
} else {
|
|
464
|
-
res.setHeader(key, value);
|
|
465
|
-
}
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
// Handle response body: support Buffer, string, and ReadableStream
|
|
469
|
-
if (Buffer.isBuffer(result.body)) {
|
|
470
|
-
res.end(result.body);
|
|
471
|
-
} else if (result.body && typeof result.body === 'object' && typeof result.body.getReader === 'function') {
|
|
472
|
-
// Detect ReadableStream (Web Streams API)
|
|
473
|
-
try {
|
|
474
|
-
const nodeStream = Readable.fromWeb(result.body);
|
|
475
|
-
nodeStream.pipe(res);
|
|
476
|
-
} catch (streamError) {
|
|
477
|
-
console.error('Stream conversion error:', streamError);
|
|
478
|
-
// If conversion fails, try to read the entire stream
|
|
479
|
-
const reader = result.body.getReader();
|
|
480
|
-
const chunks = [];
|
|
481
|
-
try {
|
|
482
|
-
while (true) {
|
|
483
|
-
const { done, value } = await reader.read();
|
|
484
|
-
if (done) break;
|
|
485
|
-
chunks.push(Buffer.from(value));
|
|
486
|
-
}
|
|
487
|
-
res.end(Buffer.concat(chunks));
|
|
488
|
-
} catch (readError) {
|
|
489
|
-
console.error('Stream read error:', readError);
|
|
490
|
-
res.end();
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
} else {
|
|
494
|
-
// Handle string or other types
|
|
495
|
-
res.end(result.body || '');
|
|
496
|
-
}
|
|
497
|
-
} catch (error) {
|
|
498
|
-
console.error('Local server error:', error);
|
|
499
|
-
res.statusCode = 500;
|
|
500
|
-
res.setHeader('Content-Type', 'text/plain');
|
|
501
|
-
res.end(`Server Error: ${error.message}`);
|
|
502
|
-
}
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
const port = process.env.DEV_PORT || 9000;
|
|
506
|
-
server.listen(port, () => {
|
|
507
|
-
console.log(`EdgeOne development server running at http://localhost:${port}`);
|
|
508
|
-
console.log(`Static assets served from: ${ASSET_DIR}`);
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
});
|