import type { LimitedResource, Resource, TemplateResultOrSymbol, } from "@src/tems"; import { LitElement, nothing } from "lit"; import * as rdf from "@src/rdf"; const rdfs = Object.values(rdf); export class TemsObjectHandler extends LitElement { object?: LimitedResource = {}; isType = (type: string, obj: Resource = (this.object as Resource)) => { const typeValue = obj["@type"]; if (Array.isArray(typeValue)) { return typeValue.includes(type); } if (typeof typeValue === "string") { return typeValue === type; } return false; }; private getNestedProperty(path: string, obj: Resource = (this.object as Resource)): any { return path.split(".").reduce((subObj: any, key) => { if (subObj === undefined) { return undefined; } const arrayMatch = key.match(/(.*)\[(.*)\]/); if (arrayMatch) { const baseKey = arrayMatch[1]; const index = arrayMatch[2]; const array = subObj[baseKey]; if (!Array.isArray(array)) { return undefined; } if (index === "") { if (array.length > 0) { return array; } return undefined; } const numericIndex = Number.parseInt(index, 10); if ( Number.isNaN(numericIndex) || numericIndex < 0 || numericIndex >= array.length ) { return undefined; } return subObj[baseKey][numericIndex]; } return subObj && subObj[key] !== "undefined" ? subObj[key] : undefined; }, obj); } renderTemplateWhenWith( requiredProperties: (string | string[])[], template: () => TemplateResultOrSymbol, obj: Resource = (this.object as Resource) ): TemplateResultOrSymbol { const tester = ( property: string | string[], cb: (some: string) => boolean ) => Array.isArray(property) ? property.some((subProp) => cb(subProp)) : cb(property); const typeProperties = requiredProperties.filter((property) => tester(property, (p) => rdfs.includes(p)) ); const keyProperties = requiredProperties.filter((property) => tester(property, (p) => !rdfs.includes(p)) ); if ( keyProperties.every((property) => tester(property, (p) => this.getNestedProperty(p, obj)) ) && typeProperties.every((property) => tester(property, (p) => this.isType(p, obj)) ) ) { return template.call(this); } return nothing; } }