55 lines
1.4 KiB
TypeScript
55 lines
1.4 KiB
TypeScript
import type { Address } from "./types";
|
|
import { isAddress } from "./types";
|
|
|
|
export const Any = "?";
|
|
type QueryPart<T> = T | T[] | typeof Any;
|
|
|
|
export class Query {
|
|
private _query: string | undefined;
|
|
|
|
public static matches(
|
|
entity: QueryPart<string>,
|
|
attribute: QueryPart<string>,
|
|
value: QueryPart<string | number | Address>
|
|
): 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;
|
|
}
|
|
}
|