import type { Address } from "./types"; import { isAddress } from "./types"; export const Any = "?"; type QueryPart = T | T[] | typeof Any; export class Query { private _query: string | undefined; public static matches( entity: QueryPart, attribute: QueryPart, value: QueryPart ): Query { const query = new Query(); let entityStr; if (entity === Any) { entityStr = "?"; } else { entityStr = Array.isArray(entity) ? `(in ${entity.join(" ")})` : entity; } let attributeStr; if (attribute === Any) { attributeStr = "?"; } else { attributeStr = Array.isArray(attribute) ? `(in ${attribute.map((a) => `"${a}"`).join(" ")})` : `"${attribute}"`; } let valueStr; if (value === Any) { valueStr = "?"; } else { valueStr = (Array.isArray(value) ? value : [value]) .map((v) => { if (typeof v === "number") return v; if (isAddress(v)) return v; if (typeof v === "string") return `"${v}"`; }) .join(" "); valueStr = Array.isArray(value) ? `(in ${valueStr})` : valueStr; } query._query = `(matches ${entityStr} ${attributeStr} ${valueStr})`; return query; } public toString(): string { if (!this._query) throw new Error("Query is not defined"); return this._query; } }