| /** |
| * This module exports modified versions of the GraphQL types from the `graphql` |
| * package that add more type-safety but are still at runtime exactly the same |
| * as the original types. Some of the constructors |
| * |
| * @module |
| */ |
| import { |
| GraphQLArgumentExtensions, |
| GraphQLEnumType, |
| type GraphQLEnumTypeConfig, |
| type GraphQLEnumValueConfig, |
| GraphQLFieldExtensions, |
| GraphQLInputField, |
| GraphQLInputFieldExtensions, |
| GraphQLInputObjectType, |
| type GraphQLInputObjectTypeConfig, |
| GraphQLInterfaceType, |
| GraphQLInterfaceTypeConfig, |
| GraphQLList, |
| GraphQLNonNull, |
| GraphQLObjectType, |
| GraphQLObjectTypeConfig, |
| GraphQLResolveInfo, |
| GraphQLScalarType, |
| type GraphQLTypeResolver, |
| GraphQLUnionType, |
| type GraphQLUnionTypeConfig, |
| type FieldDefinitionNode, |
| type InputValueDefinitionNode, |
| } from "graphql"; |
| import type { g } from "./g-for-doc-references.js"; |
|
|
| type Maybe<T> = T | null | undefined; |
|
|
| export type GNullableOutputType<Context> = |
| | GScalarType |
| | GObjectType<any, Context> |
| | GInterfaceType<any, any, Context> |
| | GUnionType<any, Context> |
| | GEnumType<Record<string, unknown>> |
| | GList<GOutputType<Context>>; |
|
|
| export type GOutputType<Context> = |
| | GNullableOutputType<Context> |
| | GNonNull<GNullableOutputType<Context>>; |
|
|
| export type GNullableInputType = |
| | GScalarType |
| | GEnumType<Record<string, unknown>> |
| | GInputObjectType<any, boolean> |
| | GList<GInputType>; |
|
|
| export type GInputType = GNullableInputType | GNonNull<GNullableInputType>; |
|
|
| export type GNullableType<Context> = |
| | GNullableOutputType<Context> |
| | GNullableInputType; |
|
|
| export type GType<Context> = GOutputType<Context> | GInputType; |
|
|
| export type GFieldResolver< |
| Source, |
| Args extends Record<string, GArg<GInputType>>, |
| Type extends GOutputType<Context>, |
| Context, |
| > = ( |
| source: Source, |
| args: InferValueFromArgs<Args>, |
| context: Context, |
| info: GraphQLResolveInfo |
| ) => InferValueFromOutputType<Type>; |
|
|
| type InferValueFromOutputTypeWithoutAddingNull<Type extends GOutputType<any>> = |
| Type extends GraphQLScalarType<infer Value> |
| ? Value |
| : Type extends GraphQLEnumType |
| ? Type extends GEnumType<infer Values> |
| ? Values[keyof Values] |
| : never |
| : Type extends GList<infer Value extends GOutputType<any>> |
| ? // the `object` bit is here because graphql checks `typeof maybeIterable === 'object'` |
| // which means that things like `string` won't be allowed |
| // (which is probably a good thing because returning a string from a resolver that needs |
| // a graphql list of strings is almost definitely not what you want and if it is, use Array.from) |
| // sadly functions that are iterables will be allowed by this type but not allowed by graphql-js |
| // (though tbh, i think the chance of that causing problems is quite low) |
| object & Iterable<InferValueFromOutputType<Value>> |
| : Type extends GraphQLObjectType<infer Source, any> |
| ? Source |
| : Type extends GraphQLUnionType | GraphQLInterfaceType |
| ? Type extends |
| | GUnionType<infer Source, any> |
| | GInterfaceType<infer Source, any, any> |
| ? Source |
| : unknown |
| : never; |
|
|
| export type InferValueFromOutputType<Type extends GOutputType<any>> = |
| MaybePromise< |
| Type extends GNonNull<infer Value extends GNullableOutputType<any>> |
| ? InferValueFromOutputTypeWithoutAddingNull<Value> |
| : InferValueFromOutputTypeWithoutAddingNull<Type> | null | undefined |
| >; |
|
|
| type MaybePromise<T> = Promise<T> | T; |
|
|
| type InferValueFromNullableInputType<Type extends GInputType> = |
| Type extends GraphQLScalarType<infer Value, any> |
| ? Value |
| : Type extends GraphQLEnumType |
| ? Type extends GEnumType<infer Values> |
| ? Values[keyof Values] |
| : unknown |
| : Type extends GList<infer Value extends GInputType> |
| ? InferValueFromInputType<Value>[] |
| : Type extends GraphQLInputObjectType |
| ? Type extends GInputObjectType<infer Fields, infer IsOneOf> |
| ? IsOneOf extends true |
| ? InferValueForOneOf<Fields> |
| : InferValueFromArgs<Fields> |
| : Record<string, unknown> |
| : never; |
|
|
| type InferValueForOneOf< |
| T extends { [key: string]: { type: GInputType } }, |
| Key extends keyof T = keyof T, |
| > = Flatten< |
| Key extends unknown |
| ? { |
| readonly [K in Key]: InferValueFromNullableInputType<T[K]["type"]>; |
| } & { |
| readonly [K in Exclude<keyof T, Key>]?: never; |
| } |
| : never |
| >; |
|
|
| export type InferValueFromArgs<Args extends Record<string, GArg<GInputType>>> = |
| { |
| readonly [Key in keyof Args]: InferValueFromArg<Args[Key]>; |
| } & {}; |
|
|
| export type InferValueFromArg<Arg extends GArg<GInputType>> = |
| // the distribution technically only needs to be around the AddUndefined |
| // but having it here instead of inside the union |
| // means that TypeScript will print the resulting type |
| // when you use it rather than keep the alias and |
| // the resulting type is generally far more readable |
| Arg extends unknown |
| ? |
| | InferValueFromInputType<Arg["type"]> |
| | AddUndefined<Arg["type"], Arg["defaultValue"]> |
| : never; |
|
|
| type AddUndefined<TInputType extends GInputType, DefaultValue> = |
| TInputType extends GNonNull<any> ? never : DefaultValue & undefined; |
|
|
| export type InferValueFromInputType<Type extends GInputType> = |
| Type extends GNonNull<infer Value extends GNullableInputType> |
| ? InferValueFromNullableInputType<Value> |
| : InferValueFromNullableInputType<Type> | null; |
|
|
| /** |
| * A GraphQL output field for an {@link GObjectType object type} which should be |
| * created using {@link g.field}. |
| */ |
| export type GField< |
| Source, |
| Args extends { [Key in keyof Args]: GArg<GInputType> }, |
| Type extends GOutputType<Context>, |
| SourceAtKey, |
| Context, |
| > = { |
| args?: Args; |
| type: Type; |
| resolve?: GFieldResolver<Source, Args, Type, Context>; |
| description?: Maybe<string>; |
| deprecationReason?: Maybe<string>; |
| extensions?: Maybe<Readonly<GraphQLFieldExtensions<any, Context>>>; |
| astNode?: Maybe<FieldDefinitionNode>; |
| __missingResolve: undefined | ((arg: SourceAtKey) => void); |
| }; |
|
|
| /** |
| * A GraphQL object type. This should generally be constructed with |
| * {@link g.object}. |
| * |
| * Note this is an **output** type, if you want an input object, use |
| * {@link GInputObjectType}. |
| * |
| * If you use the `GObjectType` constructor directly, all fields will need |
| * explicit resolvers so you should use `g.object` instead. |
| */ |
| export class GObjectType<Source, Context> extends GraphQLObjectType< |
| Source, |
| Context |
| > { |
| constructor( |
| config: Readonly< |
| GObjectTypeConfig< |
| Source, |
| Context, |
| Record<string, GField<Source, any, any, unknown, Context>>, |
| readonly GInterfaceType<Source, any, Context>[] |
| > |
| > |
| ); |
| } |
|
|
| export type GObjectTypeConfig< |
| Source, |
| Context, |
| Fields extends Record<string, GField<Source, any, any, any, Context>>, |
| Interfaces extends readonly GInterfaceType<Source, any, Context>[], |
| > = { |
| fields: Fields | (() => Fields); |
| interfaces?: [...Interfaces]; |
| } & Omit<GraphQLObjectTypeConfig<Source, Context>, "fields" | "interfaces">; |
|
|
| /** |
| * A GraphQL union type. This should generally be constructed with |
| * {@link g.union}. |
| * |
| * A union type represents an object that could be one of a list of types. Note |
| * it is similar to an {@link GInterfaceType} except that a union doesn't imply |
| * having a common set of fields among the member types. |
| * |
| * While this constructor will work, you should generally use `g.union` because |
| * you will need to explicitly provide the source type parameter as TypeScript |
| * is unable to infer it correctly. Note this is only required for this |
| * constructor, this is not required when using `g.union`. |
| */ |
| export class GUnionType<Source, Context> extends GraphQLUnionType { |
| constructor( |
| config: Readonly< |
| GUnionTypeConfig< |
| Source extends any ? GObjectType<Source, Context> : never, |
| Context |
| > |
| > |
| ); |
| resolveType: Maybe<GraphQLTypeResolver<Source, Context>>; |
| } |
|
|
| export type GUnionTypeConfig< |
| ObjectType extends GObjectType<any, Context>, |
| Context, |
| > = Flatten< |
| { |
| types: readonly ObjectType[] | (() => readonly ObjectType[]); |
| } & Omit< |
| GraphQLUnionTypeConfig< |
| ObjectType extends GObjectType<infer Source, Context> ? Source : never, |
| Context |
| >, |
| "types" |
| > |
| >; |
|
|
| export type GInterfaceField< |
| Args extends Record<string, GArg<GInputType>>, |
| Type extends GOutputType<Context>, |
| Context, |
| > = { |
| description?: Maybe<string>; |
| type: Type; |
| args?: Args; |
| deprecationReason?: Maybe<string>; |
| extensions?: Maybe<Readonly<GraphQLFieldExtensions<any, Context>>>; |
| astNode?: Maybe<FieldDefinitionNode>; |
| }; |
|
|
| /** |
| * A GraphQL interface type that can be implemented by other |
| * {@link GObjectType GraphQL object} and interface types. This should generally |
| * be constructed with {@link g.interface}. |
| * |
| * If you use the `GInterfaceType` constructor directly, all fields will need |
| * explicit resolvers so you should use `g.interface` instead. |
| */ |
| export class GInterfaceType< |
| Source, |
| Fields extends Record< |
| string, |
| GInterfaceField<any, GOutputType<Context>, Context> |
| >, |
| Context, |
| > extends GraphQLInterfaceType { |
| declare resolveType: Maybe<GraphQLTypeResolver<Source, Context>>; |
| constructor( |
| config: Readonly< |
| GInterfaceTypeConfig< |
| Source, |
| Fields, |
| readonly GInterfaceType<Source, {}, Context>[], |
| Context |
| > |
| > |
| ); |
| toConfig(): Omit<ReturnType<GraphQLInterfaceType["toConfig"]>, "fields"> & { |
| fields: Fields; |
| }; |
| } |
|
|
| export type GInterfaceTypeConfig< |
| Source, |
| Fields extends Record< |
| string, |
| GInterfaceField<any, GOutputType<Context>, Context> |
| >, |
| Interfaces extends readonly GInterfaceType<Source, any, Context>[], |
| Context, |
| > = Flatten< |
| { |
| fields: Fields | (() => Fields); |
| interfaces?: [...Interfaces]; |
| } & Omit<GraphQLInterfaceTypeConfig<Source, Context>, "interfaces" | "fields"> |
| >; |
|
|
| /** |
| * A GraphQL argument. These should be created with {@link g.arg} |
| * |
| * Args can can be used as arguments on output fields: |
| * |
| * ```ts |
| * g.field({ |
| * type: g.String, |
| * args: { |
| * something: g.arg({ type: g.String }), |
| * }, |
| * resolve(source, { something }) { |
| * return something || somethingElse; |
| * }, |
| * }); |
| * // == |
| * graphql`fieldName(something: String): String`; |
| * ``` |
| * |
| * Or as fields on input objects: |
| * |
| * ```ts |
| * g.inputObject({ |
| * name: "Something", |
| * fields: { |
| * something: g.arg({ type: g.String }), |
| * }, |
| * }); |
| * // == |
| * graphql` |
| * input Something { |
| * something: String |
| * } |
| * `; |
| * ``` |
| * |
| * When the type of an arg is {@link GNonNull non-null}, the value will always |
| * exist. |
| * |
| * ```ts |
| * g.field({ |
| * type: g.String, |
| * args: { |
| * something: g.arg({ type: g.nonNull(g.String) }), |
| * }, |
| * resolve(source, { something }) { |
| * // `something` will always be a string |
| * return something; |
| * }, |
| * }); |
| * // == |
| * graphql`fieldName(something: String!): String`; |
| * ``` |
| */ |
| export type GArg< |
| Type extends GInputType, |
| HasDefaultValue extends boolean = boolean, |
| > = { |
| type: Type; |
| defaultValue: { |
| true: {} | null; |
| false: undefined; |
| }[`${HasDefaultValue}`]; |
| description?: Maybe<string>; |
| deprecationReason?: Maybe<string>; |
| extensions?: Maybe<GraphQLInputFieldExtensions & GraphQLArgumentExtensions>; |
| astNode?: Maybe<InputValueDefinitionNode>; |
| }; |
|
|
| export type GInputObjectTypeConfig< |
| Fields extends { |
| [key: string]: IsOneOf extends true |
| ? GArg<GNullableInputType, false> |
| : GArg<GInputType>; |
| }, |
| IsOneOf extends boolean = false, |
| > = Flatten< |
| Omit<GraphQLInputObjectTypeConfig, "fields"> & { |
| fields: Fields | (() => Fields); |
| isOneOf?: IsOneOf; |
| } |
| > & |
| (true extends IsOneOf ? { isOneOf: unknown } : unknown); |
|
|
| /** |
| * A GraphQL input object type. This should generally be constructed with |
| * {@link g.inputObject}. |
| * |
| * Unlike some other constructors in this module, this constructor functions |
| * exactly the same as it's counterpart `g.inputObject` so it is safe to use |
| * directly if desired. |
| */ |
| export class GInputObjectType< |
| Fields extends { |
| [key: string]: IsOneOf extends true |
| ? GArg<GNullableInputType, false> |
| : GArg<GInputType>; |
| }, |
| IsOneOf extends boolean = false, |
| > extends GraphQLInputObjectType { |
| isOneOf: IsOneOf; |
| constructor(config: Readonly<GInputObjectTypeConfig<Fields, IsOneOf>>); |
| getFields(): { |
| [K in keyof Fields]: GraphQLInputField & { |
| type: Fields[K]["type"]; |
| defaultValue: Fields[K]["defaultValue"]; |
| }; |
| }; |
| } |
|
|
| export type GEnumValueConfig<Value> = GraphQLEnumValueConfig & { |
| value: Value; |
| }; |
|
|
| export type GEnumTypeConfig<Values extends { [key: string]: unknown }> = |
| Flatten< |
| { |
| values: { |
| [Name in keyof Values]: GEnumValueConfig<Values[Name]>; |
| }; |
| } & Omit<GraphQLEnumTypeConfig, "values"> |
| >; |
|
|
| /** |
| * A GraphQL enum type. This should generally be constructed with {@link g.enum}. |
| * |
| * Unlike some other constructors in this module, this constructor functions |
| * exactly the same as it's counterpart `g.enum` so it is safe to use directly |
| * if desired. |
| */ |
| export class GEnumType< |
| const Values extends { [key: string]: unknown }, |
| > extends GraphQLEnumType { |
| constructor(config: Readonly<GEnumTypeConfig<Values>>); |
| toConfig(): Omit<ReturnType<GraphQLEnumType["toConfig"]>, "values"> & { |
| values: { |
| [Name in keyof Values]: Partial<GEnumValueConfig<Values[Name]>>; |
| }; |
| }; |
| } |
|
|
| /** |
| * A GraphQL enum type. This should generally be constructed with |
| * {@link g.scalar}. |
| * |
| * Unlike some other constructors in this module, this constructor functions |
| * exactly the same as it's counterpart `g.scalar` so it is safe to use directly |
| * if desired. |
| * |
| * Also unlike some other types in this module, this type is exactly equivalent |
| * to the original {@link GraphQLScalarType `GraphQLScalarType`} type from the |
| * `graphql` package. |
| */ |
| export class GScalarType< |
| Internal = unknown, |
| External = Internal, |
| > extends GraphQLScalarType<Internal, External> {} |
|
|
| type Flatten<T> = { |
| [K in keyof T]: T[K]; |
| } & {}; |
|
|
| /** |
| * A GraphQL non-null type. This should generally be constructed with |
| * {@link g.nonNull}. |
| * |
| * Unlike some other constructors in this module, this constructor functions |
| * exactly the same as it's counterpart `g.nonNull` so it is safe to use |
| * directly if desired. |
| * |
| * Also unlike the named types in this module, the original |
| * {@link GraphQLNonNull `GraphQLNonNull`} type from the `graphql` package cannot |
| * be assigned to a variable of type `GNonNull`. Though `GNonNull` _is_ |
| * assignable to `GraphQLNonNull`. |
| * |
| * For example, the following code will not compile: |
| * |
| * ```ts |
| * const nonNull: GNonNull<GScalarType<string>> = new GraphQLNonNull( |
| * GraphQLString |
| * ); |
| * ``` |
| * |
| * But the following code will compile: |
| * |
| * ```ts |
| * const nonNull: GraphQLNonNull<GraphQLScalarType<string>> = new GNonNull( |
| * GraphQLString |
| * ); |
| * ``` |
| * |
| * This is due to the lack of a discriminating property between the |
| * `GraphQLNonNull` and `GraphQLList` types. |
| */ |
| export class GNonNull< |
| Of extends GNullableType<any>, |
| > extends GraphQLNonNull<Of> { |
| get [Symbol.toStringTag](): "GraphQLNonNull"; |
| } |
|
|
| /** |
| * A GraphQL list type. This should generally be constructed with {@link g.list}. |
| * |
| * Unlike some other constructors in this module, this constructor functions |
| * exactly the same as it's counterpart `g.list` so it is safe to use directly |
| * if desired. |
| * |
| * Also unlike the named types in this module, the original |
| * {@link GraphQLList `GraphQLList`} type from the `graphql` package cannot be |
| * assigned to a variable of type `GList`. Though `GList` _is_ assignable to |
| * `GraphQLList`. |
| * |
| * For example, the following code will not compile: |
| * |
| * ```ts |
| * const list: GList<GScalarType<string>> = new GraphQLList(GraphQLString); |
| * ``` |
| * |
| * But the following code will compile: |
| * |
| * ```ts |
| * const list: GraphQLList<GraphQLScalarType<string>> = new GList( |
| * GraphQLString |
| * ); |
| * ``` |
| * |
| * This is due to the lack of a discriminating property between the |
| * `GraphQLNonNull` and `GraphQLList` types. |
| */ |
| export class GList<Of extends GType<any>> extends GraphQLList<Of> { |
| get [Symbol.toStringTag](): "GraphQLList"; |
| } |
|
|
| export {}; |