chore: rename fundamentals to base (#9119)

This commit is contained in:
forehalo
2024-12-13 06:27:12 +00:00
parent 8c24f2b906
commit 4c23991047
185 changed files with 183 additions and 193 deletions
@@ -0,0 +1,17 @@
import { ApolloDriverConfig } from '@nestjs/apollo';
import { defineStartupConfig, ModuleConfig } from '../../base/config';
declare module '../../base/config' {
interface AppConfig {
graphql: ModuleConfig<ApolloDriverConfig>;
}
}
defineStartupConfig('graphql', {
buildSchemaOptions: {
numberScalarMode: 'integer',
},
introspection: true,
playground: true,
});
@@ -0,0 +1,86 @@
import './config';
import { STATUS_CODES } from 'node:http';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import type { ApolloDriverConfig } from '@nestjs/apollo';
import { ApolloDriver } from '@nestjs/apollo';
import { Global, HttpStatus, Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { Request, Response } from 'express';
import { GraphQLError } from 'graphql';
import { Config } from '../config';
import { UserFriendlyError } from '../error';
import { GQLLoggerPlugin } from './logger-plugin';
export type GraphqlContext = {
req: Request;
res: Response;
isAdminQuery: boolean;
};
@Global()
@Module({
imports: [
GraphQLModule.forRootAsync<ApolloDriverConfig>({
driver: ApolloDriver,
useFactory: (config: Config) => {
return {
...config.graphql,
path: `${config.server.path}/graphql`,
csrfPrevention: {
requestHeaders: ['content-type'],
},
autoSchemaFile: join(
fileURLToPath(import.meta.url),
config.node.dev
? '../../../schema.gql'
: '../../../../node_modules/.cache/schema.gql'
),
sortSchema: true,
context: ({
req,
res,
}: {
req: Request;
res: Response;
}): GraphqlContext => ({
req,
res,
isAdminQuery: false,
}),
includeStacktraceInErrorResponses: !config.node.prod,
plugins: [new GQLLoggerPlugin()],
formatError: (formattedError, error) => {
// @ts-expect-error allow assign
formattedError.extensions ??= {};
if (
error instanceof GraphQLError &&
error.originalError instanceof UserFriendlyError
) {
// @ts-expect-error allow assign
formattedError.extensions = error.originalError.toJSON();
formattedError.extensions.stacktrace = error.originalError.stack;
return formattedError;
} else {
// @ts-expect-error allow assign
formattedError.message = 'Internal Server Error';
formattedError.extensions['status'] =
HttpStatus.INTERNAL_SERVER_ERROR;
formattedError.extensions['code'] =
STATUS_CODES[HttpStatus.INTERNAL_SERVER_ERROR];
}
return formattedError;
},
};
},
inject: [Config],
}),
],
})
export class GqlModule {}
@@ -0,0 +1,58 @@
import {
ApolloServerPlugin,
GraphQLRequestContext,
GraphQLRequestListener,
} from '@apollo/server';
import { Plugin } from '@nestjs/apollo';
import { Response } from 'express';
import { metrics } from '../metrics/metrics';
import { mapAnyError } from '../nestjs';
export interface RequestContext {
req: Express.Request & {
res: Express.Response;
};
}
@Plugin()
export class GQLLoggerPlugin implements ApolloServerPlugin {
requestDidStart(
ctx: GraphQLRequestContext<RequestContext>
): Promise<GraphQLRequestListener<GraphQLRequestContext<RequestContext>>> {
const res = ctx.contextValue.req.res as Response;
const operation = ctx.request.operationName;
metrics.gql.counter('query_counter').add(1, { operation });
const start = Date.now();
function endTimer() {
return Date.now() - start;
}
return Promise.resolve({
willSendResponse: () => {
const time = endTimer();
res.setHeader('Server-Timing', `gql;dur=${time};desc="GraphQL"`);
metrics.gql.histogram('query_duration').record(time, { operation });
return Promise.resolve();
},
didEncounterErrors: ctx => {
ctx.errors.forEach(gqlErr => {
const error = mapAnyError(
gqlErr.originalError ? gqlErr.originalError : gqlErr
);
error.log('GraphQL');
metrics.gql.counter('query_error_counter').add(1, {
operation,
code: error.status,
type: error.type,
error: error.name,
});
});
return Promise.resolve();
},
});
}
}