@discoveryjs/discovery
Version:
Frontend framework for rapid data (JSON) analysis, shareable serverless reports and dashboards
91 lines (90 loc) • 3.07 kB
JavaScript
import * as base64 from "../../core/utils/base64.js";
function ensureString(value, fallback = "") {
return typeof value === "string" ? value : fallback;
}
export const decodedSpecialParams = ["query", "graph", "view", "viewEditorHidden", "title", "dzen", "noedit"];
export const encodedSpecialParams = ["q", "graph", "v", "vh", "title", "dzen", "noedit"];
export function encodeParams(params) {
const normalizedParams = typeof params === "string" ? { query: params } : params;
const { query, graph, view, viewEditorHidden, title, dzen, noedit, ...extra } = normalizedParams;
const pairs = [];
if (dzen) {
pairs.push(["dzen"]);
}
if (noedit) {
pairs.push(["noedit"]);
}
if (title) {
pairs.push(["title", title]);
}
if (query) {
pairs.push(["q", base64.encode(query)]);
}
if (graph) {
pairs.push(["graph", base64.encode(JSON.stringify(graph))]);
}
if (typeof view === "string") {
pairs.push(view ? ["v", base64.encode(view)] : ["v"]);
}
if (viewEditorHidden) {
pairs.push(["vh"]);
}
for (const [name, value] of Object.keys(extra || {}).sort()) {
if (!decodedSpecialParams.includes(name)) {
pairs.push([
name,
name.endsWith("-b64") && typeof value === "string" ? base64.encode(value) : value
]);
}
}
return pairs;
}
export function decodeParams(pairs) {
const params = Object.fromEntries(pairs);
const decodedParams = {
title: ensureString(params.title),
query: base64.decode(ensureString(params.q)),
graph: JSON.parse(base64.decode(ensureString(params.graph)) || "null"),
view: "v" in params ? base64.decode(ensureString(params.v)) : void 0,
viewEditorHidden: "vh" in params,
dzen: "dzen" in params,
noedit: "noedit" in params
};
for (const [name, value] of Object.entries(params)) {
if (!encodedSpecialParams.includes(name)) {
decodedParams[name] = name.endsWith("-b64") && typeof value === "string" ? base64.decode(value) : params[name];
}
}
return decodedParams;
}
function filterDecodedParams(params) {
return Object.fromEntries(Object.entries(params).filter(
([key]) => !decodedSpecialParams.includes(key)
));
}
function isEqual(a, b, ...skipKeys) {
for (const key of Object.keys(a)) {
if (a[key] !== b[key] && !skipKeys.includes(key)) {
return false;
}
}
for (const key of Object.keys(b)) {
if (a[key] !== b[key] && !skipKeys.includes(key)) {
return false;
}
}
return true;
}
export function contextWithoutEditorParams(newContext, currentContext = {}) {
const stableNewContext = {
...newContext,
params: filterDecodedParams(newContext.params)
};
if (!isEqual(currentContext, stableNewContext, "params", "actions") || !isEqual(currentContext.params, stableNewContext.params) || !isEqual(currentContext.actions, stableNewContext.actions)) {
return stableNewContext;
}
return currentContext;
}
export function getParamsFromContext(context) {
return context && typeof context === "object" && "params" in context ? context.params : {};
}