UNPKG

wizard-ql

Version:

WizardQL is a natural-language-like query language for constructing data queries for resources that meet conditions.

177 lines (176 loc) 6.71 kB
/** All available operation aliases (alias -> operation) */ export declare const OPERATION_ALIAS_DICTIONARY: { readonly AND: "AND"; readonly '&&': "AND"; readonly '&': "AND"; readonly '^': "AND"; readonly OR: "OR"; readonly '||': "OR"; readonly '|': "OR"; readonly V: "OR"; readonly GEQ: "GEQ"; readonly '>=': "GEQ"; readonly '=>': "GEQ"; readonly LEQ: "LEQ"; readonly '<=': "LEQ"; readonly '=<': "LEQ"; readonly NOTEQUALS: "NOTEQUAL"; readonly NOTEQUAL: "NOTEQUAL"; readonly NEQ: "NOTEQUAL"; readonly ISNT: "NOTEQUAL"; readonly '!==': "NOTEQUAL"; readonly '!=': "NOTEQUAL"; readonly EQUALS: "EQUAL"; readonly EQUAL: "EQUAL"; readonly EQ: "EQUAL"; readonly IS: "EQUAL"; readonly '==': "EQUAL"; readonly '=': "EQUAL"; readonly LESS: "LESS"; readonly '<': "LESS"; readonly GREATER: "GREATER"; readonly '>': "GREATER"; readonly MORE: "GREATER"; readonly NOTIN: "NOTIN"; readonly '!:': "NOTIN"; readonly IN: "IN"; readonly ':': "IN"; readonly NOTMATCHES: "NOTMATCH"; readonly NOTMATCH: "NOTMATCH"; readonly '!~': "NOTMATCH"; readonly MATCHES: "MATCH"; readonly MATCH: "MATCH"; readonly '~': "MATCH"; }; export interface Token { /** The text content of the token */ content: string; /** The index in the original expression this token originates from */ index: number; } export type Operation = (typeof OPERATION_ALIAS_DICTIONARY)[keyof typeof OPERATION_ALIAS_DICTIONARY]; export declare const ALIASES: string[]; /** All base operations and their type */ export declare const OPERATION_PURPOSE_DICTIONARY: { readonly AND: "junction"; readonly OR: "junction"; readonly EQUAL: "comparison"; readonly NOTEQUAL: "comparison"; readonly LESS: "comparison"; readonly GREATER: "comparison"; readonly GEQ: "comparison"; readonly LEQ: "comparison"; readonly IN: "comparison"; readonly NOTIN: "comparison"; readonly MATCH: "comparison"; readonly NOTMATCH: "comparison"; }; type KeysWhereValue<T, V> = Exclude<{ [K in keyof T]: T[K] extends V ? K : never; }[keyof T], never>; export type JunctionOperation = KeysWhereValue<typeof OPERATION_PURPOSE_DICTIONARY, 'junction'>; export type ComparisonOperation = KeysWhereValue<typeof OPERATION_PURPOSE_DICTIONARY, 'comparison'>; /** All comparison operations and their types */ export declare const COMPARISON_TYPE_DICTIONARY: { readonly EQUAL: "primitive"; readonly NOTEQUAL: "primitive"; readonly GEQ: "numeric"; readonly GREATER: "numeric"; readonly LEQ: "numeric"; readonly LESS: "numeric"; readonly IN: "array"; readonly NOTIN: "array"; readonly MATCH: "string"; readonly NOTMATCH: "string"; }; /** Convert an operation's comparison type to a language server type */ export type ComparisonTypeToTSType<T extends keyof typeof COMPARISON_TYPE_DICTIONARY> = { primitive: Primitive; boolean: boolean; string: string; number: number; date: Date; numeric: number | Date; array: Primitive[]; }[typeof COMPARISON_TYPE_DICTIONARY[T]]; export type FieldType = 'boolean' | 'string' | 'number' | 'date'; export type TypeRecord = Record<string, FieldType | FieldType[]>; /** Convert a field type string to a language server type */ export type FieldTypeToTSType<T extends FieldType> = { boolean: boolean; string: string; number: number; date: Date; }[T]; /** Primitive values that can be used in comparisons */ export type Primitive = FieldTypeToTSType<FieldType>; /** Convert input type record to language server type record */ export type ConvertTypeRecord<T extends TypeRecord> = { [K in keyof T]: T[K] extends FieldType[] ? FieldTypeToTSType<T[K][number]> : T[K] extends FieldType ? FieldTypeToTSType<T[K]> : Primitive; }; export declare const TYPE_PRIORITY: ["boolean", "date", "number", "string"]; /** * A group of conditions joined by a junction operator * @template R A record mapping field names to values */ export interface Group<R extends Record<string, unknown> = Record<string, Primitive>, V extends boolean = false> { type: 'group'; /** The junction operator */ operation: JunctionOperation; /** The members of the group */ constituents: Array<Expression<R, V>>; } /** * A query on a field, validated by type constraints * @template R A record mapping field names to values * @template F The name of the field being queried */ export interface Condition<R extends Record<string, unknown>, F extends keyof R, O extends ComparisonOperation> { type: 'condition'; /** The operation */ operation: O; /** The name of the field */ field: F; /** The value being checked */ value: typeof COMPARISON_TYPE_DICTIONARY[O] extends 'array' ? Array<R[F]> : Extract<ComparisonTypeToTSType<O>, R[F]>; /** Was this condition validated by the constraints or is its type unknown? */ validated: true; } /** * A query on a field */ export interface UncheckedCondition<O extends ComparisonOperation = ComparisonOperation> { type: 'condition'; /** The operation */ operation: O; /** The name of the field */ field: string; /** The value being checked */ value: Exclude<ComparisonTypeToTSType<O>, Date>; /** Was this condition validated by the constraints or is its type unknown? */ validated: false; } /** * Reverse the keys and values of a type and aggregate by common value */ type ReverseAggregate<T extends Record<any, any>> = { [V in T[keyof T]]: { [K in keyof T]: T[K] extends V ? K : never; }[keyof T]; }; type ReverseAggregatedTypes = ReverseAggregate<typeof COMPARISON_TYPE_DICTIONARY>; /** Create a union of conditions; an intersection of the operation type validation and constraint type validation */ export type CheckedConditionSpread<R extends Record<string, unknown>> = { [K in keyof R]: { [O in keyof ReverseAggregatedTypes]: Condition<R, K, ReverseAggregatedTypes[O]>; }[keyof ReverseAggregatedTypes]; }[keyof R]; /** Create a union of conditions that are operation type validated */ export type UncheckedConditionSpread = { [O in keyof ReverseAggregatedTypes]: UncheckedCondition<ReverseAggregatedTypes[O]>; }[keyof ReverseAggregatedTypes]; export type Expression<R extends Record<string, unknown> = Record<string, Primitive>, V extends boolean = false> = Group<R, V> | (V extends true ? CheckedConditionSpread<R> : CheckedConditionSpread<R> | UncheckedConditionSpread); export type UncheckedExpression = (Omit<Group, 'constituents'> & { constituents: UncheckedExpression[]; }) | UncheckedConditionSpread; export {};