UNPKG

@baqhub/sdk

Version:

The official JavaScript SDK for the BAQ federated app platform.

278 lines (277 loc) 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Query = void 0; const tslib_1 = require("tslib"); const jsonpath_plus_1 = require("jsonpath-plus"); const flow_js_1 = tslib_1.__importDefault(require("lodash/flow.js")); const isEqual_js_1 = tslib_1.__importDefault(require("lodash/isEqual.js")); const isString_js_1 = tslib_1.__importDefault(require("lodash/isString.js")); const orderBy_js_1 = tslib_1.__importDefault(require("lodash/orderBy.js")); const uniqBy_js_1 = tslib_1.__importDefault(require("lodash/uniqBy.js")); const constants_js_1 = require("../../constants.js"); const array_js_1 = require("../../helpers/array.js"); const string_js_1 = require("../../helpers/string.js"); const type_js_1 = require("../../helpers/type.js"); const record_js_1 = require("../records/record.js"); const recordKey_js_1 = require("../records/recordKey.js"); const pathHelpers_js_1 = require("./pathHelpers.js"); const queryDate_js_1 = require("./queryDate.js"); const queryFilter_js_1 = require("./queryFilter.js"); const querySort_js_1 = require("./querySort.js"); const includeLinkSpecialValues = [ "entity", "standing", "existential", ]; const defaultIncludeLinks = [ "entity", "existential", ]; const defaultSources = [ record_js_1.RecordSource.SELF, record_js_1.RecordSource.NOTIFICATION, record_js_1.RecordSource.SUBSCRIPTION, ]; const defaultSortBy = [ querySort_js_1.QuerySortProperty.VERSION_RECEIVED_AT, querySort_js_1.QuerySortDirection.DESCENDING, ]; // // I/O. // function queryNew(query) { return query; } function queryOfKey(key, baseQuery = {}) { const { entity, recordId } = recordKey_js_1.RecordKey.toComponents(key); return { ...baseQuery, pageSize: 1, filter: queryFilter_js_1.Q.and(queryFilter_js_1.Q.author(entity), queryFilter_js_1.Q.id(recordId)), }; } function querySingleToQueryString(query) { if (!query) { return ""; } return paramsToString([ ["include_links", includeLinksToString(query.includeLinks)], ["include_deleted", query.includeDeleted ? "true" : undefined], ["proxy_to", query.proxyTo], ]); } function queryToQueryString(query) { const filterStrings = query.filter && queryFilter_js_1.QueryFilter.toListString(query.filter); return paramsToString([ ["sort", query.sort && querySort_js_1.QuerySort.toString(query.sort)], ["min", query.min && queryDate_js_1.QueryDate.toString(query.min)], ["max", query.max && queryDate_js_1.QueryDate.toString(query.max)], ["page_start", query.pageStart && queryDate_js_1.QueryDate.toString(query.pageStart)], ["page_size", (query.pageSize || constants_js_1.Constants.defaultPageSize).toString()], ["distinct", query.distinct && (0, pathHelpers_js_1.normalizePath)(query.distinct)], ["sources", query.sources?.join(",")], ...(filterStrings || []).map(f => ["filter", f]), ["include_links", includeLinksToString(query.includeLinks)], ["include_deleted", query.includeDeleted ? "true" : undefined], ["proxy_to", query.proxyTo], ]); } function queryToSync(query, boundary) { return { max: undefined, min: boundary, sort: querySort_js_1.QuerySort.syncDefault, pageStart: undefined, pageSize: 100, distinct: undefined, sources: query.sources, filter: query.filter, mode: query.mode, includeLinks: query.includeLinks, includeDeleted: true, proxyTo: query.proxyTo, }; } function queryFindBoundary(query, record) { const sort = query.sort || querySort_js_1.QuerySort.default; return [querySort_js_1.QuerySort.findDateInRecord(record, sort), record.id]; } function includeLinksToString(includeLinks) { function includeLinkToString(link) { if (includeLinkSpecialValues.includes(link)) { return link; } return (0, pathHelpers_js_1.normalizePath)(link); } return includeLinks?.map(includeLinkToString).join(","); } function includeLinksIsSuperset(links1, links2) { const l1 = links1 || defaultIncludeLinks; const l2 = links2 || defaultIncludeLinks; return array_js_1.Array.isSuperset(l1, l2); } function sourcesIsSuperset(sources1, sources2) { const s1 = sources1 || defaultSources; const s2 = sources2 || defaultSources; return array_js_1.Array.isSuperset(s1, s2); } function paramsToString(params) { const filteredParams = params .map(p => ((0, type_js_1.isDefined)(p[1]) ? [p[0], p[1]] : undefined)) .filter(type_js_1.isDefined); return string_js_1.Str.buildQuery(filteredParams); } function findQueryMaxDate(query, sortDirection) { if (query.pageStart && sortDirection === querySort_js_1.QuerySortDirection.DESCENDING) { return query.pageStart; } return query.max; } function findQueryMinDate(query, sortDirection) { if (query.pageStart && sortDirection === querySort_js_1.QuerySortDirection.ASCENDING) { return query.pageStart; } return query.min; } function queryFilter(query, records, { ignorePageSize, boundary } = {}) { const sortBy = query.sort || defaultSortBy; const sortDir = querySort_js_1.QuerySort.toDirection(sortBy); const isAscending = sortDir === querySort_js_1.QuerySortDirection.ASCENDING; const maxDate = findQueryMaxDate(query, sortDir); const minDate = findQueryMinDate(query, sortDir); function sort() { const order = isAscending ? "asc" : "desc"; return (list) => { return (0, orderBy_js_1.default)(list, r => querySort_js_1.QuerySort.findDateInRecord(r, sortBy), order); }; } function distinct() { const { distinct } = query; if (!distinct) { return (list) => list; } const distinctValue = (record) => { const recordValues = (0, jsonpath_plus_1.JSONPath)({ path: distinct, json: record, }).filter(type_js_1.isDefined); if (recordValues.length === 0) { return `null+${record.author.entity}+${record.id}`; } // TODO: Implement link detection for correct logic. const valueToString = (value) => { if ((0, isString_js_1.default)(value)) { return `"${value}"`; } if ("versionHash" in value) { return `${value.entity}+${value.recordId}+${value.versionHash}`; } if ("recordId" in value) { return `${value.entity}+${value.recordId}`; } if ("entity" in value) { return value.entity; } return String(value); }; return recordValues.map(valueToString).join(":"); }; return (list) => (0, uniqBy_js_1.default)(list, distinctValue); } function filter() { function isMatch(record) { // Exclude deleted. if ("noContent" in record) { return false; } // Date boundaries. const recordDate = querySort_js_1.QuerySort.findDateInRecord(record, sortBy); const recordId = record.id; if (queryDate_js_1.QueryDate.compare(recordDate, recordId, maxDate) > 0) { return false; } if (queryDate_js_1.QueryDate.compare(recordDate, recordId, minDate) < 0) { return false; } if (boundary) { const result = queryDate_js_1.QueryDate.compare(recordDate, recordId, boundary); if (isAscending ? result > 0 : result < 0) { return false; } } if (query.mode && record.mode !== query.mode) { return false; } // Sources. const sources = query.sources || defaultSources; if (!sources.includes(record.source) && record.source !== record_js_1.RecordSource.PROXY) { return false; } // Filter. return !query.filter || queryFilter_js_1.QueryFilter.isMatch(record, query.filter); } return (list) => { return list.filter(isMatch); }; } function pageSize() { if (ignorePageSize) { return list => list; } return list => { return list.slice(0, query.pageSize || constants_js_1.Constants.defaultPageSize); }; } return (0, flow_js_1.default)(sort(), distinct(), filter(), pageSize())(records); } function queryIsMatch(query1, query2) { const { ["filter"]: filter1, ...q1 } = query1; const { ["filter"]: filter2, ...q2 } = query2; if (!(0, isEqual_js_1.default)(q1, q2)) { return false; } if (filter1 && filter2) { return (queryFilter_js_1.QueryFilter.isSuperset(filter1, filter2) && queryFilter_js_1.QueryFilter.isSuperset(filter2, filter1)); } return !filter1 && !filter2; } function queryIsSuperset(query1, query2) { if (query1.distinct !== query2.distinct) { return false; } return queryIsSyncSuperset(query1, query2); } function queryIsSyncSuperset(query1, query2) { if (query1.mode !== query2.mode || query1.proxyTo !== query2.proxyTo) { return false; } if (!includeLinksIsSuperset(query1.includeLinks, query2.includeLinks)) { return false; } if (!sourcesIsSuperset(query1.sources, query2.sources)) { return false; } if (query2.includeDeleted && !query1.includeDeleted) { return false; } if (query1.filter && query2.filter) { return queryFilter_js_1.QueryFilter.isSuperset(query1.filter, query2.filter); } return !query1.filter && !query2.filter; } exports.Query = { new: queryNew, ofKey: queryOfKey, singleToQueryString: querySingleToQueryString, toQueryString: queryToQueryString, toSync: queryToSync, findBoundary: queryFindBoundary, filter: queryFilter, isMatch: queryIsMatch, isSuperset: queryIsSuperset, isSyncSuperset: queryIsSyncSuperset, defaultIncludeLinks, defaultSources, };