UNPKG

sparnatural

Version:

Visual client-side SPARQL query builder and knowledge graph exploration tool

297 lines 9.06 kB
/** * e.g. TermIri or TermLiteral to LabelledCriteria<RdfTermCriteria> * @param term The graph term to convert * @returns The labelled criteria, or null if the term type is unsupported */ export function graphTermToLabelledCriteria(term) { if (term.subType === "namedNode") { const iri = term; return { label: "label" in iri ? iri.label : iri.value, criteria: { rdfTerm: { type: "uri", value: iri.value, }, }, }; } if (term.subType === "literal") { const lit = term; // Detect xsd:boolean → return BooleanCriteria const lo = lit.langOrIri; if (lo && typeof lo === "object") { const datatypeValue = lo.value; if (datatypeValue === "http://www.w3.org/2001/XMLSchema#boolean") { return { label: lit.value, criteria: { boolean: lit.value === "true", }, }; } } const rdfTerm = { type: "literal", value: lit.value, }; if (typeof lo === "string") rdfTerm["xml:lang"] = lo; if (lo && typeof lo === "object") { rdfTerm.datatype = lo.value; } return { label: lit.value, criteria: { rdfTerm }, }; } return null; } /** * Translates the object values in a v13 ObjectCriteria to labelled criteria in v1 * @param variableName The variable name to extract from each value row * @param obj The ObjectCriteria containing the values * @returns An array of labelled criteria */ export function translateObjectValues(variableName, obj) { const values = obj.values; if (!values || values.length === 0) return []; const first = values[0]; // Case A — GraphTerm[] if (typeof first === "object" && first !== null && "subType" in first) { return values .map(graphTermToLabelledCriteria) .filter(Boolean); } // Case B — VALUES rows return translateValueRows(variableName, values); } /** * Translates v13 VALUES rows to labelled criteria in v1 * @param variableName The variable name to extract from each value row * @param rows The VALUES rows * @returns An array of labelled criteria */ export function translateValueRows(variableName, rows) { return rows.flatMap((row) => { const term = row[variableName]; if (!term) return []; const converted = graphTermToLabelledCriteria(term); return converted ? [converted] : []; }); } /** Translates v13 labelled filters to v1 labelled criteria * @param filters The labelled filters to translate * @returns An array of labelled criteria */ export function translateFilters(filters) { return filters.map((lf) => { const mapper = filterToCriteriaMap[lf.filter.type]; if (!mapper) { throw new Error(`Unknown filter type: ${lf.filter.type}`); } return { label: lf.label, criteria: mapper(lf), }; }); } /** * Translates v13 labelled filters to v1 labelled criteria * @param filters The labelled filters to translate * @returns An array of labelled criteria */ const filterToCriteriaMap = { dateFilter: (lf) => { const f = lf.filter; return { start: f.start, stop: f.stop }; }, numberFilter: (lf) => { const f = lf.filter; return { min: f.min, max: f.max }; }, searchFilter: (lf) => { const f = lf.filter; return { search: f.search }; }, mapFilter: (lf) => { const f = lf.filter; return { coordType: f.coordType, coordinates: f.coordinates, }; }, }; /** * Converts a v13 PatternBind to a v1 VariableExpression * @param bind A v13 PatternBind * @returns A v1 VariableExpression */ export function patternBindToVariableExpression(bind) { return { expression: { type: "aggregate", aggregation: bind.expression.aggregation, distinct: bind.expression.distinct, expression: { termType: "Variable", value: bind.expression.expression[0].value, }, }, variable: { termType: "Variable", value: bind.variable.value, }, }; } // Second part /** * Converts labelled criteria to labelled filters (v1 to v13) * @param vals An array of labelled criteria v1 * @returns An array of labelled filters v13 */ const criteriaToFilterRegistry = [ { match: (c) => "start" in c || "stop" in c, build: (label, c) => ({ type: "labelledFilter", label, filter: { type: "dateFilter", start: c.start, stop: c.stop, }, }), }, { match: (c) => "min" in c || "max" in c, build: (label, c) => ({ type: "labelledFilter", label, filter: { type: "numberFilter", min: c.min, max: c.max, }, }), }, { match: (c) => "search" in c, build: (label, c) => { const sc = c; return { type: "labelledFilter", label, filter: { type: "searchFilter", search: sc.search, }, }; }, }, { match: (c) => "coordinates" in c, build: (label, c) => { const mc = c; return { type: "labelledFilter", label, filter: { type: "mapFilter", coordType: mc.coordType, coordinates: mc.coordinates, }, }; }, }, ]; /** * Converts labelled criteria to labelled filters (v1 to v13) * @param vals An array of labelled criteria v1 * @returns An array of labelled filters v13 */ export function labelledCriteriaToFilters(vals) { return vals.flatMap((v) => { const entry = criteriaToFilterRegistry.find((r) => r.match(v.criteria)); return entry ? [entry.build(v.label, v.criteria)] : []; }); } /** * Converts labelled criteria with RDFTerm to flat values (v1 to v13) * @param vals An array of labelled criteria v1 * @returns An array of GraphTerm with label (TermLabelledIri or TermLiteral with label) */ export function labelledCriteriaToFlatValues(vals) { const results = []; for (const v of vals) { // RdfTermCriteria → named node or literal if ("rdfTerm" in v.criteria) { const t = v.criteria.rdfTerm; if (t.type === "uri") { results.push({ type: "term", subType: "namedNode", value: t.value, label: v.label, }); continue; } // Literal with language tag if (t["xml:lang"]) { results.push({ type: "term", subType: "literal", value: t.value, langOrIri: t["xml:lang"], label: v.label, }); continue; } // Literal with datatype if (t.datatype) { results.push({ type: "term", subType: "literal", value: t.value, langOrIri: { type: "term", subType: "namedNode", value: t.datatype, }, label: v.label, }); continue; } // Plain literal (no lang, no datatype) results.push({ type: "term", subType: "literal", value: t.value, langOrIri: undefined, label: v.label, }); continue; } // BooleanCriteria → literal with xsd:boolean datatype if ("boolean" in v.criteria) { const boolVal = v.criteria.boolean; results.push({ type: "term", subType: "literal", value: String(boolVal), langOrIri: { type: "term", subType: "namedNode", value: "http://www.w3.org/2001/XMLSchema#boolean", }, label: v.label, }); continue; } // Other criteria types (date, number, search, map) are handled by filters, not values } return results; } //# sourceMappingURL=QueryAdapterFunc.js.map