Skip to content

Commit

Permalink
feat: provide another way of creating the formatError handler which e…
Browse files Browse the repository at this point in the history
…nables importing IoC dependencies
  • Loading branch information
stropitek committed Jan 9, 2024
1 parent 4a45139 commit b1ec50a
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 9 deletions.
19 changes: 19 additions & 0 deletions adonis-typings/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ declare module '@ioc:Zakodium/Apollo/Server' {

export type Upload = Promise<FileUpload>;

export abstract class GraphqlExceptionFormatter<
ContextType extends BaseContext,
> {
public abstract formatError: ApolloServerOptions<ContextType>['formatError'];
}

class ApolloServer {
public applyMiddleware(): void;
public getGraphqlHandler(): RouteHandler;
Expand Down Expand Up @@ -102,4 +108,17 @@ declare module '@ioc:Zakodium/Apollo/Server' {
'typeDefs' | 'resolvers'
>;
}

type ApolloServerUserOptions<ContextType extends BaseContext> = Omit<
ApolloServerOptions<ContextType>,
'formatError'
> & {
formatError?: ApolloServerOptions<ContextType>['formatError'] | string;
};
export type ApolloUserConfig<ContextType extends BaseContext> = Omit<
ApolloConfig<ContextType>,
'apolloServer'
> & {
apolloServer: ApolloServerUserOptions<ContextType>;
};
}
18 changes: 9 additions & 9 deletions providers/ApolloProvider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ApplicationContract } from '@ioc:Adonis/Core/Application';
import { ApolloConfig } from '@ioc:Zakodium/Apollo/Server';

import ApolloServer from '../src/ApolloServer';
import createApolloConfig from '../src/createApolloConfig';

export default class ApolloProvider {
protected loading = false;
Expand All @@ -15,16 +15,16 @@ export default class ApolloProvider {
'ApolloProvider was called during its initialization. To use this provider in resolvers, use dynamic `import()`.',
);
}
let apolloConfig = this.app.config.get('apollo', {}) as ApolloConfig;
const appUrl = this.app.env.get('APP_URL') as string;
if (!apolloConfig.appUrl && appUrl) {
apolloConfig = {
...apolloConfig,
appUrl,
};
}
const apolloConfig = createApolloConfig(
this.app.config.get('apollo', {}),
{
ioc: this.app.container,
fallbackUrl: this.app.env.get('APP_URL'),
},
);

this.loading = true;

return new ApolloServer(this.app, apolloConfig, this.app.logger);
});
}
Expand Down
34 changes: 34 additions & 0 deletions src/__tests__/createApolloConfig.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Ioc } from '@adonisjs/fold';

import createApolloConfig from '../createApolloConfig';

const testIoC = new Ioc();

describe('apollo config', () => {
it('create apollo configuration, formatError is callback', () => {
const config = createApolloConfig(
{
schemas: 'app/Schemas',
resolvers: 'app/Resolvers',
path: '/graphql',
apolloServer: {
introspection: true,
formatError: () => ({ message: 'error' }),
},
},
{
ioc: testIoC,
fallbackUrl: 'http://localhost:3333',
},
);
expect(config).toEqual({
schemas: 'app/Schemas',
resolvers: 'app/Resolvers',
path: '/graphql',
apolloServer: {
introspection: true,
formatError: expect.any(Function),
},
});
});
});
35 changes: 35 additions & 0 deletions src/createApolloConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { IocContract } from '@adonisjs/fold';
import { ApolloServerOptions, BaseContext } from '@apollo/server';

import type {
ApolloConfig,
ApolloUserConfig,
} from '@ioc:Zakodium/Apollo/Server';

export default function createApolloConfig<ContextType extends BaseContext>(
config: ApolloUserConfig<ContextType>,
options: {
ioc: IocContract;
fallbackUrl?: string;
},
): ApolloConfig<ContextType> {
return {
...config,
apolloServer: {
...config.apolloServer,
formatError:
typeof config.apolloServer?.formatError === 'string'
? makeFormatter(options.ioc, config.apolloServer.formatError)
: config.apolloServer.formatError,
},
};
}

function makeFormatter(
ioc: IocContract,
formatterPath: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): ApolloServerOptions<any>['formatError'] {
const formatter = ioc.make(formatterPath);
return formatter.formatError.bind(formatter);
}

0 comments on commit b1ec50a

Please sign in to comment.