const utils = require("../lib/utils") const { release } = require("../config-client") const { ssrValidatePath } = require("../config") const { ssrRequest } = require("../lib/ssr-server") ;(function () { var request = context.request() var trackingCall = request.header("x-ssr-skip") if (trackingCall) { // skip tracking throw { status: parseInt(trackingCall), html: "", log: false, } } let url = request.query("url") || request.header("x-ssr-url") || "/" const noCache = request.query("noCache") const trace_id = context.debug.sentryTraceId() /** * @param {string} content */ function addSentryTrace(content) { return content.replace("", '') } context.response.header("sentry-trace", trace_id) const auth = context.user.auth() if (auth && auth.role == 0) { } else if (url) { var comment = "" url = url.split("?")[0] comment += "url: " + url if (url && url.length > 1) { url = url.replace(/\/$/, "") } if (url == "/index" || !url) { url = "/" // see .htaccess } function useCache(/** @type {string} */ _url) { var cache = !noCache && context.db.find("ssr", { filter: { path: _url, }, }) if (cache && cache.length) { // use cache context.response.header("X-SSR-Cache", "true") throw { status: 200, log: false, html: addSentryTrace(cache[0].content), } } } // validate url var status = 200 var pNorender = false var pNotfound = false const pR = ssrValidatePath(url) if (pR === -1) { pNotfound = true comment += ", notFound" } else if (!pR) { pNorender = true comment += ", noRender" } else if (typeof pR === "string") { url = pR comment += ", cache url: " + url } if (noCache) { comment += ", noCache" } if (!pNorender && !pNotfound) { // check if we have a cache useCache(url) } let head = "" let html = "" let error = "" comment += ", path: " + url var cacheIt = false if (pNorender) { html = "" } else if (pNotfound) { status = 404 html = "404 NOT FOUND" } else { // @ts-ignore context.ssrCache = {} // @ts-ignore context.ssrRequest = ssrRequest try { // if error, output plain html without prerendering // @ts-ignore const app = require("../lib/app.server") const rendered = app.default.render({ url: url, }) head = rendered.head html = rendered.html head += "\n\n" + "" // status from webapp // @ts-ignore if (context.is404) { status = 404 } else { cacheIt = true } } catch (/** @type {any} */ e) { utils.log(e.message) utils.log(e.stack) error = "error: " + e.message + "\n\n" + e.stack // utils.log(e) // for (var property in e) { // utils.log(property + ": " + e[property]) // } // error = JSON.stringify(e) } } var tpl = context.fs.readFile("templates/spa.html") tpl = tpl.replace("", head) tpl = tpl.replace("", html) tpl = tpl.replace("", error ? "" : "") tpl = tpl.replace("", comment ? "" : "") if (cacheIt && !noCache) { // save cache context.db.create("ssr", { path: url, content: tpl, }) } throw { status: status, log: false, html: addSentryTrace(tpl), } } else { // only admins are allowed throw { status: 403, message: "invalid auth", auth: auth, release: release, } } })()