graphql-rate-limit-directive
Version:
Fixed window rate-limiting directive for GraphQL. Use to limit repeated requests to queries and mutations.
161 lines (160 loc) • 6.78 kB
TypeScript
import { GraphQLResolveInfo, GraphQLSchema } from 'graphql';
import { IRateLimiterOptions, RateLimiterAbstract, RateLimiterRes } from 'rate-limiter-flexible';
type MaybePromise<T> = Promise<T> | T;
/**
* Configure rate limit field behaviour.
*/
export type RateLimitArgs = {
/**
* Number of occurrences allowed over duration.
*/
limit: number;
/**
* Number of seconds before limit is reset.
*/
duration: number;
};
/**
* Override specific aspects of rate limit field behaviour.
*/
export type RateLimitExtensions<TContext> = {
/**
* Constructs a key to represent an operation on the field.
*/
keyGenerator?: RateLimitKeyGenerator<TContext>;
/**
* Calculate the number of points to consume.
*/
pointsCalculator?: RateLimitPointsCalculator<TContext>;
/**
* Behaviour when limit is exceeded.
*/
onLimit?: RateLimitOnLimit<TContext>;
/**
* If rate limiter information for request should be stored in context, how to record it.
*/
setState?: RateLimitSetState<TContext>;
};
export type RateLimitKeyGenerator<TContext> = (directiveArgs: RateLimitArgs, source: unknown, args: {
[key: string]: unknown;
}, context: TContext, info: GraphQLResolveInfo) => MaybePromise<string>;
export type RateLimitPointsCalculator<TContext> = (directiveArgs: RateLimitArgs, source: unknown, args: {
[key: string]: unknown;
}, context: TContext, info: GraphQLResolveInfo) => MaybePromise<number>;
export type RateLimitOnLimit<TContext> = (response: RateLimiterRes, directiveArgs: RateLimitArgs, source: unknown, args: {
[key: string]: unknown;
}, context: TContext, info: GraphQLResolveInfo) => MaybePromise<unknown>;
export type RateLimitSetState<TContext> = (response: RateLimiterRes, directiveArgs: RateLimitArgs, source: unknown, args: {
[key: string]: unknown;
}, context: TContext, info: GraphQLResolveInfo) => void;
/**
* Configure rate limit behaviour.
*/
export interface RateLimitOptions<TContext, TLimiterOptions extends IRateLimiterOptions> {
/**
* Name of the directive.
*/
name?: string;
/**
* Default value for argument limit.
*/
defaultLimit?: string;
/**
* Default value for argument duration.
*/
defaultDuration?: string;
/**
* Constructs a key to represent an operation on a field.
*/
keyGenerator?: RateLimitKeyGenerator<TContext>;
/**
* Calculate the number of points to consume.
*/
pointsCalculator?: RateLimitPointsCalculator<TContext>;
/**
* Behaviour when limit is exceeded.
*/
onLimit?: RateLimitOnLimit<TContext>;
/**
* If rate limiter information for request should be stored in context, how to record it.
*/
setState?: RateLimitSetState<TContext>;
/**
* An implementation of a limiter.
*/
limiterClass?: typeof RateLimiterAbstract;
/**
* Configuration to apply to created limiters.
*/
limiterOptions?: Pick<TLimiterOptions, Exclude<keyof TLimiterOptions, keyof {
points?: number;
duration?: number;
}>>;
}
/**
* Implementation of a rate limit schema directive.
*/
export interface RateLimitDirective {
/**
* Schema Definition Language (SDL) representation of the directive.
*/
rateLimitDirectiveTypeDefs: string;
/**
* Function to apply the directive's logic to the provided schema.
*/
rateLimitDirectiveTransformer: (schema: GraphQLSchema) => GraphQLSchema;
}
/**
* Convert milliseconds to seconds.
* @param duration Milliseconds.
*/
export declare function millisecondsToSeconds(duration: number): number;
/**
* Human readable string that uniquely identifies a schema element within a GraphQL Schema.
* @param info Holds field-specific information relevant to the current operation as well as the schema details.
*/
export declare function getSchemaCoordinate(info: GraphQLResolveInfo): string;
/**
* Get a value to uniquely identify a field in a schema.
* @param directiveArgs The arguments defined in the schema for the directive.
* @param source The previous result returned from the resolver on the parent field.
* @param args The arguments provided to the field in the GraphQL operation.
* @param context Contains per-request state shared by all resolvers in a particular operation.
* @param info Holds field-specific information relevant to the current operation as well as the schema details.
*/
export declare function defaultKeyGenerator<TContext>(directiveArgs: RateLimitArgs, source: unknown, args: {
[key: string]: unknown;
}, context: TContext, info: GraphQLResolveInfo): string;
/**
* Calculate the number of points to consume.
* @param directiveArgs The arguments defined in the schema for the directive.
* @param source The previous result returned from the resolver on the parent field.
* @param args The arguments provided to the field in the GraphQL operation.
* @param context Contains per-request state shared by all resolvers in a particular operation.
* @param info Holds field-specific information relevant to the current operation as well as the schema details.
*/
export declare function defaultPointsCalculator<TContext>(directiveArgs: RateLimitArgs, source: unknown, args: {
[key: string]: unknown;
}, context: TContext, info: GraphQLResolveInfo): number;
/**
* Raise a rate limit error when there are too many requests.
* @param response The current rate limit information for this field.
* @param directiveArgs The arguments defined in the schema for the directive.
* @param source The previous result returned from the resolver on the parent field.
* @param args The arguments provided to the field in the GraphQL operation.
* @param context Contains per-request state shared by all resolvers in a particular operation.
* @param info Holds field-specific information relevant to the current operation as well as the schema details.
*/
export declare function defaultOnLimit<TContext>(response: RateLimiterRes, directiveArgs: RateLimitArgs, source: unknown, args: {
[key: string]: unknown;
}, context: TContext, info: GraphQLResolveInfo): unknown;
/**
* Write directive state into context.
* @param name Key of rate limit state in context, likely the directive's name.
*/
export declare function defaultSetState<TContext>(name?: string): RateLimitSetState<TContext>;
/**
* Create an implementation of a rate limit directive.
*/
export declare function rateLimitDirective<TContext, TLimiterOptions extends IRateLimiterOptions = IRateLimiterOptions>({ name, defaultLimit, defaultDuration, keyGenerator, pointsCalculator, onLimit, setState, limiterClass, limiterOptions, }?: RateLimitOptions<TContext, TLimiterOptions>): RateLimitDirective;
export {};