@builder.io/sdk-vue
Version:
Builder.io SDK for Vue
278 lines (272 loc) • 9.05 kB
JavaScript
import { createRequire } from "node:module";
const TARGET = "vue", MSG_PREFIX = "[Builder.io]: ", logger = {
log: (...e) => console.log(MSG_PREFIX, ...e),
error: (...e) => console.error(MSG_PREFIX, ...e),
warn: (...e) => console.warn(MSG_PREFIX, ...e),
debug: (...e) => console.debug(MSG_PREFIX, ...e)
};
function isBrowser() {
return typeof window < "u" && typeof document < "u";
}
const convertSearchParamsToQueryObject = (e) => {
const t = {};
return e.forEach((o, n) => {
t[n] = o;
}), t;
}, normalizeSearchParams = (e) => e instanceof URLSearchParams ? convertSearchParamsToQueryObject(e) : e, getSearchString = (e) => typeof e == "string" ? e : e instanceof URLSearchParams ? e.toString() : new URLSearchParams(e).toString();
function isIframe() {
return isBrowser() && window.self !== window.top;
}
function isEditing(e) {
return isIframe() && // accessing window.location.search is safe here because `isIframe()` is only `true` if we're in a browser.
getSearchString(e || window.location.search).indexOf("builder.frameEditing=") !== -1;
}
const getLocation = () => {
if (isBrowser()) {
const e = new URL(location.href);
return e.pathname === "" && (e.pathname = "/"), e;
} else
return console.warn("Cannot get location for tracking in non-browser environment"), null;
}, getUserAgent = () => typeof navigator == "object" && navigator.userAgent || "", getUserAttributes = () => {
const e = getUserAgent(), t = {
Android() {
return e.match(/Android/i);
},
BlackBerry() {
return e.match(/BlackBerry/i);
},
iOS() {
return e.match(/iPhone|iPod/i);
},
Opera() {
return e.match(/Opera Mini/i);
},
Windows() {
return e.match(/IEMobile/i) || e.match(/WPDesktop/i);
},
any() {
return t.Android() || t.BlackBerry() || t.iOS() || t.Opera() || t.Windows() || TARGET === "reactNative";
}
}, o = e.match(/Tablet|iPad/i), n = getLocation();
return {
urlPath: n == null ? void 0 : n.pathname,
host: (n == null ? void 0 : n.host) || (n == null ? void 0 : n.hostname),
device: o ? "tablet" : t.any() ? "mobile" : "desktop"
};
}, getFunctionArguments = ({
builder: e,
context: t,
event: o,
state: n
}) => Object.entries({
state: n,
Builder: e,
// legacy
builder: e,
context: t,
event: o
}), getBuilderGlobals = () => ({
isEditing: isEditing(),
isBrowser: isBrowser(),
isServer: !isBrowser(),
getUserAttributes: () => getUserAttributes()
}), parseCode = (e, {
isExpression: t = !0
}) => /* we disable this for cases where we definitely don't want a return */ t && !(e.includes(";") || e.includes(" return ") || e.trim().startsWith("return ")) ? `return (${e});` : e;
function flattenState({
rootState: e,
localState: t,
rootSetState: o
}) {
return new Proxy(e, {
get: (n, r) => {
if (t && r in t)
return t[r];
const s = n[r];
return typeof s == "object" && s !== null ? flattenState({
rootState: s,
localState: void 0,
rootSetState: o ? (i) => {
n[r] = i, o(n);
} : void 0
}) : s;
},
set: (n, r, s) => {
if (t && r in t)
throw new Error("Writing to local state is not allowed as it is read-only.");
return n[r] = s, o == null || o(n), !0;
}
});
}
const SDK_NAME_FOR_TARGET = (() => {
switch (TARGET) {
case "rsc":
return "react-nextjs";
case "reactNative":
return "react-native";
default:
return TARGET;
}
})(), SDK_NAME = `@builder.io/sdk-${SDK_NAME_FOR_TARGET}`, fastClone = (e) => JSON.parse(JSON.stringify(e)), set = (e, t, o) => {
if (Object(e) !== e)
return e;
const n = Array.isArray(t) ? t : t.toString().match(/[^.[\]]+/g);
return n.slice(0, -1).reduce((r, s, i) => Object(r[s]) === r[s] ? r[s] : r[s] = Math.abs(Number(n[i + 1])) >> 0 === +n[i + 1] ? [] : {}, e)[n[n.length - 1]] = o, e;
}, noop = () => {
};
let safeDynamicRequire = noop;
try {
safeDynamicRequire = createRequire(import.meta.url);
} catch (error) {
try {
safeDynamicRequire = eval("require");
} catch (e) {
}
}
const getSyncValName = (e) => `bldr_${e}_sync`, BUILDER_SET_STATE_NAME = "BUILDER_SET_STATE", INJECTED_IVM_GLOBAL = "BUILDER_IVM", REF_TO_PROXY_FN = `
var refToProxy = (obj) => {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
return new Proxy({}, {
get(target, key) {
if (key === 'copySync') {
return () => obj.copySync();
}
const val = obj.getSync(key);
if (typeof val?.getSync === 'function') {
return refToProxy(val);
}
return val;
},
set(target, key, value) {
const v = typeof value === 'object' ? new ${INJECTED_IVM_GLOBAL}.Reference(value) : value;
obj.setSync(key, v);
${BUILDER_SET_STATE_NAME}(key, value)
},
deleteProperty(target, key) {
obj.deleteSync(key);
}
})
}
`, processCode = ({
code: e,
args: t
}) => {
const o = t.map(([n]) => `var ${n} = refToProxy(${getSyncValName(n)}); `).join("");
return `
${REF_TO_PROXY_FN}
${o}
function theFunction() {
${e}
}
const output = theFunction()
if (typeof output === 'object' && output !== null) {
return JSON.stringify(output.copySync ? output.copySync() : output);
} else {
return output;
}
`;
};
let IVM_INSTANCE = null, IVM_CONTEXT = null;
const setIvm = (e, t = {}) => {
IVM_INSTANCE || (IVM_INSTANCE = e, setIsolateContext(t));
}, SHOULD_MENTION_INITIALIZE_SCRIPT = SDK_NAME === "@builder.io/sdk-react-nextjs" || SDK_NAME === "@builder.io/sdk-react" || SDK_NAME === "@builder.io/sdk-qwik" || SDK_NAME === "@builder.io/sdk-vue", getIvm = () => {
try {
if (IVM_INSTANCE)
return IVM_INSTANCE;
const t = safeDynamicRequire("isolated-vm");
if (t)
return t;
} catch (t) {
logger.error("isolated-vm import error.", t);
}
const e = `${MSG_PREFIX}could not import \`isolated-vm\` module for safe script execution on a Node server.
SOLUTION: In a server-only execution path within your application, do one of the following:
${SHOULD_MENTION_INITIALIZE_SCRIPT ? `- import and call \`initializeNodeRuntime()\` from "${SDK_NAME}/node/init".` : ""}
- add the following import: \`await import('isolated-vm')\`.
For more information, visit https://builder.io/c/docs/integration-tips#enabling-data-bindings-in-node-environments`;
throw new Error(e);
};
function setIsolateContext(e = {
memoryLimit: 128
}) {
if (IVM_CONTEXT)
return IVM_CONTEXT;
const t = getIvm(), n = new t.Isolate(e).createContextSync(), r = n.global;
return r.setSync("global", r.derefInto()), r.setSync("log", function(...s) {
console.log(...s);
}), r.setSync(INJECTED_IVM_GLOBAL, t), IVM_CONTEXT = n, n;
}
const getIsolateContext = () => setIsolateContext(), runInNode = ({
code: e,
builder: t,
context: o,
event: n,
localState: r,
rootSetState: s,
rootState: i
}) => {
const g = getIvm(), m = fastClone({
...i,
...r
}), u = getFunctionArguments({
builder: t,
context: o,
event: n,
state: m
}), l = getIsolateContext(), d = l.global;
d.setSync(BUILDER_SET_STATE_NAME, function(c, a) {
set(i, c, a), s == null || s(i);
}), u.forEach(([c, a]) => {
const I = typeof a == "object" ? new g.Reference(
// workaround: methods with default values for arguments is not being cloned over
c === "builder" ? {
...a,
getUserAttributes: () => a.getUserAttributes()
} : a
) : null;
d.setSync(getSyncValName(c), I);
});
const E = processCode({
code: e,
args: u
}), f = l.evalClosureSync(E);
try {
return JSON.parse(f);
} catch {
return f;
}
}, checkIsDefined = (e) => e != null;
function isNodeRuntime() {
var e;
return typeof process < "u" && checkIsDefined((e = process == null ? void 0 : process.versions) == null ? void 0 : e.node);
}
const shouldForceBrowserRuntimeInNode = ({
shouldLogWarning: e
}) => {
var r;
if (!isNodeRuntime())
return !1;
const t = process.arch === "arm64", o = process.version.startsWith("v20"), n = (r = process.env.NODE_OPTIONS) == null ? void 0 : r.includes("--no-node-snapshot");
return t && o && !n ? (e && logger.log("Skipping usage of `isolated-vm` to avoid crashes in Node v20 on an arm64 machine.\n If you would like to use the `isolated-vm` package on this machine, please provide the `NODE_OPTIONS=--no-node-snapshot` config to your Node process.\n See https://github.com/BuilderIO/builder/blob/main/packages/sdks/README.md#node-v20--m1-macs-apple-silicon-support for more information.\n "), !0) : !1;
};
export {
TARGET as T,
getBuilderGlobals as a,
set as b,
fastClone as c,
getSearchString as d,
checkIsDefined as e,
flattenState as f,
getFunctionArguments as g,
isEditing as h,
isBrowser as i,
getUserAttributes as j,
setIvm as k,
logger as l,
normalizeSearchParams as n,
parseCode as p,
runInNode as r,
shouldForceBrowserRuntimeInNode as s
};