UNPKG

vike

Version:

The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.

131 lines (130 loc) 7.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.execHookOnRenderHtml = execHookOnRenderHtml; const renderHtml_js_1 = require("../html/renderHtml.js"); const getHook_js_1 = require("../../../shared/hooks/getHook.js"); const utils_js_1 = require("../utils.js"); const stream_js_1 = require("../html/stream.js"); const assertPageContextProvidedByUser_js_1 = require("../../../shared/assertPageContextProvidedByUser.js"); const preparePageContextForPublicUsageServer_js_1 = require("./preparePageContextForPublicUsageServer.js"); const assertHookReturnedObject_js_1 = require("../../../shared/assertHookReturnedObject.js"); const loggerRuntime_js_1 = require("../loggerRuntime.js"); const picocolors_1 = __importDefault(require("@brillout/picocolors")); const execHook_js_1 = require("../../../shared/hooks/execHook.js"); async function execHookOnRenderHtml(pageContext) { const hook = getRenderHook(pageContext); (0, utils_js_1.objectAssign)(pageContext, { _renderHook: hook }); const { hookReturn } = await (0, execHook_js_1.execHookDirectSingleWithReturn)(hook, pageContext, preparePageContextForPublicUsageServer_js_1.preparePageContextForPublicUsageServer); const { documentHtml, pageContextProvidedByRenderHook, pageContextPromise, injectFilter } = processHookReturnValue(hookReturn, hook); Object.assign(pageContext, pageContextProvidedByRenderHook); (0, utils_js_1.objectAssign)(pageContext, { _pageContextPromise: pageContextPromise }); const onErrorWhileStreaming = (err) => { // Should the stream inject the following? // ``` // <script>console.error("An error occurred on the server side while streaming the page to HTML, see server logs.")</script> // ``` (0, loggerRuntime_js_1.logRuntimeError)(err, pageContext._httpRequestId); if (!pageContext.errorWhileRendering) { pageContext.errorWhileRendering = err; } }; const htmlRender = await (0, renderHtml_js_1.renderDocumentHtml)(documentHtml, pageContext, onErrorWhileStreaming, injectFilter); (0, utils_js_1.assert)(typeof htmlRender === 'string' || (0, stream_js_1.isStream)(htmlRender)); return { htmlRender, renderHook: hook }; } function getRenderHook(pageContext) { let hookFound; { let hook; let hookName = undefined; hook = (0, getHook_js_1.getHookFromPageContext)(pageContext, 'onRenderHtml'); if (hook) { hookName = 'onRenderHtml'; } else { hook = (0, getHook_js_1.getHookFromPageContext)(pageContext, 'render'); if (hook) { hookName = 'render'; } } if (hook) { (0, utils_js_1.assert)(hookName); const { hookFilePath, hookFn, hookTimeout } = hook; hookFound = { hookFn, hookFilePath, hookName, hookTimeout }; } } if (!hookFound) { const hookName = pageContext._globalContext._pageConfigs.length > 0 ? 'onRenderHtml' : 'render'; (0, utils_js_1.assertUsage)(false, [ `No ${hookName}() hook found, see https://vike.dev/${hookName}`, /* 'See https://vike.dev/render-modes for more information.', [ // 'Loaded config files (none of them define the onRenderHtml() hook):', 'Loaded server-side page files (none of them `export { render }`):', ...pageContext._pageFilePathsLoaded.map((f, i) => ` (${i + 1}): ${f}`) ].join('\n') */ ].join(' ')); } return hookFound; } function processHookReturnValue(hookReturnValue, renderHook) { let documentHtml; let pageContextPromise = null; let pageContextProvidedByRenderHook = null; let injectFilter = null; if ((0, renderHtml_js_1.isDocumentHtml)(hookReturnValue)) { documentHtml = hookReturnValue; return { documentHtml, pageContextProvidedByRenderHook, pageContextPromise, injectFilter }; } const errPrefix = `The ${renderHook.hookName}() hook defined at ${renderHook.hookFilePath}`; const errSuffix = `a string generated with ${picocolors_1.default.cyan('escapeInject`<html>...</html>`')} or the value returned by ${picocolors_1.default.cyan('dangerouslySkipEscape()')}, see https://vike.dev/escapeInject`; if (typeof hookReturnValue === 'string') { (0, utils_js_1.assertWarning)(false, [ errPrefix, `returned a plain JavaScript string which is ${picocolors_1.default.red(picocolors_1.default.bold('dangerous'))}: it should instead return`, errSuffix, ].join(' '), { onlyOnce: true }); hookReturnValue = (0, renderHtml_js_1.dangerouslySkipEscape)(hookReturnValue); } const wrongReturnValue = `should return the value ${picocolors_1.default.cyan('documentHtml')} or an object ${picocolors_1.default.cyan('{ documentHtml }')} where ${picocolors_1.default.cyan('documentHtml')} is ${errSuffix}`; (0, utils_js_1.assertUsage)((0, utils_js_1.isObject)(hookReturnValue), `${errPrefix} ${wrongReturnValue}`); (0, assertHookReturnedObject_js_1.assertHookReturnedObject)(hookReturnValue, ['documentHtml', 'pageContext', 'injectFilter'], errPrefix); (0, utils_js_1.assertUsage)(hookReturnValue.documentHtml, `${errPrefix} returned an object that is missing the ${picocolors_1.default.code('documentHtml')} property: it ${wrongReturnValue}`); if (hookReturnValue.injectFilter) { (0, utils_js_1.assertUsage)((0, utils_js_1.isCallable)(hookReturnValue.injectFilter), 'injectFilter should be a function'); injectFilter = hookReturnValue.injectFilter; } { let val = hookReturnValue.documentHtml; const errBegin = `${errPrefix} returned ${picocolors_1.default.cyan('{ documentHtml }')}, but ${picocolors_1.default.cyan('documentHtml')}`; if (typeof val === 'string') { (0, utils_js_1.assertWarning)(false, [ errBegin, `is a plain JavaScript string which is ${picocolors_1.default.bold(picocolors_1.default.red('dangerous'))}: ${picocolors_1.default.cyan('documentHtml')} should be`, errSuffix, ].join(' '), { onlyOnce: true }); val = (0, renderHtml_js_1.dangerouslySkipEscape)(val); } (0, utils_js_1.assertUsage)((0, renderHtml_js_1.isDocumentHtml)(val), [errBegin, 'should be', errSuffix].join(' ')); documentHtml = val; } if (hookReturnValue.pageContext) { const val = hookReturnValue.pageContext; const errBegin = `${errPrefix} returned ${picocolors_1.default.cyan('{ pageContext }')}, but ${picocolors_1.default.cyan('pageContext')}`; if ((0, utils_js_1.isPromise)(val) || (0, utils_js_1.isCallable)(val)) { (0, utils_js_1.assertWarning)(!(0, utils_js_1.isPromise)(val), `${errBegin} is a promise which is deprecated in favor of async functions, see https://vike.dev/streaming#initial-data-after-stream-end`, { onlyOnce: true }); pageContextPromise = val; } else { (0, utils_js_1.assertUsage)((0, utils_js_1.isObject)(val), `${errBegin} should be an object or an async function, see https://vike.dev/streaming#initial-data-after-stream-end`); (0, assertPageContextProvidedByUser_js_1.assertPageContextProvidedByUser)(val, renderHook); pageContextProvidedByRenderHook = val; } } return { documentHtml, pageContextProvidedByRenderHook, pageContextPromise, injectFilter }; }