52 lines
2.3 KiB
TypeScript
52 lines
2.3 KiB
TypeScript
import { INestApplication } from '@nestjs/common';
|
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
|
|
import { HttpErrorCode } from './common/error-code';
|
|
import { MoexErrorCode } from './integrations/moex/moex.client';
|
|
import { NcrErrorCode } from './integrations/ncr/ncr-ratings.client';
|
|
import { TbankErrorCode } from './integrations/tbank/tbank-error-code';
|
|
import { AuthErrorCode } from './modules/auth/application/auth-error-code';
|
|
import { BankErrorCode } from './modules/banking/bank-cards/application/bank-card-input';
|
|
import { IncomeErrorCode } from './modules/investments/income/income-period';
|
|
import { InstrumentErrorCode } from './modules/investments/instruments/domain/instrument-error-code';
|
|
import { OperationErrorCode } from './modules/investments/operations/domain/operation-error-code';
|
|
import { EventsErrorCode } from './modules/investments/upcoming-events/upcoming-events.api';
|
|
|
|
export const API_PREFIX = 'api/v1';
|
|
|
|
// Nest Swagger cannot express additionalProperties on a class, so closed request
|
|
// bodies are restored here after generation; the runtime allowlist stays in the controller.
|
|
const CLOSED_SCHEMAS = ['StockScreenerCriteriaDto'];
|
|
|
|
// Every code HttpExceptionFilter can emit. Assembled at the composition root so
|
|
// common/ProblemDetailsDto does not depend on modules.
|
|
export const PROBLEM_CODES = [
|
|
...Object.values(HttpErrorCode),
|
|
...Object.values(AuthErrorCode),
|
|
...Object.values(OperationErrorCode),
|
|
...Object.values(InstrumentErrorCode),
|
|
...Object.values(TbankErrorCode),
|
|
...Object.values(BankErrorCode),
|
|
...Object.values(MoexErrorCode),
|
|
...Object.values(NcrErrorCode),
|
|
...Object.values(EventsErrorCode),
|
|
...Object.values(IncomeErrorCode),
|
|
];
|
|
|
|
export function createOpenApiDocument(app: INestApplication) {
|
|
const document = SwaggerModule.createDocument(
|
|
app,
|
|
new DocumentBuilder().setTitle('WealthLedger API').setVersion('v1').build(),
|
|
);
|
|
const schemas = document.components?.schemas ?? {};
|
|
for (const [name, schema] of Object.entries(schemas)) {
|
|
if (CLOSED_SCHEMAS.includes(name) && 'properties' in schema) {
|
|
schema.additionalProperties = false;
|
|
}
|
|
}
|
|
const problem = schemas.ProblemDetailsDto;
|
|
const problemCode = problem && 'properties' in problem ? problem.properties?.code : undefined;
|
|
if (problemCode && !('$ref' in problemCode)) problemCode.enum = PROBLEM_CODES;
|
|
return document;
|
|
}
|