|
| 1 | +import { GraphQLResolveInfo, GraphQLSchema } from 'graphql'; |
| 2 | +import { IResolvers, PruneSchemaOptions, TypeSource, SchemaMapper } from '@graphql-tools/utils'; |
| 3 | +import { IMocks } from '@graphql-tools/mock'; |
| 4 | +import { SubschemaConfig } from '@graphql-tools/delegate'; |
| 5 | +export type ResolverFunction = (_: any, args: any, ctx: any, info: GraphQLResolveInfo) => any; |
| 6 | +export interface IGraphQLComponentConfigObject { |
| 7 | + component: IGraphQLComponent; |
| 8 | + configuration?: SubschemaConfig; |
| 9 | +} |
| 10 | +export interface ComponentContext extends Record<string, unknown> { |
| 11 | + dataSources: DataSourceMap; |
| 12 | +} |
| 13 | +export type ContextFunction = ((context: Record<string, unknown>) => any); |
| 14 | +export interface IDataSource { |
| 15 | + name?: string; |
| 16 | + [key: string | symbol]: any; |
| 17 | +} |
| 18 | +/** |
| 19 | + * Type for implementing data sources |
| 20 | + * When defining a data source class, methods should accept context as their first parameter |
| 21 | + * @example |
| 22 | + * class MyDataSource { |
| 23 | + * name = 'MyDataSource'; |
| 24 | + * |
| 25 | + * // Context is required as first parameter when implementing |
| 26 | + * getData(context: ComponentContext, id: string) { |
| 27 | + * return { id }; |
| 28 | + * } |
| 29 | + * } |
| 30 | + */ |
| 31 | +export type DataSourceDefinition<T> = { |
| 32 | + [P in keyof T]: T[P] extends Function ? (context: ComponentContext, ...args: any[]) => any : T[P]; |
| 33 | +}; |
| 34 | +/** |
| 35 | + * Type for consuming data sources in resolvers |
| 36 | + * When using a data source method, the context is automatically injected |
| 37 | + * @example |
| 38 | + * // In a resolver: |
| 39 | + * Query: { |
| 40 | + * getData(_, { id }, context) { |
| 41 | + * // Context is automatically injected, so you don't pass it |
| 42 | + * return context.dataSources.MyDataSource.getData(id); |
| 43 | + * } |
| 44 | + * } |
| 45 | + */ |
| 46 | +export type DataSource<T> = { |
| 47 | + [P in keyof T]: T[P] extends (context: ComponentContext, ...p: infer P) => infer R ? (...p: P) => R : T[P]; |
| 48 | +}; |
| 49 | +export type DataSourceMap = { |
| 50 | + [key: string]: IDataSource; |
| 51 | +}; |
| 52 | +export type DataSourceInjectionFunction = ((context: Record<string, unknown>) => DataSourceMap); |
| 53 | +export interface IContextConfig { |
| 54 | + namespace: string; |
| 55 | + factory: ContextFunction; |
| 56 | +} |
| 57 | +export interface IContextWrapper extends ContextFunction { |
| 58 | + use: (name: string | ContextFunction | null, fn?: ContextFunction | string) => void; |
| 59 | +} |
| 60 | +export interface IGraphQLComponentOptions<TContextType extends ComponentContext = ComponentContext> { |
| 61 | + types?: TypeSource; |
| 62 | + resolvers?: IResolvers<any, TContextType>; |
| 63 | + mocks?: boolean | IMocks; |
| 64 | + imports?: (IGraphQLComponent | IGraphQLComponentConfigObject)[]; |
| 65 | + context?: IContextConfig; |
| 66 | + dataSources?: IDataSource[]; |
| 67 | + dataSourceOverrides?: IDataSource[]; |
| 68 | + pruneSchema?: boolean; |
| 69 | + pruneSchemaOptions?: PruneSchemaOptions; |
| 70 | + federation?: boolean; |
| 71 | + transforms?: SchemaMapper[]; |
| 72 | +} |
| 73 | +export interface IGraphQLComponent<TContextType extends ComponentContext = ComponentContext> { |
| 74 | + readonly name: string; |
| 75 | + readonly schema: GraphQLSchema; |
| 76 | + readonly context: IContextWrapper; |
| 77 | + readonly types: TypeSource; |
| 78 | + readonly resolvers: IResolvers<any, TContextType>; |
| 79 | + readonly imports?: (IGraphQLComponent | IGraphQLComponentConfigObject)[]; |
| 80 | + readonly dataSources?: IDataSource[]; |
| 81 | + readonly dataSourceOverrides?: IDataSource[]; |
| 82 | + federation?: boolean; |
| 83 | +} |
| 84 | +/** |
| 85 | + * GraphQLComponent class for building modular GraphQL schemas |
| 86 | + * @template TContextType - The type of the context object |
| 87 | + * @implements {IGraphQLComponent} |
| 88 | + */ |
| 89 | +export default class GraphQLComponent<TContextType extends ComponentContext = ComponentContext> implements IGraphQLComponent<TContextType> { |
| 90 | + _schema: GraphQLSchema; |
| 91 | + _types: TypeSource; |
| 92 | + _resolvers: IResolvers<any, TContextType>; |
| 93 | + _mocks: boolean | IMocks; |
| 94 | + _imports: IGraphQLComponentConfigObject[]; |
| 95 | + _context: ContextFunction; |
| 96 | + _dataSources: IDataSource[]; |
| 97 | + _dataSourceOverrides: IDataSource[]; |
| 98 | + _pruneSchema: boolean; |
| 99 | + _pruneSchemaOptions: PruneSchemaOptions; |
| 100 | + _federation: boolean; |
| 101 | + _dataSourceContextInject: DataSourceInjectionFunction; |
| 102 | + _transforms: SchemaMapper[]; |
| 103 | + private _transformedSchema; |
| 104 | + constructor({ types, resolvers, mocks, imports, context, dataSources, dataSourceOverrides, pruneSchema, pruneSchemaOptions, federation, transforms }: IGraphQLComponentOptions); |
| 105 | + get context(): IContextWrapper; |
| 106 | + get name(): string; |
| 107 | + get schema(): GraphQLSchema; |
| 108 | + get types(): TypeSource; |
| 109 | + get resolvers(): IResolvers<any, TContextType>; |
| 110 | + get imports(): IGraphQLComponentConfigObject[]; |
| 111 | + get dataSources(): IDataSource[]; |
| 112 | + get dataSourceOverrides(): IDataSource[]; |
| 113 | + set federation(flag: boolean); |
| 114 | + get federation(): boolean; |
| 115 | + dispose(): void; |
| 116 | + private transformSchema; |
| 117 | + private validateConfig; |
| 118 | +} |
0 commit comments