UNPKG

one

Version:

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

519 lines (514 loc) 26.7 kB
"use strict"; 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("fs/promises"), import_path = require("path"), import_constants = require("../constants.native.js"), import_createHandleRequest = require("../createHandleRequest.native.js"), import_cleanUrl = require("../utils/cleanUrl.native.js"), import_toAbsolute = require("../utils/toAbsolute.native.js"), import_staticHtmlFetcher = require("./staticHtmlFetcher.native.js"); function _type_of(obj) { "@swc/helpers - typeof"; return obj && typeof Symbol < "u" && obj.constructor === Symbol ? "symbol" : typeof obj; } var debugRouter = process.env.ONE_DEBUG_ROUTER; async function oneServe(oneOptions, buildInfo, app, options) { var _oneOptions_web, _oneOptions_build_api, _oneOptions_build, { resolveAPIRoute, resolveLoaderRoute, resolvePageRoute } = await import("../createHandleRequest"), { isResponse } = await import("../utils/isResponse"), { isStatusRedirect } = await import("../utils/isStatus"), isAPIRequest = /* @__PURE__ */new WeakMap(), redirects = (_oneOptions_web = oneOptions.web) === null || _oneOptions_web === void 0 ? void 0 : _oneOptions_web.redirects; if (redirects) { var _iteratorNormalCompletion = !0, _didIteratorError = !1, _iteratorError = void 0; try { for (var _loop = function () { var redirect = _step.value; app.get(redirect.source, function (context) { var destinationUrl = redirect.destination.replace(/:\w+/g, function (param) { var 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); }); }, _iterator = redirects[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) _loop(); } catch (err) { _didIteratorError = !0, _iteratorError = err; } finally { try { !_iteratorNormalCompletion && _iterator.return != null && _iterator.return(); } finally { if (_didIteratorError) throw _iteratorError; } } } if (!buildInfo) throw new Error("No build info found, have you run build?"); var { routeToBuildInfo, routeMap } = buildInfo; function findNearestNotFoundPath(urlPath) { for (var cur = urlPath; cur;) { var parent = cur.lastIndexOf("/") > 0 ? cur.slice(0, cur.lastIndexOf("/")) : ""; if (routeMap[`${parent}/+not-found`]) return `${parent}/+not-found`; if (!parent) break; cur = parent; } return "/+not-found"; } var serverOptions = { ...oneOptions, root: "." }, apiCJS = ((_oneOptions_build = oneOptions.build) === null || _oneOptions_build === void 0 || (_oneOptions_build_api = _oneOptions_build.api) === null || _oneOptions_build_api === void 0 ? void 0 : _oneOptions_build_api.outputFormat) === "cjs", render = null; async function getRender() { if (!render) { var _options_lazyRoutes, _oneOptions_build2, entry = !(options == null || (_options_lazyRoutes = options.lazyRoutes) === null || _options_lazyRoutes === void 0) && _options_lazyRoutes.serverEntry ? await options.lazyRoutes.serverEntry() : await import((0, import_path.resolve)(process.cwd(), `${serverOptions.root}/dist/server/_virtual_one-entry.${_type_of((_oneOptions_build2 = oneOptions.build) === null || _oneOptions_build2 === void 0 ? void 0 : _oneOptions_build2.server) === "object" && oneOptions.build.server.outputFormat === "cjs" ? "c" : ""}js`)); render = entry.default.render; } return render; } var requestHandlers = { async handleAPI(param) { var { route: route2 } = param, _options_lazyRoutes_api, _options_lazyRoutes; if (!(options == null || (_options_lazyRoutes = options.lazyRoutes) === null || _options_lazyRoutes === void 0 || (_options_lazyRoutes_api = _options_lazyRoutes.api) === null || _options_lazyRoutes_api === void 0) && _options_lazyRoutes_api[route2.page]) return await options.lazyRoutes.api[route2.page](); var fileName = route2.page.slice(1).replace(/\[/g, "_").replace(/\]/g, "_"), apiFile = (0, import_path.join)(process.cwd(), "dist", "api", fileName + (apiCJS ? ".cjs" : ".js")); return await import(apiFile); }, async loadMiddleware(route2) { var _options_lazyRoutes_middlewares, _options_lazyRoutes; return !(options == null || (_options_lazyRoutes = options.lazyRoutes) === null || _options_lazyRoutes === void 0 || (_options_lazyRoutes_middlewares = _options_lazyRoutes.middlewares) === null || _options_lazyRoutes_middlewares === void 0) && _options_lazyRoutes_middlewares[route2.contextKey] ? await options.lazyRoutes.middlewares[route2.contextKey]() : await import((0, import_toAbsolute.toAbsolute)(route2.contextKey)); }, async handleLoader(param) { var { route: route2, loaderProps } = param, routeFile = route2.routeFile || route2.file, serverPath = route2.file.includes("dist/server") ? route2.file : (0, import_path.join)("./", "dist/server", route2.file), exports; try { var _options_lazyRoutes_pages, _options_lazyRoutes; exports = !(options == null || (_options_lazyRoutes = options.lazyRoutes) === null || _options_lazyRoutes === void 0 || (_options_lazyRoutes_pages = _options_lazyRoutes.pages) === null || _options_lazyRoutes_pages === void 0) && _options_lazyRoutes_pages[routeFile] ? await options.lazyRoutes.pages[routeFile]() : await import((0, import_toAbsolute.toAbsolute)(serverPath)); } catch (err) { if (err?.code === "ERR_MODULE_NOT_FOUND") return null; throw err; } var { loader } = exports; if (!loader) return null; var json = await loader(loaderProps); if (isResponse(json)) throw json; return `export function loader() { return ${JSON.stringify(json)} }`; }, async handlePage(param) { var { route: route2, url, loaderProps } = param, _$buildInfo = routeToBuildInfo[route2.file]; if (route2.type === "ssr") { if (!_$buildInfo) throw console.error("Error in route", route2), new Error(`No buildinfo found for ${url}, route: ${route2.file}, in keys: ${Object.keys(routeToBuildInfo).join(` `)}`); try { var _options_lazyRoutes_pages, _options_lazyRoutes, _globalThis___vxrnresetState, _globalThis, exported = !(options == null || (_options_lazyRoutes = options.lazyRoutes) === null || _options_lazyRoutes === void 0 || (_options_lazyRoutes_pages = _options_lazyRoutes.pages) === null || _options_lazyRoutes_pages === void 0) && _options_lazyRoutes_pages[route2.file] ? await options.lazyRoutes.pages[route2.file]() : await import((0, import_toAbsolute.toAbsolute)(_$buildInfo.serverJsPath)); async function runLoader(routeId, serverPath, lazyKey) { if (!serverPath && !lazyKey) return { loaderData: void 0, routeId }; try { var _options_lazyRoutes_pages2, _options_lazyRoutes2, _routeExported_loader, pathToResolve = serverPath || lazyKey || "", resolvedPath = pathToResolve.includes("dist/server") ? pathToResolve : (0, import_path.join)("./", "dist/server", pathToResolve), routeExported = lazyKey ? !(options == null || (_options_lazyRoutes2 = options.lazyRoutes) === null || _options_lazyRoutes2 === void 0 || (_options_lazyRoutes_pages2 = _options_lazyRoutes2.pages) === null || _options_lazyRoutes_pages2 === void 0) && _options_lazyRoutes_pages2[lazyKey] ? await options.lazyRoutes.pages[lazyKey]() : await import((0, import_toAbsolute.toAbsolute)(resolvedPath)) : await import((0, import_toAbsolute.toAbsolute)(serverPath)), loaderData2 = await (routeExported == null || (_routeExported_loader = routeExported.loader) === null || _routeExported_loader === void 0 ? void 0 : _routeExported_loader.call(routeExported, loaderProps)); return { loaderData: loaderData2, routeId }; } catch (err) { if (isResponse(err)) throw err; return console.error(`[one] Error running loader for ${routeId}:`, err), { loaderData: void 0, routeId }; } } var layoutRoutes = route2.layouts || [], layoutLoaderPromises = layoutRoutes.map(function (layout) { var serverPath = layout.loaderServerPath || layout.contextKey; return runLoader(layout.contextKey, serverPath, layout.contextKey); }), pageLoaderPromise = runLoader(route2.file, _$buildInfo.serverJsPath, route2.file), layoutResults, pageResult; try { [layoutResults, pageResult] = await Promise.all([Promise.all(layoutLoaderPromises), pageLoaderPromise]); } catch (err) { if (isResponse(err)) return err; throw err; } var matches = [...layoutResults.map(function (result) { return { routeId: result.routeId, pathname: loaderProps?.path || "/", params: loaderProps?.params || {}, loaderData: result.loaderData }; }), { routeId: pageResult.routeId, pathname: loaderProps?.path || "/", params: loaderProps?.params || {}, loaderData: pageResult.loaderData }], loaderData = pageResult.loaderData, headers = new Headers(); headers.set("content-type", "text/html"), (_globalThis___vxrnresetState = (_globalThis = globalThis).__vxrnresetState) === null || _globalThis___vxrnresetState === void 0 || _globalThis___vxrnresetState.call(_globalThis); var rendered = await (await getRender())({ mode: route2.type, loaderData, loaderProps, path: loaderProps?.path || "/", // Use separated preloads for optimal loading preloads: _$buildInfo.criticalPreloads || _$buildInfo.preloads, deferredPreloads: _$buildInfo.deferredPreloads, css: _$buildInfo.css, cssContents: _$buildInfo.cssContents, matches }); return new Response(rendered, { headers, status: route2.isNotFound ? 404 : 200 }); } catch (err) { var _ref; if (isResponse(err)) return err; console.error(`[one] Error rendering SSR route ${route2.file} ${(_ref = err?.stack) !== null && _ref !== void 0 ? _ref : err} url: ${url}`); } } else { var layoutRoutes1 = route2.layouts || [], needsSpaShell = route2.type === "spa" && layoutRoutes1.some(function (layout) { return layout.layoutRenderMode === "ssg" || layout.layoutRenderMode === "ssr"; }); if (needsSpaShell) try { var _globalThis___vxrnresetState1, _globalThis1; async function runShellLoader(routeId, serverPath, lazyKey) { if (!serverPath && !lazyKey) return { loaderData: void 0, routeId }; try { var _options_lazyRoutes_pages2, _options_lazyRoutes2, _routeExported_loader, pathToResolve = serverPath || lazyKey || "", resolvedPath = pathToResolve.includes("dist/server") ? pathToResolve : (0, import_path.join)("./", "dist/server", pathToResolve), routeExported = lazyKey ? !(options == null || (_options_lazyRoutes2 = options.lazyRoutes) === null || _options_lazyRoutes2 === void 0 || (_options_lazyRoutes_pages2 = _options_lazyRoutes2.pages) === null || _options_lazyRoutes_pages2 === void 0) && _options_lazyRoutes_pages2[lazyKey] ? await options.lazyRoutes.pages[lazyKey]() : await import((0, import_toAbsolute.toAbsolute)(resolvedPath)) : await import((0, import_toAbsolute.toAbsolute)(serverPath)), loaderData2 = await (routeExported == null || (_routeExported_loader = routeExported.loader) === null || _routeExported_loader === void 0 ? void 0 : _routeExported_loader.call(routeExported, loaderProps)); return { loaderData: loaderData2, routeId }; } catch (err) { if (isResponse(err)) throw err; return console.error(`[one] Error running shell loader for ${routeId}:`, err), { loaderData: void 0, routeId }; } } var layoutResults1 = await Promise.all(layoutRoutes1.map(function (layout) { var serverPath = layout.loaderServerPath || layout.contextKey; return runShellLoader(layout.contextKey, serverPath, layout.contextKey); })), matches1 = layoutResults1.map(function (result) { return { routeId: result.routeId, pathname: loaderProps?.path || "/", params: loaderProps?.params || {}, loaderData: result.loaderData }; }), headers1 = new Headers(); headers1.set("content-type", "text/html"), (_globalThis___vxrnresetState1 = (_globalThis1 = globalThis).__vxrnresetState) === null || _globalThis___vxrnresetState1 === void 0 || _globalThis___vxrnresetState1.call(_globalThis1); var rendered1 = await (await getRender())({ mode: "spa-shell", // don't pass loaderData for spa-shell - the page loader runs on client // passing {} here would make useLoaderState think data is preloaded loaderData: void 0, loaderProps, path: loaderProps?.path || "/", preloads: _$buildInfo?.criticalPreloads || _$buildInfo?.preloads, deferredPreloads: _$buildInfo?.deferredPreloads, css: _$buildInfo?.css, cssContents: _$buildInfo?.cssContents, matches: matches1 }); return new Response(rendered1, { headers: headers1, status: route2.isNotFound ? 404 : 200 }); } catch (err) { var _ref1; if (isResponse(err)) return err; console.error(`[one] Error rendering spa-shell for ${route2.file} ${(_ref1 = err?.stack) !== null && _ref1 !== void 0 ? _ref1 : err} url: ${url}`); } var isDynamicRoute = Object.keys(route2.routeKeys).length > 0, routeCleanPath = route2.urlCleanPath.replace(/\?/g, ""), notFoundKey = route2.isNotFound ? route2.page.replace(/\[([^\]]+)\]/g, ":$1") : null, htmlPath = notFoundKey ? routeMap[notFoundKey] : isDynamicRoute ? routeMap[routeCleanPath] || routeMap[url.pathname] : routeMap[url.pathname] || routeMap[_$buildInfo?.cleanPath]; if (htmlPath) { var fetchStaticHtml = (0, import_staticHtmlFetcher.getFetchStaticHtml)(), html = null; if (fetchStaticHtml && (html = await fetchStaticHtml(htmlPath)), !html) try { html = await (0, import_promises.readFile)((0, import_path.join)("dist/client", htmlPath), "utf-8"); } catch {} if (html) { var headers2 = new Headers(); return headers2.set("content-type", "text/html"), new Response(html, { headers: headers2, status: route2.isNotFound ? 404 : 200 }); } } if (isDynamicRoute) { var notFoundRoute = findNearestNotFoundPath(url.pathname), notFoundHtmlPath = routeMap[notFoundRoute]; if (notFoundHtmlPath) { var fetchStaticHtml1 = (0, import_staticHtmlFetcher.getFetchStaticHtml)(), notFoundHtml = null; if (fetchStaticHtml1 && (notFoundHtml = await fetchStaticHtml1(notFoundHtmlPath)), !notFoundHtml) try { notFoundHtml = await (0, import_promises.readFile)((0, import_path.join)("dist/client", notFoundHtmlPath), "utf-8"); } catch {} if (notFoundHtml) { var headers3 = new Headers(); return headers3.set("content-type", "text/html"), new Response(notFoundHtml, { headers: headers3, status: 404 }); } } return new Response("404 Not Found", { status: 404 }); } } } }; function createHonoHandler(route2) { return async function (context, next) { try { var request = context.req.raw; if ((route2.page.endsWith("/+not-found") || Reflect.ownKeys(route2.routeKeys).length > 0) && options?.serveStaticAssets) { var staticAssetResponse = await options.serveStaticAssets({ context }); if (staticAssetResponse) return await (0, import_createHandleRequest.runMiddlewares)(requestHandlers, request, route2, async function () { return staticAssetResponse; }); } if ((0, import_path.extname)(request.url) === ".js" || (0, import_path.extname)(request.url) === ".css") return next(); var url = (0, import_createHandleRequest.getURLfromRequestURL)(request), response = await function () { if (url.pathname.endsWith(import_constants.LOADER_JS_POSTFIX_UNCACHED)) { var originalUrl = (0, import_cleanUrl.getPathFromLoaderPath)(url.pathname); if (route2.type === "ssg" && Object.keys(route2.routeKeys).length > 0 && !routeMap[originalUrl]) { var nfPath = findNearestNotFoundPath(originalUrl); return new Response(`export function loader(){return{__oneError:404,__oneErrorMessage:'Not Found',__oneNotFoundPath:${JSON.stringify(nfPath)}}}`, { headers: { "Content-Type": "text/javascript" } }); } var finalUrl = new URL(originalUrl, url.origin), cleanedRequest = new Request(finalUrl, request); return resolveLoaderRoute(requestHandlers, cleanedRequest, finalUrl, route2); } switch (route2.type) { case "api": return debugRouter && console.info(`[one] \u26A1 ${url.pathname} \u2192 matched API route: ${route2.page}`), resolveAPIRoute(requestHandlers, request, url, route2); case "ssg": case "spa": case "ssr": return debugRouter && console.info(`[one] \u26A1 ${url.pathname} \u2192 matched page route: ${route2.page} (${route2.type})`), resolvePageRoute(requestHandlers, request, url, route2); } }(); if (response) { if (isResponse(response)) { if (isStatusRedirect(response.status)) { var location = `${response.headers.get("location") || ""}`; return response.headers.forEach(function (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.headers.has("cache-control") && !response.headers.has("Cache-Control") && response.headers.set("cache-control", "no-cache"), response; } return next(); } } catch (err) { console.error(` [one] Error handling request: ${err.stack}`); } return next(); }; } var compiledManifest = (0, import_createHandleRequest.compileManifest)(buildInfo.manifest), _iteratorNormalCompletion1 = !0, _didIteratorError1 = !1, _iteratorError1 = void 0; try { for (var _iterator1 = compiledManifest.apiRoutes[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = !0) { var route = _step1.value; 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))); } } catch (err) { _didIteratorError1 = !0, _iteratorError1 = err; } finally { try { !_iteratorNormalCompletion1 && _iterator1.return != null && _iterator1.return(); } finally { if (_didIteratorError1) throw _iteratorError1; } } var _iteratorNormalCompletion2 = !0, _didIteratorError2 = !1, _iteratorError2 = void 0; try { for (var _iterator2 = compiledManifest.pageRoutes[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = !0) { var route1 = _step2.value; app.get(route1.urlPath, createHonoHandler(route1)), route1.urlPath !== route1.urlCleanPath && app.get(route1.urlCleanPath, createHonoHandler(route1)); } } catch (err) { _didIteratorError2 = !0, _iteratorError2 = err; } finally { try { !_iteratorNormalCompletion2 && _iterator2.return != null && _iterator2.return(); } finally { if (_didIteratorError2) throw _iteratorError2; } } var { preloads, cssPreloads } = buildInfo; app.get("*", async function (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)) { var request = c.req.raw, url = (0, import_createHandleRequest.getURLfromRequestURL)(request), originalUrl = (0, import_cleanUrl.getPathFromLoaderPath)(c.req.path), _iteratorNormalCompletion3 = !0, _didIteratorError3 = !1, _iteratorError3 = void 0; try { for (var _iterator3 = compiledManifest.pageRoutes[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = !0) { var route2 = _step3.value; if (route2.file !== "" && route2.compiledRegex.test(originalUrl)) { if (route2.type === "ssg" && Object.keys(route2.routeKeys).length > 0 && !routeMap[originalUrl]) { var nfPath = findNearestNotFoundPath(originalUrl); return c.header("Content-Type", "text/javascript"), c.status(200), c.body(`export function loader(){return{__oneError:404,__oneErrorMessage:'Not Found',__oneNotFoundPath:${JSON.stringify(nfPath)}}}`); } var loaderRoute = { ...route2, routeFile: route2.file, // preserve original for lazy route lookup file: route2.loaderServerPath || c.req.path }, finalUrl = new URL(originalUrl, url.origin), cleanedRequest = new Request(finalUrl, request); try { var resolved = await resolveLoaderRoute(requestHandlers, cleanedRequest, finalUrl, loaderRoute); return resolved; } catch (err) { return err?.code === "ERR_MODULE_NOT_FOUND" ? (c.header("Content-Type", "text/javascript"), c.status(200), c.body("export function loader() { return undefined }")) : (console.error(`Error running loader: ${err}`), next()); } } } } catch (err) { _didIteratorError3 = !0, _iteratorError3 = err; } finally { try { !_iteratorNormalCompletion3 && _iterator3.return != null && _iterator3.return(); } finally { if (_didIteratorError3) throw _iteratorError3; } } } return next(); }); } //# sourceMappingURL=oneServe.native.js.map