Skip to content

Commit

Permalink
chore: Add sorting to API v2 OpenAPI doc (#16786)
Browse files Browse the repository at this point in the history
  • Loading branch information
keithwillcode authored Sep 24, 2024
1 parent 9a40838 commit f6ba77c
Show file tree
Hide file tree
Showing 2 changed files with 2,012 additions and 2,043 deletions.
66 changes: 66 additions & 0 deletions apps/api/v2/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import { ConfigService } from "@nestjs/config";
import { NestFactory } from "@nestjs/core";
import type { NestExpressApplication } from "@nestjs/platform-express";
import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger";
import {
PathItemObject,
PathsObject,
OperationObject,
TagObject,
} from "@nestjs/swagger/dist/interfaces/open-api-spec.interface";
import "dotenv/config";
import * as fs from "fs";
import { Server } from "http";
Expand All @@ -13,6 +19,8 @@ import { bootstrap } from "./app";
import { AppModule } from "./app.module";
import { loggerConfig } from "./lib/logger";

const HttpMethods: (keyof PathItemObject)[] = ["get", "post", "put", "delete", "patch", "options", "head"];

const run = async () => {
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
logger: WinstonModule.createLogger(loggerConfig()),
Expand All @@ -35,12 +43,70 @@ const run = async () => {
}
};

function customTagSort(a: string, b: string): number {
const platformPrefix = "Platform";
const orgsPrefix = "Orgs";

if (a.startsWith(platformPrefix) && !b.startsWith(platformPrefix)) {
return -1;
}
if (!a.startsWith(platformPrefix) && b.startsWith(platformPrefix)) {
return 1;
}

if (a.startsWith(orgsPrefix) && !b.startsWith(orgsPrefix)) {
return -1;
}
if (!a.startsWith(orgsPrefix) && b.startsWith(orgsPrefix)) {
return 1;
}

return a.localeCompare(b);
}

function isOperationObject(obj: any): obj is OperationObject {
return obj && typeof obj === "object" && "tags" in obj;
}

function groupAndSortPathsByFirstTag(paths: PathsObject): PathsObject {
const groupedPaths: { [key: string]: PathsObject } = {};

Object.keys(paths).forEach((pathKey) => {
const pathItem = paths[pathKey];

HttpMethods.forEach((method) => {
const operation = pathItem[method];

if (isOperationObject(operation) && operation.tags && operation.tags.length > 0) {
const firstTag = operation.tags[0];

if (!groupedPaths[firstTag]) {
groupedPaths[firstTag] = {};
}

groupedPaths[firstTag][pathKey] = pathItem;
}
});
});

const sortedTags = Object.keys(groupedPaths).sort(customTagSort);
const sortedPaths: PathsObject = {};

sortedTags.forEach((tag) => {
Object.assign(sortedPaths, groupedPaths[tag]);
});

return sortedPaths;
}

async function generateSwagger(app: NestExpressApplication<Server>) {
const logger = new Logger("App");
logger.log(`Generating Swagger documentation...\n`);

const config = new DocumentBuilder().setTitle("Cal.com API v2").build();
const document = SwaggerModule.createDocument(app, config);
document.paths = groupAndSortPathsByFirstTag(document.paths);

const outputFile = "./swagger/documentation.json";

if (fs.existsSync(outputFile)) {
Expand Down
Loading

0 comments on commit f6ba77c

Please sign in to comment.