Skip to content

Commit

Permalink
Merge pull request #141 from saiichihashimoto/more-groq
Browse files Browse the repository at this point in the history
feat(groq): groq this and parent
  • Loading branch information
kodiakhq[bot] authored Jul 21, 2023
2 parents 8c2a97f + b6bc41b commit e2276f7
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 18 deletions.
63 changes: 62 additions & 1 deletion packages/groq/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { describe, it } from "@jest/globals";
import { expectType } from "@sanity-typed/test-utils";
import type { DocumentValue } from "@sanity-typed/types";

import type { ExecuteQuery } from ".";
import type { ExecuteQuery, Scope } from ".";

describe("groq", () => {
it("null", () =>
Expand Down Expand Up @@ -61,6 +61,22 @@ describe("groq", () => {
ExecuteQuery<"[[null,null],[null,null,null]]", { [key: string]: never }>
>().toStrictEqual<[[null, null], [null, null, null]]>());

it("@", () => {
const UNIQUE_VALUE: unique symbol = Symbol("");

expectType<
ExecuteQuery<"@", Scope<never, typeof UNIQUE_VALUE, never>>
>().toStrictEqual<typeof UNIQUE_VALUE>();
});

it("key", () => {
const UNIQUE_VALUE: unique symbol = Symbol("");

expectType<
ExecuteQuery<"key", Scope<never, { key: typeof UNIQUE_VALUE }, never>>
>().toStrictEqual<typeof UNIQUE_VALUE>();
});

it("*", () =>
expectType<
ExecuteQuery<
Expand All @@ -75,6 +91,51 @@ describe("groq", () => {
(DocumentValue<"bar", never> | DocumentValue<"foo", never>)[]
>());

it("^", () => {
const UNIQUE_VALUE: unique symbol = Symbol("");

expectType<
ExecuteQuery<
"^",
Scope<never, never, Scope<never, typeof UNIQUE_VALUE, never>>
>
>().toStrictEqual<typeof UNIQUE_VALUE>();
});

it("^.^", () => {
const UNIQUE_VALUE: unique symbol = Symbol("");

expectType<
ExecuteQuery<
"^.^",
Scope<
never,
never,
Scope<never, never, Scope<never, typeof UNIQUE_VALUE, never>>
>
>
>().toStrictEqual<typeof UNIQUE_VALUE>();
});

it("^.^.^", () => {
const UNIQUE_VALUE: unique symbol = Symbol("");

expectType<
ExecuteQuery<
"^.^.^",
Scope<
never,
never,
Scope<
never,
never,
Scope<never, never, Scope<never, typeof UNIQUE_VALUE, never>>
>
>
>
>().toStrictEqual<typeof UNIQUE_VALUE>();
});

it("(*)", () =>
expectType<
ExecuteQuery<
Expand Down
81 changes: 64 additions & 17 deletions packages/groq/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Context<Dataset> = {
/**
* @link https://sanity-io.github.io/GROQ/GROQ-1.revision1/#sec-Scope
*/
type Scope<
export type Scope<
TContext extends Context<any>,
Value,
ParentScope extends Scope<any, any, any> | null
Expand Down Expand Up @@ -115,18 +115,63 @@ type Everything<
: never
: never;

/**
* @link https://sanity-io.github.io/GROQ/GROQ-1.revision1/#Parent
*/
type Parent<
TExpression extends string,
TScope extends Scope<any, any, any>
> = TExpression extends "^"
? TScope extends Scope<any, any, Scope<any, infer Value, any>>
? Value
: never
: TExpression extends `^.${infer TParents}`
? TScope extends Scope<
any,
any,
infer TParentScope extends Scope<any, any, any>
>
? Parent<TParents, TParentScope>
: never
: never;

/**
* @link https://sanity-io.github.io/GROQ/GROQ-1.revision1/#This
*/
type This<
TExpression extends string,
TScope extends Scope<any, any, any>
> = TExpression extends "@"
? TScope extends Scope<any, infer Value, any>
? Value
: never
: never;

/**
* @link https://sanity-io.github.io/GROQ/GROQ-1.revision1/#ThisAttribute
*/
type ThisAttribute<
TExpression extends string,
TScope extends Scope<any, any, any>
> = TScope extends Scope<any, infer Value, any>
? TExpression extends keyof Value
? Value[TExpression]
: never
: never;

/**
* @link https://sanity-io.github.io/GROQ/GROQ-1.revision1/#SimpleExpression
*
* @todo This
* @todo ThisAttribute
* @todo Parent
* @todo FuncCall
*/
type SimpleExpression<
TExpression extends string,
TScope extends Scope<any, any, any>
> = Everything<TExpression, TScope>;
> =
| Everything<TExpression, TScope>
| Parent<TExpression, TScope>
| This<TExpression, TScope>
| ThisAttribute<TExpression, TScope>;

/**
* @link https://sanity-io.github.io/GROQ/GROQ-1.revision1/#Parenthesis
Expand Down Expand Up @@ -176,18 +221,20 @@ type Evaluate<
*/
export type ExecuteQuery<
TQuery extends string,
Values extends InferSchemaValues<any>
ValuesOrScope extends InferSchemaValues<any> | Scope<any, any, any>
> = Evaluate<
TQuery,
Scope<
Context<
Extract<
Values[keyof Values],
// TODO Is is true that we should only use documents?
DocumentValue<string, any>
>[]
>,
null,
null
>
ValuesOrScope extends Scope<any, any, any>
? ValuesOrScope
: Scope<
Context<
Extract<
ValuesOrScope[keyof ValuesOrScope],
// TODO Is is true that we should only use documents?
DocumentValue<string, any>
>[]
>,
null,
null
>
>;

0 comments on commit e2276f7

Please sign in to comment.