vike
Version:
The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.
57 lines (56 loc) • 3.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getProxyForPublicUsage = getProxyForPublicUsage;
// We use a proxy instead of property getters.
// - The issue with property getters is that they can't be `writable: true` but we do want the user to be able to modify the value of internal properties.
// ```console
// TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object>
// ```
// - Previous implementation using property getters: https://github.com/vikejs/vike/blob/4dbb354b0bcec04e862041fc9183fc4691bb8711/vike/utils/makePublicCopy.ts
// Show warning when user is accessing internal `_` properties.
const NOT_SERIALIZABLE_js_1 = require("./NOT_SERIALIZABLE.js");
const utils_js_1 = require("./utils.js");
function getProxyForPublicUsage(obj, objName, skipOnInternalProp, fallback) {
return new Proxy(obj, {
get: getTrapGet(obj, objName, skipOnInternalProp, fallback),
});
}
function getTrapGet(obj, objName, skipOnInternalProp, fallback) {
return function (_, prop) {
const propStr = String(prop);
if (prop === '_isProxyObject')
return true;
if (!skipOnInternalProp)
onInternalProp(propStr, objName);
if (fallback && !(prop in obj)) {
// Rudimentary flat pageContext implementation https://github.com/vikejs/vike/issues/1268
// Failed full-fledged implementation: https://github.com/vikejs/vike/pull/2458
return fallback(prop);
}
const val = obj[prop];
onNotSerializable(propStr, val, objName);
return val;
};
}
function onNotSerializable(propStr, val, objName) {
if (val !== NOT_SERIALIZABLE_js_1.NOT_SERIALIZABLE)
return;
const propName = (0, utils_js_1.getPropAccessNotation)(propStr);
(0, utils_js_1.assert)((0, utils_js_1.isBrowser)());
(0, utils_js_1.assertUsage)(false, `Can't access ${objName}${propName} on the client side. Because it can't be serialized, see server logs.`);
}
function onInternalProp(propStr, objName) {
// - We must skip it in the client-side because of the reactivity mechanism of UI frameworks like Solid.
// - TO-DO/eventually: use import.meta.CLIENT instead of isBrowser()
// - Where import.meta.CLIENT is defined by Vike
// - Using import.meta.env.CLIENT (note `.env.`) doesn't seem possible: https://github.com/brillout/playground_node_import.meta.env
// - If Rolldown Vite + Rolldowns always transpiles node_modules/ then we can simply use import.meta.env.SSR
if ((0, utils_js_1.isBrowser)())
return;
// TODO/now-proxy remove this and only warn on built-in access instead
if (propStr === '_configFromHook')
return;
if (propStr.startsWith('_')) {
(0, utils_js_1.assertWarning)(false, `Using internal ${objName}.${propStr} which may break in any minor version update. Reach out on GitHub to request official support for your use case.`, { onlyOnce: true, showStackTrace: true });
}
}