From 518f17f1d9849e92dcac2efb92fba5d430bb4b94 Mon Sep 17 00:00:00 2001 From: marcus-sa Date: Tue, 23 Jan 2024 18:12:45 +0100 Subject: [PATCH] feat(apollo,yoga,core): use graphql child injector context as graphql context --- .../apollo/src/lib/apollo-graphql-driver.ts | 4 ++-- packages/core/src/index.ts | 1 - packages/core/src/lib/decorators.spec.ts | 22 +++++++++---------- packages/core/src/lib/graphql-http-context.ts | 8 ------- packages/core/src/lib/schema-builder.ts | 13 ++++++----- packages/core/src/lib/types-builder.ts | 20 ++++++++--------- packages/core/src/lib/types.ts | 5 +++++ packages/yoga/src/lib/yoga-graphql-driver.ts | 4 ++-- 8 files changed, 37 insertions(+), 40 deletions(-) delete mode 100644 packages/core/src/lib/graphql-http-context.ts diff --git a/packages/apollo/src/lib/apollo-graphql-driver.ts b/packages/apollo/src/lib/apollo-graphql-driver.ts index 14e7116..bc99d4d 100644 --- a/packages/apollo/src/lib/apollo-graphql-driver.ts +++ b/packages/apollo/src/lib/apollo-graphql-driver.ts @@ -5,7 +5,7 @@ import { InjectorContext } from '@deepkit/injector'; import { GraphQLSchema } from 'graphql'; import { WebWorkerFactory, ApplicationServer } from '@deepkit/framework'; import { HttpBadRequestError, httpWorkflow } from '@deepkit/http'; -import { Driver } from '@deepkit-graphql/core'; +import { Driver, GraphQLContext } from '@deepkit-graphql/core'; import { ApolloGraphQLConfig } from './apollo-graphql-config'; import { ApolloServerPlugins } from './plugins'; @@ -53,7 +53,7 @@ export class ApolloDriver extends Driver { const response = await this.server!.executeHTTPGraphQLRequest({ httpGraphQLRequest, - context: async () => injectorContext, + context: async (): Promise => ({ injectorContext }), }); if (!response) { throw new HttpBadRequestError(JSON.stringify(httpGraphQLRequest)); diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 8bc54af..5ff26e7 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -2,7 +2,6 @@ export * from './lib/decorators'; export * from './lib/types-builder'; export * from './lib/schema-builder'; export * from './lib/graphql.module'; -export * from './lib/graphql-http-context'; export * from './lib/driver'; export * from './lib/types'; export * from './lib/resolvers'; diff --git a/packages/core/src/lib/decorators.spec.ts b/packages/core/src/lib/decorators.spec.ts index 80623e1..8a5ced9 100644 --- a/packages/core/src/lib/decorators.spec.ts +++ b/packages/core/src/lib/decorators.spec.ts @@ -79,7 +79,7 @@ test('middleware errors', async () => { await executeGraphQL({ schema, - contextValue: injectorContext, + contextValue: { injectorContext }, source: `{ get }`, }); @@ -124,7 +124,7 @@ test('resolver middleware is invoked', async () => { await executeGraphQL({ schema, - contextValue: injectorContext, + contextValue: { injectorContext }, source: `{ get }`, }); @@ -169,7 +169,7 @@ test('query middleware is invoked', async () => { await executeGraphQL({ schema, - contextValue: injectorContext, + contextValue: { injectorContext }, source: `{ get }`, }); @@ -214,7 +214,7 @@ test('mutation middleware is invoked', async () => { await executeGraphQL({ schema, - contextValue: injectorContext, + contextValue: { injectorContext }, source: `mutation { create }`, }); @@ -259,7 +259,7 @@ test('subscription middleware is invoked', async () => { await executeGraphQL({ schema, - contextValue: injectorContext, + contextValue: { injectorContext }, source: `subscription { create }`, }); @@ -298,7 +298,7 @@ test('mutation', async () => { await expect( executeGraphQL({ schema, - contextValue: injectorContext, + contextValue: { injectorContext }, source: `mutation { createUser(data: { username: "Test" }) { id } }`, }), ).resolves.toMatchSnapshot(); @@ -329,7 +329,7 @@ test('query', async () => { await expect( executeGraphQL({ schema, - contextValue: injectorContext, + contextValue: { injectorContext }, source: `{ getUser(id: 1) { id } }`, rootValue: {}, }), @@ -364,7 +364,7 @@ test('mutation args validation', async () => { await expect( executeGraphQL({ - contextValue: injectorContext, + contextValue: { injectorContext }, source: `mutation { createUser(data: { username: "Test" }) { username } }`, schema, }), @@ -403,7 +403,7 @@ test.skip('Context', async () => { await expect( executeGraphQL({ - contextValue: injectorContext, + contextValue: { injectorContext }, source: ` { info { @@ -468,7 +468,7 @@ describe('resolveField', () => { await expect( executeGraphQL({ schema, - contextValue: injectorContext, + contextValue: { injectorContext }, source: ` { getUser(id: "9f617521-b9c2-4ab9-a339-3c551c799027") { @@ -529,7 +529,7 @@ describe('resolveField', () => { await expect( executeGraphQL({ - contextValue: injectorContext, + contextValue: { injectorContext }, source: ` { getUser(id: "398cdf36-e3ac-475c-90aa-c70f99add874") { diff --git a/packages/core/src/lib/graphql-http-context.ts b/packages/core/src/lib/graphql-http-context.ts deleted file mode 100644 index 677de7b..0000000 --- a/packages/core/src/lib/graphql-http-context.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { HttpRequest, HttpResponse } from '@deepkit/http'; - -import { Context } from './types'; - -export type GraphQLHttpContext = Context<{ - readonly request: HttpRequest; - readonly response: HttpResponse; -}>; diff --git a/packages/core/src/lib/schema-builder.ts b/packages/core/src/lib/schema-builder.ts index e950dc2..d4d9c63 100644 --- a/packages/core/src/lib/schema-builder.ts +++ b/packages/core/src/lib/schema-builder.ts @@ -12,6 +12,7 @@ import { import { Resolvers } from './resolvers'; import { TypesBuilder } from './types-builder'; import { gqlClassDecorator } from './decorators'; +import { GraphQLContext } from './types'; export interface SchemaBuilderOptions { readonly inputTypes?: readonly Type[]; @@ -56,10 +57,10 @@ export class SchemaBuilder { generateMutationResolverFields(): GraphQLFieldConfigMap< unknown, - InjectorContext + GraphQLContext > { return [...this.resolvers].reduce< - GraphQLFieldConfigMap + GraphQLFieldConfigMap >( (fields, resolver) => ({ // TODO: validate that fields don't override each other @@ -72,10 +73,10 @@ export class SchemaBuilder { generateSubscriptionResolverFields(): GraphQLFieldConfigMap< unknown, - InjectorContext + GraphQLContext > { return [...this.resolvers].reduce< - GraphQLFieldConfigMap + GraphQLFieldConfigMap >( (fields, resolver) => ({ // TODO: validate that fields don't override each other @@ -88,10 +89,10 @@ export class SchemaBuilder { generateQueryResolverFields(): GraphQLFieldConfigMap< unknown, - InjectorContext + GraphQLContext > { return [...this.resolvers].reduce< - GraphQLFieldConfigMap + GraphQLFieldConfigMap >( (fields, resolver) => ({ // TODO: validate that fields don't override each other diff --git a/packages/core/src/lib/types-builder.ts b/packages/core/src/lib/types-builder.ts index 40b09e2..9cbbe5d 100644 --- a/packages/core/src/lib/types-builder.ts +++ b/packages/core/src/lib/types-builder.ts @@ -44,7 +44,7 @@ import { GraphQLUnionType, } from 'graphql'; -import { Context, GraphQLFields, Instance, InternalMiddleware } from './types'; +import { Context, GraphQLContext, GraphQLFields, Instance, InternalMiddleware } from './types'; import { typeResolvers } from './decorators'; import { Resolver, Resolvers } from './resolvers'; import { InvalidSubscriptionTypeError, TypeNameRequiredError } from './errors'; @@ -612,7 +612,7 @@ export class TypesBuilder { reflectionMethod: ReflectionMethod, middlewares: readonly InternalMiddleware[], type: 'query' | 'mutation' | 'subscription' | 'resolveField', - ): GraphQLFieldResolver { + ): GraphQLFieldResolver { const resolve = (injectorContext: InjectorContext) => { const instance = injectorContext.get( resolver.controller, @@ -670,7 +670,7 @@ export class TypesBuilder { returnType, ); - return async (parent, _args, injectorContext) => { + return async (parent, _args, { injectorContext }: GraphQLContext) => { const args = deserializeArgs(_args, { loosely: false }) as Record; const argsValidationErrors = validateArgs(args); if (argsValidationErrors.length) { @@ -734,14 +734,14 @@ export class TypesBuilder { generateSubscriptionResolverFields( resolver: Resolver, - ): GraphQLFieldConfigMap { + ): GraphQLFieldConfigMap { const metadata = getClassDecoratorMetadata(resolver.controller); const resolverType = reflect(resolver.controller); const reflectionClass = ReflectionClass.from(resolverType); const fields = new Map< string, - GraphQLFieldConfig + GraphQLFieldConfig >(); // eslint-disable-next-line functional/no-loop-statement @@ -775,14 +775,14 @@ export class TypesBuilder { generateMutationResolverFields( resolver: Resolver, - ): GraphQLFieldConfigMap { + ): GraphQLFieldConfigMap { const metadata = getClassDecoratorMetadata(resolver.controller); const resolverType = reflect(resolver.controller); const reflectionClass = ReflectionClass.from(resolverType); const fields = new Map< string, - GraphQLFieldConfig + GraphQLFieldConfig >(); // eslint-disable-next-line functional/no-loop-statement @@ -817,7 +817,7 @@ export class TypesBuilder { generateFieldResolver( resolver: Resolver, fieldName: string, - ): Pick, 'args' | 'resolve'> { + ): Pick, 'args' | 'resolve'> { const metadata = getClassDecoratorMetadata(resolver.controller); const resolverType = reflect(resolver.controller); const reflectionClass = ReflectionClass.from(resolverType); @@ -852,14 +852,14 @@ export class TypesBuilder { generateQueryResolverFields( resolver: Resolver, - ): GraphQLFieldConfigMap { + ): GraphQLFieldConfigMap { const metadata = getClassDecoratorMetadata(resolver.controller); const resolverType = reflect(resolver.controller); const reflectionClass = ReflectionClass.from(resolverType); const fields = new Map< string, - GraphQLFieldConfig + GraphQLFieldConfig >(); // eslint-disable-next-line functional/no-loop-statement diff --git a/packages/core/src/lib/types.ts b/packages/core/src/lib/types.ts index b3af404..5009b7c 100644 --- a/packages/core/src/lib/types.ts +++ b/packages/core/src/lib/types.ts @@ -1,5 +1,6 @@ import { ClassType, AbstractClassType } from '@deepkit/core'; import { TypeAnnotation } from '@deepkit/type'; +import { InjectorContext } from '@deepkit/injector'; export type GraphQLFields = Record; @@ -29,3 +30,7 @@ export type GraphQLMiddlewareFn = ( export type InternalMiddleware = | ClassType | GraphQLMiddlewareFn; + +export interface GraphQLContext { + readonly injectorContext: InjectorContext; +} diff --git a/packages/yoga/src/lib/yoga-graphql-driver.ts b/packages/yoga/src/lib/yoga-graphql-driver.ts index 5ded794..cf3edaa 100644 --- a/packages/yoga/src/lib/yoga-graphql-driver.ts +++ b/packages/yoga/src/lib/yoga-graphql-driver.ts @@ -1,7 +1,7 @@ import { GraphQLSchema } from 'graphql'; import { WebWorkerFactory, ApplicationServer } from '@deepkit/framework'; import { httpWorkflow } from '@deepkit/http'; -import { Driver } from '@deepkit-graphql/core'; +import { Driver, GraphQLContext } from '@deepkit-graphql/core'; import { createYoga, YogaServerInstance } from 'graphql-yoga'; import { InjectorContext } from '@deepkit/injector'; import { Logger } from '@deepkit/logger'; @@ -29,7 +29,7 @@ export class YogaDriver extends Driver { ): Promise { if (!event.request.method || !this.server) return; - await this.server.handle(event.request, event.response, injectorContext); + await this.server.handle(event.request, event.response, { injectorContext }); } async start(schema: GraphQLSchema): Promise {