Skip to content

Commit

Permalink
feat: export operations interface (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
gr2m committed Nov 11, 2020
1 parent 8c7c1d8 commit bf009b7
Show file tree
Hide file tree
Showing 8 changed files with 42,672 additions and 41,503 deletions.
4 changes: 4 additions & 0 deletions src/types/OpenAPI3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface OpenAPI3Paths {
}

export interface OpenAPI3Operation {
operationId?: string;
description?: string;
parameters?: Parameter[];
requestBody?: OpenAPI3RequestBody;
Expand Down Expand Up @@ -57,6 +58,9 @@ export interface OpenAPI3 {
openapi: string;
paths?: OpenAPI3Paths; // technically required by spec, but this library tries to be lenient
components?: OpenAPI3Components;
operations?: {
[key: string]: OpenAPI3Operation;
};
[key: string]: any; // handle other properties beyond this library’s concern
}

Expand Down
109 changes: 66 additions & 43 deletions src/v3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export default function generateTypesV3(
}
}

const operations: Record<string, OpenAPI3Operation> = {};

// propertyMapper
const propertyMapped = options
? propertyMapper(components.schemas, options.propertyMapper)
Expand Down Expand Up @@ -211,6 +213,52 @@ export default function generateTypesV3(
return output;
}

function transformOperation(operation: OpenAPI3Operation): string {
let output = "";
output += `{\n`;

// handle operation parameters
if (operation.parameters) {
output += transformParameters(operation.parameters);
}

// handle requestBody
if (operation.requestBody) {
output += `requestBody: {\n`;
Object.entries(operation.requestBody.content).forEach(
([contentType, { schema }]) => {
output += `"${contentType}": ${transform(schema)};\n`;
}
);
output += `}\n`;
}

// handle responses
output += `responses: {\n`;
Object.entries(operation.responses).forEach(([statusCode, response]) => {
if (response.description) output += comment(response.description);
if (!response.content || !Object.keys(response.content).length) {
const type =
statusCode === "204" || Math.floor(+statusCode / 100) === 3
? "never"
: "unknown";
output += `"${statusCode}": ${type};\n`;
return;
}
output += `"${statusCode}": {\n`;
Object.entries(response.content).forEach(
([contentType, encodedResponse]) => {
output += `"${contentType}": ${transform(encodedResponse.schema)};\n`;
}
);
output += `}\n`;
});
output += `}\n`;
output += `}\n`;

return output;
}

function transformPaths(paths: OpenAPI3Paths): string {
let output = "";
Object.entries(paths).forEach(([path, methods]) => {
Expand All @@ -220,51 +268,16 @@ export default function generateTypesV3(
// skip the parameters "method" for shared parameters - we'll handle it later
if (method !== "parameters") {
operation = operation as OpenAPI3Operation;
if (operation.description) output += comment(operation.description);
output += `"${method}": {\n`;

// handle operation parameters
if (operation.parameters) {
output += transformParameters(operation.parameters);
}

// handle requestBody
if (operation.requestBody) {
output += `requestBody: {\n`;
Object.entries(operation.requestBody.content).forEach(
([contentType, { schema }]) => {
output += `"${contentType}": ${transform(schema)};\n`;
}
);
output += `}\n`;
if (operation.operationId) {
output += `"${method}": operations["${operation.operationId}"];\n`;
operations[operation.operationId] = operation;
} else {
if (operation.description) output += comment(operation.description);
output += `"${method}": ${transformOperation(
operation as OpenAPI3Operation
)}`;
}

// handle responses
output += `responses: {\n`;
Object.entries(operation.responses).forEach(
([statusCode, response]) => {
if (response.description) output += comment(response.description);
if (!response.content || !Object.keys(response.content).length) {
const type =
statusCode === "204" || Math.floor(+statusCode / 100) === 3
? "never"
: "unknown";
output += `"${statusCode}": ${type};\n`;
return;
}
output += `"${statusCode}": {\n`;
Object.entries(response.content).forEach(
([contentType, encodedResponse]) => {
output += `"${contentType}": ${transform(
encodedResponse.schema
)};\n`;
}
);
output += `}\n`;
}
);
output += `}\n`;
output += `}\n`;
}
});

Expand Down Expand Up @@ -295,6 +308,16 @@ export default function generateTypesV3(
`;
}

finalOutput += "export interface operations {\n";
for (const [operationId, operation] of Object.entries(operations)) {
if (operation.description) finalOutput += comment(operation.description);
finalOutput += `"${operationId}": ${transformOperation(
operation as OpenAPI3Operation
)}`;
}
// close operations wrapper
finalOutput += "\n}\n\n";

finalOutput += "export interface components {\n";

if (components.parameters && Object.keys(components.parameters).length) {
Expand Down
Loading

0 comments on commit bf009b7

Please sign in to comment.