UNPKG

graphql-yoga

Version:
191 lines (190 loc) • 8.51 kB
import type { ExecutionResult } from 'graphql'; import type { GetEnvelopedFn, PromiseOrValue } from '@envelop/core'; import { type Logger, type LogLevel } from '@graphql-hive/logger'; import type { MaybePromise } from '@whatwg-node/promise-helpers'; import type { ServerAdapter, ServerAdapterBaseObject, ServerAdapterInitialContext, ServerAdapterOptions, ServerAdapterRequestHandler } from '@whatwg-node/server'; import { useCORS } from '@whatwg-node/server'; import type { ParamsHandler, Plugin } from './plugins/types.cjs'; import type { GraphiQLOptions, GraphiQLOptionsOrFactory } from './plugins/use-graphiql.cjs'; import type { ParserAndValidationCacheOptions } from './plugins/use-parser-and-validation-cache.cjs'; import type { RequestIdOptions } from './plugins/use-request-id.cjs'; import type { YogaSchemaDefinition } from './plugins/use-schema.cjs'; import type { LandingPageRenderer } from './plugins/use-unhandled-route.cjs'; import type { FetchAPI, GraphQLParams, YogaConfigContext, YogaInitialContext, YogaMaskedErrorOpts } from './types.cjs'; /** * Configuration options for the server */ export type YogaServerOptions<TServerContext, TUserContext> = Omit<ServerAdapterOptions<TServerContext>, 'plugins'> & { /** * Enable, disable or implement a custom logger for logging. * * @default true * * @see https://the-guild.dev/graphql/yoga-server/docs/features/logging-and-debugging */ logging?: boolean | Logger | LogLevel | undefined; /** * Enable, disable or configure the request id. * * A request id the host integration already assigned to the native request object (e.g. * Fastify's `request.id`) is reused first, if there is one; otherwise, the `x-request-id` * header of the incoming request is used if present (see `trustHeader`); otherwise, one is * generated. It is added to the `log`ger available in the context as the `requestId` * attribute, and set on the outgoing response's headers. * * @default true */ requestId?: boolean | RequestIdOptions<TServerContext> | undefined; /** * Prevent leaking unexpected errors to the client. We highly recommend enabling this in production. * If you throw `EnvelopError`/`GraphQLError` within your GraphQL resolvers then that error will be sent back to the client. * * You can lean more about this here: * @see https://the-guild.dev/graphql/yoga-server/docs/features/error-masking * * @default true */ maskedErrors?: boolean | Partial<YogaMaskedErrorOpts> | undefined; /** * Context */ context?: ((initialContext: YogaInitialContext & TServerContext) => Promise<TUserContext> | TUserContext) | Promise<TUserContext> | TUserContext | undefined; cors?: Parameters<typeof useCORS>[0] | undefined; /** * GraphQL endpoint * So you need to define it explicitly if GraphQL API lives in a different path other than `/graphql` * * @default "/graphql" */ graphqlEndpoint?: string | undefined; /** * Readiness check endpoint * * @default "/health" */ healthCheckEndpoint?: string | undefined; /** * Whether the landing page should be shown. */ landingPage?: boolean | LandingPageRenderer | undefined; /** * GraphiQL options * * @default true */ graphiql?: GraphiQLOptionsOrFactory<TServerContext> | undefined; renderGraphiQL?: ((options: GraphiQLOptions) => PromiseOrValue<BodyInit>) | undefined; schema?: YogaSchemaDefinition<TServerContext, TUserContext> | undefined; /** * Envelop Plugins * @see https://envelop.dev/plugins */ plugins?: Array<Plugin<TUserContext & TServerContext & YogaInitialContext> | Plugin | {}> | undefined; parserAndValidationCache?: boolean | ParserAndValidationCacheOptions | undefined; fetchAPI?: Partial<Record<keyof FetchAPI, any>> | undefined; /** * GraphQL Multipart Request spec support * * @see https://github.com/jaydenseric/graphql-multipart-request-spec * * @default true */ multipart?: boolean | undefined; id?: string | undefined; /** * Limit the size (in bytes) of the incoming HTTP request body that will be read by the * built-in request parsers (JSON, GraphQL string, url-encoded and multipart). * * Requests whose `Content-Length` exceeds this value (or whose `Content-Length` is invalid) * are rejected with an HTTP 413/400 response before the body is read. Bodies are also counted * while streaming, so requests with a missing, wrong, or chunked-transfer-encoded body cannot * bypass the limit. * * Set to `false` to disable the limit. This is not recommended unless an upstream reverse * proxy already enforces a body-size limit (e.g. nginx's `client_max_body_size`). * * @default 25_000_000 (25 MB) */ maxRequestBodySize?: number | false | undefined; /** * Batching RFC Support configuration * * @see https://github.com/graphql/graphql-over-http/blob/main/rfcs/Batching.md * * @default false */ batching?: BatchingOptions | undefined; /** * By default, GraphQL Yoga does not allow parameters in the request body except `query`, `variables`, `extensions`, and `operationName`. * * This option allows you to specify additional parameters that are allowed in the request body. * * @default [] * * @example ['doc_id', 'id'] */ extraParamNames?: string[] | undefined; /** * Allowed headers. Headers not part of this list will be striped out. */ allowedHeaders?: { /** Allowed headers for outgoing responses */ response?: string[] | undefined; /** Allowed headers for ingoing requests */ request?: string[] | undefined; }; }; export type BatchingOptions = boolean | { /** * You can limit the number of batched operations per request. * * @default 10 */ limit?: number; }; /** * Base class that can be extended to create a GraphQL server with any HTTP server framework. * @internal */ export declare class YogaServer<TServerContext extends Record<string, any>, TUserContext extends Record<string, any>> implements ServerAdapterBaseObject<TServerContext> { /** * Instance of envelop */ readonly getEnveloped: GetEnvelopedFn<TUserContext & TServerContext & YogaInitialContext>; log: Logger; fetchAPI: FetchAPI; protected plugins: Array<Plugin<TUserContext & TServerContext & YogaInitialContext, TServerContext, TUserContext>>; private instrumentation; private onRequestParseHooks; private onParamsHooks; private onExecutionResultHooks; private onResultProcessHooks; private maskedErrorsOpts; private id; /** * Operation type resolved for a given request, read back for the per-request summary log. */ private operationTypeByContext; private _graphqlEndpoint; private _graphqlEndpointURLPattern; readonly version = "__YOGA_VERSION__"; constructor(options?: YogaServerOptions<TServerContext, TUserContext>); get graphqlEndpoint(): string; set graphqlEndpoint(endpoint: string); private getUrlPatternForGraphQLEndpoint; handleParams: ParamsHandler<TServerContext>; getResultForParams: ({ params, request, }: { params: GraphQLParams; request: Request; }, context: TServerContext, fetchAPI?: FetchAPI) => PromiseOrValue<ExecutionResult | AsyncIterable<ExecutionResult> | undefined>; parseRequest: (request: Request, serverContext: TServerContext & ServerAdapterInitialContext & YogaConfigContext, fetchAPI?: FetchAPI) => MaybePromise<{ requestParserResult: GraphQLParams<Record<string, any>, Record<string, any>> | GraphQLParams<Record<string, any>, Record<string, any>>[]; response?: never; } | { requestParserResult?: never; response: Response; }>; handle: ServerAdapterRequestHandler<TServerContext>; } export type YogaServerInstance<TServerContext extends Record<string, any>, TUserContext extends Record<string, any>> = ServerAdapter<TServerContext, YogaServer<TServerContext, TUserContext>>; export declare function createYoga<TServerContext extends Record<string, any> = {}, TUserContext extends Record<string, any> = {}>(options: YogaServerOptions<TServerContext, TUserContext>): YogaServerInstance<TServerContext, TUserContext>;