Skip to content

Commit

Permalink
feature(variables): moved createGroqBuilder back into index, since th…
Browse files Browse the repository at this point in the history
…e import order was important
  • Loading branch information
scottrippey committed Feb 6, 2024
1 parent 42370b6 commit 94b8f3c
Show file tree
Hide file tree
Showing 20 changed files with 563 additions and 340 deletions.
4 changes: 2 additions & 2 deletions packages/groq-builder/src/commands/conditional-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
} from "./projection-types";
import { Empty, IntersectionOfValues, Simplify, ValueOf } from "../types/utils";
import { ExtractTypeNames, QueryConfig } from "../types/schema-types";
import { GroqBuilder, IGroqBuilder } from "../groq-builder";
import { InferResultType } from "../types/public-types";
import { GroqBuilder } from "../groq-builder";
import { IGroqBuilder, InferResultType } from "../types/public-types";
import { Expressions } from "../types/groq-expressions";

export type ConditionalProjectionMap<
Expand Down
8 changes: 6 additions & 2 deletions packages/groq-builder/src/commands/conditional.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { describe, expect, expectTypeOf, it } from "vitest";
import { GroqBuilder, InferResultItem, InferResultType } from "../index";
import {
createGroqBuilder,
GroqBuilder,
InferResultItem,
InferResultType,
} from "../index";
import { SchemaConfig } from "../tests/schemas/nextjs-sanity-fe";
import { ExtractConditionalProjectionTypes } from "./conditional-types";
import { Empty, Simplify } from "../types/utils";
import { createGroqBuilder } from "../createGroqBuilder";

const q = createGroqBuilder<SchemaConfig>({ indent: " " });
const qVariants = q.star.filterByType("variant");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, it, expect, expectTypeOf } from "vitest";
import {
createGroqBuilder,
ExtractTypeNames,
GroqBuilder,
IGroqBuilder,
Expand All @@ -11,7 +12,6 @@ import { ExtractConditionalProjectionTypes } from "./conditional-types";
import { executeBuilder } from "../tests/mocks/executeQuery";
import { mock } from "../tests/mocks/nextjs-sanity-fe-mocks";
import { Empty, Simplify, SimplifyDeep } from "../types/utils";
import { createGroqBuilder } from "../createGroqBuilder";

const q = createGroqBuilder<SchemaConfig>({ indent: " " });
const data = mock.generateSeedData({
Expand Down
3 changes: 2 additions & 1 deletion packages/groq-builder/src/commands/deref.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { InferResultType } from "../types/public-types";
import { executeBuilder } from "../tests/mocks/executeQuery";
import { mock } from "../tests/mocks/nextjs-sanity-fe-mocks";
import { SanitySchema, SchemaConfig } from "../tests/schemas/nextjs-sanity-fe";
import { createGroqBuilder } from "../createGroqBuilder";

import { createGroqBuilder } from "../index";

const q = createGroqBuilder<SchemaConfig>();
const data = mock.generateSeedData({});
Expand Down
2 changes: 1 addition & 1 deletion packages/groq-builder/src/commands/filter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SanitySchema, SchemaConfig } from "../tests/schemas/nextjs-sanity-fe";
import { InferResultType } from "../types/public-types";
import { executeBuilder } from "../tests/mocks/executeQuery";
import { mock } from "../tests/mocks/nextjs-sanity-fe-mocks";
import { createGroqBuilder } from "../createGroqBuilder";
import { createGroqBuilder } from "../index";

const q = createGroqBuilder<SchemaConfig>();
const qVariants = q.star.filterByType("variant");
Expand Down
3 changes: 2 additions & 1 deletion packages/groq-builder/src/commands/projection-types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GroqBuilder, IGroqBuilder } from "../groq-builder";
import { GroqBuilder } from "../groq-builder";
import {
Empty,
IsAny,
Expand All @@ -12,6 +12,7 @@ import {
} from "../types/utils";
import {
FragmentInputTypeTag,
IGroqBuilder,
Parser,
ParserWithWidenedInput,
} from "../types/public-types";
Expand Down
4 changes: 2 additions & 2 deletions packages/groq-builder/src/commands/select-types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ExtractTypeNames, QueryConfig } from "../types/schema-types";
import { StringKeys, ValueOf } from "../types/utils";
import { GroqBuilder, IGroqBuilder } from "../groq-builder";
import { InferResultType } from "../types/public-types";
import { GroqBuilder } from "../groq-builder";
import { IGroqBuilder, InferResultType } from "../types/public-types";
import { Expressions } from "../types/groq-expressions";

// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down
6 changes: 5 additions & 1 deletion packages/groq-builder/src/commands/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { GroqBuilder } from "../groq-builder";
import { ResultItem } from "../types/result-types";
import { ExtractSelectResult, SelectProjections } from "./select-types";
import { notNull } from "../types/utils";
import { InferResultType, ParserFunction } from "../types/public-types";
import {
IGroqBuilder,
InferResultType,
ParserFunction,
} from "../types/public-types";

declare module "../groq-builder" {
export interface GroqBuilder<TResult, TQueryConfig> {
Expand Down
4 changes: 2 additions & 2 deletions packages/groq-builder/src/commands/selectByType.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { GroqBuilder, IGroqBuilder } from "../groq-builder";
import { GroqBuilder } from "../groq-builder";
import { ResultItem } from "../types/result-types";
import { keys, Simplify } from "../types/utils";
import {
ExtractSelectByTypeResult,
SelectByTypeProjections,
SelectProjections,
} from "./select-types";
import { InferResultType } from "../types/public-types";
import { IGroqBuilder, InferResultType } from "../types/public-types";

declare module "../groq-builder" {
export interface GroqBuilder<TResult, TQueryConfig> {
Expand Down
26 changes: 0 additions & 26 deletions packages/groq-builder/src/createGroqBuilder.ts

This file was deleted.

20 changes: 0 additions & 20 deletions packages/groq-builder/src/createGroqBuilderWithZod.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/groq-builder/src/groq-builder.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { describe, expect, expectTypeOf, it } from "vitest";
import { createGroqBuilder } from "./index";
import { SchemaConfig } from "./tests/schemas/nextjs-sanity-fe";
import { InferResultType } from "./types/public-types";
import { Empty } from "./types/utils";
import { createGroqBuilder } from "./createGroqBuilder";

const q = createGroqBuilder<SchemaConfig>({ indent: " " });

Expand Down
41 changes: 10 additions & 31 deletions packages/groq-builder/src/groq-builder.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { Parser, ParserFunction } from "./types/public-types";
import {
GroqBuilderConfigType,
GroqBuilderResultType,
IGroqBuilder,
Parser,
ParserFunction,
} from "./types/public-types";
import type { ExtractTypeNames, QueryConfig } from "./types/schema-types";
import { normalizeValidationFunction } from "./commands/validate-utils";
import { ValidationErrors } from "./validation/validation-errors";
import { Empty } from "./types/utils";
import type { Empty } from "./types/utils";
import { QueryError } from "./types/query-error";

export type RootResult = Empty;
Expand Down Expand Up @@ -40,9 +46,9 @@ export class GroqBuilder<
TQueryConfig extends QueryConfig = QueryConfig
> implements IGroqBuilder<TResult>
{
// @ts-expect-error --- This property doesn't actually exist, it's only used to capture type info
// @ts-expect-error --- This property doesn't actually exist, it's only used to capture type info */
readonly [GroqBuilderResultType]: TResult;
// @ts-expect-error --- This property doesn't actually exist, it's only used to capture type info
// @ts-expect-error --- This property doesn't actually exist, it's only used to capture type info */
readonly [GroqBuilderConfigType]: TQueryConfig;

/**
Expand Down Expand Up @@ -186,30 +192,3 @@ export class GroqBuilder<
};
}
}

export declare const GroqBuilderResultType: unique symbol;
export declare const GroqBuilderConfigType: unique symbol;
/**
* IGroqBuilder is the bare minimum GroqBuilder, used to prevent circular references
* @internal
*/
export type IGroqBuilder<
TResult = unknown,
TQueryConfig extends QueryConfig = QueryConfig
> = {
/**
* Used to infer the Result types of a GroqBuilder.
* This symbol is not used at runtime.
* @internal
*/
readonly [GroqBuilderResultType]: TResult;
/**
* Used to infer the TQueryConfig types of a GroqBuilder.
* This symbol is not used at runtime
* @internal
*/
readonly [GroqBuilderConfigType]: TQueryConfig;
query: string;
parser: ParserFunction | null;
parse: ParserFunction;
};
52 changes: 48 additions & 4 deletions packages/groq-builder/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,54 @@
// Be sure to keep this import as the very first import
// Be sure to keep these first 2 imports in this order:
import "./groq-builder";
import "./commands";

import type { RootQueryConfig } from "./types/schema-types";
import { GroqBuilder, GroqBuilderOptions, RootResult } from "./groq-builder";
import { zod } from "./validation/zod";

// Re-export all our public types:
export * from "./groq-builder";
export * from "./types/public-types";
export * from "./types/schema-types";
export * from "./groq-builder";
export { zod } from "./validation/zod";
export { createGroqBuilder } from "./createGroqBuilder";
export { createGroqBuilderWithZod } from "./createGroqBuilderWithZod";
export { makeSafeQueryRunner } from "./makeSafeQueryRunner";

/**
* Creates the root `q` query builder.
*
* Does not include runtime validation methods like `q.string()`.
* Instead, you have 3 options:
* - You can import `zod` and use `zod.string()` instead of `q.string()`
* - You can use inferred types without runtime validation
* - You can provide your own validation methods
* The Zod dependency can be tree-shaken with the latter 2 approaches.
*
* The TRootConfig type argument is used to bind the query builder to the Sanity schema config.
* If you specify `any`, then your schema will be loosely-typed, but the output types will still be strongly typed.
*/
export function createGroqBuilder<TRootConfig extends RootQueryConfig>(
options: GroqBuilderOptions = {}
) {
const q = new GroqBuilder<RootResult, TRootConfig>({
query: "",
parser: null,
options,
});
return q;
}

/**
* Creates the root `q` query builder.
*
* Includes all Zod validation methods attached to the `q` object,
* like `q.string()` etc. This ensures an API that's backwards compatible with GroqD syntax.
*
* The TRootConfig type argument is used to bind the query builder to the Sanity schema config.
* If you specify `any`, then your schema will be loosely-typed, but the output types will still be strongly typed.
*/
export function createGroqBuilderWithZod<TRootConfig extends RootQueryConfig>(
options: GroqBuilderOptions = {}
) {
const q = createGroqBuilder<TRootConfig>(options);
return Object.assign(q, zod);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, it, expect, expectTypeOf } from "vitest";
import { SchemaConfig } from "./tests/schemas/nextjs-sanity-fe";
import { createGroqBuilder } from "./createGroqBuilder";
import { createGroqBuilder } from "./index";
import { makeSafeQueryRunner } from "./makeSafeQueryRunner";

const q = createGroqBuilder<SchemaConfig>({ indent: " " });
Expand Down
2 changes: 1 addition & 1 deletion packages/groq-builder/src/makeSafeQueryRunner.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { HasRequiredKeys, IsUnknown } from "type-fest";
import type { QueryConfig } from "./types/schema-types";

import { IGroqBuilder } from "./groq-builder";
import { IGroqBuilder } from "./types/public-types";

export type QueryRunnerOptions<TQueryConfig extends QueryConfig = QueryConfig> =
IsUnknown<TQueryConfig["parameters"]> extends true
Expand Down
1 change: 0 additions & 1 deletion packages/groq-builder/src/types/groq-expressions.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { describe, expectTypeOf, it } from "vitest";
import { Expressions } from "./groq-expressions";
import { QueryConfig, RootQueryConfig } from "./schema-types";
import { Simplify } from "type-fest";

describe("Expressions", () => {
it("literal values are properly escaped", () => {
Expand Down
30 changes: 29 additions & 1 deletion packages/groq-builder/src/types/public-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ZodType } from "zod";
import type { ResultItem } from "./result-types";
import type { Simplify } from "./utils";
import type { ExtractProjectionResult } from "../commands/projection-types";
import { IGroqBuilder } from "../groq-builder";
import type { QueryConfig } from "./schema-types";

/* eslint-disable @typescript-eslint/no-explicit-any */

Expand Down Expand Up @@ -58,6 +58,34 @@ export type ParserFunctionMaybe<
TOutput = any
> = null | ParserFunction<TInput, TOutput>;

// Not used at runtime, just used to infer types:
export declare const GroqBuilderResultType: unique symbol;
export declare const GroqBuilderConfigType: unique symbol;

/**
* IGroqBuilder is the bare minimum GroqBuilder, used to prevent circular references
* @internal
*/
export type IGroqBuilder<
TResult = unknown,
TQueryConfig extends QueryConfig = QueryConfig
> = {
/**
* Used to infer the Result types of a GroqBuilder.
* This symbol is not used at runtime.
* @internal
*/
readonly [GroqBuilderResultType]: TResult;
/**
* Used to infer the TQueryConfig types of a GroqBuilder.
* This symbol is not used at runtime
* @internal
*/
readonly [GroqBuilderConfigType]: TQueryConfig;
query: string;
parser: ParserFunction | null;
parse: ParserFunction;
};
/**
* Extracts the Result type from a GroqBuilder query
*/
Expand Down
3 changes: 1 addition & 2 deletions packages/groq-builder/src/validation/zod.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { expect, describe, it, expectTypeOf } from "vitest";
import { InferResultType } from "../index";
import { createGroqBuilderWithZod, InferResultType } from "../index";
import { SchemaConfig } from "../tests/schemas/nextjs-sanity-fe";
import { mock } from "../tests/mocks/nextjs-sanity-fe-mocks";
import { executeBuilder } from "../tests/mocks/executeQuery";
import { TypeMismatchError } from "../types/utils";
import { createGroqBuilderWithZod } from "../createGroqBuilderWithZod";

const q = createGroqBuilderWithZod<SchemaConfig>();
const qVariants = q.star.filterByType("variant");
Expand Down
Loading

0 comments on commit 94b8f3c

Please sign in to comment.