UNPKG

vike

Version:

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

171 lines (170 loc) 7.92 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPageContextClientSerialized = getPageContextClientSerialized; exports.getPageContextClientSerializedAbort = getPageContextClientSerializedAbort; exports.getGlobalContextClientSerialized = getGlobalContextClientSerialized; const stringify_1 = require("@brillout/json-serializer/stringify"); const utils_js_1 = require("../utils.js"); const error_page_js_1 = require("../../../shared/error-page.js"); const addIs404ToPageProps_js_1 = require("../../../shared/addIs404ToPageProps.js"); const picocolors_1 = __importDefault(require("@brillout/picocolors")); const NOT_SERIALIZABLE_js_1 = require("../../../shared/NOT_SERIALIZABLE.js"); const pageContextInitIsPassedToClient_js_1 = require("../../../shared/misc/pageContextInitIsPassedToClient.js"); const isServerSideError_js_1 = require("../../../shared/misc/isServerSideError.js"); const propKeys_js_1 = require("./propKeys.js"); const passToClientBuiltInPageContext = [ 'abortReason', '_urlRewrite', '_urlRedirect', 'abortStatusCode', '_abortCall', /* Not needed on the client-side '_abortCaller', */ pageContextInitIsPassedToClient_js_1.pageContextInitIsPassedToClient, 'pageId', 'routeParams', 'data', // for data() hook ]; const pageToClientBuiltInPageContextError = ['pageProps', 'is404', isServerSideError_js_1.isServerSideError]; function getPageContextClientSerialized(pageContext) { const passToClientPageContext = getPassToClientPageContext(pageContext); const pageContextClient = applyPassToClient(passToClientPageContext, pageContext); if (passToClientPageContext.some((prop) => (0, propKeys_js_1.getPropVal)(pageContext._pageContextInit, prop))) { pageContextClient[pageContextInitIsPassedToClient_js_1.pageContextInitIsPassedToClient] = true; } const pageContextClientSerialized = serializeObject(pageContextClient, 'pageContext', passToClientPageContext); return pageContextClientSerialized; } function getGlobalContextClientSerialized(pageContext) { const passToClient = pageContext._passToClient; const globalContextClient = applyPassToClient(passToClient, pageContext._globalContext); const globalContextClientSerialized = serializeObject(globalContextClient, 'globalContext', passToClient); return globalContextClientSerialized; } function serializeObject(obj, objName, passToClient) { let serialized; try { serialized = serializeValue(obj); } catch (err) { const h = (s) => picocolors_1.default.cyan(s); let hasWarned = false; const propsNonSerializable = []; passToClient.forEach((prop) => { const res = (0, propKeys_js_1.getPropVal)(obj, prop); if (!res) return; const { value } = res; const varName = `${objName}${(0, propKeys_js_1.getPropKeys)(prop).map(utils_js_1.getPropAccessNotation).join('')}`; try { serializeValue(value, varName); } catch (err) { propsNonSerializable.push(prop); // useConfig() wrong usage if (prop === '_configFromHook') { let pathString = ''; if ((0, stringify_1.isJsonSerializerError)(err)) { pathString = err.pathString; } // There used to be a `## Serialization Error` section in the docs but we removed it at: // https://github.com/vikejs/vike/commit/c9da2f577db01bd1c8f72265ff83e78484ddc2c0 (0, utils_js_1.assertUsage)(false, `Cannot serialize config value ${h(pathString)} set by useConfig()`); } // Non-serializable property set by the user let msg = [ `${h(varName)} can't be serialized and, therefore, can't be passed to the client side.`, `Make sure ${h(varName)} is serializable, or remove ${h(JSON.stringify(prop))} from ${h('passToClient')}.`, ].join(' '); if ((0, stringify_1.isJsonSerializerError)(err)) { msg = `${msg} Serialization error: ${err.messageCore}.`; } else { // When a property getter throws an error console.warn('Serialization error:'); console.warn(err); msg = `${msg} The serialization failed because of the error printed above.`; } // We warn (instead of throwing an error) since Vike's client runtime throws an error (with `assertUsage()`) if the user's client code tries to access the property that cannot be serialized (0, utils_js_1.assertWarning)(false, msg, { onlyOnce: false }); hasWarned = true; } }); (0, utils_js_1.assert)(hasWarned); propsNonSerializable.forEach((prop) => { obj[(0, propKeys_js_1.getPropKeys)(prop)[0]] = NOT_SERIALIZABLE_js_1.NOT_SERIALIZABLE; }); try { serialized = serializeValue(obj); } catch (err) { (0, utils_js_1.assert)(false); } } return serialized; } function serializeValue(value, varName) { return (0, stringify_1.stringify)(value, { forbidReactElements: true, valueName: varName }); } function getPassToClientPageContext(pageContext) { let passToClient = [...pageContext._passToClient, ...passToClientBuiltInPageContext]; if ((0, error_page_js_1.isErrorPage)(pageContext.pageId, pageContext._globalContext._pageConfigs)) { (0, utils_js_1.assert)((0, utils_js_1.hasProp)(pageContext, 'is404', 'boolean')); (0, addIs404ToPageProps_js_1.addIs404ToPageProps)(pageContext); passToClient.push(...pageToClientBuiltInPageContextError); } passToClient = (0, utils_js_1.unique)(passToClient); return passToClient; } function getPageContextClientSerializedAbort(pageContext) { (0, utils_js_1.assert)(pageContext._urlRedirect || pageContext._urlRewrite || pageContext.abortStatusCode); (0, utils_js_1.assert)(pageContext._abortCall); (0, utils_js_1.assert)(pageContext._abortCaller); // Not needed on the client-side delete pageContext._abortCaller; const unknownProps = Object.keys(pageContext).filter((prop) => ![ // prettier-ignore // biome-ignore format: '_abortCall', /* Not needed on the client-side '_abortCaller', */ '_urlRedirect', '_urlRewrite', 'abortStatusCode', 'abortReason', 'is404', 'pageProps', ].includes(prop)); if (!pageContext._isLegacyRenderErrorPage) { (0, utils_js_1.assert)(unknownProps.length === 0); } else { // TODO/v1-release: remove (0, utils_js_1.assertWarning)(unknownProps.length === 0, [ "The following pageContext values won't be available on the client-side:", unknownProps.map((p) => ` pageContext[${JSON.stringify(p)}]`), 'Use `throw render()` instead of `throw RenderErrorPage()`', ].join('\n'), { onlyOnce: false, }); } return serializeValue(pageContext); } function applyPassToClient(passToClient, pageContext) { const pageContextClient = {}; passToClient.forEach((prop) => { // Get value from pageContext const res = (0, propKeys_js_1.getPropVal)(pageContext, prop); if (!res) return; const { value } = res; // Set value to pageContextClient (0, propKeys_js_1.setPropVal)(pageContextClient, prop, value); }); return pageContextClient; }