graphql-yoga
Version:
191 lines (190 loc) • 8.51 kB
text/typescript
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>;