@edgeone/nuxt-pages 1.0.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.
Files changed (47) hide show
  1. package/README.md +275 -0
  2. package/dist/build/content/server.js +18 -0
  3. package/dist/build/content/static.js +17 -0
  4. package/dist/build/functions/server.js +19 -0
  5. package/dist/build/plugin-context.js +18 -0
  6. package/dist/build/routes.js +18 -0
  7. package/dist/build/templates/nuxt-handler-backup.js +305 -0
  8. package/dist/build/templates/nuxt-handler-monorepo.tmpl-ipx_backup.js +511 -0
  9. package/dist/build/templates/nuxt-handler-monorepo.tmpl.js +243 -0
  10. package/dist/build/templates/nuxt-handler.tmpl.js +212 -0
  11. package/dist/esm-chunks/chunk-5YBUNNZ4.js +81 -0
  12. package/dist/esm-chunks/chunk-6BT4RYQJ.js +43 -0
  13. package/dist/esm-chunks/chunk-6YERJDAJ.js +208 -0
  14. package/dist/esm-chunks/chunk-GX4Z7KQX.js +15065 -0
  15. package/dist/esm-chunks/chunk-HBXUWFGE.js +19 -0
  16. package/dist/esm-chunks/chunk-HY3HNABZ.js +87 -0
  17. package/dist/esm-chunks/chunk-KGYBHZC3.js +1467 -0
  18. package/dist/esm-chunks/chunk-MMMRMLH2.js +132 -0
  19. package/dist/esm-chunks/chunk-NJ4SUJNF.js +5635 -0
  20. package/dist/esm-chunks/chunk-QG7JLDXY.js +127 -0
  21. package/dist/esm-chunks/chunk-RPSYO4VM.js +562 -0
  22. package/dist/esm-chunks/chunk-UOPC2N5A.js +69 -0
  23. package/dist/esm-chunks/chunk-V2LFVP3C.js +838 -0
  24. package/dist/index.js +61 -0
  25. package/dist/run/config.js +17 -0
  26. package/dist/run/constants.js +17 -0
  27. package/dist/run/handlers/cache.cjs +1410 -0
  28. package/dist/run/handlers/nuxt-cache.cjs +200 -0
  29. package/dist/run/handlers/nuxt-server.js +156 -0
  30. package/dist/run/handlers/request-context.cjs +148 -0
  31. package/dist/run/handlers/server.js +77 -0
  32. package/dist/run/handlers/tags-handler.cjs +177 -0
  33. package/dist/run/handlers/tracer.cjs +1004 -0
  34. package/dist/run/handlers/use-cache-handler.js +220 -0
  35. package/dist/run/handlers/wait-until.cjs +123 -0
  36. package/dist/run/headers.js +17 -0
  37. package/dist/run/revalidate.js +34 -0
  38. package/dist/run/storage/regional-blob-store.cjs +64 -0
  39. package/dist/run/storage/request-scoped-in-memory-cache.cjs +1582 -0
  40. package/dist/run/storage/storage.cjs +191 -0
  41. package/dist/shared/blob-types.cjs +37 -0
  42. package/dist/shared/blobkey.js +25 -0
  43. package/dist/shared/cache-types.cjs +33 -0
  44. package/dist/shared/nuxt-cache-types.cjs +18 -0
  45. package/dist/types/options.js +6 -0
  46. package/dist/utils.js +25 -0
  47. package/package.json +58 -0
@@ -0,0 +1,127 @@
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_out,
9
+ verifyNuxtHandlerDirStructure
10
+ } from "./chunk-NJ4SUJNF.js";
11
+ import {
12
+ trace,
13
+ wrapTracer
14
+ } from "./chunk-V2LFVP3C.js";
15
+ import {
16
+ __require,
17
+ __toESM
18
+ } from "./chunk-6BT4RYQJ.js";
19
+
20
+ // src/build/functions/server.ts
21
+ import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
22
+ import { join, relative } from "node:path";
23
+ 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
+ var copyHandlerDependencies = async (ctx) => {
27
+ const promises = [];
28
+ const { included_files: includedFiles = [] } = {};
29
+ includedFiles.push(
30
+ posixJoin(ctx.relativeAppDir, ".env"),
31
+ posixJoin(ctx.relativeAppDir, ".env.production"),
32
+ posixJoin(ctx.relativeAppDir, ".env.local"),
33
+ posixJoin(ctx.relativeAppDir, ".env.production.local")
34
+ );
35
+ const resolvedFiles = await Promise.all(
36
+ includedFiles.map((globPattern) => (0, import_fast_glob.glob)(globPattern, { cwd: process.cwd() }))
37
+ );
38
+ for (const filePath of resolvedFiles.flat()) {
39
+ promises.push(
40
+ cp(
41
+ join(process.cwd(), filePath),
42
+ // the serverHandlerDir is aware of the dist dir.
43
+ // The distDir must not be the package path therefore we need to rely on the
44
+ // serverHandlerDir instead of the serverHandlerRootDir
45
+ // therefore we need to remove the package path from the filePath
46
+ join(ctx.serverHandlerDir, relative(ctx.relativeAppDir, filePath)),
47
+ {
48
+ recursive: true,
49
+ force: true
50
+ }
51
+ )
52
+ );
53
+ }
54
+ promises.push(
55
+ writeFile(
56
+ join(ctx.serverHandlerRuntimeModulesDir, "package.json"),
57
+ JSON.stringify({ type: "module" })
58
+ )
59
+ );
60
+ const fileList = await (0, import_fast_glob.glob)("dist/**/*", { cwd: ctx.pluginDir });
61
+ for (const filePath of fileList) {
62
+ promises.push(
63
+ cp(join(ctx.pluginDir, filePath), join(ctx.serverHandlerRuntimeModulesDir, filePath), {
64
+ recursive: true,
65
+ force: true
66
+ })
67
+ );
68
+ }
69
+ await Promise.all(promises);
70
+ };
71
+ var applyTemplateVariables = (template, variables) => {
72
+ return Object.entries(variables).reduce((acc, [key, value]) => {
73
+ return acc.replaceAll(key, value);
74
+ }, template);
75
+ };
76
+ var getHandlerFile = async (ctx) => {
77
+ const templatesDir = join(ctx.pluginDir, "dist/build/templates");
78
+ const templateVariables = {
79
+ "{{useRegionalBlobs}}": ctx.useRegionalBlobs.toString()
80
+ };
81
+ if (ctx.relativeAppDir.length !== 0) {
82
+ const templateName2 = "nuxt-handler-monorepo.tmpl.js";
83
+ const template = await readFile(join(templatesDir, templateName2), "utf-8");
84
+ console.log("Lambda working directory:", ctx.lambdaWorkingDirectory);
85
+ console.log("Server handler path:", ctx.nuxtServerHandler);
86
+ templateVariables["{{cwd}}"] = posixJoin(ctx.lambdaWorkingDirectory);
87
+ templateVariables["{{nuxtServerHandler}}"] = posixJoin(ctx.nuxtServerHandler);
88
+ return applyTemplateVariables(template, templateVariables);
89
+ }
90
+ const templateName = "nuxt-handler.tmpl.js";
91
+ console.log(`Using 'Nuxt' handler template: ${templateName}`);
92
+ return applyTemplateVariables(
93
+ await readFile(join(templatesDir, templateName), "utf-8"),
94
+ templateVariables
95
+ );
96
+ };
97
+ var writeHandlerFile = async (ctx) => {
98
+ const handler = await getHandlerFile(ctx);
99
+ await writeFile(join(ctx.serverHandlerRootDir, `handler.js`), handler);
100
+ };
101
+ var clearStaleServerHandlers = async (ctx) => {
102
+ await rm(ctx.serverFunctionsDir, { recursive: true, force: true });
103
+ };
104
+ var createServerHandler = async (ctx) => {
105
+ await mkdir(join(ctx.serverHandlerRuntimeModulesDir), { recursive: true });
106
+ await copyHandlerDependencies(ctx);
107
+ await writeHandlerFile(ctx);
108
+ await verifyNuxtHandlerDirStructure(ctx);
109
+ };
110
+ async function patchNitroHandler(ctx) {
111
+ const fs = __require("fs");
112
+ const nitroMjsPath = ".edgeone/server-handler/chunks/nitro/nitro.mjs";
113
+ const handlerTmplPath = ".edgeone/server-handler/handler.js";
114
+ const nitroCode = fs.readFileSync(nitroMjsPath, "utf-8");
115
+ const match = nitroCode.match(/useNitroApp as (\w)/);
116
+ if (!match) throw new Error("Cannot find useNitroApp export symbol!");
117
+ const symbol = match[1];
118
+ let handlerCode = await fs.readFileSync(handlerTmplPath, "utf-8");
119
+ handlerCode = handlerCode.replace(/{{USE_NITRO_APP_SYMBOL}}/g, symbol);
120
+ await fs.writeFileSync(handlerTmplPath, handlerCode);
121
+ }
122
+
123
+ export {
124
+ clearStaleServerHandlers,
125
+ createServerHandler,
126
+ patchNitroHandler
127
+ };
@@ -0,0 +1,562 @@
1
+
2
+ var require = await (async () => {
3
+ var { createRequire } = await import("node:module");
4
+ return createRequire(import.meta.url);
5
+ })();
6
+
7
+ import {
8
+ getModulesWithAST,
9
+ getPrerenderRoutesWithAST,
10
+ getRouteRulesWithAST,
11
+ getRoutesArrayWithAST
12
+ } from "./chunk-GX4Z7KQX.js";
13
+
14
+ // src/build/plugin-context.ts
15
+ import { existsSync, readFileSync } from "node:fs";
16
+ import { readFile } from "node:fs/promises";
17
+ import { createRequire } from "node:module";
18
+ import { join, relative, resolve } from "node:path";
19
+ import { join as posixJoin } from "node:path/posix";
20
+ import { fileURLToPath } from "node:url";
21
+ var MODULE_DIR = fileURLToPath(new URL(".", import.meta.url));
22
+ var PLUGIN_DIR = join(MODULE_DIR, "../..");
23
+ var DEFAULT_BUILD_DIR = ".nuxt";
24
+ var DEFAULT_OUTPUT_DIR = ".edgeone";
25
+ var NUXT_STATIC_DIR = "assets";
26
+ var SERVER_HANDLER_NAME = "server-handler";
27
+ var EDGE_HANDLER_NAME = "edgeone-edge-handler";
28
+ var PluginContext = class {
29
+ edgeoneConfig;
30
+ pluginName;
31
+ pluginVersion;
32
+ utils;
33
+ constants;
34
+ packageJSON;
35
+ _nuxtConfigPath = null;
36
+ _nuxtServerFile = null;
37
+ /** The directory where the plugin is located */
38
+ pluginDir = PLUGIN_DIR;
39
+ serverlessWrapHandler;
40
+ get relPublishDir() {
41
+ return this.constants.PUBLISH_DIR ?? join(this.constants.PACKAGE_PATH || "", DEFAULT_OUTPUT_DIR);
42
+ }
43
+ /** Temporary directory for stashing the build output */
44
+ get tempPublishDir() {
45
+ return this.resolveFromPackagePath(".edgeone/server-handler");
46
+ }
47
+ /** Absolute path of the publish directory */
48
+ get publishDir() {
49
+ return resolve(this.relPublishDir);
50
+ }
51
+ /**
52
+ * Relative package path in non monorepo setups this is an empty string
53
+ * This path is provided by Nuxt build manifest
54
+ * @example ''
55
+ * @example 'apps/my-app'
56
+ */
57
+ get relativeAppDir() {
58
+ return this.buildManifest?.buildDir ?? "";
59
+ }
60
+ /**
61
+ * The working directory inside the lambda that is used for monorepos to execute the serverless function
62
+ */
63
+ get lambdaWorkingDirectory() {
64
+ return "";
65
+ }
66
+ /**
67
+ * Retrieves the root of the `.output` directory
68
+ */
69
+ get outputRootDir() {
70
+ return join(this.publishDir, "server-handler");
71
+ }
72
+ /**
73
+ * The resolved relative nuxt build directory defaults to `.nuxt`,
74
+ * but can be configured through the nuxt.config.js. For monorepos this will include the packagePath
75
+ * If we need just the plain build dir use the `nuxtBuildDir`
76
+ */
77
+ get buildDir() {
78
+ const dir = this.buildConfig?.buildDir ?? DEFAULT_BUILD_DIR;
79
+ return relative(process.cwd(), resolve(this.relativeAppDir, dir));
80
+ }
81
+ /** Represents the parent directory of the .nuxt folder or custom buildDir */
82
+ get distDirParent() {
83
+ return join(this.buildDir, "..");
84
+ }
85
+ /** The `.nuxt` folder or what the custom build dir is set to */
86
+ get nuxtBuildDir() {
87
+ return relative(this.distDirParent, this.buildDir);
88
+ }
89
+ /** The directory where the Nuxt output is stored */
90
+ get outputDir() {
91
+ return DEFAULT_OUTPUT_DIR;
92
+ }
93
+ /** Retrieves the `.output/server/` directory monorepo aware */
94
+ get serverDir() {
95
+ return join(this.outputRootDir);
96
+ }
97
+ /** The directory where the Nuxt static files are stored */
98
+ get nuxtStaticDir() {
99
+ return join(this.outputDir, NUXT_STATIC_DIR);
100
+ }
101
+ /**
102
+ * Absolute path of the directory that is published and deployed to the CDN
103
+ * Will be swapped with the publish directory
104
+ * `.edgeone/static`
105
+ */
106
+ get staticDir() {
107
+ return this.resolveFromPackagePath(".edgeone/assets");
108
+ }
109
+ /**
110
+ * Absolute path of the directory that will be deployed to the blob store
111
+ * region aware: `.edgeone/deploy/v1/blobs/deploy`
112
+ * default: `.edgeone/blobs/deploy`
113
+ */
114
+ get blobDir() {
115
+ if (this.useRegionalBlobs) {
116
+ return this.resolveFromPackagePath(".edgeone/deploy/v1/blobs/deploy");
117
+ }
118
+ return this.resolveFromPackagePath(".edgeone/blobs/deploy");
119
+ }
120
+ get buildVersion() {
121
+ return this.constants.BUILD_VERSION || "v0.0.0";
122
+ }
123
+ get useRegionalBlobs() {
124
+ const REQUIRED_BUILD_VERSION = ">=29.41.5";
125
+ const currentVersion = this.buildVersion.replace("v", "");
126
+ const requiredVersion = REQUIRED_BUILD_VERSION.replace(">=", "");
127
+ return currentVersion >= requiredVersion;
128
+ }
129
+ /**
130
+ * Absolute path of the directory containing the files for the serverless lambda function
131
+ * `.edgeone/functions-internal`
132
+ */
133
+ get serverFunctionsDir() {
134
+ return this.resolveFromPackagePath(".edgeone");
135
+ }
136
+ /** Absolute path of the server handler */
137
+ get serverHandlerRootDir() {
138
+ return join(this.serverFunctionsDir, SERVER_HANDLER_NAME);
139
+ }
140
+ get serverHandlerDir() {
141
+ return this.serverHandlerRootDir;
142
+ }
143
+ get serverHandlerRuntimeModulesDir() {
144
+ return join(this.serverHandlerDir, ".edgeone");
145
+ }
146
+ get nuxtServerHandler() {
147
+ return "./.edgeone/dist/run/handlers/server.js";
148
+ }
149
+ /**
150
+ * Absolute path of the directory containing the files for deno edge functions
151
+ * `.edgeone/edge-functions`
152
+ */
153
+ get edgeFunctionsDir() {
154
+ return this.resolveFromPackagePath(".edgeone/edge-functions");
155
+ }
156
+ /** Absolute path of the edge handler */
157
+ get edgeHandlerDir() {
158
+ return join(this.edgeFunctionsDir, EDGE_HANDLER_NAME);
159
+ }
160
+ constructor(options) {
161
+ options = {
162
+ ...options,
163
+ functions: {
164
+ "*": {}
165
+ },
166
+ constants: {
167
+ // BUILD_VERSION: '32.1.4',
168
+ ...options.constants,
169
+ PUBLISH_DIR: options.constants?.PUBLISH_DIR || ".output"
170
+ }
171
+ };
172
+ this.constants = options.constants;
173
+ this.packageJSON = JSON.parse(readFileSync(join(PLUGIN_DIR, "package.json"), "utf-8"));
174
+ this.pluginName = this.packageJSON.name;
175
+ this.pluginVersion = this.packageJSON.version;
176
+ }
177
+ /** Resolves a path correctly with mono repository awareness for .edgeone directories mainly */
178
+ resolveFromPackagePath(...args) {
179
+ return resolve(this.constants.PACKAGE_PATH || "", ...args);
180
+ }
181
+ /** Resolves a path correctly from site directory */
182
+ resolveFromSiteDir(...args) {
183
+ return resolve(this.buildManifest?.buildDir || process.cwd(), ...args);
184
+ }
185
+ /** Get the nuxt routes manifest */
186
+ async getRoutesManifest() {
187
+ try {
188
+ let routesData = await this.getRouteRules();
189
+ if (!routesData) {
190
+ return { routes: [], prerendered: [] };
191
+ }
192
+ const routes = Array.isArray(routesData) ? routesData.map((route) => ({
193
+ path: route.path || route.route,
194
+ file: route.file || "",
195
+ prerender: route.prerender || false,
196
+ ssr: route.ssr !== false,
197
+ swr: route.swr ? route.swr : route.isr ? route.isr : false
198
+ })) : [];
199
+ return { routes, prerendered: routes.filter((r) => r.prerender).map((r) => r.path) };
200
+ } catch (error) {
201
+ return { routes: [], prerendered: [] };
202
+ }
203
+ }
204
+ /** Get the nuxt build manifest */
205
+ async getBuildManifest() {
206
+ const buildInfoPath = join(this.nuxtBuildDir, "build-info.json");
207
+ const nitroConfigPath = join(this.outputDir, "nitro.json");
208
+ try {
209
+ let manifestData;
210
+ if (existsSync(buildInfoPath)) {
211
+ manifestData = JSON.parse(await readFile(buildInfoPath, "utf-8"));
212
+ } else if (existsSync(nitroConfigPath)) {
213
+ const nitroConfig = JSON.parse(await readFile(nitroConfigPath, "utf-8"));
214
+ manifestData = {
215
+ version: nitroConfig.version || "1.0.0",
216
+ config: nitroConfig.config || {},
217
+ buildDir: this.buildDir,
218
+ outputDir: this.outputDir,
219
+ routes: nitroConfig.routes || {},
220
+ assets: nitroConfig.assets || {}
221
+ };
222
+ } else {
223
+ manifestData = {
224
+ version: "1.0.0",
225
+ config: {},
226
+ buildDir: DEFAULT_BUILD_DIR,
227
+ outputDir: DEFAULT_OUTPUT_DIR,
228
+ routes: {},
229
+ assets: {}
230
+ };
231
+ }
232
+ return manifestData;
233
+ } catch (error) {
234
+ return {
235
+ version: "1.0.0",
236
+ config: {},
237
+ buildDir: DEFAULT_BUILD_DIR,
238
+ outputDir: DEFAULT_OUTPUT_DIR,
239
+ routes: {},
240
+ assets: {}
241
+ };
242
+ }
243
+ }
244
+ /**
245
+ * Uses various heuristics to try to find the .output dir.
246
+ * Works by looking for nitro.json, so requires the site to have been built
247
+ */
248
+ findDotOutput() {
249
+ for (const dir of [
250
+ // The publish directory
251
+ this.publishDir,
252
+ // In the root
253
+ resolve(DEFAULT_OUTPUT_DIR),
254
+ // The sibling of the publish directory
255
+ resolve(this.publishDir, "..", DEFAULT_OUTPUT_DIR),
256
+ // In the package dir
257
+ resolve(this.constants.PACKAGE_PATH || "", DEFAULT_OUTPUT_DIR)
258
+ ]) {
259
+ if (existsSync(join(dir, "nitro.json"))) {
260
+ return dir;
261
+ }
262
+ }
263
+ return false;
264
+ }
265
+ /**
266
+ * Get Nuxt nitro config from the build output
267
+ */
268
+ async getNitroConfig() {
269
+ const nitroPath = join(this.publishDir, "nitro.json");
270
+ try {
271
+ if (!existsSync(nitroPath)) {
272
+ return {};
273
+ }
274
+ return JSON.parse(await readFile(nitroPath, "utf-8"));
275
+ } catch (error) {
276
+ return {};
277
+ }
278
+ }
279
+ // don't make private as it is handy inside testing to override the config
280
+ _buildManifest = null;
281
+ /** Get Build manifest from build output **/
282
+ get buildManifest() {
283
+ if (!this._buildManifest) {
284
+ let buildManifestJson = join(this.publishDir, "build-manifest.json");
285
+ if (!existsSync(buildManifestJson)) {
286
+ const dotOutput = this.findDotOutput();
287
+ if (dotOutput) {
288
+ buildManifestJson = join(dotOutput, "build-manifest.json");
289
+ }
290
+ }
291
+ if (existsSync(buildManifestJson)) {
292
+ this._buildManifest = JSON.parse(
293
+ readFileSync(buildManifestJson, "utf-8")
294
+ );
295
+ } else {
296
+ this._buildManifest = {
297
+ version: "1.0.0",
298
+ config: {},
299
+ buildDir: DEFAULT_BUILD_DIR,
300
+ outputDir: DEFAULT_OUTPUT_DIR,
301
+ routes: {},
302
+ assets: {}
303
+ };
304
+ }
305
+ }
306
+ return this._buildManifest;
307
+ }
308
+ #exportDetail = null;
309
+ /** Get metadata when output = static */
310
+ get exportDetail() {
311
+ if (this.buildConfig?.nitro?.prerender !== true) {
312
+ return null;
313
+ }
314
+ if (!this.#exportDetail) {
315
+ const detailFile = join(
316
+ this.buildManifest.buildDir,
317
+ "export-detail.json"
318
+ );
319
+ if (!existsSync(detailFile)) {
320
+ return null;
321
+ }
322
+ try {
323
+ this.#exportDetail = JSON.parse(readFileSync(detailFile, "utf-8"));
324
+ } catch {
325
+ }
326
+ }
327
+ return this.#exportDetail;
328
+ }
329
+ /** Get Nuxt Config from build output **/
330
+ get buildConfig() {
331
+ return this.buildManifest.config;
332
+ }
333
+ /** Get the path to nuxt.config.ts file */
334
+ get nuxtConfigPath() {
335
+ if (!this._nuxtConfigPath) {
336
+ this._nuxtConfigPath = this.detectNuxtConfigPath();
337
+ }
338
+ return this._nuxtConfigPath;
339
+ }
340
+ get nuxtServerFile() {
341
+ if (!this._nuxtServerFile) {
342
+ this._nuxtServerFile = this.detectNuxtServerFile();
343
+ }
344
+ return this._nuxtServerFile;
345
+ }
346
+ /** Detect and locate nuxt.config.ts file */
347
+ detectNuxtConfigPath() {
348
+ const configFiles = ["nuxt.config.ts", "nuxt.config.js", "nuxt.config.mjs"];
349
+ for (const configFile of configFiles) {
350
+ const configPath = this.resolveFromPackagePath(configFile);
351
+ if (existsSync(configPath)) {
352
+ return configPath;
353
+ }
354
+ }
355
+ return null;
356
+ }
357
+ /** Detect and locate server.mjs file */
358
+ detectNuxtServerFile() {
359
+ const serverFilePath = this.resolveFromPackagePath(".edgeone", "server-handler", "chunks", "build", "server.mjs");
360
+ if (existsSync(serverFilePath)) {
361
+ return serverFilePath;
362
+ }
363
+ return null;
364
+ }
365
+ /** Read and parse nuxt.config.ts file content */
366
+ async getNuxtConfig() {
367
+ const configPath = this.nuxtConfigPath;
368
+ if (!configPath) {
369
+ console.warn("No Nuxt config file found");
370
+ return null;
371
+ }
372
+ try {
373
+ console.log("Loading Nuxt config from:", configPath);
374
+ const configContent = readFileSync(configPath, "utf-8");
375
+ console.log("Reading config file content...");
376
+ return configContent;
377
+ } catch (error) {
378
+ console.warn(`Failed to load Nuxt config from ${configPath}:`, error);
379
+ return null;
380
+ }
381
+ }
382
+ async getNuxtServerFile() {
383
+ const serverFilePath = this.nuxtServerFile;
384
+ if (!serverFilePath) {
385
+ console.warn("No Nuxt server file found");
386
+ return null;
387
+ }
388
+ try {
389
+ console.log("Loading Nuxt server file from:", serverFilePath);
390
+ const serverContent = readFileSync(serverFilePath, "utf-8");
391
+ console.log("Reading server file content...");
392
+ return serverContent;
393
+ } catch (error) {
394
+ console.warn(`Failed to load Nuxt server file from ${serverFilePath}:`, error);
395
+ return null;
396
+ }
397
+ }
398
+ /** Get routeRules from nuxt.config.ts */
399
+ async getRouteRules() {
400
+ const nitroPrerenderRoutes = await this.getPrerenderRoutes();
401
+ const nuxtConfigRoutes = getRouteRulesWithAST(await this.getNuxtConfig() || "");
402
+ const result = [];
403
+ for (const key in nuxtConfigRoutes) {
404
+ const obj = {
405
+ path: key,
406
+ prerender: nuxtConfigRoutes[key].prerender === true,
407
+ ssr: !nuxtConfigRoutes[key].prerender && !(nuxtConfigRoutes[key].hasOwnProperty("swr") || nuxtConfigRoutes[key].hasOwnProperty("isr")),
408
+ swr: false
409
+ };
410
+ if (nuxtConfigRoutes[key].hasOwnProperty("swr")) {
411
+ obj.swr = nuxtConfigRoutes[key].swr;
412
+ }
413
+ if (nuxtConfigRoutes[key].hasOwnProperty("isr")) {
414
+ obj.swr = nuxtConfigRoutes[key].isr;
415
+ }
416
+ if (nuxtConfigRoutes[key].hasOwnProperty("prerender") && nuxtConfigRoutes[key].prerender) {
417
+ Object.defineProperty(obj, "file", {
418
+ value: `asset${key}/index.html`,
419
+ enumerable: true
420
+ });
421
+ }
422
+ result.push(obj);
423
+ }
424
+ const serverRoutes = getRoutesArrayWithAST(await this.getNuxtServerFile() || "");
425
+ serverRoutes.forEach((item) => {
426
+ const keys = result.map((obj) => obj.path);
427
+ if (!keys.includes(item.path)) {
428
+ if (nitroPrerenderRoutes.includes(item.path)) {
429
+ result.push({
430
+ path: item.path,
431
+ prerender: true,
432
+ ssr: false,
433
+ swr: false
434
+ });
435
+ } else {
436
+ result.push({
437
+ path: item.path,
438
+ prerender: false,
439
+ ssr: true,
440
+ swr: false
441
+ });
442
+ }
443
+ }
444
+ });
445
+ return result;
446
+ }
447
+ /** Extract _routes array from server.mjs content */
448
+ extractRoutesFromServerMjs(content) {
449
+ try {
450
+ const routesArray = getRoutesArrayWithAST(content);
451
+ if (!routesArray) {
452
+ console.log("_routes array not found in server.mjs");
453
+ return null;
454
+ }
455
+ console.log("Found _routes array with", routesArray.length, "routes");
456
+ return routesArray;
457
+ } catch (error) {
458
+ console.error("Error extracting routes from server.mjs:", error);
459
+ return null;
460
+ }
461
+ }
462
+ /**
463
+ * Get Nuxt assets manifest from the build output
464
+ * This handles the asset optimization routes for Nuxt
465
+ */
466
+ async getAssetsManifest() {
467
+ const clientManifestPath = join(this.nuxtBuildDir, "dist/client/manifest.json");
468
+ const publicManifestPath = join(this.outputDir, "public/_nuxt/manifest.json");
469
+ const fallbackPath = join(this.publishDir, "assets-manifest.json");
470
+ try {
471
+ let manifestPath;
472
+ if (existsSync(clientManifestPath)) {
473
+ manifestPath = clientManifestPath;
474
+ } else if (existsSync(publicManifestPath)) {
475
+ manifestPath = publicManifestPath;
476
+ } else if (existsSync(fallbackPath)) {
477
+ manifestPath = fallbackPath;
478
+ } else {
479
+ return {};
480
+ }
481
+ const manifest = JSON.parse(await readFile(manifestPath, "utf-8"));
482
+ if (manifest && typeof manifest === "object") {
483
+ return manifest;
484
+ }
485
+ return {};
486
+ } catch (error) {
487
+ return {};
488
+ }
489
+ }
490
+ #nuxtVersion = void 0;
491
+ /**
492
+ * Get Nuxt version that was used to build the site
493
+ */
494
+ get nuxtVersion() {
495
+ if (this.#nuxtVersion === void 0) {
496
+ try {
497
+ const serverHandlerRequire = createRequire(posixJoin(this.outputRootDir, ":internal:"));
498
+ const { version } = serverHandlerRequire("nuxt/package.json");
499
+ this.#nuxtVersion = version;
500
+ } catch {
501
+ this.#nuxtVersion = null;
502
+ }
503
+ }
504
+ return this.#nuxtVersion;
505
+ }
506
+ #nuxtModules = null;
507
+ async nuxtModules() {
508
+ if (!this.#nuxtModules) {
509
+ const nuxtConfig = await this.getNuxtConfig();
510
+ try {
511
+ const modules = getModulesWithAST(nuxtConfig);
512
+ this.#nuxtModules = modules;
513
+ } catch (error) {
514
+ console.error("Error extracting modules from nuxt.config.ts:", error);
515
+ this.#nuxtModules = null;
516
+ }
517
+ }
518
+ return this.#nuxtModules;
519
+ }
520
+ #staticPages = null;
521
+ /**
522
+ * Get an array of static pages that are fully prerendered.
523
+ * Those are being served as-is without involving server-side rendering
524
+ */
525
+ async getStaticPages() {
526
+ if (!this.#staticPages) {
527
+ const routesManifest = await this.getRoutesManifest();
528
+ this.#staticPages = routesManifest.routes.filter((route) => route.prerender === true).map((route) => route.path);
529
+ }
530
+ return this.#staticPages;
531
+ }
532
+ /** Get prerender routes from nuxt.config.ts */
533
+ async getPrerenderRoutes() {
534
+ try {
535
+ const configPath = join(process.cwd(), "nuxt.config.ts");
536
+ if (!existsSync(configPath)) {
537
+ console.warn("nuxt.config.ts not found, returning empty prerender routes");
538
+ return [];
539
+ }
540
+ const configContent = await readFile(configPath, "utf-8");
541
+ const prerenderRoutes = getPrerenderRoutesWithAST(configContent);
542
+ return prerenderRoutes;
543
+ } catch (error) {
544
+ console.error("Error reading prerender routes from nuxt.config.ts:", error);
545
+ return [];
546
+ }
547
+ }
548
+ /** Fails a build with a message and an optional error */
549
+ failBuild(message, error) {
550
+ console.error(message);
551
+ if (error) {
552
+ console.error(error);
553
+ }
554
+ process.exit(1);
555
+ }
556
+ };
557
+
558
+ export {
559
+ SERVER_HANDLER_NAME,
560
+ EDGE_HANDLER_NAME,
561
+ PluginContext
562
+ };