UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

243 lines (240 loc) 12.6 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: !0 }); }, __copyProps = (to, from, except, desc) => { if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target, mod )), __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod); var oneServe_exports = {}; __export(oneServe_exports, { oneServe: () => oneServe }); module.exports = __toCommonJS(oneServe_exports); var import_promises = require("node:fs/promises"), import_node_path = require("node:path"), import_constants = require("../constants"), import_createHandleRequest = require("../createHandleRequest"), import_cleanUrl = require("../utils/cleanUrl"), import_toAbsolute = require("../utils/toAbsolute"), import_staticHtmlFetcher = require("./staticHtmlFetcher"); const debugRouter = process.env.ONE_DEBUG_ROUTER; async function oneServe(oneOptions, buildInfo, app, options) { const { resolveAPIRoute, resolveLoaderRoute, resolvePageRoute } = await import("../createHandleRequest"), { isResponse } = await import("../utils/isResponse"), { isStatusRedirect } = await import("../utils/isStatus"), isAPIRequest = /* @__PURE__ */ new WeakMap(), redirects = oneOptions.web?.redirects; if (redirects) for (const redirect of redirects) app.get(redirect.source, (context) => { const destinationUrl = redirect.destination.replace(/:\w+/g, (param) => { const paramName = param.substring(1); return context.req.param(paramName) || ""; }); return debugRouter && console.info(`[one] \u21AA redirect ${context.req.path} \u2192 ${destinationUrl}`), context.redirect(destinationUrl, redirect.permanent ? 301 : 302); }); if (!buildInfo) throw new Error("No build info found, have you run build?"); const { routeToBuildInfo, routeMap } = buildInfo, serverOptions = { ...oneOptions, root: "." }, apiCJS = oneOptions.build?.api?.outputFormat === "cjs", useRolldown = buildInfo.useRolldown ?? !1; let render = null; async function getRender() { return render || (render = (options?.lazyRoutes?.serverEntry ? await options.lazyRoutes.serverEntry() : await import((0, import_node_path.resolve)( process.cwd(), `${serverOptions.root}/dist/server/_virtual_one-entry.${typeof oneOptions.build?.server == "object" && oneOptions.build.server.outputFormat === "cjs" ? "c" : ""}js` ))).default.render), render; } const requestHandlers = { async handleAPI({ route }) { if (options?.lazyRoutes?.api?.[route.page]) return await options.lazyRoutes.api[route.page](); const fileName = useRolldown ? route.page.slice(1) : route.page.slice(1).replace(/\[/g, "_").replace(/\]/g, "_"); return await import((0, import_node_path.join)( process.cwd(), "dist", "api", fileName + (apiCJS ? ".cjs" : ".js") )); }, async loadMiddleware(route) { return options?.lazyRoutes?.middlewares?.[route.contextKey] ? await options.lazyRoutes.middlewares[route.contextKey]() : await import((0, import_toAbsolute.toAbsolute)(route.contextKey)); }, async handleLoader({ route, loaderProps }) { const routeFile = route.routeFile || route.file, exports = options?.lazyRoutes?.pages?.[routeFile] ? await options.lazyRoutes.pages[routeFile]() : await import((0, import_toAbsolute.toAbsolute)((0, import_node_path.join)("./", "dist/server", route.file))), { loader } = exports; if (!loader) return console.warn("No loader found in exports", route.file), null; const json = await loader(loaderProps); return `export function loader() { return ${JSON.stringify(json)} }`; }, async handlePage({ route, url, loaderProps }) { const buildInfo2 = routeToBuildInfo[route.file]; if (route.type === "ssr") { if (!buildInfo2) throw console.error("Error in route", route), new Error( `No buildinfo found for ${url}, route: ${route.file}, in keys: ${Object.keys(routeToBuildInfo).join(` `)}` ); try { const exported = options?.lazyRoutes?.pages?.[route.file] ? await options.lazyRoutes.pages[route.file]() : await import((0, import_toAbsolute.toAbsolute)(buildInfo2.serverJsPath)); let loaderData; try { loaderData = await exported.loader?.(loaderProps); } catch (loaderErr) { if (isResponse(loaderErr)) return loaderErr; throw loaderErr; } const headers = new Headers(); headers.set("content-type", "text/html"), globalThis.__vxrnresetState?.(); const rendered = await (await getRender())({ mode: route.type, loaderData, loaderProps, path: loaderProps?.path || "/", // Use separated preloads for optimal loading preloads: buildInfo2.criticalPreloads || buildInfo2.preloads, deferredPreloads: buildInfo2.deferredPreloads, css: buildInfo2.css, cssContents: buildInfo2.cssContents }); return new Response(rendered, { headers, status: route.isNotFound ? 404 : 200 }); } catch (err) { if (isResponse(err)) return err; console.error(`[one] Error rendering SSR route ${route.file} ${err?.stack ?? err} url: ${url}`); } } else { const htmlPath = routeMap[url.pathname] || routeMap[buildInfo2?.cleanPath]; if (htmlPath) { const fetchStaticHtml = (0, import_staticHtmlFetcher.getFetchStaticHtml)(); let html = null; if (fetchStaticHtml && (html = await fetchStaticHtml(htmlPath)), !html) try { html = await (0, import_promises.readFile)((0, import_node_path.join)("dist/client", htmlPath), "utf-8"); } catch { } if (html) { const headers = new Headers(); return headers.set("content-type", "text/html"), new Response(html, { headers, status: route.isNotFound ? 404 : 200 }); } } } } }; function createHonoHandler(route) { return async (context, next) => { try { const request = context.req.raw; if ((route.page.endsWith("/+not-found") || Reflect.ownKeys(route.routeKeys).length > 0) && options?.serveStaticAssets) { const staticAssetResponse = await options.serveStaticAssets({ context }); if (staticAssetResponse) return await (0, import_createHandleRequest.runMiddlewares)( requestHandlers, request, route, async () => staticAssetResponse ); } if ((0, import_node_path.extname)(request.url) === ".js" || (0, import_node_path.extname)(request.url) === ".css") return next(); const url = (0, import_createHandleRequest.getURLfromRequestURL)(request), response = await (() => { if (url.pathname.endsWith(import_constants.LOADER_JS_POSTFIX_UNCACHED)) { const originalUrl = (0, import_cleanUrl.getPathFromLoaderPath)(url.pathname), finalUrl = new URL(originalUrl, url.origin), cleanedRequest = new Request(finalUrl, request); return resolveLoaderRoute(requestHandlers, cleanedRequest, finalUrl, route); } switch (route.type) { case "api": return debugRouter && console.info( `[one] \u26A1 ${url.pathname} \u2192 matched API route: ${route.page}` ), resolveAPIRoute(requestHandlers, request, url, route); case "ssg": case "spa": case "ssr": return debugRouter && console.info( `[one] \u26A1 ${url.pathname} \u2192 matched page route: ${route.page} (${route.type})` ), resolvePageRoute(requestHandlers, request, url, route); } })(); if (response) { if (isResponse(response)) { if (isStatusRedirect(response.status)) { const location = `${response.headers.get("location") || ""}`; return response.headers.forEach((value, key) => { context.header(key, value); }), context.redirect(location, response.status); } if (isAPIRequest.get(request)) try { return !response.headers.has("cache-control") && !response.headers.has("Cache-Control") && response.headers.set("cache-control", "no-store"), response; } catch (err) { console.info( `Error updating cache header on api route "${context.req.path}" to no-store, it is ${response.headers.get("cache-control")}, continue`, err ); } return response; } return next(); } } catch (err) { console.error(` [one] Error handling request: ${err.stack}`); } return next(); }; } const compiledManifest = (0, import_createHandleRequest.compileManifest)(buildInfo.manifest); for (const route of compiledManifest.apiRoutes) app.get(route.urlPath, createHonoHandler(route)), app.put(route.urlPath, createHonoHandler(route)), app.post(route.urlPath, createHonoHandler(route)), app.delete(route.urlPath, createHonoHandler(route)), app.patch(route.urlPath, createHonoHandler(route)), route.urlPath !== route.urlCleanPath && (app.get(route.urlCleanPath, createHonoHandler(route)), app.put(route.urlCleanPath, createHonoHandler(route)), app.post(route.urlCleanPath, createHonoHandler(route)), app.delete(route.urlCleanPath, createHonoHandler(route)), app.patch(route.urlCleanPath, createHonoHandler(route))); for (const route of compiledManifest.pageRoutes) app.get(route.urlPath, createHonoHandler(route)), route.urlPath !== route.urlCleanPath && app.get(route.urlCleanPath, createHonoHandler(route)); const { preloads, cssPreloads } = buildInfo; app.get("*", async (c, next) => { if (c.req.path.endsWith(import_constants.PRELOAD_JS_POSTFIX) && !preloads[c.req.path]) return c.header("Content-Type", "text/javascript"), c.status(200), c.body(""); if (c.req.path.endsWith(import_constants.CSS_PRELOAD_JS_POSTFIX) && !cssPreloads?.[c.req.path]) return c.header("Content-Type", "text/javascript"), c.status(200), c.body("export default Promise.resolve()"); if (c.req.path.endsWith(import_constants.LOADER_JS_POSTFIX_UNCACHED)) { const request = c.req.raw, url = (0, import_createHandleRequest.getURLfromRequestURL)(request), originalUrl = (0, import_cleanUrl.getPathFromLoaderPath)(c.req.path); for (const route of compiledManifest.pageRoutes) { if (route.file === "" || !route.compiledRegex.test(originalUrl)) continue; const loaderRoute = { ...route, routeFile: route.file, // preserve original for lazy route lookup file: route.loaderServerPath || c.req.path }, finalUrl = new URL(originalUrl, url.origin), cleanedRequest = new Request(finalUrl, request); try { return await resolveLoaderRoute( requestHandlers, cleanedRequest, finalUrl, loaderRoute ); } catch (err) { return console.error(`Error running loader: ${err}`), next(); } } } return next(); }); } //# sourceMappingURL=oneServe.js.map