New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

openapi-typescript

Package Overview
Dependencies
Maintainers
1
Versions
145
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

openapi-typescript - npm Package Compare versions

Comparing version 3.3.0-next.0 to 3.3.0

dist/cjs/transform/request.d.ts

26

bin/cli.js

@@ -15,9 +15,10 @@ #!/usr/bin/env node

Options
--help display this
--output, -o Specify output file (default: stdout)
--auth (optional) Provide an authentication token for private URL
--immutable-types (optional) Generates immutable types (readonly properties and readonly array)
--prettier-config (optional) specify path to Prettier config file
--raw-schema (optional) Read from raw schema instead of document
--version (optional) Schema version (must be present for raw schemas)
--help display this
--output, -o Specify output file (default: stdout)
--auth (optional) Provide an authentication token for private URL
--immutable-types, -it (optional) Generates immutable types (readonly properties and readonly array)
--additional-properties, -ap (optional) Allow arbitrary properties for all schema objects without "additionalProperties: false"
--prettier-config, -c (optional) specify path to Prettier config file
--raw-schema (optional) Parse as partial schema (raw components)
--version (optional) Force schema parsing version
`,

@@ -35,5 +36,11 @@ {

type: "boolean",
alias: "it",
},
additionalProperties: {
type: "boolean",
alias: "ap",
},
prettierConfig: {
type: "string",
alias: "c",
},

@@ -63,2 +70,5 @@ rawSchema: {

}
if (cli.flags.rawSchema && !cli.flags.version) {
throw new Error(`--raw-schema requires --version flag`);
}

@@ -79,2 +89,4 @@ // 1. input

const result = openapiTS(spec, {
auth: cli.flags.auth,
additionalProperties: cli.flags.additionalProperties,
immutableTypes: cli.flags.immutableTypes,

@@ -81,0 +93,0 @@ prettierConfig: cli.flags.prettierConfig,

@@ -30,12 +30,18 @@ "use strict";

`;
function openapiTS(schema, options) {
const version = (options && options.version) || utils_1.swaggerVersion(schema);
let output = `${exports.WARNING_MESSAGE}
${index_1.transformAll(schema, {
formatter: options && typeof options.formatter === "function" ? options.formatter : undefined,
immutableTypes: (options && options.immutableTypes) || false,
rawSchema: options && options.rawSchema,
version,
})}
`;
function openapiTS(schema, options = {}) {
const ctx = {
auth: options.auth,
additionalProperties: options.additionalProperties || false,
formatter: typeof options.formatter === "function" ? options.formatter : undefined,
immutableTypes: options.immutableTypes || false,
rawSchema: options.rawSchema || false,
version: options.version || utils_1.swaggerVersion(schema),
};
let output = exports.WARNING_MESSAGE;
const rootTypes = index_1.transformAll(schema, { ...ctx });
for (const k of Object.keys(rootTypes)) {
if (typeof rootTypes[k] !== "string")
continue;
output += `export interface ${k} {\n ${rootTypes[k]}\n}\n\n`;
}
let prettierOptions = {

@@ -42,0 +48,0 @@ parser: "typescript",

@@ -1,5 +0,6 @@

import { HeaderObject, SchemaFormatter } from "../types";
export declare function transformHeaderObjMap(headerMap: Record<string, HeaderObject>, options: {
formatter?: SchemaFormatter;
immutableTypes: boolean;
}): string;
import { GlobalContext, HeaderObject } from "../types";
interface TransformHeadersOptions extends GlobalContext {
required: Set<string>;
}
export declare function transformHeaderObjMap(headerMap: Record<string, HeaderObject>, options: TransformHeadersOptions): string;
export {};

@@ -8,5 +8,6 @@ "use strict";

let output = "";
Object.entries(headerMap).forEach(([k, v]) => {
for (const k of Object.keys(headerMap)) {
const v = headerMap[k];
if (!v.schema)
return;
continue;
if (v.description)

@@ -17,3 +18,3 @@ output += utils_1.comment(v.description);

output += ` ${readonly}"${k}"${required}: ${schema_1.transformSchemaObj(v.schema, options)}\n`;
});
}
return output;

@@ -20,0 +21,0 @@ }

@@ -1,9 +0,2 @@

import { SchemaFormatter } from "../types";
interface TransformOptions {
formatter?: SchemaFormatter;
immutableTypes: boolean;
rawSchema?: boolean;
version: number;
}
export declare function transformAll(schema: any, { formatter, immutableTypes, rawSchema, version }: TransformOptions): string;
export {};
import { GlobalContext } from "../types";
export declare function transformAll(schema: any, ctx: GlobalContext): Record<string, string>;

@@ -8,58 +8,46 @@ "use strict";

const paths_1 = require("./paths");
const request_1 = require("./request");
const responses_1 = require("./responses");
const schema_1 = require("./schema");
function transformAll(schema, { formatter, immutableTypes, rawSchema, version }) {
const readonly = utils_1.tsReadonly(immutableTypes);
let output = "";
function transformAll(schema, ctx) {
const readonly = utils_1.tsReadonly(ctx.immutableTypes);
let output = {};
let operations = {};
if (rawSchema) {
switch (version) {
if (ctx.rawSchema) {
const required = new Set(Object.keys(schema));
switch (ctx.version) {
case 2: {
return `export interface definitions {\n ${schema_1.transformSchemaObjMap(schema, {
formatter,
immutableTypes,
required: Object.keys(schema),
})}\n}`;
output.definitions = schema_1.transformSchemaObjMap(schema, { ...ctx, required });
return output;
}
case 3: {
return `export interface schemas {\n ${schema_1.transformSchemaObjMap(schema, {
formatter,
immutableTypes,
required: Object.keys(schema),
})}\n }\n\n`;
output.schemas = schema_1.transformSchemaObjMap(schema, { ...ctx, required });
return output;
}
}
}
output += `export interface paths {\n`;
output.paths = "";
if (schema.paths) {
output += paths_1.transformPathsObj(schema.paths, {
output.paths += paths_1.transformPathsObj(schema.paths, {
...ctx,
globalParameters: (schema.components && schema.components.parameters) || schema.parameters,
immutableTypes,
operations,
version,
});
}
output += `}\n\n`;
switch (version) {
switch (ctx.version) {
case 2: {
if (schema.definitions) {
output += `export interface definitions {\n ${schema_1.transformSchemaObjMap(schema.definitions, {
formatter,
immutableTypes,
required: Object.keys(schema.definitions),
})}\n}\n\n`;
output.definitions = schema_1.transformSchemaObjMap(schema.definitions, {
...ctx,
required: new Set(Object.keys(schema.definitions)),
});
}
if (schema.parameters) {
const required = Object.keys(schema.parameters);
output += `export interface parameters {\n ${schema_1.transformSchemaObjMap(schema.parameters, {
formatter,
immutableTypes,
required,
})}\n }\n\n`;
output.parameters = schema_1.transformSchemaObjMap(schema.parameters, {
...ctx,
required: new Set(Object.keys(schema.parameters)),
});
}
if (schema.responses) {
output += `export interface responses {\n ${responses_1.transformResponsesObj(schema.responses, {
formatter,
immutableTypes,
})}\n }\n\n`;
output.responses = responses_1.transformResponsesObj(schema.responses, ctx);
}

@@ -69,60 +57,53 @@ break;

case 3: {
output += `export interface components {\n`;
output.components = "";
if (schema.components) {
if (schema.components.schemas) {
const required = Object.keys(schema.components.schemas);
output += ` ${readonly}schemas: {\n ${schema_1.transformSchemaObjMap(schema.components.schemas, {
formatter,
immutableTypes,
required,
output.components += ` ${readonly}schemas: {\n ${schema_1.transformSchemaObjMap(schema.components.schemas, {
...ctx,
required: new Set(Object.keys(schema.components.schemas)),
})}\n }\n`;
}
if (schema.components.responses) {
output += ` ${readonly}responses: {\n ${responses_1.transformResponsesObj(schema.components.responses, {
formatter,
immutableTypes,
})}\n }\n`;
output.components += ` ${readonly}responses: {\n ${responses_1.transformResponsesObj(schema.components.responses, ctx)}\n }\n`;
}
if (schema.components.parameters) {
const required = Object.keys(schema.components.parameters);
output += ` ${readonly}parameters: {\n ${schema_1.transformSchemaObjMap(schema.components.parameters, {
formatter,
immutableTypes,
required,
output.components += ` ${readonly}parameters: {\n ${schema_1.transformSchemaObjMap(schema.components.parameters, {
...ctx,
required: new Set(Object.keys(schema.components.parameters)),
})}\n }\n`;
}
if (schema.components.requestBodies) {
output += ` ${readonly}requestBodies: {\n ${responses_1.transformRequestBodies(schema.components.requestBodies, {
formatter,
immutableTypes,
})}\n }\n`;
output.components += ` ${readonly}requestBodies: {\n ${request_1.transformRequestBodies(schema.components.requestBodies, ctx)}\n }\n`;
}
if (schema.components.headers) {
output += ` ${readonly}headers: {\n ${headers_1.transformHeaderObjMap(schema.components.headers, {
formatter,
immutableTypes,
})} }\n`;
output.components += ` ${readonly}headers: {\n ${headers_1.transformHeaderObjMap(schema.components.headers, {
...ctx,
required: new Set(),
})}\n }\n`;
}
}
output += `}\n\n`;
break;
}
}
output += `export interface operations {\n`;
output.operations = "";
if (Object.keys(operations).length) {
Object.entries(operations).forEach(([operationId, { operation, pathItem }]) => {
for (const id of Object.keys(operations)) {
const { operation, pathItem } = operations[id];
if (operation.description)
output += utils_1.comment(operation.description);
output += ` ${readonly}"${operationId}": {\n ${operation_1.transformOperationObj(operation, {
output.operations += utils_1.comment(operation.description);
output.operations += ` ${readonly}"${id}": {\n ${operation_1.transformOperationObj(operation, {
...ctx,
pathItem,
globalParameters: (schema.components && schema.components.parameters) || schema.parameters,
immutableTypes,
version,
})}\n }\n`;
});
}
}
output += `}\n`;
return output.trim();
for (const k of Object.keys(output)) {
if (typeof output[k] === "string") {
output[k] = output[k].trim();
}
}
return output;
}
exports.transformAll = transformAll;
//# sourceMappingURL=index.js.map

@@ -1,10 +0,7 @@

import { OperationObject, ParameterObject, PathItemObject, RequestBody } from "../types";
export declare function transformOperationObj(operation: OperationObject, { globalParameters, immutableTypes, pathItem, version, }: {
import { GlobalContext, OperationObject, ParameterObject, PathItemObject } from "../types";
interface TransformOperationOptions extends GlobalContext {
globalParameters?: Record<string, ParameterObject>;
pathItem?: PathItemObject;
globalParameters?: Record<string, ParameterObject>;
immutableTypes: boolean;
version: number;
}): string;
export declare function transformRequestBodyObj(requestBody: RequestBody, { immutableTypes }: {
immutableTypes: boolean;
}): string;
}
export declare function transformOperationObj(operation: OperationObject, options: TransformOperationOptions): string;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformRequestBodyObj = exports.transformOperationObj = void 0;
exports.transformOperationObj = void 0;
const utils_1 = require("../utils");
const parameters_1 = require("./parameters");
const request_1 = require("./request");
const responses_1 = require("./responses");
const schema_1 = require("./schema");
function transformOperationObj(operation, { globalParameters, immutableTypes, pathItem = {}, version, }) {
const readonly = utils_1.tsReadonly(immutableTypes);
function transformOperationObj(operation, options) {
const { pathItem = {}, globalParameters, ...ctx } = options;
const readonly = utils_1.tsReadonly(ctx.immutableTypes);
let output = "";

@@ -14,11 +15,8 @@ if (operation.parameters || pathItem.parameters) {

output += ` ${readonly}parameters: {\n ${parameters_1.transformParametersArray(parameters, {
...ctx,
globalParameters,
immutableTypes,
version,
})}\n }\n`;
}
if (operation.responses) {
output += ` ${readonly}responses: {\n ${responses_1.transformResponsesObj(operation.responses, {
immutableTypes,
})}\n }\n`;
output += ` ${readonly}responses: {\n ${responses_1.transformResponsesObj(operation.responses, ctx)}\n }\n`;
}

@@ -32,5 +30,3 @@ if (operation.requestBody) {

output += utils_1.comment(operation.requestBody.description);
output += ` ${readonly}requestBody: {\n`;
output += ` ${transformRequestBodyObj(operation.requestBody, { immutableTypes })}`;
output += ` }\n`;
output += ` ${readonly}requestBody: {\n ${request_1.transformRequestBodyObj(operation.requestBody, ctx)} }\n`;
}

@@ -41,19 +37,2 @@ }

exports.transformOperationObj = transformOperationObj;
function transformRequestBodyObj(requestBody, { immutableTypes }) {
const readonly = utils_1.tsReadonly(immutableTypes);
let output = "";
const { content } = requestBody;
if (content && Object.keys(content).length) {
output += ` ${readonly}content: {\n`;
Object.entries(content).forEach(([k, v]) => {
output += ` ${readonly}"${k}": ${schema_1.transformSchemaObj(v.schema, { immutableTypes })};\n`;
});
output += ` }\n`;
}
else {
output += ` unknown;\n`;
}
return output;
}
exports.transformRequestBodyObj = transformRequestBodyObj;
//# sourceMappingURL=operation.js.map

@@ -1,6 +0,6 @@

import { ParameterObject, ReferenceObject } from "../types";
export declare function transformParametersArray(parameters: (ReferenceObject | ParameterObject)[], { globalParameters, immutableTypes, version, }: {
import { GlobalContext, ParameterObject, ReferenceObject } from "../types";
interface TransformParametersOptions extends GlobalContext {
globalParameters?: Record<string, ParameterObject>;
immutableTypes: boolean;
version: number;
}): string;
}
export declare function transformParametersArray(parameters: (ReferenceObject | ParameterObject)[], options: TransformParametersOptions): string;
export {};

@@ -6,7 +6,8 @@ "use strict";

const schema_1 = require("./schema");
function transformParametersArray(parameters, { globalParameters, immutableTypes, version, }) {
const readonly = utils_1.tsReadonly(immutableTypes);
function transformParametersArray(parameters, options) {
const { globalParameters = {}, ...ctx } = options;
const readonly = utils_1.tsReadonly(ctx.immutableTypes);
let output = "";
let mappedParams = {};
parameters.forEach((paramObj) => {
for (const paramObj of parameters) {
if (paramObj.$ref && globalParameters) {

@@ -18,26 +19,30 @@ const paramName = paramObj.$ref.split("/").pop();

mappedParams[reference.in] = {};
if (version === 2) {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
$ref: paramObj.$ref,
};
switch (ctx.version) {
case 3: {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
schema: { $ref: paramObj.$ref },
};
break;
}
case 2: {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
$ref: paramObj.$ref,
};
break;
}
}
else if (version === 3) {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
schema: { $ref: paramObj.$ref },
};
}
}
return;
continue;
}
if (!paramObj.in || !paramObj.name)
return;
continue;
if (!mappedParams[paramObj.in])
mappedParams[paramObj.in] = {};
mappedParams[paramObj.in][paramObj.name] = paramObj;
});
Object.entries(mappedParams).forEach(([paramIn, paramGroup]) => {
}
for (const [paramIn, paramGroup] of Object.entries(mappedParams)) {
output += ` ${readonly}${paramIn}: {\n`;
Object.entries(paramGroup).forEach(([paramName, paramObj]) => {
for (const [paramName, paramObj] of Object.entries(paramGroup)) {
let paramComment = "";

@@ -52,20 +57,26 @@ if (paramObj.deprecated)

let paramType = ``;
if (version === 2) {
if (paramObj.in === "body" && paramObj.schema) {
paramType = schema_1.transformSchemaObj(paramObj.schema, { immutableTypes });
switch (ctx.version) {
case 3: {
paramType = paramObj.schema
? schema_1.transformSchemaObj(paramObj.schema, { ...ctx, required: new Set() })
: "unknown";
break;
}
else if (paramObj.type) {
paramType = schema_1.transformSchemaObj(paramObj, { immutableTypes });
case 2: {
if (paramObj.in === "body" && paramObj.schema) {
paramType = schema_1.transformSchemaObj(paramObj.schema, { ...ctx, required: new Set() });
}
else if (paramObj.type) {
paramType = schema_1.transformSchemaObj(paramObj, { ...ctx, required: new Set() });
}
else {
paramType = "unknown";
}
break;
}
else {
paramType = "unknown";
}
}
else if (version === 3) {
paramType = paramObj.schema ? schema_1.transformSchemaObj(paramObj.schema, { immutableTypes }) : "unknown";
}
output += ` ${readonly}"${paramName}"${required}: ${paramType};\n`;
});
}
output += ` }\n`;
});
}
return output;

@@ -72,0 +83,0 @@ }

@@ -1,5 +0,4 @@

import { OperationObject, ParameterObject, PathItemObject } from "../types";
interface TransformPathsObjOption {
import { GlobalContext, OperationObject, ParameterObject, PathItemObject } from "../types";
interface TransformPathsObjOption extends GlobalContext {
globalParameters: Record<string, ParameterObject>;
immutableTypes: boolean;
operations: Record<string, {

@@ -9,5 +8,4 @@ operation: OperationObject;

}>;
version: number;
}
export declare function transformPathsObj(paths: Record<string, PathItemObject>, { globalParameters, immutableTypes, operations, version }: TransformPathsObjOption): string;
export declare function transformPathsObj(paths: Record<string, PathItemObject>, options: TransformPathsObjOption): string;
export {};

@@ -7,6 +7,7 @@ "use strict";

const parameters_1 = require("./parameters");
function transformPathsObj(paths, { globalParameters, immutableTypes, operations, version }) {
const readonly = utils_1.tsReadonly(immutableTypes);
function transformPathsObj(paths, options) {
const { globalParameters, operations, ...ctx } = options;
const readonly = utils_1.tsReadonly(ctx.immutableTypes);
let output = "";
Object.entries(paths).forEach(([url, pathItem]) => {
for (const [url, pathItem] of Object.entries(paths)) {
if (pathItem.description)

@@ -16,9 +17,9 @@ output += utils_1.comment(pathItem.description);

output += ` ${readonly}"${url}": ${utils_1.transformRef(pathItem.$ref)};\n`;
return;
continue;
}
output += ` ${readonly}"${url}": {\n`;
["get", "put", "post", "delete", "options", "head", "patch", "trace"].forEach((method) => {
for (const method of ["get", "put", "post", "delete", "options", "head", "patch", "trace"]) {
const operation = pathItem[method];
if (!operation)
return;
continue;
if (operation.description)

@@ -29,20 +30,19 @@ output += utils_1.comment(operation.description);

output += ` ${readonly}"${method}": operations["${operation.operationId}"];\n`;
return;
}
output += ` ${readonly}"${method}": {\n ${operation_1.transformOperationObj(operation, {
globalParameters,
immutableTypes,
pathItem,
version,
})}\n }\n`;
});
else {
output += ` ${readonly}"${method}": {\n ${operation_1.transformOperationObj(operation, {
...ctx,
globalParameters,
pathItem,
})}\n }\n`;
}
}
if (pathItem.parameters) {
output += ` ${readonly}parameters: {\n ${parameters_1.transformParametersArray(pathItem.parameters, {
...ctx,
globalParameters,
immutableTypes,
version,
})}\n }\n`;
}
output += ` }\n`;
});
}
return output;

@@ -49,0 +49,0 @@ }

@@ -1,8 +0,2 @@

import { RequestBody, SchemaFormatter } from "../types";
interface Options {
formatter?: SchemaFormatter;
immutableTypes: boolean;
}
export declare function transformResponsesObj(responsesObj: Record<string, any>, options: Options): string;
export declare function transformRequestBodies(requestBodies: Record<string, RequestBody>, options: Options): string;
export {};
import { GlobalContext } from "../types";
export declare function transformResponsesObj(responsesObj: Record<string, any>, ctx: GlobalContext): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformRequestBodies = exports.transformResponsesObj = void 0;
exports.transformResponsesObj = void 0;
const utils_1 = require("../utils");
const headers_1 = require("./headers");
const schema_1 = require("./schema");
const operation_1 = require("./operation");
const resType = (res) => (res === 204 || (res >= 300 && res < 400) ? "never" : "unknown");
function transformResponsesObj(responsesObj, options) {
const { immutableTypes } = options;
const readonly = utils_1.tsReadonly(immutableTypes);
function transformResponsesObj(responsesObj, ctx) {
const readonly = utils_1.tsReadonly(ctx.immutableTypes);
let output = "";
Object.entries(responsesObj).forEach(([httpStatusCode, response]) => {
for (const httpStatusCode of Object.keys(responsesObj)) {
const statusCode = Number(httpStatusCode) || `"${httpStatusCode}"`;
const response = responsesObj[httpStatusCode];
if (response.description)
output += utils_1.comment(response.description);
const statusCode = Number(httpStatusCode) || `"${httpStatusCode}"`;
if (response.$ref) {
output += ` ${readonly}${statusCode}: ${utils_1.transformRef(response.$ref)};\n`;
return;
continue;
}
if ((!response.content && !response.schema) || (response.content && !Object.keys(response.content).length)) {
output += ` ${readonly}${statusCode}: ${resType(statusCode)};\n`;
return;
continue;
}

@@ -31,35 +30,34 @@ output += ` ${readonly}${statusCode}: {\n`;

else {
output += ` ${readonly}headers: {\n ${headers_1.transformHeaderObjMap(response.headers, options)}\n }\n`;
output += ` ${readonly}headers: {\n ${headers_1.transformHeaderObjMap(response.headers, {
...ctx,
required: new Set(),
})}\n }\n`;
}
}
if (response.content && Object.keys(response.content).length) {
output += ` ${readonly}content: {\n`;
Object.entries(response.content).forEach(([contentType, contentResponse]) => {
const responseType = contentResponse && contentResponse.schema
? schema_1.transformSchemaObj(contentResponse.schema, options)
: "unknown";
output += ` ${readonly}"${contentType}": ${responseType};\n`;
});
output += ` }\n`;
switch (ctx.version) {
case 3: {
output += ` ${readonly}content: {\n`;
for (const contentType of Object.keys(response.content)) {
const contentResponse = response.content[contentType];
const responseType = contentResponse && (contentResponse === null || contentResponse === void 0 ? void 0 : contentResponse.schema)
? schema_1.transformSchemaObj(contentResponse.schema, { ...ctx, required: new Set() })
: "unknown";
output += ` ${readonly}"${contentType}": ${responseType};\n`;
}
output += ` }\n`;
break;
}
case 2: {
output += ` ${readonly} schema: ${schema_1.transformSchemaObj(response.schema, {
...ctx,
required: new Set(),
})};\n`;
break;
}
}
else if (response.schema) {
output += ` ${readonly} schema: ${schema_1.transformSchemaObj(response.schema, options)};\n`;
}
output += ` }\n`;
});
}
return output;
}
exports.transformResponsesObj = transformResponsesObj;
function transformRequestBodies(requestBodies, options) {
let output = "";
Object.entries(requestBodies).forEach(([bodyName, requestBody]) => {
if (requestBody && requestBody.description)
output += ` ${utils_1.comment(requestBody.description)}`;
output += ` "${bodyName}": {`;
output += ` ${operation_1.transformRequestBodyObj(requestBody, options)}`;
output += ` }\n`;
});
return output;
}
exports.transformRequestBodies = transformRequestBodies;
//# sourceMappingURL=responses.js.map

@@ -1,15 +0,9 @@

import { SchemaFormatter } from "types";
interface TransformSchemaObjMapOptions {
formatter?: SchemaFormatter;
immutableTypes: boolean;
required?: string[];
import { GlobalContext } from "../types";
interface TransformSchemaObjOptions extends GlobalContext {
required: Set<string>;
}
export declare function transformSchemaObjMap(obj: Record<string, any>, options: TransformSchemaObjMapOptions): string;
interface Options {
formatter?: SchemaFormatter;
immutableTypes: boolean;
}
export declare function transformAnyOf(anyOf: any, options: Options): string;
export declare function transformOneOf(oneOf: any, options: Options): string;
export declare function transformSchemaObj(node: any, options: Options): string;
export declare function transformSchemaObjMap(obj: Record<string, any>, options: TransformSchemaObjOptions): string;
export declare function transformAnyOf(anyOf: any, options: TransformSchemaObjOptions): string;
export declare function transformOneOf(oneOf: any, options: TransformSchemaObjOptions): string;
export declare function transformSchemaObj(node: any, options: TransformSchemaObjOptions): string;
export {};

@@ -6,15 +6,12 @@ "use strict";

function transformSchemaObjMap(obj, options) {
const readonly = options.immutableTypes ? "readonly " : "";
let required = (options && options.required) || [];
const readonly = utils_1.tsReadonly(options.immutableTypes);
let output = "";
Object.entries(obj).forEach(([key, value]) => {
if (value.description)
output += utils_1.comment(value.description);
output += `${readonly}"${key}"${required.includes(key) ? "" : "?"}: `;
output += transformSchemaObj(value.schema || value, {
formatter: options.formatter,
immutableTypes: options.immutableTypes,
});
for (const k of Object.keys(obj)) {
const v = obj[k];
if (v.description)
output += utils_1.comment(v.description);
output += `${readonly}"${k}"${options.required.has(k) ? "" : "?"}: `;
output += transformSchemaObj(v.schema || v, options);
output += `;\n`;
});
}
return output.replace(/\n+$/, "\n");

@@ -32,3 +29,4 @@ }

function transformSchemaObj(node, options) {
const readonly = options.immutableTypes ? "readonly " : "";
var _a;
const readonly = utils_1.tsReadonly(options.immutableTypes);
let output = "";

@@ -76,9 +74,10 @@ if (node.nullable) {

let properties = transformSchemaObjMap(node.properties || {}, {
immutableTypes: options.immutableTypes,
required: node.required,
...options,
required: new Set(node.required || []),
});
let additionalProperties;
if (node.additionalProperties) {
if (node.additionalProperties === true || Object.keys(node.additionalProperties).length === 0) {
additionalProperties = `{ [key: string]: any }`;
if (node.additionalProperties ||
(node.additionalProperties === undefined && options.additionalProperties && options.version === 3)) {
if (((_a = node.additionalProperties) !== null && _a !== void 0 ? _a : true) === true || Object.keys(node.additionalProperties).length === 0) {
additionalProperties = `{ ${readonly}[key: string]: any }`;
}

@@ -85,0 +84,0 @@ else if (typeof node.additionalProperties === "object") {

@@ -0,1 +1,3 @@

/// <reference types="node" />
import { URL } from "url";
export interface OpenAPI2 {

@@ -106,2 +108,5 @@ swagger: string;

export interface SwaggerToTSOptions {
additionalProperties?: boolean;
auth?: string;
cwd?: URL;
formatter?: SchemaFormatter;

@@ -113,1 +118,11 @@ immutableTypes?: boolean;

}
export interface GlobalContext {
additionalProperties: boolean;
auth?: string;
formatter?: SchemaFormatter;
immutableTypes: boolean;
silent?: boolean;
namespace?: string;
rawSchema: boolean;
version: number;
}

@@ -14,12 +14,18 @@ import path from "path";

`;
export default function openapiTS(schema, options) {
const version = (options && options.version) || swaggerVersion(schema);
let output = `${WARNING_MESSAGE}
${transformAll(schema, {
formatter: options && typeof options.formatter === "function" ? options.formatter : undefined,
immutableTypes: (options && options.immutableTypes) || false,
rawSchema: options && options.rawSchema,
version,
})}
`;
export default function openapiTS(schema, options = {}) {
const ctx = {
auth: options.auth,
additionalProperties: options.additionalProperties || false,
formatter: typeof options.formatter === "function" ? options.formatter : undefined,
immutableTypes: options.immutableTypes || false,
rawSchema: options.rawSchema || false,
version: options.version || swaggerVersion(schema),
};
let output = WARNING_MESSAGE;
const rootTypes = transformAll(schema, { ...ctx });
for (const k of Object.keys(rootTypes)) {
if (typeof rootTypes[k] !== "string")
continue;
output += `export interface ${k} {\n ${rootTypes[k]}\n}\n\n`;
}
let prettierOptions = {

@@ -26,0 +32,0 @@ parser: "typescript",

@@ -1,5 +0,6 @@

import { HeaderObject, SchemaFormatter } from "../types";
export declare function transformHeaderObjMap(headerMap: Record<string, HeaderObject>, options: {
formatter?: SchemaFormatter;
immutableTypes: boolean;
}): string;
import { GlobalContext, HeaderObject } from "../types";
interface TransformHeadersOptions extends GlobalContext {
required: Set<string>;
}
export declare function transformHeaderObjMap(headerMap: Record<string, HeaderObject>, options: TransformHeadersOptions): string;
export {};

@@ -5,5 +5,6 @@ import { comment, tsReadonly } from "../utils";

let output = "";
Object.entries(headerMap).forEach(([k, v]) => {
for (const k of Object.keys(headerMap)) {
const v = headerMap[k];
if (!v.schema)
return;
continue;
if (v.description)

@@ -14,5 +15,5 @@ output += comment(v.description);

output += ` ${readonly}"${k}"${required}: ${transformSchemaObj(v.schema, options)}\n`;
});
}
return output;
}
//# sourceMappingURL=headers.js.map

@@ -1,9 +0,2 @@

import { SchemaFormatter } from "../types";
interface TransformOptions {
formatter?: SchemaFormatter;
immutableTypes: boolean;
rawSchema?: boolean;
version: number;
}
export declare function transformAll(schema: any, { formatter, immutableTypes, rawSchema, version }: TransformOptions): string;
export {};
import { GlobalContext } from "../types";
export declare function transformAll(schema: any, ctx: GlobalContext): Record<string, string>;

@@ -5,58 +5,46 @@ import { comment, tsReadonly } from "../utils";

import { transformPathsObj } from "./paths";
import { transformResponsesObj, transformRequestBodies } from "./responses";
import { transformRequestBodies } from "./request";
import { transformResponsesObj } from "./responses";
import { transformSchemaObjMap } from "./schema";
export function transformAll(schema, { formatter, immutableTypes, rawSchema, version }) {
const readonly = tsReadonly(immutableTypes);
let output = "";
export function transformAll(schema, ctx) {
const readonly = tsReadonly(ctx.immutableTypes);
let output = {};
let operations = {};
if (rawSchema) {
switch (version) {
if (ctx.rawSchema) {
const required = new Set(Object.keys(schema));
switch (ctx.version) {
case 2: {
return `export interface definitions {\n ${transformSchemaObjMap(schema, {
formatter,
immutableTypes,
required: Object.keys(schema),
})}\n}`;
output.definitions = transformSchemaObjMap(schema, { ...ctx, required });
return output;
}
case 3: {
return `export interface schemas {\n ${transformSchemaObjMap(schema, {
formatter,
immutableTypes,
required: Object.keys(schema),
})}\n }\n\n`;
output.schemas = transformSchemaObjMap(schema, { ...ctx, required });
return output;
}
}
}
output += `export interface paths {\n`;
output.paths = "";
if (schema.paths) {
output += transformPathsObj(schema.paths, {
output.paths += transformPathsObj(schema.paths, {
...ctx,
globalParameters: (schema.components && schema.components.parameters) || schema.parameters,
immutableTypes,
operations,
version,
});
}
output += `}\n\n`;
switch (version) {
switch (ctx.version) {
case 2: {
if (schema.definitions) {
output += `export interface definitions {\n ${transformSchemaObjMap(schema.definitions, {
formatter,
immutableTypes,
required: Object.keys(schema.definitions),
})}\n}\n\n`;
output.definitions = transformSchemaObjMap(schema.definitions, {
...ctx,
required: new Set(Object.keys(schema.definitions)),
});
}
if (schema.parameters) {
const required = Object.keys(schema.parameters);
output += `export interface parameters {\n ${transformSchemaObjMap(schema.parameters, {
formatter,
immutableTypes,
required,
})}\n }\n\n`;
output.parameters = transformSchemaObjMap(schema.parameters, {
...ctx,
required: new Set(Object.keys(schema.parameters)),
});
}
if (schema.responses) {
output += `export interface responses {\n ${transformResponsesObj(schema.responses, {
formatter,
immutableTypes,
})}\n }\n\n`;
output.responses = transformResponsesObj(schema.responses, ctx);
}

@@ -66,59 +54,52 @@ break;

case 3: {
output += `export interface components {\n`;
output.components = "";
if (schema.components) {
if (schema.components.schemas) {
const required = Object.keys(schema.components.schemas);
output += ` ${readonly}schemas: {\n ${transformSchemaObjMap(schema.components.schemas, {
formatter,
immutableTypes,
required,
output.components += ` ${readonly}schemas: {\n ${transformSchemaObjMap(schema.components.schemas, {
...ctx,
required: new Set(Object.keys(schema.components.schemas)),
})}\n }\n`;
}
if (schema.components.responses) {
output += ` ${readonly}responses: {\n ${transformResponsesObj(schema.components.responses, {
formatter,
immutableTypes,
})}\n }\n`;
output.components += ` ${readonly}responses: {\n ${transformResponsesObj(schema.components.responses, ctx)}\n }\n`;
}
if (schema.components.parameters) {
const required = Object.keys(schema.components.parameters);
output += ` ${readonly}parameters: {\n ${transformSchemaObjMap(schema.components.parameters, {
formatter,
immutableTypes,
required,
output.components += ` ${readonly}parameters: {\n ${transformSchemaObjMap(schema.components.parameters, {
...ctx,
required: new Set(Object.keys(schema.components.parameters)),
})}\n }\n`;
}
if (schema.components.requestBodies) {
output += ` ${readonly}requestBodies: {\n ${transformRequestBodies(schema.components.requestBodies, {
formatter,
immutableTypes,
})}\n }\n`;
output.components += ` ${readonly}requestBodies: {\n ${transformRequestBodies(schema.components.requestBodies, ctx)}\n }\n`;
}
if (schema.components.headers) {
output += ` ${readonly}headers: {\n ${transformHeaderObjMap(schema.components.headers, {
formatter,
immutableTypes,
})} }\n`;
output.components += ` ${readonly}headers: {\n ${transformHeaderObjMap(schema.components.headers, {
...ctx,
required: new Set(),
})}\n }\n`;
}
}
output += `}\n\n`;
break;
}
}
output += `export interface operations {\n`;
output.operations = "";
if (Object.keys(operations).length) {
Object.entries(operations).forEach(([operationId, { operation, pathItem }]) => {
for (const id of Object.keys(operations)) {
const { operation, pathItem } = operations[id];
if (operation.description)
output += comment(operation.description);
output += ` ${readonly}"${operationId}": {\n ${transformOperationObj(operation, {
output.operations += comment(operation.description);
output.operations += ` ${readonly}"${id}": {\n ${transformOperationObj(operation, {
...ctx,
pathItem,
globalParameters: (schema.components && schema.components.parameters) || schema.parameters,
immutableTypes,
version,
})}\n }\n`;
});
}
}
output += `}\n`;
return output.trim();
for (const k of Object.keys(output)) {
if (typeof output[k] === "string") {
output[k] = output[k].trim();
}
}
return output;
}
//# sourceMappingURL=index.js.map

@@ -1,10 +0,7 @@

import { OperationObject, ParameterObject, PathItemObject, RequestBody } from "../types";
export declare function transformOperationObj(operation: OperationObject, { globalParameters, immutableTypes, pathItem, version, }: {
import { GlobalContext, OperationObject, ParameterObject, PathItemObject } from "../types";
interface TransformOperationOptions extends GlobalContext {
globalParameters?: Record<string, ParameterObject>;
pathItem?: PathItemObject;
globalParameters?: Record<string, ParameterObject>;
immutableTypes: boolean;
version: number;
}): string;
export declare function transformRequestBodyObj(requestBody: RequestBody, { immutableTypes }: {
immutableTypes: boolean;
}): string;
}
export declare function transformOperationObj(operation: OperationObject, options: TransformOperationOptions): string;
export {};
import { comment, isRef, transformRef, tsReadonly } from "../utils";
import { transformParametersArray } from "./parameters";
import { transformRequestBodyObj } from "./request";
import { transformResponsesObj } from "./responses";
import { transformSchemaObj } from "./schema";
export function transformOperationObj(operation, { globalParameters, immutableTypes, pathItem = {}, version, }) {
const readonly = tsReadonly(immutableTypes);
export function transformOperationObj(operation, options) {
const { pathItem = {}, globalParameters, ...ctx } = options;
const readonly = tsReadonly(ctx.immutableTypes);
let output = "";

@@ -11,11 +12,8 @@ if (operation.parameters || pathItem.parameters) {

output += ` ${readonly}parameters: {\n ${transformParametersArray(parameters, {
...ctx,
globalParameters,
immutableTypes,
version,
})}\n }\n`;
}
if (operation.responses) {
output += ` ${readonly}responses: {\n ${transformResponsesObj(operation.responses, {
immutableTypes,
})}\n }\n`;
output += ` ${readonly}responses: {\n ${transformResponsesObj(operation.responses, ctx)}\n }\n`;
}

@@ -29,5 +27,3 @@ if (operation.requestBody) {

output += comment(operation.requestBody.description);
output += ` ${readonly}requestBody: {\n`;
output += ` ${transformRequestBodyObj(operation.requestBody, { immutableTypes })}`;
output += ` }\n`;
output += ` ${readonly}requestBody: {\n ${transformRequestBodyObj(operation.requestBody, ctx)} }\n`;
}

@@ -37,18 +33,2 @@ }

}
export function transformRequestBodyObj(requestBody, { immutableTypes }) {
const readonly = tsReadonly(immutableTypes);
let output = "";
const { content } = requestBody;
if (content && Object.keys(content).length) {
output += ` ${readonly}content: {\n`;
Object.entries(content).forEach(([k, v]) => {
output += ` ${readonly}"${k}": ${transformSchemaObj(v.schema, { immutableTypes })};\n`;
});
output += ` }\n`;
}
else {
output += ` unknown;\n`;
}
return output;
}
//# sourceMappingURL=operation.js.map

@@ -1,6 +0,6 @@

import { ParameterObject, ReferenceObject } from "../types";
export declare function transformParametersArray(parameters: (ReferenceObject | ParameterObject)[], { globalParameters, immutableTypes, version, }: {
import { GlobalContext, ParameterObject, ReferenceObject } from "../types";
interface TransformParametersOptions extends GlobalContext {
globalParameters?: Record<string, ParameterObject>;
immutableTypes: boolean;
version: number;
}): string;
}
export declare function transformParametersArray(parameters: (ReferenceObject | ParameterObject)[], options: TransformParametersOptions): string;
export {};
import { comment, tsReadonly } from "../utils";
import { transformSchemaObj } from "./schema";
export function transformParametersArray(parameters, { globalParameters, immutableTypes, version, }) {
const readonly = tsReadonly(immutableTypes);
export function transformParametersArray(parameters, options) {
const { globalParameters = {}, ...ctx } = options;
const readonly = tsReadonly(ctx.immutableTypes);
let output = "";
let mappedParams = {};
parameters.forEach((paramObj) => {
for (const paramObj of parameters) {
if (paramObj.$ref && globalParameters) {

@@ -14,26 +15,30 @@ const paramName = paramObj.$ref.split("/").pop();

mappedParams[reference.in] = {};
if (version === 2) {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
$ref: paramObj.$ref,
};
switch (ctx.version) {
case 3: {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
schema: { $ref: paramObj.$ref },
};
break;
}
case 2: {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
$ref: paramObj.$ref,
};
break;
}
}
else if (version === 3) {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
schema: { $ref: paramObj.$ref },
};
}
}
return;
continue;
}
if (!paramObj.in || !paramObj.name)
return;
continue;
if (!mappedParams[paramObj.in])
mappedParams[paramObj.in] = {};
mappedParams[paramObj.in][paramObj.name] = paramObj;
});
Object.entries(mappedParams).forEach(([paramIn, paramGroup]) => {
}
for (const [paramIn, paramGroup] of Object.entries(mappedParams)) {
output += ` ${readonly}${paramIn}: {\n`;
Object.entries(paramGroup).forEach(([paramName, paramObj]) => {
for (const [paramName, paramObj] of Object.entries(paramGroup)) {
let paramComment = "";

@@ -48,22 +53,28 @@ if (paramObj.deprecated)

let paramType = ``;
if (version === 2) {
if (paramObj.in === "body" && paramObj.schema) {
paramType = transformSchemaObj(paramObj.schema, { immutableTypes });
switch (ctx.version) {
case 3: {
paramType = paramObj.schema
? transformSchemaObj(paramObj.schema, { ...ctx, required: new Set() })
: "unknown";
break;
}
else if (paramObj.type) {
paramType = transformSchemaObj(paramObj, { immutableTypes });
case 2: {
if (paramObj.in === "body" && paramObj.schema) {
paramType = transformSchemaObj(paramObj.schema, { ...ctx, required: new Set() });
}
else if (paramObj.type) {
paramType = transformSchemaObj(paramObj, { ...ctx, required: new Set() });
}
else {
paramType = "unknown";
}
break;
}
else {
paramType = "unknown";
}
}
else if (version === 3) {
paramType = paramObj.schema ? transformSchemaObj(paramObj.schema, { immutableTypes }) : "unknown";
}
output += ` ${readonly}"${paramName}"${required}: ${paramType};\n`;
});
}
output += ` }\n`;
});
}
return output;
}
//# sourceMappingURL=parameters.js.map

@@ -1,5 +0,4 @@

import { OperationObject, ParameterObject, PathItemObject } from "../types";
interface TransformPathsObjOption {
import { GlobalContext, OperationObject, ParameterObject, PathItemObject } from "../types";
interface TransformPathsObjOption extends GlobalContext {
globalParameters: Record<string, ParameterObject>;
immutableTypes: boolean;
operations: Record<string, {

@@ -9,5 +8,4 @@ operation: OperationObject;

}>;
version: number;
}
export declare function transformPathsObj(paths: Record<string, PathItemObject>, { globalParameters, immutableTypes, operations, version }: TransformPathsObjOption): string;
export declare function transformPathsObj(paths: Record<string, PathItemObject>, options: TransformPathsObjOption): string;
export {};
import { comment, transformRef, tsReadonly } from "../utils";
import { transformOperationObj } from "./operation";
import { transformParametersArray } from "./parameters";
export function transformPathsObj(paths, { globalParameters, immutableTypes, operations, version }) {
const readonly = tsReadonly(immutableTypes);
export function transformPathsObj(paths, options) {
const { globalParameters, operations, ...ctx } = options;
const readonly = tsReadonly(ctx.immutableTypes);
let output = "";
Object.entries(paths).forEach(([url, pathItem]) => {
for (const [url, pathItem] of Object.entries(paths)) {
if (pathItem.description)

@@ -12,9 +13,9 @@ output += comment(pathItem.description);

output += ` ${readonly}"${url}": ${transformRef(pathItem.$ref)};\n`;
return;
continue;
}
output += ` ${readonly}"${url}": {\n`;
["get", "put", "post", "delete", "options", "head", "patch", "trace"].forEach((method) => {
for (const method of ["get", "put", "post", "delete", "options", "head", "patch", "trace"]) {
const operation = pathItem[method];
if (!operation)
return;
continue;
if (operation.description)

@@ -25,22 +26,21 @@ output += comment(operation.description);

output += ` ${readonly}"${method}": operations["${operation.operationId}"];\n`;
return;
}
output += ` ${readonly}"${method}": {\n ${transformOperationObj(operation, {
globalParameters,
immutableTypes,
pathItem,
version,
})}\n }\n`;
});
else {
output += ` ${readonly}"${method}": {\n ${transformOperationObj(operation, {
...ctx,
globalParameters,
pathItem,
})}\n }\n`;
}
}
if (pathItem.parameters) {
output += ` ${readonly}parameters: {\n ${transformParametersArray(pathItem.parameters, {
...ctx,
globalParameters,
immutableTypes,
version,
})}\n }\n`;
}
output += ` }\n`;
});
}
return output;
}
//# sourceMappingURL=paths.js.map

@@ -1,8 +0,2 @@

import { RequestBody, SchemaFormatter } from "../types";
interface Options {
formatter?: SchemaFormatter;
immutableTypes: boolean;
}
export declare function transformResponsesObj(responsesObj: Record<string, any>, options: Options): string;
export declare function transformRequestBodies(requestBodies: Record<string, RequestBody>, options: Options): string;
export {};
import { GlobalContext } from "../types";
export declare function transformResponsesObj(responsesObj: Record<string, any>, ctx: GlobalContext): string;
import { comment, transformRef, tsReadonly } from "../utils";
import { transformHeaderObjMap } from "./headers";
import { transformSchemaObj } from "./schema";
import { transformRequestBodyObj } from "./operation";
const resType = (res) => (res === 204 || (res >= 300 && res < 400) ? "never" : "unknown");
export function transformResponsesObj(responsesObj, options) {
const { immutableTypes } = options;
const readonly = tsReadonly(immutableTypes);
export function transformResponsesObj(responsesObj, ctx) {
const readonly = tsReadonly(ctx.immutableTypes);
let output = "";
Object.entries(responsesObj).forEach(([httpStatusCode, response]) => {
for (const httpStatusCode of Object.keys(responsesObj)) {
const statusCode = Number(httpStatusCode) || `"${httpStatusCode}"`;
const response = responsesObj[httpStatusCode];
if (response.description)
output += comment(response.description);
const statusCode = Number(httpStatusCode) || `"${httpStatusCode}"`;
if (response.$ref) {
output += ` ${readonly}${statusCode}: ${transformRef(response.$ref)};\n`;
return;
continue;
}
if ((!response.content && !response.schema) || (response.content && !Object.keys(response.content).length)) {
output += ` ${readonly}${statusCode}: ${resType(statusCode)};\n`;
return;
continue;
}

@@ -28,33 +27,33 @@ output += ` ${readonly}${statusCode}: {\n`;

else {
output += ` ${readonly}headers: {\n ${transformHeaderObjMap(response.headers, options)}\n }\n`;
output += ` ${readonly}headers: {\n ${transformHeaderObjMap(response.headers, {
...ctx,
required: new Set(),
})}\n }\n`;
}
}
if (response.content && Object.keys(response.content).length) {
output += ` ${readonly}content: {\n`;
Object.entries(response.content).forEach(([contentType, contentResponse]) => {
const responseType = contentResponse && contentResponse.schema
? transformSchemaObj(contentResponse.schema, options)
: "unknown";
output += ` ${readonly}"${contentType}": ${responseType};\n`;
});
output += ` }\n`;
switch (ctx.version) {
case 3: {
output += ` ${readonly}content: {\n`;
for (const contentType of Object.keys(response.content)) {
const contentResponse = response.content[contentType];
const responseType = contentResponse && contentResponse?.schema
? transformSchemaObj(contentResponse.schema, { ...ctx, required: new Set() })
: "unknown";
output += ` ${readonly}"${contentType}": ${responseType};\n`;
}
output += ` }\n`;
break;
}
case 2: {
output += ` ${readonly} schema: ${transformSchemaObj(response.schema, {
...ctx,
required: new Set(),
})};\n`;
break;
}
}
else if (response.schema) {
output += ` ${readonly} schema: ${transformSchemaObj(response.schema, options)};\n`;
}
output += ` }\n`;
});
}
return output;
}
export function transformRequestBodies(requestBodies, options) {
let output = "";
Object.entries(requestBodies).forEach(([bodyName, requestBody]) => {
if (requestBody && requestBody.description)
output += ` ${comment(requestBody.description)}`;
output += ` "${bodyName}": {`;
output += ` ${transformRequestBodyObj(requestBody, options)}`;
output += ` }\n`;
});
return output;
}
//# sourceMappingURL=responses.js.map

@@ -1,15 +0,9 @@

import { SchemaFormatter } from "types";
interface TransformSchemaObjMapOptions {
formatter?: SchemaFormatter;
immutableTypes: boolean;
required?: string[];
import { GlobalContext } from "../types";
interface TransformSchemaObjOptions extends GlobalContext {
required: Set<string>;
}
export declare function transformSchemaObjMap(obj: Record<string, any>, options: TransformSchemaObjMapOptions): string;
interface Options {
formatter?: SchemaFormatter;
immutableTypes: boolean;
}
export declare function transformAnyOf(anyOf: any, options: Options): string;
export declare function transformOneOf(oneOf: any, options: Options): string;
export declare function transformSchemaObj(node: any, options: Options): string;
export declare function transformSchemaObjMap(obj: Record<string, any>, options: TransformSchemaObjOptions): string;
export declare function transformAnyOf(anyOf: any, options: TransformSchemaObjOptions): string;
export declare function transformOneOf(oneOf: any, options: TransformSchemaObjOptions): string;
export declare function transformSchemaObj(node: any, options: TransformSchemaObjOptions): string;
export {};

@@ -1,16 +0,13 @@

import { comment, nodeType, transformRef, tsArrayOf, tsIntersectionOf, tsPartial, tsTupleOf, tsUnionOf, } from "../utils";
import { comment, nodeType, transformRef, tsArrayOf, tsIntersectionOf, tsPartial, tsReadonly, tsTupleOf, tsUnionOf, } from "../utils";
export function transformSchemaObjMap(obj, options) {
const readonly = options.immutableTypes ? "readonly " : "";
let required = (options && options.required) || [];
const readonly = tsReadonly(options.immutableTypes);
let output = "";
Object.entries(obj).forEach(([key, value]) => {
if (value.description)
output += comment(value.description);
output += `${readonly}"${key}"${required.includes(key) ? "" : "?"}: `;
output += transformSchemaObj(value.schema || value, {
formatter: options.formatter,
immutableTypes: options.immutableTypes,
});
for (const k of Object.keys(obj)) {
const v = obj[k];
if (v.description)
output += comment(v.description);
output += `${readonly}"${k}"${options.required.has(k) ? "" : "?"}: `;
output += transformSchemaObj(v.schema || v, options);
output += `;\n`;
});
}
return output.replace(/\n+$/, "\n");

@@ -25,3 +22,3 @@ }

export function transformSchemaObj(node, options) {
const readonly = options.immutableTypes ? "readonly " : "";
const readonly = tsReadonly(options.immutableTypes);
let output = "";

@@ -69,9 +66,10 @@ if (node.nullable) {

let properties = transformSchemaObjMap(node.properties || {}, {
immutableTypes: options.immutableTypes,
required: node.required,
...options,
required: new Set(node.required || []),
});
let additionalProperties;
if (node.additionalProperties) {
if (node.additionalProperties === true || Object.keys(node.additionalProperties).length === 0) {
additionalProperties = `{ [key: string]: any }`;
if (node.additionalProperties ||
(node.additionalProperties === undefined && options.additionalProperties && options.version === 3)) {
if ((node.additionalProperties ?? true) === true || Object.keys(node.additionalProperties).length === 0) {
additionalProperties = `{ ${readonly}[key: string]: any }`;
}

@@ -78,0 +76,0 @@ else if (typeof node.additionalProperties === "object") {

@@ -0,1 +1,3 @@

/// <reference types="node" />
import { URL } from "url";
export interface OpenAPI2 {

@@ -106,2 +108,5 @@ swagger: string;

export interface SwaggerToTSOptions {
additionalProperties?: boolean;
auth?: string;
cwd?: URL;
formatter?: SchemaFormatter;

@@ -113,1 +118,11 @@ immutableTypes?: boolean;

}
export interface GlobalContext {
additionalProperties: boolean;
auth?: string;
formatter?: SchemaFormatter;
immutableTypes: boolean;
silent?: boolean;
namespace?: string;
rawSchema: boolean;
version: number;
}
{
"name": "openapi-typescript",
"description": "Generate TypeScript types from Swagger OpenAPI specs",
"version": "3.3.0-next.0",
"version": "3.3.0",
"engines": {

@@ -57,7 +57,8 @@ "node": ">= 10.0.0"

"dependencies": {
"js-yaml": "^4.0.0",
"kleur": "^4.1.3",
"hosted-git-info": "^3.0.8",
"js-yaml": "^4.1.0",
"kleur": "^4.1.4",
"meow": "^9.0.0",
"mime": "^2.5.2",
"prettier": "^2.2.1"
"prettier": "^2.3.0"
},

@@ -67,12 +68,12 @@ "devDependencies": {

"@types/js-yaml": "^4.0.0",
"@typescript-eslint/eslint-plugin": "^4.4.1",
"@typescript-eslint/parser": "^4.4.1",
"@typescript-eslint/eslint-plugin": "^4.24.0",
"@typescript-eslint/parser": "^4.24.0",
"codecov": "^3.8.1",
"eslint": "^7.11.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.1.4",
"jest": "^26.5.3",
"ts-jest": "^26.4.1",
"typescript": "^4.1.3"
"eslint": "^7.26.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"jest": "^26.6.3",
"ts-jest": "^26.5.6",
"typescript": "^4.2.4"
}
}

@@ -6,3 +6,3 @@ [![version(scoped)](https://img.shields.io/npm/v/openapi-typescript.svg)](https://www.npmjs.com/package/openapi-typescript)

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-33-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-34-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

@@ -115,2 +115,3 @@

| `--immutable-types` | | `false` | (optional) Generates immutable types (readonly properties and readonly array). |
| `--additional-properties` | `-ap` | `false` | (optional) Allow arbitrary properties for all schema objects without `additionalProperties: false` |
| `--prettier-config [location]` | | | (optional) Path to your custom Prettier configuration for output |

@@ -242,2 +243,3 @@ | `--raw-schema` | | `false` | Generate TS types from partial schema (e.g. having `components.schema` at the top level) |

<td align="center"><a href="https://www.ashsmith.io"><img src="https://avatars.githubusercontent.com/u/1086841?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ash Smith</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=ashsmith" title="Code">💻</a> <a href="https://github.com/drwpow/openapi-typescript/issues?q=author%3Aashsmith" title="Bug reports">🐛</a> <a href="https://github.com/drwpow/openapi-typescript/commits?author=ashsmith" title="Tests">⚠️</a></td>
<td align="center"><a href="http://mehalter.com"><img src="https://avatars.githubusercontent.com/u/1591837?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Micah Halter</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=mehalter" title="Code">💻</a> <a href="https://github.com/drwpow/openapi-typescript/commits?author=mehalter" title="Tests">⚠️</a> <a href="https://github.com/drwpow/openapi-typescript/issues?q=author%3Amehalter" title="Bug reports">🐛</a></td>
</tr>

@@ -244,0 +246,0 @@ </table>

@@ -6,3 +6,3 @@ import path from "path";

import { transformAll } from "./transform/index";
import { OpenAPI2, OpenAPI3, SchemaObject, SwaggerToTSOptions } from "./types";
import { GlobalContext, OpenAPI2, OpenAPI3, SchemaObject, SwaggerToTSOptions } from "./types";
export * from "./types"; // expose all types to consumers

@@ -20,18 +20,23 @@

schema: OpenAPI2 | OpenAPI3 | Record<string, SchemaObject>,
options?: SwaggerToTSOptions
options: SwaggerToTSOptions = {}
): string {
// 1. determine version
const version = (options && options.version) || swaggerVersion(schema as OpenAPI2 | OpenAPI3);
// 1. set up context
const ctx: GlobalContext = {
auth: options.auth,
additionalProperties: options.additionalProperties || false,
formatter: typeof options.formatter === "function" ? options.formatter : undefined,
immutableTypes: options.immutableTypes || false,
rawSchema: options.rawSchema || false,
version: options.version || swaggerVersion(schema as OpenAPI2 | OpenAPI3),
} as any;
// 2. generate output
let output = `${WARNING_MESSAGE}
${transformAll(schema, {
formatter: options && typeof options.formatter === "function" ? options.formatter : undefined,
immutableTypes: (options && options.immutableTypes) || false,
rawSchema: options && options.rawSchema,
version,
})}
`;
let output = WARNING_MESSAGE;
const rootTypes = transformAll(schema, { ...ctx });
for (const k of Object.keys(rootTypes)) {
if (typeof rootTypes[k] !== "string") continue;
output += `export interface ${k} {\n ${rootTypes[k]}\n}\n\n`;
}
// 3. Prettify output
// 3. Prettify
let prettierOptions: prettier.Options = {

@@ -38,0 +43,0 @@ parser: "typescript",

@@ -1,13 +0,18 @@

import { HeaderObject, SchemaFormatter } from "../types";
import { GlobalContext, HeaderObject } from "../types";
import { comment, tsReadonly } from "../utils";
import { transformSchemaObj } from "./schema";
interface TransformHeadersOptions extends GlobalContext {
required: Set<string>;
}
export function transformHeaderObjMap(
headerMap: Record<string, HeaderObject>,
options: { formatter?: SchemaFormatter; immutableTypes: boolean }
options: TransformHeadersOptions
): string {
let output = "";
Object.entries(headerMap).forEach(([k, v]) => {
if (!v.schema) return;
for (const k of Object.keys(headerMap)) {
const v = headerMap[k];
if (!v.schema) continue;

@@ -20,5 +25,5 @@ if (v.description) output += comment(v.description);

output += ` ${readonly}"${k}"${required}: ${transformSchemaObj(v.schema, options)}\n`;
});
}
return output;
}

@@ -1,2 +0,2 @@

import { OperationObject, PathItemObject, SchemaFormatter } from "../types";
import { GlobalContext, OperationObject, PathItemObject } from "../types";
import { comment, tsReadonly } from "../utils";

@@ -6,35 +6,24 @@ import { transformHeaderObjMap } from "./headers";

import { transformPathsObj } from "./paths";
import { transformResponsesObj, transformRequestBodies } from "./responses";
import { transformRequestBodies } from "./request";
import { transformResponsesObj } from "./responses";
import { transformSchemaObjMap } from "./schema";
interface TransformOptions {
formatter?: SchemaFormatter;
immutableTypes: boolean;
rawSchema?: boolean;
version: number;
}
export function transformAll(schema: any, ctx: GlobalContext): Record<string, string> {
const readonly = tsReadonly(ctx.immutableTypes);
export function transformAll(schema: any, { formatter, immutableTypes, rawSchema, version }: TransformOptions): string {
const readonly = tsReadonly(immutableTypes);
let output: Record<string, string> = {};
let output = "";
let operations: Record<string, { operation: OperationObject; pathItem: PathItemObject }> = {};
// --raw-schema mode
if (rawSchema) {
switch (version) {
if (ctx.rawSchema) {
const required = new Set(Object.keys(schema));
switch (ctx.version) {
case 2: {
return `export interface definitions {\n ${transformSchemaObjMap(schema, {
formatter,
immutableTypes,
required: Object.keys(schema),
})}\n}`;
output.definitions = transformSchemaObjMap(schema, { ...ctx, required });
return output;
}
case 3: {
return `export interface schemas {\n ${transformSchemaObjMap(schema, {
formatter,
immutableTypes,
required: Object.keys(schema),
})}\n }\n\n`;
output.schemas = transformSchemaObjMap(schema, { ...ctx, required });
return output;
}

@@ -45,22 +34,19 @@ }

// #/paths (V2 & V3)
output += `export interface paths {\n`; // open paths
output.paths = ""; // open paths
if (schema.paths) {
output += transformPathsObj(schema.paths, {
output.paths += transformPathsObj(schema.paths, {
...ctx,
globalParameters: (schema.components && schema.components.parameters) || schema.parameters,
immutableTypes,
operations,
version,
});
}
output += `}\n\n`; // close paths
switch (version) {
switch (ctx.version) {
case 2: {
// #/definitions
if (schema.definitions) {
output += `export interface definitions {\n ${transformSchemaObjMap(schema.definitions, {
formatter,
immutableTypes,
required: Object.keys(schema.definitions),
})}\n}\n\n`;
output.definitions = transformSchemaObjMap(schema.definitions, {
...ctx,
required: new Set(Object.keys(schema.definitions)),
});
}

@@ -70,8 +56,6 @@

if (schema.parameters) {
const required = Object.keys(schema.parameters);
output += `export interface parameters {\n ${transformSchemaObjMap(schema.parameters, {
formatter,
immutableTypes,
required,
})}\n }\n\n`;
output.parameters = transformSchemaObjMap(schema.parameters, {
...ctx,
required: new Set(Object.keys(schema.parameters)),
});
}

@@ -81,6 +65,3 @@

if (schema.responses) {
output += `export interface responses {\n ${transformResponsesObj(schema.responses, {
formatter,
immutableTypes,
})}\n }\n\n`;
output.responses = transformResponsesObj(schema.responses, ctx);
}

@@ -91,3 +72,3 @@ break;

// #/components
output += `export interface components {\n`; // open components
output.components = "";

@@ -97,7 +78,5 @@ if (schema.components) {

if (schema.components.schemas) {
const required = Object.keys(schema.components.schemas);
output += ` ${readonly}schemas: {\n ${transformSchemaObjMap(schema.components.schemas, {
formatter,
immutableTypes,
required,
output.components += ` ${readonly}schemas: {\n ${transformSchemaObjMap(schema.components.schemas, {
...ctx,
required: new Set(Object.keys(schema.components.schemas)),
})}\n }\n`;

@@ -108,6 +87,6 @@ }

if (schema.components.responses) {
output += ` ${readonly}responses: {\n ${transformResponsesObj(schema.components.responses, {
formatter,
immutableTypes,
})}\n }\n`;
output.components += ` ${readonly}responses: {\n ${transformResponsesObj(
schema.components.responses,
ctx
)}\n }\n`;
}

@@ -117,7 +96,5 @@

if (schema.components.parameters) {
const required = Object.keys(schema.components.parameters);
output += ` ${readonly}parameters: {\n ${transformSchemaObjMap(schema.components.parameters, {
formatter,
immutableTypes,
required,
output.components += ` ${readonly}parameters: {\n ${transformSchemaObjMap(schema.components.parameters, {
...ctx,
required: new Set(Object.keys(schema.components.parameters)),
})}\n }\n`;

@@ -128,6 +105,6 @@ }

if (schema.components.requestBodies) {
output += ` ${readonly}requestBodies: {\n ${transformRequestBodies(schema.components.requestBodies, {
formatter,
immutableTypes,
})}\n }\n`;
output.components += ` ${readonly}requestBodies: {\n ${transformRequestBodies(
schema.components.requestBodies,
ctx
)}\n }\n`;
}

@@ -137,10 +114,8 @@

if (schema.components.headers) {
output += ` ${readonly}headers: {\n ${transformHeaderObjMap(schema.components.headers, {
formatter,
immutableTypes,
})} }\n`;
output.components += ` ${readonly}headers: {\n ${transformHeaderObjMap(schema.components.headers, {
...ctx,
required: new Set<string>(),
})}\n }\n`;
}
}
output += `}\n\n`; // close components
break;

@@ -150,17 +125,24 @@ }

output += `export interface operations {\n`; // open operations
// #/operations
output.operations = "";
if (Object.keys(operations).length) {
Object.entries(operations).forEach(([operationId, { operation, pathItem }]) => {
if (operation.description) output += comment(operation.description); // handle comment
output += ` ${readonly}"${operationId}": {\n ${transformOperationObj(operation, {
for (const id of Object.keys(operations)) {
const { operation, pathItem } = operations[id];
if (operation.description) output.operations += comment(operation.description); // handle comment
output.operations += ` ${readonly}"${id}": {\n ${transformOperationObj(operation, {
...ctx,
pathItem,
globalParameters: (schema.components && schema.components.parameters) || schema.parameters,
immutableTypes,
version,
})}\n }\n`;
});
}
}
output += `}\n`; // close operations
return output.trim();
// cleanup: trim whitespace
for (const k of Object.keys(output)) {
if (typeof output[k] === "string") {
output[k] = output[k].trim();
}
}
return output;
}

@@ -1,23 +0,16 @@

import { OperationObject, ParameterObject, PathItemObject, RequestBody } from "../types";
import { GlobalContext, OperationObject, ParameterObject, PathItemObject } from "../types";
import { comment, isRef, transformRef, tsReadonly } from "../utils";
import { transformParametersArray } from "./parameters";
import { transformRequestBodyObj } from "./request";
import { transformResponsesObj } from "./responses";
import { transformSchemaObj } from "./schema";
export function transformOperationObj(
operation: OperationObject,
{
globalParameters,
immutableTypes,
pathItem = {},
version,
}: {
pathItem?: PathItemObject;
globalParameters?: Record<string, ParameterObject>;
immutableTypes: boolean;
version: number;
}
): string {
const readonly = tsReadonly(immutableTypes);
interface TransformOperationOptions extends GlobalContext {
globalParameters?: Record<string, ParameterObject>;
pathItem?: PathItemObject;
}
export function transformOperationObj(operation: OperationObject, options: TransformOperationOptions): string {
const { pathItem = {}, globalParameters, ...ctx } = options;
const readonly = tsReadonly(ctx.immutableTypes);
let output = "";

@@ -28,5 +21,4 @@

output += ` ${readonly}parameters: {\n ${transformParametersArray(parameters, {
...ctx,
globalParameters,
immutableTypes,
version,
})}\n }\n`;

@@ -36,5 +28,3 @@ }

if (operation.responses) {
output += ` ${readonly}responses: {\n ${transformResponsesObj(operation.responses, {
immutableTypes,
})}\n }\n`;
output += ` ${readonly}responses: {\n ${transformResponsesObj(operation.responses, ctx)}\n }\n`;
}

@@ -47,6 +37,3 @@

if (operation.requestBody.description) output += comment(operation.requestBody.description);
output += ` ${readonly}requestBody: {\n`; // open requestBody
output += ` ${transformRequestBodyObj(operation.requestBody, { immutableTypes })}`;
output += ` }\n`; // close requestBody
output += ` ${readonly}requestBody: {\n ${transformRequestBodyObj(operation.requestBody, ctx)} }\n`;
}

@@ -57,25 +44,1 @@ }

}
export function transformRequestBodyObj(
requestBody: RequestBody,
{ immutableTypes }: { immutableTypes: boolean }
): string {
const readonly = tsReadonly(immutableTypes);
let output = "";
const { content } = requestBody;
if (content && Object.keys(content).length) {
output += ` ${readonly}content: {\n`; // open content
Object.entries(content).forEach(([k, v]) => {
output += ` ${readonly}"${k}": ${transformSchemaObj(v.schema, { immutableTypes })};\n`;
});
output += ` }\n`; // close content
} else {
output += ` unknown;\n`;
}
return output;
}

@@ -1,18 +0,15 @@

import { ParameterObject, ReferenceObject } from "../types";
import { GlobalContext, ParameterObject, ReferenceObject } from "../types";
import { comment, tsReadonly } from "../utils";
import { transformSchemaObj } from "./schema";
interface TransformParametersOptions extends GlobalContext {
globalParameters?: Record<string, ParameterObject>;
}
export function transformParametersArray(
parameters: (ReferenceObject | ParameterObject)[],
{
globalParameters,
immutableTypes,
version,
}: {
globalParameters?: Record<string, ParameterObject>;
immutableTypes: boolean;
version: number;
}
options: TransformParametersOptions
): string {
const readonly = tsReadonly(immutableTypes);
const { globalParameters = {}, ...ctx } = options;
const readonly = tsReadonly(ctx.immutableTypes);

@@ -23,3 +20,3 @@ let output = "";

let mappedParams: Record<string, Record<string, ParameterObject>> = {};
parameters.forEach((paramObj: any) => {
for (const paramObj of parameters as any[]) {
if (paramObj.$ref && globalParameters) {

@@ -30,26 +27,31 @@ const paramName = paramObj.$ref.split("/").pop(); // take last segment

if (!mappedParams[reference.in]) mappedParams[reference.in] = {};
if (version === 2) {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
$ref: paramObj.$ref,
};
} else if (version === 3) {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
schema: { $ref: paramObj.$ref },
};
switch (ctx.version) {
case 3: {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
schema: { $ref: paramObj.$ref },
};
break;
}
case 2: {
mappedParams[reference.in][reference.name || paramName] = {
...reference,
$ref: paramObj.$ref,
};
break;
}
}
}
return;
continue;
}
if (!paramObj.in || !paramObj.name) return;
if (!paramObj.in || !paramObj.name) continue;
if (!mappedParams[paramObj.in]) mappedParams[paramObj.in] = {};
mappedParams[paramObj.in][paramObj.name] = paramObj;
});
}
// transform output
Object.entries(mappedParams).forEach(([paramIn, paramGroup]) => {
for (const [paramIn, paramGroup] of Object.entries(mappedParams)) {
output += ` ${readonly}${paramIn}: {\n`; // open in
Object.entries(paramGroup).forEach(([paramName, paramObj]) => {
for (const [paramName, paramObj] of Object.entries(paramGroup)) {
let paramComment = "";

@@ -62,19 +64,26 @@ if (paramObj.deprecated) paramComment += `@deprecated `;

let paramType = ``;
if (version === 2) {
if (paramObj.in === "body" && paramObj.schema) {
paramType = transformSchemaObj(paramObj.schema, { immutableTypes });
} else if (paramObj.type) {
paramType = transformSchemaObj(paramObj, { immutableTypes });
} else {
paramType = "unknown";
switch (ctx.version) {
case 3: {
paramType = paramObj.schema
? transformSchemaObj(paramObj.schema, { ...ctx, required: new Set<string>() })
: "unknown";
break;
}
} else if (version === 3) {
paramType = paramObj.schema ? transformSchemaObj(paramObj.schema, { immutableTypes }) : "unknown";
case 2: {
if (paramObj.in === "body" && paramObj.schema) {
paramType = transformSchemaObj(paramObj.schema, { ...ctx, required: new Set<string>() });
} else if (paramObj.type) {
paramType = transformSchemaObj(paramObj, { ...ctx, required: new Set<string>() });
} else {
paramType = "unknown";
}
break;
}
}
output += ` ${readonly}"${paramName}"${required}: ${paramType};\n`;
});
}
output += ` }\n`; // close in
});
}
return output;
}

@@ -1,2 +0,2 @@

import { OperationObject, ParameterObject, PathItemObject } from "../types";
import { GlobalContext, OperationObject, ParameterObject, PathItemObject } from "../types";
import { comment, transformRef, tsReadonly } from "../utils";

@@ -6,19 +6,15 @@ import { transformOperationObj } from "./operation";

interface TransformPathsObjOption {
interface TransformPathsObjOption extends GlobalContext {
globalParameters: Record<string, ParameterObject>;
immutableTypes: boolean;
operations: Record<string, { operation: OperationObject; pathItem: PathItemObject }>;
version: number;
}
/** Note: this needs to mutate objects passed in */
export function transformPathsObj(
paths: Record<string, PathItemObject>,
{ globalParameters, immutableTypes, operations, version }: TransformPathsObjOption
): string {
const readonly = tsReadonly(immutableTypes);
export function transformPathsObj(paths: Record<string, PathItemObject>, options: TransformPathsObjOption): string {
const { globalParameters, operations, ...ctx } = options;
const readonly = tsReadonly(ctx.immutableTypes);
let output = "";
Object.entries(paths).forEach(([url, pathItem]) => {
for (const [url, pathItem] of Object.entries(paths)) {
if (pathItem.description) output += comment(pathItem.description); // add comment

@@ -28,3 +24,3 @@

output += ` ${readonly}"${url}": ${transformRef(pathItem.$ref)};\n`;
return;
continue;
}

@@ -35,23 +31,19 @@

// methods
["get", "put", "post", "delete", "options", "head", "patch", "trace"].forEach((method) => {
for (const method of ["get", "put", "post", "delete", "options", "head", "patch", "trace"]) {
const operation = (pathItem as any)[method];
if (!operation) return; // only allow valid methods
if (!operation) continue; // only allow valid methods
if (operation.description) output += comment(operation.description); // add comment
// if operation has operationId, abstract into top-level operations object
if (operation.operationId) {
// if operation has operationId, abstract into top-level operations object
operations[operation.operationId] = { operation, pathItem };
output += ` ${readonly}"${method}": operations["${operation.operationId}"];\n`;
return;
} else {
// otherwise, inline operation
output += ` ${readonly}"${method}": {\n ${transformOperationObj(operation, {
...ctx,
globalParameters,
pathItem,
})}\n }\n`;
}
// otherwise, inline operation
output += ` ${readonly}"${method}": {\n ${transformOperationObj(operation, {
globalParameters,
immutableTypes,
pathItem,
version,
})}\n }\n`;
});
}

@@ -61,5 +53,4 @@ // parameters

output += ` ${readonly}parameters: {\n ${transformParametersArray(pathItem.parameters, {
...ctx,
globalParameters,
immutableTypes,
version,
})}\n }\n`;

@@ -69,5 +60,5 @@ }

output += ` }\n`; // close PathItem
});
}
return output;
}

@@ -1,28 +0,21 @@

import { RequestBody, SchemaFormatter } from "../types";
import { GlobalContext } from "../types";
import { comment, transformRef, tsReadonly } from "../utils";
import { transformHeaderObjMap } from "./headers";
import { transformSchemaObj } from "./schema";
import { transformRequestBodyObj } from "./operation";
const resType = (res: string | number) => (res === 204 || (res >= 300 && res < 400) ? "never" : "unknown");
interface Options {
formatter?: SchemaFormatter;
immutableTypes: boolean;
}
export function transformResponsesObj(responsesObj: Record<string, any>, ctx: GlobalContext): string {
const readonly = tsReadonly(ctx.immutableTypes);
export function transformResponsesObj(responsesObj: Record<string, any>, options: Options): string {
const { immutableTypes } = options;
const readonly = tsReadonly(immutableTypes);
let output = "";
Object.entries(responsesObj).forEach(([httpStatusCode, response]) => {
for (const httpStatusCode of Object.keys(responsesObj)) {
const statusCode = Number(httpStatusCode) || `"${httpStatusCode}"`; // don’t surround w/ quotes if numeric status code
const response = responsesObj[httpStatusCode];
if (response.description) output += comment(response.description);
const statusCode = Number(httpStatusCode) || `"${httpStatusCode}"`; // don’t surround w/ quotes if numeric status code
if (response.$ref) {
output += ` ${readonly}${statusCode}: ${transformRef(response.$ref)};\n`; // reference
return;
continue;
}

@@ -32,3 +25,3 @@

output += ` ${readonly}${statusCode}: ${resType(statusCode)};\n`; // unknown / missing response
return;
continue;
}

@@ -43,3 +36,6 @@

} else {
output += ` ${readonly}headers: {\n ${transformHeaderObjMap(response.headers, options)}\n }\n`;
output += ` ${readonly}headers: {\n ${transformHeaderObjMap(response.headers, {
...ctx,
required: new Set<string>(),
})}\n }\n`;
}

@@ -49,34 +45,30 @@ }

// response
if (response.content && Object.keys(response.content).length) {
// V3
output += ` ${readonly}content: {\n`; // open content
Object.entries(response.content).forEach(([contentType, contentResponse]) => {
const responseType =
contentResponse && (contentResponse as any).schema
? transformSchemaObj((contentResponse as any).schema, options)
: "unknown";
output += ` ${readonly}"${contentType}": ${responseType};\n`;
});
output += ` }\n`; //close content
} else if (response.schema) {
// V2 (note: because of the presence of "headers", we have to namespace this somehow; "schema" seemed natural)
output += ` ${readonly} schema: ${transformSchemaObj(response.schema, options)};\n`;
switch (ctx.version) {
case 3: {
output += ` ${readonly}content: {\n`; // open content
for (const contentType of Object.keys(response.content)) {
const contentResponse = response.content[contentType] as any;
const responseType =
contentResponse && contentResponse?.schema
? transformSchemaObj(contentResponse.schema, { ...ctx, required: new Set<string>() })
: "unknown";
output += ` ${readonly}"${contentType}": ${responseType};\n`;
}
output += ` }\n`; // close content
break;
}
case 2: {
// note: because of the presence of "headers", we have to namespace this somehow; "schema" seemed natural
output += ` ${readonly} schema: ${transformSchemaObj(response.schema, {
...ctx,
required: new Set<string>(),
})};\n`;
break;
}
}
output += ` }\n`; // close response
});
return output;
}
}
export function transformRequestBodies(requestBodies: Record<string, RequestBody>, options: Options) {
let output = "";
Object.entries(requestBodies).forEach(([bodyName, requestBody]) => {
if (requestBody && requestBody.description) output += ` ${comment(requestBody.description)}`;
output += ` "${bodyName}": {`;
output += ` ${transformRequestBodyObj(requestBody, options)}`;
output += ` }\n`;
});
return output;
}

@@ -1,2 +0,2 @@

import { SchemaFormatter } from "types";
import { GlobalContext } from "../types";
import {

@@ -9,2 +9,3 @@ comment,

tsPartial,
tsReadonly,
tsTupleOf,

@@ -14,31 +15,26 @@ tsUnionOf,

interface TransformSchemaObjMapOptions {
formatter?: SchemaFormatter;
immutableTypes: boolean;
required?: string[];
interface TransformSchemaObjOptions extends GlobalContext {
required: Set<string>;
}
/** Take object keys and convert to TypeScript interface */
export function transformSchemaObjMap(obj: Record<string, any>, options: TransformSchemaObjMapOptions): string {
const readonly = options.immutableTypes ? "readonly " : "";
let required = (options && options.required) || [];
export function transformSchemaObjMap(obj: Record<string, any>, options: TransformSchemaObjOptions): string {
const readonly = tsReadonly(options.immutableTypes);
let output = "";
Object.entries(obj).forEach(([key, value]) => {
for (const k of Object.keys(obj)) {
const v = obj[k];
// 1. JSDoc comment (goes above property)
if (value.description) output += comment(value.description);
if (v.description) output += comment(v.description);
// 2. name (with “?” if optional property)
output += `${readonly}"${key}"${required.includes(key) ? "" : "?"}: `;
output += `${readonly}"${k}"${options.required.has(k) ? "" : "?"}: `;
// 3. transform
output += transformSchemaObj(value.schema || value, {
formatter: options.formatter,
immutableTypes: options.immutableTypes,
});
output += transformSchemaObj(v.schema || v, options);
// 4. close
output += `;\n`;
});
}

@@ -48,9 +44,4 @@ return output.replace(/\n+$/, "\n"); // replace repeat line endings with only one

interface Options {
formatter?: SchemaFormatter;
immutableTypes: boolean;
}
/** transform anyOf */
export function transformAnyOf(anyOf: any, options: Options): string {
export function transformAnyOf(anyOf: any, options: TransformSchemaObjOptions): string {
return tsIntersectionOf(anyOf.map((s: any) => tsPartial(transformSchemaObj(s, options))));

@@ -60,3 +51,3 @@ }

/** transform oneOf */
export function transformOneOf(oneOf: any, options: Options): string {
export function transformOneOf(oneOf: any, options: TransformSchemaObjOptions): string {
return tsUnionOf(oneOf.map((value: any) => transformSchemaObj(value, options)));

@@ -66,4 +57,4 @@ }

/** Convert schema object to TypeScript */
export function transformSchemaObj(node: any, options: Options): string {
const readonly = options.immutableTypes ? "readonly " : "";
export function transformSchemaObj(node: any, options: TransformSchemaObjOptions): string {
const readonly = tsReadonly(options.immutableTypes);

@@ -118,4 +109,4 @@ let output = "";

let properties = transformSchemaObjMap(node.properties || {}, {
immutableTypes: options.immutableTypes,
required: node.required,
...options,
required: new Set(node.required || []),
});

@@ -125,5 +116,8 @@

let additionalProperties: string | undefined;
if (node.additionalProperties) {
if (node.additionalProperties === true || Object.keys(node.additionalProperties).length === 0) {
additionalProperties = `{ [key: string]: any }`;
if (
node.additionalProperties ||
(node.additionalProperties === undefined && options.additionalProperties && options.version === 3)
) {
if ((node.additionalProperties ?? true) === true || Object.keys(node.additionalProperties).length === 0) {
additionalProperties = `{ ${readonly}[key: string]: any }`;
} else if (typeof node.additionalProperties === "object") {

@@ -130,0 +124,0 @@ const oneOf: any[] | undefined = (node.additionalProperties as any).oneOf || undefined; // TypeScript does a really bad job at inference here, so we enforce a type

@@ -0,1 +1,3 @@

import { URL } from "url";
export interface OpenAPI2 {

@@ -114,2 +116,8 @@ swagger: string; // required

export interface SwaggerToTSOptions {
/** Allow arbitrary properties on schemas (default: false) */
additionalProperties?: boolean;
/** (optional) Specify auth if using openapi-typescript to fetch URL */
auth?: string;
/** (optional) Specify current working directory (cwd) to resolve remote schemas on disk (not needed for remote URL schemas) */
cwd?: URL;
/** Specify a formatter */

@@ -126,1 +134,14 @@ formatter?: SchemaFormatter;

}
/** Context passed to all submodules */
export interface GlobalContext {
additionalProperties: boolean;
auth?: string;
formatter?: SchemaFormatter;
immutableTypes: boolean;
/** (optional) Should logging be suppressed? (necessary for STDOUT) */
silent?: boolean;
namespace?: string;
rawSchema: boolean;
version: number;
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc