Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.

This commit is contained in:
becarta
2025-05-23 12:43:00 +02:00
parent f40db0f5c9
commit a544759a3b
11127 changed files with 1647032 additions and 0 deletions

8
node_modules/astro/dist/core/preview/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
import type { AstroInlineConfig, PreviewServer } from '../../@types/astro.js';
/**
* Starts a local server to serve your static dist/ directory. This command is useful for previewing
* your build locally, before deploying it. It is not designed to be run in production.
*
* @experimental The JavaScript API is experimental
*/
export default function preview(inlineConfig: AstroInlineConfig): Promise<PreviewServer>;

68
node_modules/astro/dist/core/preview/index.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
import fs from "node:fs";
import { createRequire } from "node:module";
import { fileURLToPath, pathToFileURL } from "node:url";
import { AstroIntegrationLogger } from "../../core/logger/core.js";
import { telemetry } from "../../events/index.js";
import { eventCliSession } from "../../events/session.js";
import { runHookConfigDone, runHookConfigSetup } from "../../integrations/hooks.js";
import { resolveConfig } from "../config/config.js";
import { createNodeLogger } from "../config/logging.js";
import { createSettings } from "../config/settings.js";
import { apply as applyPolyfills } from "../polyfill.js";
import { ensureProcessNodeEnv } from "../util.js";
import createStaticPreviewServer from "./static-preview-server.js";
import { getResolvedHostForHttpServer } from "./util.js";
async function preview(inlineConfig) {
applyPolyfills();
ensureProcessNodeEnv("production");
const logger = createNodeLogger(inlineConfig);
const { userConfig, astroConfig } = await resolveConfig(inlineConfig ?? {}, "preview");
telemetry.record(eventCliSession("preview", userConfig));
const _settings = await createSettings(astroConfig, fileURLToPath(astroConfig.root));
const settings = await runHookConfigSetup({
settings: _settings,
command: "preview",
logger
});
await runHookConfigDone({ settings, logger });
if (settings.config.output === "static") {
if (!fs.existsSync(settings.config.outDir)) {
const outDirPath = fileURLToPath(settings.config.outDir);
throw new Error(
`[preview] The output directory ${outDirPath} does not exist. Did you run \`astro build\`?`
);
}
const server2 = await createStaticPreviewServer(settings, logger);
return server2;
}
if (!settings.adapter) {
throw new Error(`[preview] No adapter found.`);
}
if (!settings.adapter.previewEntrypoint) {
throw new Error(
`[preview] The ${settings.adapter.name} adapter does not support the preview command.`
);
}
const require2 = createRequire(settings.config.root);
const previewEntrypointUrl = pathToFileURL(
require2.resolve(settings.adapter.previewEntrypoint)
).href;
const previewModule = await import(previewEntrypointUrl);
if (typeof previewModule.default !== "function") {
throw new Error(`[preview] ${settings.adapter.name} cannot preview your app.`);
}
const server = await previewModule.default({
outDir: settings.config.outDir,
client: settings.config.build.client,
serverEntrypoint: new URL(settings.config.build.serverEntry, settings.config.build.server),
host: getResolvedHostForHttpServer(settings.config.server.host),
port: settings.config.server.port,
base: settings.config.base,
logger: new AstroIntegrationLogger(logger.options, settings.adapter.name),
headers: settings.config.server.headers
});
return server;
}
export {
preview as default
};

View File

@@ -0,0 +1,11 @@
import type http from 'node:http';
import type { AstroSettings } from '../../@types/astro.js';
import type { Logger } from '../logger/core.js';
export interface PreviewServer {
host?: string;
port: number;
server: http.Server;
closed(): Promise<void>;
stop(): Promise<void>;
}
export default function createStaticPreviewServer(settings: AstroSettings, logger: Logger): Promise<PreviewServer>;

View File

@@ -0,0 +1,57 @@
import { performance } from "node:perf_hooks";
import { fileURLToPath } from "node:url";
import { preview } from "vite";
import * as msg from "../messages.js";
import { getResolvedHostForHttpServer } from "./util.js";
import { vitePluginAstroPreview } from "./vite-plugin-astro-preview.js";
async function createStaticPreviewServer(settings, logger) {
const startServerTime = performance.now();
let previewServer;
try {
previewServer = await preview({
configFile: false,
base: settings.config.base,
appType: "mpa",
build: {
outDir: fileURLToPath(settings.config.outDir)
},
preview: {
host: settings.config.server.host,
port: settings.config.server.port,
headers: settings.config.server.headers,
open: settings.config.server.open
},
plugins: [vitePluginAstroPreview(settings)]
});
} catch (err) {
if (err instanceof Error) {
logger.error(null, err.stack || err.message);
}
throw err;
}
logger.info(
"SKIP_FORMAT",
msg.serverStart({
startupTime: performance.now() - startServerTime,
resolvedUrls: previewServer.resolvedUrls ?? { local: [], network: [] },
host: settings.config.server.host,
base: settings.config.base
})
);
function closed() {
return new Promise((resolve, reject) => {
previewServer.httpServer.addListener("close", resolve);
previewServer.httpServer.addListener("error", reject);
});
}
return {
host: getResolvedHostForHttpServer(settings.config.server.host),
port: settings.config.server.port,
closed,
server: previewServer.httpServer,
stop: previewServer.close.bind(previewServer)
};
}
export {
createStaticPreviewServer as default
};

2
node_modules/astro/dist/core/preview/util.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export declare function getResolvedHostForHttpServer(host: string | boolean): string | undefined;
export declare function stripBase(path: string, base: string): string;

20
node_modules/astro/dist/core/preview/util.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
function getResolvedHostForHttpServer(host) {
if (host === false) {
return "localhost";
} else if (host === true) {
return void 0;
} else {
return host;
}
}
function stripBase(path, base) {
if (path === base) {
return "/";
}
const baseWithSlash = base.endsWith("/") ? base : base + "/";
return path.replace(RegExp("^" + baseWithSlash), "/");
}
export {
getResolvedHostForHttpServer,
stripBase
};

View File

@@ -0,0 +1,3 @@
import type { Plugin } from 'vite';
import type { AstroSettings } from '../../@types/astro.js';
export declare function vitePluginAstroPreview(settings: AstroSettings): Plugin;

View File

@@ -0,0 +1,77 @@
import fs from "node:fs";
import { fileURLToPath } from "node:url";
import { notFoundTemplate, subpathNotUsedTemplate } from "../../template/4xx.js";
import { cleanUrl } from "../../vite-plugin-utils/index.js";
import { stripBase } from "./util.js";
const HAS_FILE_EXTENSION_REGEXP = /\.[^/]+$/;
function vitePluginAstroPreview(settings) {
const { base, outDir, trailingSlash } = settings.config;
function handle404(req, res) {
const errorPagePath = fileURLToPath(outDir + "/404.html");
if (fs.existsSync(errorPagePath)) {
res.statusCode = 404;
res.setHeader("Content-Type", "text/html;charset=utf-8");
res.end(fs.readFileSync(errorPagePath));
} else {
res.statusCode = 404;
res.end(notFoundTemplate(req.url, "Not Found"));
}
}
return {
name: "astro:preview",
apply: "serve",
configurePreviewServer(server) {
server.middlewares.use((req, res, next) => {
if (!req.url.startsWith(base)) {
res.statusCode = 404;
res.end(subpathNotUsedTemplate(base, req.url));
return;
}
const pathname = cleanUrl(stripBase(req.url, base));
const isRoot = pathname === "/";
if (!isRoot) {
const hasTrailingSlash = pathname.endsWith("/");
if (hasTrailingSlash && trailingSlash == "never") {
res.statusCode = 404;
res.end(notFoundTemplate(pathname, 'Not Found (trailingSlash is set to "never")'));
return;
}
if (!hasTrailingSlash && trailingSlash == "always" && !HAS_FILE_EXTENSION_REGEXP.test(pathname)) {
res.statusCode = 404;
res.end(notFoundTemplate(pathname, 'Not Found (trailingSlash is set to "always")'));
return;
}
}
for (const middleware of server.middlewares.stack) {
if (middleware.handle.name === "vite404Middleware") {
middleware.handle = handle404;
}
}
next();
});
return () => {
server.middlewares.use((req, _res, next) => {
const pathname = cleanUrl(req.url);
if (pathname.endsWith("/")) {
const pathnameWithoutSlash = pathname.slice(0, -1);
const htmlPath = fileURLToPath(outDir + pathnameWithoutSlash + ".html");
if (fs.existsSync(htmlPath)) {
req.url = pathnameWithoutSlash + ".html";
return next();
}
} else {
const htmlPath = fileURLToPath(outDir + pathname + "/index.html");
if (fs.existsSync(htmlPath)) {
req.url = pathname + "/index.html";
return next();
}
}
next();
});
};
}
};
}
export {
vitePluginAstroPreview
};