@baqhub/sdk
Version:
The official JavaScript SDK for the BAQ federated app platform.
89 lines (88 loc) • 3.18 kB
JavaScript
import { JSONPath } from "jsonpath-plus";
import compact from "lodash/compact.js";
import { unreachable } from "../../helpers/type.js";
import { normalizePath } from "./pathHelpers.js";
import { QueryLinkValue } from "./queryLinkValue.js";
//
// Model.
//
export var QueryLinkType;
(function (QueryLinkType) {
QueryLinkType["LINK"] = "link";
QueryLinkType["PATH_LINK"] = "path_link";
QueryLinkType["EMPTY_PATH_LINK"] = "empty_path_link";
})(QueryLinkType || (QueryLinkType = {}));
//
// I/O.
//
function buildLink(value) {
return [QueryLinkType.LINK, value];
}
function buildPathLink(path, value) {
return [QueryLinkType.PATH_LINK, path, value];
}
function buildEmptyPathLink(path) {
return [QueryLinkType.EMPTY_PATH_LINK, path];
}
function queryLinkToString(queryLink) {
switch (queryLink[0]) {
case QueryLinkType.LINK:
return QueryLinkValue.toString(queryLink[1]);
case QueryLinkType.PATH_LINK: {
const normalizedPath = normalizePath(queryLink[1]);
const valueString = QueryLinkValue.toString(queryLink[2]);
return `${normalizedPath}=${valueString}`;
}
case QueryLinkType.EMPTY_PATH_LINK:
return `${normalizePath(queryLink[1])}=`;
default:
unreachable(queryLink[0]);
}
}
// TODO: Implement link detection for accurate comparison.
function recordHasLinkAtPath(path, value, record) {
const recordValues = JSONPath({ path, json: record });
return recordValues.some(v => QueryLinkValue.is(value, v));
}
// TODO: Implement link detection for accurate comparison.
function recordHasEmptyPathLink(path, record) {
const recordValues = JSONPath({ path, json: record });
return compact(recordValues).length === 0;
}
function linkIsInRecord(record, queryLink) {
switch (queryLink[0]) {
case QueryLinkType.LINK:
throw new Error("TODO: Implement local link detection.");
case QueryLinkType.PATH_LINK:
return recordHasLinkAtPath(queryLink[1], queryLink[2], record);
case QueryLinkType.EMPTY_PATH_LINK:
return recordHasEmptyPathLink(queryLink[1], record);
default:
unreachable(queryLink[0]);
}
}
function queryLinkIsSuperset(link1, link2) {
switch (link1[0]) {
case QueryLinkType.LINK:
return ((link2[0] === QueryLinkType.LINK &&
QueryLinkValue.match(link1[1], link2[1])) ||
(link2[0] === QueryLinkType.PATH_LINK &&
QueryLinkValue.match(link1[1], link2[2])));
case QueryLinkType.PATH_LINK:
return (link2[0] === QueryLinkType.PATH_LINK &&
link1[1] === link2[1] &&
QueryLinkValue.match(link1[2], link2[2]));
case QueryLinkType.EMPTY_PATH_LINK:
return (link2[0] === QueryLinkType.EMPTY_PATH_LINK && link1[1] === link2[1]);
default:
unreachable(link1[0]);
}
}
export const QueryLink = {
link: buildLink,
pathLink: buildPathLink,
emptyPathLink: buildEmptyPathLink,
isInRecord: linkIsInRecord,
toString: queryLinkToString,
isSuperset: queryLinkIsSuperset,
};