GraphQL
Typed GraphQL operations for GraphQLGroup and GraphQLClient.make,
written by hand or generated by @effect/graphql-generator.
Includes the generator's lenient decoders, otherTypename and enumLiterals.
Constructors
Defines a mutation. Same shape as query.
Signature
declare const mutation: <Name extends string, Result extends Schema.Top, Variables extends Schema.Top | Schema.Struct.Fields = Schema.Struct<{}>>(name: Name, options: { readonly document: string | DocumentTemplate; readonly result: Result; readonly variables?: Variables;}) => Operation<"mutation", Name, Variables extends Schema.Struct.Fields ? Schema.Struct<Variables> : Variables, Result>Example A mutation
import { Schema } from "effect"import { GraphQL } from "effect/graphql"
const AddComment = GraphQL.mutation("AddComment", { document: "mutation AddComment($subjectId:ID!,$body:String!){addComment(input:{subjectId:$subjectId,body:$body}){clientMutationId}}", variables: { subjectId: Schema.String, body: Schema.String }, result: Schema.Struct({ addComment: Schema.NullOr(Schema.Struct({ clientMutationId: Schema.NullOr(Schema.String) })) })})
AddComment.kind // => "mutation"Defines a query. The client accepts decoded variables and encodes them
through their Schema, including custom scalar codecs. variables accepts
struct fields or a Schema; omit it for an operation without variables.
document accepts printed text or a DocumentTemplate, joined once
when the operation is defined.
Signature
declare const query: <Name extends string, Result extends Schema.Top, Variables extends Schema.Top | Schema.Struct.Fields = Schema.Struct<{}>>(name: Name, options: { readonly document: string | DocumentTemplate; readonly result: Result; readonly variables?: Variables;}) => Operation<"query", Name, Variables extends Schema.Struct.Fields ? Schema.Struct<Variables> : Variables, Result>Example A query with variables
import { Schema } from "effect"import { GraphQL } from "effect/graphql"
const RepoIssues = GraphQL.query("RepoIssues", { document: "query RepoIssues($owner:String!,$name:String!){repository(owner:$owner,name:$name){issues(first:10){nodes{number title}}}}", variables: { owner: Schema.String, name: Schema.String }, result: Schema.Struct({ repository: Schema.NullOr(Schema.Struct({ issues: Schema.Struct({ nodes: Schema.NullOr(Schema.Array(Schema.NullOr(Schema.Struct({ number: Schema.Int, title: Schema.String })))) }) })) })})
RepoIssues.kind // => "query"RepoIssues.name // => "RepoIssues"Defines a subscription. The client method for a subscription returns a
Stream of decoded events instead of an Effect.
Signature
declare const subscription: <Name extends string, Result extends Schema.Top, Variables extends Schema.Top | Schema.Struct.Fields = Schema.Struct<{}>>(name: Name, options: { readonly document: string | DocumentTemplate; readonly result: Result; readonly variables?: Variables;}) => Operation<"subscription", Name, Variables extends Schema.Struct.Fields ? Schema.Struct<Variables> : Variables, Result>Example A subscription
import { Schema } from "effect"import { GraphQL } from "effect/graphql"
const IssueUpdated = GraphQL.subscription("IssueUpdated", { document: "subscription IssueUpdated($id:ID!){issueUpdated(id:$id){title}}", variables: { id: Schema.String }, result: Schema.Struct({ issueUpdated: Schema.Struct({ title: Schema.String }) })})
IssueUpdated.kind // => "subscription"Guards
Models
DocumentTemplate
interfaceAn operation document split into the pieces needed to rename and alias it without a GraphQL parser. The generator emits one for every query and mutation.
Details
A body is a DocumentTemplate.Parts array: literal text at even
indices and, at odd indices, the variable names and fragment names that
would be renamed if the operation were repeated under a prefix. Joining the
pieces gives the printed document, which is what the operation sends.
A fragment whose body has a name in it is per-slice: it references a
variable, directly or through a fragment it spreads. Every other fragment is
shared.
Signature
interface DocumentTemplate { readonly directives?: Parts; readonly fragments: readonly Array<Fragment>; readonly selections: readonly Array<Selection>; readonly variables: readonly Array<Variable>;}The three kinds of GraphQL operation.
Signature
type Kind = "query" | "mutation" | "subscription"A named GraphQL document with variable and result schemas and middleware.
Variables are encoded before sending; results are decoded from data.
Signature
interface Operation<out K extends Kind, out Name extends string, out Variables extends Schema.Top, out Result extends Schema.Top, out Middleware = never> extends Pipeable { readonly "~effect/graphql/GraphQL": "~effect/graphql/GraphQL"; readonly "~middleware"?: Middleware; readonly document: string; readonly kind: K; readonly middlewares: readonly Array<AnyService>; readonly name: Name; readonly result: Result; readonly template: DocumentTemplate | undefined; readonly variables: Variables; middleware<M extends AnyService>(middleware: M): Operation<K, Name, Variables, Result, Middleware | M>;}Other
The pieces of a DocumentTemplate.
Schemas
The Schema for a GraphQL enum in a result position.
Details
It is typed as the declared literals but decodes any string, so a value the
server adds later does not fail the whole query. Inputs stay strict: the
generator uses Schema.Literals for enums in variables and input objects.
Signature
declare function enumLiterals<Literals extends readonly Array<string>>(literals: Literals): refine<Literals[number], String>Example An enum that tolerates new values
import { Schema } from "effect"import { GraphQL } from "effect/graphql"
const IssueState = GraphQL.enumLiterals(["OPEN", "CLOSED"])
Schema.decodeUnknownSync(IssueState)("OPEN") // => "OPEN"Schema.decodeUnknownSync(IssueState)("MERGED") // => "MERGED"Schema.is(IssueState)(42) // => falseThe __typename Schema for the "every other type" member of a generated
union.
Details
The type excludes selected names, allowing __typename narrowing. The
decoder accepts any other string, including types added by the server
later. Selected names are rejected so malformed selected results cannot
fall through to the catch-all member.
Signature
declare function otherTypename<All extends string>(): <Selected extends readonly Array<All>>(selected: Selected) => refine<Exclude<All, Selected[number]>, String>Example The catch-all member of a union
import { Schema } from "effect"import { GraphQL } from "effect/graphql"
type Node = "Issue" | "PullRequest" | "Repository"
const OtherNode = Schema.Struct({ __typename: GraphQL.otherTypename<Node>()(["Issue"]), id: Schema.String})
Schema.decodeUnknownSync(OtherNode)({ __typename: "PullRequest", id: "1" }).__typename // => "PullRequest"Schema.decodeUnknownSync(OtherNode)({ __typename: "AddedLater", id: "2" }).__typename // => "AddedLater"Schema.is(OtherNode)({ __typename: "Issue", id: "3" }) // => falseUtility Types
AddMiddleware
typeThe type of an operation after attaching middleware M.
Signature
type AddMiddleware<Op, M> = Op extends Operation<infer K, infer N, infer V, infer R, infer Old> ? Operation<K, N, V, R, Old | M> : neverAny operation, with its type parameters erased.
Signature
type Any = Operation<Kind, string, Schema.Top, Schema.Top, any>The error type of a client method for an operation: GraphQLClientError
plus the errors of every attached middleware.
Signature
type Error<Op extends Any> = GraphQLClientError | GraphQLMiddleware.Error<Middleware<Op>>Middleware
typeExtracts the union of middleware attached to an operation.
Signature
type Middleware<Op> = Op extends Operation<any, any, any, any, infer M> ? M : neverThe decoded result type of an operation.
Signature
type Result<Op extends Any> = Op["result"]["Type"]The services a client method for an operation requires: the Schemas' encoding and decoding services plus the requirements of every attached middleware.
Signature
type Services<Op extends Any> = Op["variables"]["EncodingServices"] | Op["result"]["DecodingServices"] | GraphQLMiddleware.Requires<Middleware<Op>>The decoded variables type of an operation, which is what a client method takes.
Signature
type Variables<Op extends Any> = Op["variables"]["Type"]