vike
Version:
The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.
171 lines (170 loc) • 7.92 kB
JavaScript
;
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;
}