UNPKG

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**.

39 lines (38 loc) 2.35 kB
import { QueryConfig } from "./schema-types"; import type { IsLiteral, LiteralUnion } from "type-fest"; import { StringKeys, UndefinedToNull, ValueOf } from "./utils"; import { Path, PathValue } from "./path-types"; export declare namespace Expressions { /** * This type allows any string, but provides * TypeScript suggestions for common expressions, * like '_type == "product"' or 'slug.current == $slug'. */ export type AnyConditional<TResultItem, TQueryConfig extends QueryConfig> = LiteralUnion<Conditional<TResultItem, TQueryConfig>, string>; /** * A strongly-typed conditional Groq conditional expression. * Currently, this only supports simple "equality" expressions, * like '_type == "product"' or 'slug.current == $slug'. * */ export type Conditional<TResultItem, TQueryConfig extends QueryConfig> = Equality<TResultItem, TQueryConfig>; export type Equality<TResultItem, TQueryConfig extends QueryConfig, /** (local use only) Calculate our Parameter entries once, and reuse across suggestions */ _ParameterEntries = ParameterEntries<TQueryConfig["parameters"]>> = ValueOf<{ [Key in SuggestedKeys<TResultItem>]: `${Key} == ${SuggestedValues<_ParameterEntries, SuggestedKeysValue<TResultItem, Key>>}`; }>; type LiteralValue<TValue> = TValue extends string ? `"${TValue}"` : TValue extends number | boolean | null ? TValue : never; type LiteralSuggestion<TValue> = IsLiteral<TValue> extends true ? never : TValue extends string ? "(string)" : TValue extends number ? "(number)" : never; type SuggestedKeys<TResultItem> = Path<TResultItem>; type SuggestedKeysValue<TResultItem, TKey extends SuggestedKeys<TResultItem>> = UndefinedToNull<PathValue<TResultItem, TKey>>; type SuggestedValues<TParameterEntries, TValue> = StringKeysWithType<TParameterEntries, TValue> | LiteralSuggestion<TValue> | LiteralValue<TValue>; export type ParameterEntries<TParameters> = { [P in Path<TParameters> as `$${P}`]: PathValue<TParameters, P>; }; /** * Finds all (string) keys of TObject where the value matches the given TType */ export type StringKeysWithType<TObject, TType> = StringKeys<ValueOf<{ [P in keyof TObject]: TObject[P] extends TType ? P : TType extends TObject[P] ? P : never; }>>; export {}; }