UNPKG

@sanity-typed/groq

Version:
920 lines (918 loc) 63.7 kB
import { ClientConfig } from '@sanity/client'; import { GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Position } from 'geojson'; import { ExprNode, AccessAttributeNode, AccessElementNode, ArrayNode, ArrayElementNode, ArrayCoerceNode, AndNode, OrNode, SelectAlternativeNode, OpCallNode, ContextNode, DerefNode, EverythingNode, FilterNode, FuncCallNode, DateTime, Path, InRangeNode, MapNode, NegNode, NotNode, ObjectNode, ObjectAttributeNode, ObjectAttributeValueNode, ObjectSplatNode, ParameterNode, ParentNode, GroupNode, PipeFuncCallNode, PosNode, ProjectionNode, SelectNode, SelectorNode, SliceNode, ThisNode, ValueNode, GroqPipeFunction, AscNode, DescNode, GroqFunction } from 'groq-js'; import { IsNumericLiteral, SetOptional, IsNever, Join, IsUnknown, Split, Simplify as Simplify$1, UnionToIntersection } from 'type-fest'; import { PortableTextBlock } from '@portabletext-typed/types'; import { ReferenceValue, referenced } from '@sanity-typed/types'; type IsPlainObject<T> = T extends any[] ? false : T extends object ? true : false; type TupleOfLength<T, Min extends number = number, Max extends number = number, Result extends T[] = []> = Result["length"] extends Min ? IsNumericLiteral<Max> extends false ? [...Result, ...T[]] : Result["length"] extends Max ? Result : Result | TupleOfLength<T, [ T, ...Result ]["length"] & number, Max, [ T, ...Result ]> : TupleOfLength<T, Min, Max, [T, ...Result]>; type Simplify<AnyType> = Simplify$1<AnyType> extends AnyType ? Simplify$1<AnyType> : AnyType; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Query-context */ interface Context<Dataset extends any[], DeltaElement extends Dataset[number]> { client: ClientConfig; dataset: Dataset; delta: { after: DeltaElement | null; before: DeltaElement | null; }; identity: string; parameters: { [param: string]: any; }; } /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Scope */ interface Scope<TContext extends Context<any[], any>> { context: TContext; parent: Scope<TContext> | null; this: any; } /** * @link https://spec.groq.dev/GROQ-1.revision1/#NewNestedScope() */ interface NestedScope<Value, TScope extends Scope<Context<any[], any>>> { context: TScope["context"]; parent: TScope; this: Value; } type EscapedDoubleQuote = "__ESCAPED__DOUBLE__QUOTE___"; type EscapedSingleQuote = "__ESCAPED__SINGLE__QUOTE___"; type PrefixWithSpace<TString extends string> = `__PREFIX__WITH_SPACE__${TString}___`; type SurroundWithSpace<TString extends string> = `__SURROUNDED_WITH_SPACES__${TString}___`; type AddPlaceholders<TString extends string> = TString extends `${infer TLeft} in ${infer TRight}` ? `${AddPlaceholders<TLeft>}${SurroundWithSpace<"in">}${AddPlaceholders<TRight>}` : TString extends `${infer TLeft} match ${infer TRight}` ? `${AddPlaceholders<TLeft>}${SurroundWithSpace<"match">}${AddPlaceholders<TRight>}` : TString extends `${infer TLeft} asc${infer TRight}` ? `${AddPlaceholders<TLeft>}${PrefixWithSpace<"asc">}${AddPlaceholders<TRight>}` : TString extends `${infer TLeft} desc${infer TRight}` ? `${AddPlaceholders<TLeft>}${PrefixWithSpace<"desc">}${AddPlaceholders<TRight>}` : TString extends `${infer TLeft}\\${infer TRight}` ? `${AddPlaceholders<TLeft>}${TRight extends `${infer TRightHead}${infer TRightRest}` ? `${TRightHead extends '"' ? EscapedDoubleQuote : TRightHead extends "'" ? EscapedSingleQuote : `\\${TRightHead}`}${AddPlaceholders<TRightRest>}` : `\\${TRight}`}` : TString; type RemovePlaceholders<TString extends string> = TString extends `${infer TLeft}${SurroundWithSpace<infer TOp>}${infer TRight}` ? `${RemovePlaceholders<TLeft>} ${TOp} ${RemovePlaceholders<TRight>}` : TString extends `${infer TLeft}${PrefixWithSpace<infer TOp>}${infer TRight}` ? `${RemovePlaceholders<TLeft>} ${TOp}${RemovePlaceholders<TRight>}` : TString extends `${infer TLeft}${EscapedDoubleQuote}${infer TRight}` ? `${RemovePlaceholders<TLeft>}\\"${RemovePlaceholders<TRight>}` : TString extends `${infer TLeft}${EscapedSingleQuote}${infer TRight}` ? `${RemovePlaceholders<TLeft>}\\'${RemovePlaceholders<TRight>}` : TString; type RemoveWhitespace<TExpression extends string> = TExpression extends `${infer TLeft}${'"'}${infer TQuoted}${'"'}${infer TRight}` ? `${RemoveWhitespace<TLeft>}${'"'}${TQuoted}${'"'}${RemoveWhitespace<TRight>}` : TExpression extends `${infer TLeft}${"'"}${infer TQuoted}${"'"}${infer TRight}` ? `${RemoveWhitespace<TLeft>}${"'"}${TQuoted}${"'"}${RemoveWhitespace<TRight>}` : TExpression extends `${infer TLeft}${"\n"}${infer TRight}` ? `${RemoveWhitespace<TLeft>}${RemoveWhitespace<TRight>}` : TExpression extends `${infer TLeft}${"\t"}${infer TRight}` ? `${RemoveWhitespace<TLeft>}${RemoveWhitespace<TRight>}` : TExpression extends `${infer TLeft}${" "}${infer TRight}` ? `${RemoveWhitespace<TLeft>}${RemoveWhitespace<TRight>}` : TExpression extends `${infer TLeft}${" "}${infer TRight}` ? `${RemoveWhitespace<TLeft>}${RemoveWhitespace<TRight>}` : TExpression; type CleanGROQ<TExpression extends string> = RemovePlaceholders<RemoveWhitespace<AddPlaceholders<TExpression>>>; type ParseInner<TExpression extends string> = Expression<TExpression>; type Parse<TExpression extends string> = ParseInner<CleanGROQ<TExpression>>; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Evaluate() */ type Evaluate<TNode extends ExprNode, TScope extends Scope<Context<any[], any>>> = EvaluateExpression<TNode, TScope>; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Boolean * @link https://spec.groq.dev/GROQ-1.revision1/#Null * @link https://spec.groq.dev/GROQ-1.revision1/#Number */ type Primitives<TExpression extends string> = TExpression extends `+${number}` ? never : TExpression extends `-${number}` ? never : TExpression extends `.${string}` ? never : TExpression extends `${infer TValue extends boolean | number | null}` ? { type: "Value"; value: TValue; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#SingleEscapeSequence */ type SingleEscapeSequence = '"' | "'" | "/" | "\\" | "b" | "f" | "n" | "r" | "t"; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EscapeSequence */ type EscapeSequence = SingleEscapeSequence; type ReplaceInString<TString extends string, TReplace extends string, TReplaceWith extends string = ""> = TString extends `${infer TLeft}${TReplace}${infer TRight}` ? `${TLeft}${TReplaceWith}${ReplaceInString<TRight, TReplace, TReplaceWith>}` : TString; type IfStringHas<TString extends string, THas extends string> = TString extends `${string}${THas}${string}` ? true : false; /** * @link https://spec.groq.dev/GROQ-1.revision1/#String */ type StringType<TExpression extends string> = (TExpression extends `'${infer TString}'` ? IfStringHas<ReplaceInString<TString, `\\${EscapeSequence}`>, "'"> extends true ? never : { type: "Value"; value: ReplaceInString<TString, `\\'`, // TODO https://github.com/saiichihashimoto/sanity-typed/issues/331 "'">; } : never) | (TExpression extends `"${infer TString}"` ? IfStringHas<ReplaceInString<TString, `\\${EscapeSequence}`>, '"'> extends true ? never : { type: "Value"; value: ReplaceInString<TString, `\\"`, // TODO https://github.com/saiichihashimoto/sanity-typed/issues/331 '"'>; } : never); /** * @link https://spec.groq.dev/GROQ-1.revision1/#ArrayElement */ type ArrayElement<TArrayElement extends string> = TArrayElement extends `...${infer TExpression}` ? ParseInner<TExpression> extends never ? never : { isSplat: true; type: "ArrayElement"; value: ParseInner<TExpression>; } : ParseInner<TArrayElement> extends never ? never : { isSplat: false; type: "ArrayElement"; value: ParseInner<TArrayElement>; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#ArrayElements */ type ArrayElements<TArrayElements extends string, _Prefix extends string = ""> = `${_Prefix}${TArrayElements}` extends "" ? [] : (ArrayElement<`${_Prefix}${TArrayElements}`> extends never ? never : [ArrayElement<`${_Prefix}${TArrayElements}`>]) | (TArrayElements extends `${infer TArrayElement},${infer TRemainingElements}` ? ArrayElements<TRemainingElements, `${_Prefix}${TArrayElement},`> | (ArrayElement<`${_Prefix}${TArrayElement}`> extends never ? never : ArrayElements<TRemainingElements> extends never ? never : [ ArrayElement<`${_Prefix}${TArrayElement}`>, ...ArrayElements<TRemainingElements> ]) : never); /** * @link https://spec.groq.dev/GROQ-1.revision1/#Array */ type ArrayType<TExpression extends string> = TExpression extends `[${infer TArrayElements}]` ? ArrayElements<TArrayElements> extends never ? never : { elements: ArrayElements<TArrayElements>; type: "Array"; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#DetermineName() */ type DetermineName<TNode extends ExprNode> = Extract<TNode, AccessAttributeNode>["name"] | (TNode extends AccessElementNode | ArrayCoerceNode | DerefNode | FilterNode | MapNode | ProjectionNode | SliceNode ? DetermineName<TNode["base"]> : never); /** * @link https://spec.groq.dev/GROQ-1.revision1/#ObjectAttribute */ type ObjectAttribute<TObjectAttribute extends string> = TObjectAttribute extends `...${infer TExpression}` ? TExpression extends "" ? { type: "ObjectSplat"; value: { type: "This"; }; } : ParseInner<TExpression> extends never ? never : { type: "ObjectSplat"; value: ParseInner<TExpression>; } : TObjectAttribute extends `${infer TName}:${infer TExpression}` ? StringType<TName> extends never ? never : ParseInner<TExpression> extends never ? never : { name: StringType<TName>["value"]; type: "ObjectAttributeValue"; value: ParseInner<TExpression>; } : ParseInner<TObjectAttribute> extends never ? never : DetermineName<ParseInner<TObjectAttribute>> extends never ? never : { name: DetermineName<ParseInner<TObjectAttribute>>; type: "ObjectAttributeValue"; value: ParseInner<TObjectAttribute>; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#ObjectAttributes */ type ObjectAttributes<TObjectAttributes extends string, _Prefix extends string = ""> = `${_Prefix}${TObjectAttributes}` extends "" ? [] : (ObjectAttribute<`${_Prefix}${TObjectAttributes}`> extends never ? never : [ObjectAttribute<`${_Prefix}${TObjectAttributes}`>]) | (TObjectAttributes extends `${infer TObjectAttribute},${infer TRemainingAttributes}` ? ObjectAttributes<TRemainingAttributes, `${_Prefix}${TObjectAttribute},`> | (ObjectAttribute<`${_Prefix}${TObjectAttribute}`> extends never ? never : ObjectAttributes<TRemainingAttributes> extends never ? never : [ ObjectAttribute<`${_Prefix}${TObjectAttribute}`>, ...ObjectAttributes<TRemainingAttributes> ]) : never); /** * @link https://spec.groq.dev/GROQ-1.revision1/#Object */ type ObjectType<TExpression extends string> = TExpression extends `{${infer TObjectAttributes}}` ? ObjectAttributes<TObjectAttributes> extends never ? never : { attributes: ObjectAttributes<TObjectAttributes>; type: "Object"; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Literal */ type Literal<TExpression extends string> = ArrayType<TExpression> | ObjectType<TExpression> | Primitives<TExpression> | StringType<TExpression>; /** * @link https://spec.groq.dev/GROQ-1.revision1/#This */ type This<TExpression extends string> = TExpression extends "@" ? { type: "This"; } : never; type AlphaLower = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"; type AlphaUpper = Uppercase<AlphaLower>; type Alpha = AlphaLower | AlphaUpper; type Numeric = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"; type IdentifierRest<TIdentifierRest extends string> = TIdentifierRest extends "" ? true : TIdentifierRest extends `${Alpha | Numeric | "_"}${infer TIdentifierRestInner}` ? IdentifierRest<TIdentifierRestInner> : false; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Identifier */ type Identifier<TIdentifier extends string> = TIdentifier extends `${Alpha | "_"}${infer TIdentifierRest}` ? IdentifierRest<TIdentifierRest> extends true ? TIdentifier : never : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#ThisAttribute */ type ThisAttribute<TExpression extends string> = TExpression extends `${boolean | number | null}` ? never : Identifier<TExpression> extends never ? never : { name: TExpression; type: "AccessAttribute"; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Everything */ type Everything<TExpression extends string> = TExpression extends "*" ? { type: "Everything"; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Parent */ type Parent<TExpression extends string, Levels extends null[] = [null]> = TExpression extends "^" ? { n: Levels["length"]; type: "Parent"; } : TExpression extends `^.${infer TParents}` ? Parent<TParents, [null, ...Levels]> : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-geo-type */ type Geo = GeometryCollection | LineString | MultiLineString | MultiPoint | MultiPolygon | Point | Polygon | Position; declare const ArbitrarySelectorValue: unique symbol; interface Functions<TArgs extends any[], TScope extends Scope<Context<any[], any>>> { /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Array-namespace */ array: { /** * @link https://spec.groq.dev/GROQ-1.revision1/#array_compact() */ compact: TArgs extends [infer TArr] ? TArr extends any[] ? TArr extends null[] | [] ? [] : TArr extends [infer THead, ...infer TTail] ? THead extends null ? Functions<[TTail], TScope>["array"]["compact"] : [THead, ...Functions<[TTail], TScope>["array"]["compact"]] : TArr extends (infer TElement)[] ? NonNullable<TElement>[] : never : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#array_join() */ join: TArgs extends [infer TArr, infer TSep] ? TArr extends any[] ? TSep extends string ? Functions<[TArr[number]], TScope>["global"]["string"] extends string ? Join<TArr, TSep> : null : null : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#array_unique() */ unique: TArgs extends [infer TArr] ? TArr extends any[] ? TArr extends null[] | [] ? [] : TArr extends [...infer TInitial, infer TLast] ? TLast extends boolean | number | string ? TLast extends Functions<[ TInitial ], TScope>["array"]["unique"][number] ? Functions<[TInitial], TScope>["array"]["unique"] : [...Functions<[TInitial], TScope>["array"]["unique"], TLast] : [...Functions<[TInitial], TScope>["array"]["unique"], TLast] : TArr : null : never; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Date-time-namespace */ dateTime: { /** * @link https://spec.groq.dev/GROQ-1.revision1/#dateTime_now() */ now: TArgs extends [] ? DateTime : never; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Delta-namespace */ delta: { /** * @link https://spec.groq.dev/GROQ-1.revision1/#delta_changedAny() */ changedAny: TArgs extends [infer TSelector] ? TSelector extends typeof ArbitrarySelectorValue ? TScope extends { context: { delta: { after: infer TAfter; before: infer TBefore; }; }; } ? TBefore extends null ? never : TAfter extends null ? never : Functions<[ TBefore, TAfter, TSelector ], TScope>["diff"]["changedAny"] : never : never : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#delta_changedOnly() */ changedOnly: TArgs extends [infer TSelector] ? TSelector extends typeof ArbitrarySelectorValue ? TScope extends { context: { delta: { after: infer TAfter; before: infer TBefore; }; }; } ? TBefore extends null ? never : TAfter extends null ? never : Functions<[ TBefore, TAfter, TSelector ], TScope>["diff"]["changedOnly"] : never : never : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#delta_operation() */ operation: TArgs extends [] ? TScope extends { context: { delta: { after: infer TAfter; before: infer TBefore; }; }; } ? TBefore extends null ? TAfter extends null ? null : "create" : TAfter extends null ? "delete" : "update" : never : never; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Diff-namespace */ diff: { /** * @link https://spec.groq.dev/GROQ-1.revision1/#diff_changedAny() */ changedAny: TArgs extends [any, any, infer TSelector] ? TSelector extends typeof ArbitrarySelectorValue ? boolean : never : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#diff_changedOnly() */ changedOnly: TArgs extends [any, any, infer TSelector] ? TSelector extends typeof ArbitrarySelectorValue ? boolean : never : never; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Geography-Extension */ geo: { /** * @link https://spec.groq.dev/GROQ-1.revision1/#geo_contains() */ contains: TArgs extends [infer TFirst, infer TSecond] ? TFirst extends Geo ? TSecond extends Geo ? boolean : null : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#geo_distance() */ distance: TArgs extends [infer TFirst, infer TSecond] ? TFirst extends Point ? TSecond extends Point ? number : null : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#geo_intersects() */ intersects: TArgs extends [infer TFirst, infer TSecond] ? TFirst extends Geo ? TSecond extends Geo ? boolean : null : null : never; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Global-namespace */ global: { /** * @link https://spec.groq.dev/GROQ-1.revision1/#boost() */ boost: never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_coalesce() */ coalesce: TArgs extends [] ? null : TArgs extends [infer THead, ...infer TTail] ? null extends THead ? Functions<TTail, TScope>["global"]["coalesce"] | NonNullable<THead> : THead : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_count() */ count: TArgs extends [infer TBase] ? TBase extends any[] ? TBase["length"] : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_dateTime() */ dateTime: TArgs extends [infer TBase] ? TBase extends DateTime | string ? DateTime : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_defined() */ defined: TArgs extends [infer TBase] ? TBase extends null ? false : true : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_geo() */ geo: TArgs extends [infer TBase] ? TBase extends Geo ? TBase : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-global-identity- */ identity: TArgs extends [] ? TScope extends { context: { identity: infer TIdentity; }; } ? TIdentity : never : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_length() */ length: TArgs extends [infer TBase] ? TBase extends any[] | string ? TBase["length"] : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_lower() */ lower: TArgs extends [infer TValue] ? TValue extends string ? Lowercase<TValue> : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_now() */ now: TArgs extends [] ? string : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-global-path- * @link https://www.sanity.io/docs/groq-functions#0ecd1b7eac78 */ path: TArgs extends (infer TBase)[] ? TBase extends string ? Path : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_pt() */ pt: TArgs extends [infer TBase] ? TBase extends PortableTextBlock<any, any, any, any, any> | PortableTextBlock<any, any, any, any, any>[] ? TBase : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_references() */ references: TArgs extends (infer TElement)[] ? Extract<Exclude<TElement, []>, string[] | string> extends never ? false : boolean : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_round() */ round: TArgs extends [infer TNum, infer TPrecision] | [infer TNum] ? TNum extends number ? IsUnknown<TPrecision> extends true ? number : TPrecision extends number ? number : null : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_string() */ string: TArgs extends [infer TVal] ? TVal extends boolean | number | string ? `${TVal}` : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_upper() */ upper: TArgs extends [infer TValue] ? TValue extends string ? Uppercase<TValue> : null : never; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Math-namespace */ math: { [mathFn in "avg" | "max" | "min" | "sum"]: TArgs extends [infer TArr] ? TArr extends null[] | [] ? mathFn extends "sum" ? 0 : null : TArr extends (number | null)[] ? mathFn extends "max" | "min" ? Exclude<TArr[number], null> : number : null : never; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-Portable-Text-Extension */ pt: { /** * @link https://spec.groq.dev/GROQ-1.revision1/#pt_text() */ text: TArgs extends (infer TBase)[] ? TBase extends PortableTextBlock<any, any, any, any, any> | PortableTextBlock<any, any, any, any, any>[] ? string : null : never; }; /** * @link https://www.sanity.io/docs/groq-functions#61e2649fc0d8 */ sanity: { /** * @link https://www.sanity.io/docs/groq-functions#48b1e793d6b9 */ dataset: TArgs extends [] ? TScope["context"]["client"]["dataset"] : never; /** * @link https://www.sanity.io/docs/groq-functions#b89053823742 */ projectId: TArgs extends [] ? TScope["context"]["client"]["projectId"] : never; }; /** * @link https://spec.groq.dev/GROQ-1.revision1/#sec-String-namespace */ string: { /** * @link https://spec.groq.dev/GROQ-1.revision1/#string_split() */ split: TArgs extends [infer TStr, infer TSep] ? TStr extends string ? TSep extends string ? Split<TStr, TSep> : null : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#string_startsWith() */ startsWith: TArgs extends [infer TStr, infer TPrefix] ? TStr extends string ? TPrefix extends string ? TStr extends `${TPrefix}${string}` ? true : false : null : null : never; }; } /** * @link https://spec.groq.dev/GROQ-1.revision1/#Asc */ type Asc<TExpression extends string> = TExpression extends `${infer TBase} asc` ? ParseInner<TBase> extends never ? never : { base: ParseInner<TBase>; type: "Asc"; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Desc */ type Desc<TExpression extends string> = TExpression extends `${infer TBase} desc` ? ParseInner<TBase> extends never ? never : { base: ParseInner<TBase>; type: "Desc"; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Pair */ type Pair<TExpression extends string> = TExpression extends `${infer TCondition}=>${infer TValue}` ? ParseInner<TCondition> extends never ? never : ParseInner<TValue> extends never ? never : { condition: ParseInner<TCondition>; type: "SelectAlternative"; value: ParseInner<TValue>; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#ConstantEvaluate() */ type ConstantEvaluate<TNode extends ExprNode> = Evaluate<TNode, never>; /** * @link https://spec.groq.dev/GROQ-1.revision1/#SelectorTuple */ type SelectorTupleInner<TExpression extends string> = TExpression extends `${infer TFirst},${infer TRest}` ? Selector<TFirst> extends never ? never : // eslint-disable-next-line @typescript-eslint/no-use-before-define -- Recursion Selector<TRest> | SelectorTupleInner<TRest> : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Selector */ type Selector<TExpression extends string> = (TExpression extends `(${infer TInnerExpression})` ? Selector<TInnerExpression> | SelectorTupleInner<TInnerExpression> : never) | (TExpression extends `${infer TSelector}.${infer TIdentifier}` ? Selector<TSelector> extends never ? never : Identifier<TIdentifier> extends never ? TIdentifier extends `(${infer TInnerExpression})` ? Selector<TInnerExpression> | SelectorTupleInner<TInnerExpression> : never : { type: "Selector"; } : never) | (TExpression extends `${infer TSelector}[${infer TBracketExpression}]` ? Selector<TSelector> extends never ? never : TBracketExpression extends "" ? { type: "Selector"; } : ConstantEvaluate<ParseInner<TBracketExpression>> extends never ? never : ConstantEvaluate<ParseInner<TBracketExpression>> extends number ? never : { type: "Selector"; } : never) | (ThisAttribute<TExpression> extends never ? never : { type: "Selector"; }); interface FuncArgCustomParse<TExpression extends string, TFuncLastArg extends boolean> { delta: { changedAny: TFuncLastArg extends true ? Selector<TExpression> : ParseInner<TExpression>; changedOnly: TFuncLastArg extends true ? Selector<TExpression> : ParseInner<TExpression>; }; diff: { changedAny: TFuncLastArg extends true ? Selector<TExpression> : ParseInner<TExpression>; changedOnly: TFuncLastArg extends true ? Selector<TExpression> : ParseInner<TExpression>; }; global: { order: Asc<TExpression> | Desc<TExpression> | ParseInner<TExpression>; select: Pair<TExpression> | (TFuncLastArg extends true ? ParseInner<TExpression> : never); }; } type FuncArgParse<TExpression extends string, TFuncNamespace extends string, TFuncName extends string, TFuncLastArg extends boolean = false> = TFuncNamespace extends keyof FuncArgCustomParse<TExpression, TFuncLastArg> ? TFuncName extends keyof FuncArgCustomParse<TExpression, TFuncLastArg>[TFuncNamespace] ? FuncArgCustomParse<TExpression, TFuncLastArg>[TFuncNamespace][TFuncName] : ParseInner<TExpression> : ParseInner<TExpression>; type FuncArgs<TArgs extends string, TFuncNamespace extends string, TFuncName extends string, _Prefix extends string = ""> = `${_Prefix}${TArgs}` extends "" ? [] : (FuncArgParse<`${_Prefix}${TArgs}`, TFuncNamespace, TFuncName, true> extends never ? never : [ FuncArgParse<`${_Prefix}${TArgs}`, TFuncNamespace, TFuncName, true> ]) | (TArgs extends `${infer TFuncArg},${infer TFuncArgs}` ? FuncArgs<TFuncArgs, TFuncNamespace, TFuncName, `${_Prefix}${TFuncArg},`> | (FuncArgParse<`${_Prefix}${TFuncArg}`, TFuncNamespace, TFuncName> extends never ? never : FuncArgs<TFuncArgs, TFuncNamespace, TFuncName> extends never ? never : [ FuncArgParse<`${_Prefix}${TFuncArg}`, TFuncNamespace, TFuncName>, ...FuncArgs<TFuncArgs, TFuncNamespace, TFuncName> ]) : never); type FunctionsToOtherNodes<TFuncName extends string, TFuncArgs extends any[]> = TFuncName extends "after" | "before" ? { key: TFuncName; type: "Context"; } : TFuncName extends "select" ? TFuncArgs extends [ ...infer TAlternatives extends SelectAlternativeNode[], infer TFallback extends ExprNode ] ? { alternatives: TAlternatives; fallback: TFallback; type: "Select"; } : TFuncArgs extends infer TAlternatives extends SelectAlternativeNode[] ? { alternatives: TAlternatives; type: "Select"; } : never : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#FuncCall */ type FuncCall<TExpression extends string> = TExpression extends `${infer TFuncFullName}(${infer TFuncCallArgs})` ? TFuncFullName extends `${infer TFuncNamespace}::${infer TFuncName}` ? TFuncNamespace extends keyof Functions<any, any> ? FuncArgs<TFuncCallArgs, TFuncNamespace, TFuncName> extends never ? never : TFuncName extends keyof Functions<any, any>[TFuncNamespace] ? { args: Simplify<FuncArgs<TFuncCallArgs, TFuncNamespace, TFuncName>>; func: GroqFunction; name: TFuncName; namespace: TFuncNamespace; type: "FuncCall"; } : FunctionsToOtherNodes<TFuncName, Simplify<FuncArgs<TFuncCallArgs, TFuncNamespace, TFuncName>>> : never : FuncArgs<TFuncCallArgs, "global", TFuncFullName> extends never ? never : TFuncFullName extends keyof Functions<any, any>["global"] ? { args: Simplify<FuncArgs<TFuncCallArgs, "global", TFuncFullName>>; func: GroqFunction; name: TFuncFullName; namespace: "global"; type: "FuncCall"; } : FunctionsToOtherNodes<TFuncFullName, Simplify<FuncArgs<TFuncCallArgs, "global", TFuncFullName>>> : never; /** * @link https://www.sanity.io/docs/groq-parameters */ type Parameter<TExpression extends string> = TExpression extends `$${infer TIdentifier}` ? Identifier<TIdentifier> extends never ? never : { name: TIdentifier; type: "Parameter"; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#SimpleExpression */ type SimpleExpression<TExpression extends string> = Everything<TExpression> | FuncCall<TExpression> | Parameter<TExpression> | Parent<TExpression> | This<TExpression> | ThisAttribute<TExpression>; type Level1 = SelectAlternativeNode; type Level2 = Level1 | OrNode; type Level3 = AndNode | Level2; type Level4 = AscNode | DescNode | Level3 | (OpCallNode & { op: "!=" | "<" | "<=" | "==" | ">" | ">=" | "in" | "match"; }); type Level5 = Level4; type Level6 = Level5 | (OpCallNode & { op: "-" | "+"; }); type Level7 = Level6 | (OpCallNode & { op: "*" | "/" | "%"; }); type Level8 = Level7 | NegNode; type Level9 = Level8 | (OpCallNode & { op: "**"; }); type Level10 = Level9 | NotNode | PosNode; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Parenthesis */ type Parenthesis<TExpression extends string> = TExpression extends `(${infer TInnerExpression})` ? ParseInner<TInnerExpression> extends never ? never : { base: ParseInner<TInnerExpression>; type: "Group"; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#ArrayPostfix */ type ArrayPostfix<TExpression extends string> = TExpression extends `${infer TBase}[]` ? Exclude<ParseInner<TBase>, Level10> extends never ? never : { base: Exclude<ParseInner<TBase>, Level10>; type: "ArrayCoerce"; } : never; type KnownArrayNode = ArrayCoerceNode | ArrayNode | EverythingNode | FilterNode | MapNode | PipeFuncCallNode | SliceNode; type MaybeMapBase<TBase extends ExprNode> = TBase extends never ? never : TBase extends KnownArrayNode ? { type: "This"; } : TBase; type MaybeMap<TBase extends ExprNode, TNode extends ExprNode> = TBase extends never ? never : TNode extends never ? never : TBase extends KnownArrayNode ? { base: TBase; expr: TNode; type: "Map"; } : TNode; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Range */ type Range<TExpression extends string> = { [TOp in "..." | ".."]: TExpression extends `${infer TStart}${TOp}${infer TEnd}` ? ParseInner<TStart> extends never ? never : ParseInner<TEnd> extends never ? never : { isInclusive: TOp extends ".." ? true : false; left: ParseInner<TStart>; right: ParseInner<TEnd>; type: "Range"; } : never; }["..." | ".."]; /** * @link https://spec.groq.dev/GROQ-1.revision1/#SquareBracketTraversal * @link https://spec.groq.dev/GROQ-1.revision1/#AttributeAccess * @link https://spec.groq.dev/GROQ-1.revision1/#ElementAccess * @link https://spec.groq.dev/GROQ-1.revision1/#Filter */ type SquareBracketTraversal<TExpression extends string, _Prefix extends string = ""> = TExpression extends `${infer TBase}[${infer TBracketExpression}]` ? SquareBracketTraversal<`${TBracketExpression}]`, `${_Prefix}${TBase}[`> | (Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10> extends never ? never : (ConstantEvaluate<ParseInner<TBracketExpression>> extends never ? never : ConstantEvaluate<ParseInner<TBracketExpression>> extends string ? MaybeMap<Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>, { base: MaybeMapBase<Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>>; name: ConstantEvaluate<ParseInner<TBracketExpression>>; type: "AccessAttribute"; }> : ConstantEvaluate<ParseInner<TBracketExpression>> extends number ? { base: Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>; index: ConstantEvaluate<ParseInner<TBracketExpression>>; type: "AccessElement"; } : { base: Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>; expr: ParseInner<TBracketExpression>; type: "Filter"; }) | (Range<TBracketExpression> extends never ? never : ConstantEvaluate<Range<TBracketExpression>["left"]> extends number ? ConstantEvaluate<Range<TBracketExpression>["right"]> extends number ? { base: Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>; isInclusive: Range<TBracketExpression>["isInclusive"]; left: ConstantEvaluate<Range<TBracketExpression>["left"]>; right: ConstantEvaluate<Range<TBracketExpression>["right"]>; type: "Slice"; } : never : never)) : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#AttributeAccess */ type AttributeAccess<TExpression extends string, _Prefix extends string = ""> = TExpression extends `${infer TBase}.${infer TIdentifier}` ? AttributeAccess<TIdentifier, `${_Prefix}${TBase}.`> | (Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10> extends never ? never : Identifier<TIdentifier> extends never ? never : MaybeMap<Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>, { base: MaybeMapBase<Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>>; name: TIdentifier; type: "AccessAttribute"; }>) : never; type ProjectionInner<TBase extends string, TProjection extends string> = Exclude<ParseInner<TBase>, Level10> extends never ? never : ObjectType<`{${TProjection}}`> extends never ? never : MaybeMap<Exclude<ParseInner<TBase>, Level10>, { base: MaybeMapBase<Exclude<ParseInner<TBase>, Level10>>; expr: ObjectType<`{${TProjection}}`>; type: "Projection"; }>; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Projection */ type Projection<TExpression extends string, _Prefix extends string = ""> = TExpression extends `${infer TBase}|{${infer TProjection}}` ? Projection<`${TProjection}}`, `${_Prefix}${TBase}|{`> | ProjectionInner<`${_Prefix}${TBase}`, TProjection> : TExpression extends `${infer TBase}{${infer TProjection}}` ? Projection<`${TProjection}}`, `${_Prefix}${TBase}{`> | ProjectionInner<`${_Prefix}${TBase}`, TProjection> : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Dereference */ type Dereference<TExpression extends string, _Prefix extends string = ""> = TExpression extends `${infer TBase}->${infer TIdentifier}` ? Dereference<TIdentifier, `${_Prefix}${TBase}->`> | (Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10> extends never ? never : TIdentifier extends "" ? MaybeMap<Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>, { base: MaybeMapBase<Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>>; type: "Deref"; }> : Identifier<TIdentifier> extends never ? never : MaybeMap<Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>, { base: { base: MaybeMapBase<Exclude<ParseInner<`${_Prefix}${TBase}`>, Level10>>; type: "Deref"; }; name: TIdentifier; type: "AccessAttribute"; }>) : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#TraversalExpression */ type TraversalExpression<TExpression extends string> = ArrayPostfix<TExpression> | AttributeAccess<TExpression> | Dereference<TExpression> | Projection<TExpression> | SquareBracketTraversal<TExpression>; /** * Whenever a tuple is reordered, we can't be certain what the types are. * So each member is a union of all members. * We also map instead of TArray[number][] to ensure the length of the tuple is preserved. */ type TupleToUnionArray<TArray extends any[]> = { [Index in keyof TArray]: TArray[number]; }; interface PipeFunctions<TBase extends any[], TArgs extends any[]> { global: { /** * @link https://spec.groq.dev/GROQ-1.revision1/#order() */ order: TArgs extends [] ? never : TupleToUnionArray<TBase>; /** * @link https://spec.groq.dev/GROQ-1.revision1/#score() */ score: TArgs extends [] ? never : TBase extends (infer Element)[] ? (IsPlainObject<Element> extends false ? never : Element & { _score: number; })[] : never; }; } /** * @link https://spec.groq.dev/GROQ-1.revision1/#PipeFuncCall */ type PipeFuncCall<TExpression extends string> = TExpression extends `${infer TBase}|${infer TFuncFullName}(${infer TFuncCallArgs})` ? Parse<TBase> extends never ? never : TFuncFullName extends `${infer TFuncNamespace}::${infer TFuncName}` ? TFuncNamespace extends keyof PipeFunctions<any, any> ? FuncArgs<TFuncCallArgs, TFuncNamespace, TFuncName> extends never ? never : TFuncName extends keyof PipeFunctions<any, any>[TFuncNamespace] ? { args: Simplify<FuncArgs<TFuncCallArgs, TFuncNamespace, TFuncName>>; base: Parse<TBase>; func: GroqPipeFunction; name: TFuncNamespace extends "global" ? TFuncName : TFuncFullName; type: "PipeFuncCall"; } : never : never : FuncArgs<TFuncCallArgs, "global", TFuncFullName> extends never ? never : TFuncFullName extends keyof PipeFunctions<any, any>["global"] ? { args: Simplify<FuncArgs<TFuncCallArgs, "global", TFuncFullName>>; base: Parse<TBase>; func: GroqPipeFunction; name: TFuncFullName; type: "PipeFuncCall"; } : never : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#CompoundExpression */ type CompoundExpression<TExpression extends string> = Parenthesis<TExpression> | PipeFuncCall<TExpression> | TraversalExpression<TExpression>; interface BooleanOperators { "&&": { leftLevel: Level2; rightLevel: Level3; stronger: false; type: "And"; weaker: true; }; "||": { leftLevel: Level1; rightLevel: Level2; stronger: true; type: "Or"; weaker: false; }; } /** * @link https://spec.groq.dev/GROQ-1.revision1/#And * @link https://spec.groq.dev/GROQ-1.revision1/#Or */ type BooleanOperator<TExpression extends string, TOp extends keyof BooleanOperators | null = null, _Prefix extends string = ""> = TOp extends null ? { [TOp in keyof BooleanOperators]: BooleanOperator<TExpression, TOp>; }[keyof BooleanOperators] : TExpression extends `${infer TLeft}${TOp}${infer TRight}` ? BooleanOperator<TRight, TOp, `${_Prefix}${TLeft}${TOp}`> | (Exclude<ParseInner<`${_Prefix}${TLeft}`>, BooleanOperators[NonNullable<TOp>]["leftLevel"]> extends never ? never : Exclude<ParseInner<TRight>, BooleanOperators[NonNullable<TOp>]["rightLevel"]> extends never ? never : { left: Exclude<ParseInner<`${_Prefix}${TLeft}`>, BooleanOperators[NonNullable<TOp>]["leftLevel"]>; right: Exclude<ParseInner<TRight>, BooleanOperators[NonNullable<TOp>]["rightLevel"]>; type: BooleanOperators[NonNullable<TOp>]["type"]; }) : never; interface PrefixOperators { "!": { level: Exclude<Level9, NegNode>; type: "Not"; }; "+": { level: Exclude<Level9, NegNode>; type: "Pos"; }; "-": { level: Level7; type: "Neg"; }; } /** * @link https://spec.groq.dev/GROQ-1.revision1/#Not * @link https://spec.groq.dev/GROQ-1.revision1/#UnaryPlus * @link https://spec.groq.dev/GROQ-1.revision1/#UnaryMinus */ type PrefixOperator<TExpression extends string, TOp extends keyof PrefixOperators | null = null> = TOp extends null ? { [TOp in keyof PrefixOperators]: PrefixOperator<TExpression, TOp>; }[keyof PrefixOperators] : TExpression extends `${TOp}${infer TBase}` ? Exclude<ParseInner<TBase>, PrefixOperators[NonNullable<TOp>]["level"]> extends never ? never : { base: Exclude<ParseInner<TBase>, PrefixOperators[NonNullable<TOp>]["level"]>; type: PrefixOperators[NonNullable<TOp>]["type"]; } : never; interface Operators { "!=": { leftLevel: Level4; rightLevel: Level4; }; "%": { leftLevel: Level6; rightLevel: Level7; }; "*": { leftLevel: Level6; rightLevel: // HACK https://github.com/sanity-io/GROQ/issues/112 EverythingNode | Level7; }; "**": { leftLevel: Level9; rightLevel: Level7; }; "+": { leftLevel: Level5; rightLevel: Level6; }; "-": { leftLevel: Level5; rightLevel: Level6; }; "/": { leftLevel: Level6; rightLevel: Level7; }; "<": { leftLevel: Level4; rightLevel: Level4; }; "<=": { leftLevel: Level4; rightLevel: Level4; }; "==": { leftLevel: Level4; rightLevel: Level4; }; ">": { leftLevel: Level4; rightLevel: Level4; }; ">=": { leftLevel: Level4; rightLevel: Level4; }; "match": { leftLevel: Level4; rightLevel: Level4; withSpaces: true; }; } /** * @link https://spec.groq.dev/GROQ-1.revision1/#Equality * @link https://spec.groq.dev/GROQ-1.revision1/#Comparison * @link https://spec.groq.dev/GROQ-1.revision1/#Match * @link https://spec.groq.dev/GROQ-1.revision1/#Plus * @link https://spec.groq.dev/GROQ-1.revision1/#Minus * @link https://spec.groq.dev/GROQ-1.revision1/#Star * @link https://spec.groq.dev/GROQ-1.revision1/#Slash * @link https://spec.groq.dev/GROQ-1.revision1/#Percent * @link https://spec.groq.dev/GROQ-1.revision1/#StarStar */ type OpCall<TExpression extends string, TOp extends keyof Operators | null = null, _Prefix extends string = ""> = TOp extends null ? { [TOp in keyof Operators]: OpCall<TExpression, TOp>; }[keyof Operators] : TExpression extends `${infer TLeft}${Operators[NonNullable<TOp>] extends { withSpaces: true; } ? ` ${TOp} ` : TOp}${infer TRight}` ? OpCall<TRight, TOp, `${_Prefix}${TLeft}${Operators[NonNullable<TOp>] extends { withSpaces: true; } ? ` ${TOp} ` : TOp}`> | (Exclude<ParseInner<`${_Prefix}${TLeft}`>, Operators[NonNullable<TOp>]["leftLevel"]> extends never ? never : Exclude<ParseInner<TRight>, Operators[NonNullable<TOp>]["rightLevel"]> extends never ? never : { left: Exclude<ParseInner<`${_Prefix}${TLeft}`>, Operators[NonNullable<TOp>]["leftLevel"]>; op: TOp; right: Exclude<ParseInner<TRight>, Operators[NonNullable<TOp>]["rightLevel"]>; type: "OpCall"; }) : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#In */ type InOperator<TExpression extends string, _Prefix extends string = ""> = TExpression extends `${infer TLeft} in ${infer TRight}` ? Exclude<ParseInner<`${_Prefix}${TLeft}`>, Level4> extends never ? never : Exclude<ParseInner<TRight>, Level4> extends never ? Range<TRight> extends never ? never : { base: Exclude<ParseInner<`${_Prefix}${TLeft}`>, Level4>; isInclusive: Range<TRight>["isInclusive"]; left: Range<TRight>["left"]; right: Range<TRight>["right"]; type: "InRange"; } : { left: Exclude<ParseInner<`${_Prefix}${TLeft}`>, Level4>; op: "in"; right: Exclude<ParseInner<TRight>, Level4>; type: "OpCall"; } : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#OperatorCall */ type OperatorCall<TExpression extends string> = BooleanOperator<TExpression> | InOperator<TExpression> | OpCall<TExpression> | PrefixOperator<TExpression>; /** * @link https://spec.groq.dev/GROQ-1.revision1/#Expression */ type Expression<TExpression extends string> = CompoundExpression<TExpression> | Literal<TExpression> | OperatorCall<TExpression> | SimpleExpression<TExpression>; type EvaluateBaseOrThis<TNode extends AccessAttributeNode, TScope extends Scope<Context<any[], any>>> = TNode extends { base: infer TBase extends ExprNode; } ? Evaluate<TBase, TScope> : TScope["this"]; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateAttributeAccess() * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateThisAttribute() */ type EvaluateAccessAttribute<TNode extends ExprNode, TScope extends Scope<Context<any[], any>>> = TNode extends AccessAttributeNode ? EvaluateBaseOrThis<TNode, TScope> extends object ? EvaluateBaseOrThis<TNode, TScope> extends { [name in TNode["name"]]: infer TValue; } ? TValue : EvaluateBaseOrThis<TNode, TScope> extends { [name in TNode["name"]]?: infer TValue; } ? TValue | undefined : null : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateElementAccess() */ type EvaluateAccessElement<TNode extends ExprNode, TScope extends Scope<Context<any[], any>>> = TNode extends AccessElementNode ? Evaluate<TNode["base"], TScope> extends any[] ? TNode["index"] extends keyof Evaluate<TNode["base"], TScope> ? Evaluate<TNode["base"], TScope>[TNode["index"]] | (Evaluate<TNode["base"], TScope> extends [any, ...any] ? never : null) : null : null : never; type FlattenDoubleArray<TArray extends any[][]> = TArray extends [] ? [] : TArray extends [infer THead extends any[], ...infer TTail extends any[][]] ? [...THead, ...FlattenDoubleArray<TTail>] : TArray extends (infer TElement extends any[])[] ? TElement[number][] : never; type EvaluateArrayElement<TElement extends ArrayElementNode, TScope extends Scope<Context<any[], any>>> = TElement["isSplat"] extends true ? Evaluate<TElement["value"], TScope> extends any[] ? Evaluate<TElement["value"], TScope> : [Evaluate<TElement["value"], TScope>] : [Evaluate<TElement["value"], TScope>]; type EvaluateArrayElements<TElements extends ArrayElementNode[], TScope extends Scope<Context<any[], any>>> = FlattenDoubleArray<{ [Index in keyof TElements]: EvaluateArrayElement<TElements[Index], TScope>; }>; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateArray() */ type EvaluateArray<TNode extends ExprNode, TScope extends Scope<Context<any[], any>>> = TNode extends ArrayNode ? EvaluateArrayElements<TNode["elements"], TScope> : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateArrayPostfix() */ type EvaluateArrayPostfix<TNode extends ExprNode, TScope extends Scope<Context<any[], any>>> = TNode extends ArrayCoerceNode ? Evaluate<TNode["base"], TScope> extends any[] ? Evaluate<TNode["base"], TScope> : null : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateAnd() * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateOr() */ type EvaluateBooleanOperator<TNode extends ExprNode, TScope extends Scope<Context<any[], any>>> = TNode extends AndNode | OrNode ? TNode extends { left: infer TLeft extends ExprNode; right: infer TRight extends ExprNode; type: infer TType; } ? Extract<BooleanOperators[keyof BooleanOperators], { type: TType; }> extends { stronger: infer TStronger; weaker: infer TWeaker; } ? boolean extends Evaluate<TLeft, TScope> ? Evaluate<TRight, TScope> : boolean extends Evaluate<TRight, TScope> ? Evaluate<TLeft, TScope> : Evaluate<TLeft, TScope> extends TStronger ? TStronger : Evaluate<TRight, TScope> extends TStronger ? TStronger : Evaluate<TLeft, TScope> extends TWeaker ? Evaluate<TRight, TScope> extends TWeaker ? TWeaker : null : null : never : never : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateComparison() */ type EvaluateComparison<TNode extends ExprNode> = TNode extends OpCallNode & { op: "<" | "<=" | ">" | ">="; } ? boolean : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#global_after() * @link https://spec.groq.dev/GROQ-1.revision1/#global_before() */ type EvaluateContext<TNode extends ExprNode, TScope extends Scope<Context<any[], any>>> = TNode extends ContextNode ? TNode extends { key: infer TKey extends "after" | "before"; } ? TScope extends { context: { delta: { [key in TKey]: infer TValue; }; }; } ? TValue : null : never : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateDereference() */ type EvaluateDereference<TNode extends ExprNode, TScope extends Scope<Context<any[], any>>> = TNode extends DerefNode ? Evaluate<TNode["base"], TScope> extends SetOptional<ReferenceValue<infer TReferenced>, typeof referenced> & { _ref: infer TRef; } ? TScope["context"]["dataset"] extends (infer TDataset)[] ? IsNever<Extract<TDataset, { _id: TRef; _type: TReferenced; }>> extends true ? null : Extract<TDataset, { _id: TRef; _type: TReferenced; }> : null : null : never; type Not<TBoolean, Enabled extends boolean = true> = TBoolean extends boolean ? Enabled extends false ? TBoolean : TBoolean extends true ? false : true : null; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateEquality() */ type EvaluateEquality<TNode extends ExprNode, TScope extends Scope<Context<any[], any>>> = TNode extends OpCallNode & { op: "!=" | "=="; } ? Not<Evaluate<TNode["left"], TScope> extends Evaluate<TNode["right"], TScope> ? true : Evaluate<TNode["right"], TScope> extends Evaluate<TNode["left"], TScope> ? true : false, TNode["op"] extends "!=" ? true : false> : never; /** * @link https://spec.groq.dev/GROQ-1.revision1/#EvaluateEverything() */ type EvaluateEverything<TNode extends ExprNo