groq-builder
Version:
A **schema-aware**, strongly-typed GROQ query builder. It enables you to build GROQ queries using **auto-completion**, **type-checking**, and **runtime validation**.
76 lines (75 loc) • 3.08 kB
TypeScript
import { Override as _Override, Simplify } from "./utils";
/**
* The results of a query can be a single item, or an array of items,
* and the results can be nullable too.
*
* However, most chainable methods need to look at the shape
* of the inner "ResultItem", ignoring the nullable and Array wrappers.
* You can do this with `ResultItem.Infer<TResult>`.
*
* Additionally, these methods might need to rewrap a new type,
* while preserving the nullable/Array wrappers.
* You can do this with `ResultItem.Override<TResult, TResultItemNew>`
*/
export declare namespace ResultItem {
/**
* Retrieves just the shape of the TResult, unwrapping nulls and arrays.
*
* @example
* Infer<"FOO"> // Result: "FOO"
* Infer<Array<"FOO">> // Result: "FOO"
* Infer<null | "FOO"> // Result: "FOO"
* Infer<null | Array<"FOO">> // Result: "FOO"
*/
type Infer<TResult> = ResultUtils.Unwrap<TResult>["TResultItem"];
/**
* Retrieves just the shape of the TResult, unwrapping arrays.
*
* Preserves nulls.
*
* @example
* Infer<"FOO"> // Result: "FOO"
* Infer<Array<"FOO">> // Result: "FOO"
* Infer<null | "FOO"> // Result: null | "FOO"
* Infer<null | Array<"FOO">> // Result: null | "FOO"
*/
type InferMaybe<TResult> = ResultUtils.Wrap<_Override<ResultUtils.Unwrap<TResult>, {
IsArray: false;
}>>;
/**
* Overrides the shape of the result, while preserving IsArray and IsNullable
*
* @example
* OverrideResultItem<null | Array<"FOO">, "BAR">; // Result: null | Array<"BAR">
* OverrideResultItem<Array<"FOO">, "BAR">; // Result: Array<"BAR">
* OverrideResultItem<null | "FOO", "BAR">; // Result: null | "BAR"
* OverrideResultItem<"FOO", "BAR">; // Result: "BAR"
*/
type Override<TResult, TResultItemNew> = Simplify<ResultUtils.Wrap<_Override<ResultUtils.Unwrap<TResult>, {
TResultItem: TResultItemNew;
}>>>;
}
/**
* This namespace provides utilities for unwrapping
* and re-wrapping the null/Array types.
*
* @internal Only exported for tests
*/
export declare namespace ResultUtils {
type Unwrapped = {
TResultItem: unknown;
IsArray: boolean;
IsNullable: boolean;
};
export type Unwrap<TResult> = {
TResultItem: NonNullable<TResult> extends Array<infer U> ? U : NonNullable<TResult>;
IsArray: IsArray<NonNullable<TResult>>;
IsNullable: IsNullable<TResult>;
};
export type Wrap<TDetails extends Unwrapped> = MakeNullable<TDetails["IsNullable"], MakeArray<TDetails["IsArray"], TDetails["TResultItem"]>>;
type MakeNullable<IsNullable extends boolean, T> = IsNullable extends true ? null | T : T;
type MakeArray<IsArray extends boolean, T> = IsArray extends true ? Array<T> : T;
type IsArray<T> = T extends Array<any> ? true : false;
export type IsNullable<T> = null extends T ? true : undefined extends T ? true : false;
export {};
}