All files / src openapi.ts

92.85% Statements 13/14
81.81% Branches 9/11
100% Functions 4/4
92.3% Lines 12/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3722x 1x       1x                   1x 23x         1x 19x 23x   23x         23x   19x     1x  
import { contract } from "@cooper/ts-rest/src/contract";
import { generateOpenApi } from "@ts-rest/open-api";
import { PathsObject, OperationObject } from "openapi3-ts/oas31";
 
// Auto-generated Swagger API docs
const openapi = generateOpenApi(
  contract,
  {
    info: { title: "API Documentation", version: "1.0.0" },
  },
  {
    setOperationId: true,
  },
);
 
function isOperationObject(value: unknown): value is OperationObject {
  return typeof value === "object" && value !== null && "tags" in value;
}
 
// Group sub-sub-routes in contract as child routes under their parent routes
// https://github.com/ts-rest/ts-rest/issues/680
openapi.paths = Object.entries(openapi.paths).reduce<PathsObject>((paths, [path, definition]) => {
  paths[path] = Object.entries(definition).reduce<Record<string, unknown>>((newDefinition, [key, value]) => {
    if (isOperationObject(value))
      // Limit tags to 1 so sub-sub-routes are gathered under the parent router
      newDefinition[key] = {
        ...value,
        tags: value.tags?.slice(0, 1),
      };
    else EnewDefinition[key] = value;
    return newDefinition;
  }, {});
  return paths;
}, {});
 
export default openapi;