one
Version:
One is a new React Framework that makes Vite serve both native and web.
317 lines (313 loc) • 15.7 kB
JavaScript
import { readFile } from "fs/promises";
import { extname, join, resolve } from "path";
import { CSS_PRELOAD_JS_POSTFIX, LOADER_JS_POSTFIX_UNCACHED, PRELOAD_JS_POSTFIX } from "../constants.native.js";
import { compileManifest, getURLfromRequestURL, runMiddlewares } from "../createHandleRequest.native.js";
import { getPathFromLoaderPath } from "../utils/cleanUrl.native.js";
import { toAbsolute } from "../utils/toAbsolute.native.js";
import { getFetchStaticHtml } from "./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 _buildInfo_useRolldown,
_oneOptions_web,
_oneOptions_build_api,
_oneOptions_build,
{
resolveAPIRoute,
resolveLoaderRoute,
resolvePageRoute
} = await import("../createHandleRequest.native.js"),
{
isResponse
} = await import("../utils/isResponse.native.js"),
{
isStatusRedirect
} = await import("../utils/isStatus.native.js"),
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,
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",
useRolldown = (_buildInfo_useRolldown = buildInfo.useRolldown) !== null && _buildInfo_useRolldown !== void 0 ? _buildInfo_useRolldown : !1,
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(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 = useRolldown ? route2.page.slice(1) : route2.page.slice(1).replace(/\[/g, "_").replace(/\]/g, "_"),
apiFile = 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(toAbsolute(route2.contextKey));
},
async handleLoader(param) {
var {
route: route2,
loaderProps
} = param,
_options_lazyRoutes_pages,
_options_lazyRoutes,
routeFile = route2.routeFile || route2.file,
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(toAbsolute(join("./", "dist/server", route2.file))),
{
loader
} = exports;
if (!loader) return console.warn("No loader found in exports", route2.file), null;
var json = await loader(loaderProps);
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(toAbsolute(_$buildInfo.serverJsPath)),
loaderData;
try {
var _exported_loader;
loaderData = await ((_exported_loader = exported.loader) === null || _exported_loader === void 0 ? void 0 : _exported_loader.call(exported, loaderProps));
} catch (loaderErr) {
if (isResponse(loaderErr)) return loaderErr;
throw loaderErr;
}
var 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
});
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 htmlPath = routeMap[url.pathname] || routeMap[_$buildInfo?.cleanPath];
if (htmlPath) {
var fetchStaticHtml = getFetchStaticHtml(),
html = null;
if (fetchStaticHtml && (html = await fetchStaticHtml(htmlPath)), !html) try {
html = await readFile(join("dist/client", htmlPath), "utf-8");
} catch {}
if (html) {
var headers1 = new Headers();
return headers1.set("content-type", "text/html"), new Response(html, {
headers: headers1,
status: route2.isNotFound ? 404 : 200
});
}
}
}
}
};
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 runMiddlewares(requestHandlers, request, route2, async function () {
return staticAssetResponse;
});
}
if (extname(request.url) === ".js" || extname(request.url) === ".css") return next();
var url = getURLfromRequestURL(request),
response = await function () {
if (url.pathname.endsWith(LOADER_JS_POSTFIX_UNCACHED)) {
var originalUrl = getPathFromLoaderPath(url.pathname),
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;
}
return next();
}
} catch (err) {
console.error(` [one] Error handling request: ${err.stack}`);
}
return next();
};
}
var compiledManifest = 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(PRELOAD_JS_POSTFIX) && !preloads[c.req.path]) return c.header("Content-Type", "text/javascript"), c.status(200), c.body("");
if (c.req.path.endsWith(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(LOADER_JS_POSTFIX_UNCACHED)) {
var request = c.req.raw,
url = getURLfromRequestURL(request),
originalUrl = 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)) {
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 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();
});
}
export { oneServe };
//# sourceMappingURL=oneServe.native.js.map