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

openapi-to-typescript

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

openapi-to-typescript - npm Package Compare versions

Comparing version 3.1.0 to 3.2.0

3

dist/cli.js

@@ -13,3 +13,3 @@ "use strict";

const { typeStore, clientStore } = await _1.GenerateTypings(JSON.parse(fs_1.default.readFileSync(`${argv.input}`).toString()), {
operationFormatters: [formatters_1.FetchClientFormatter]
operationFormatters: [new formatters_1.FetchClientFormatter]
});

@@ -38,3 +38,2 @@ const outputFileWithoutExtension = `${argv.output === true ? argv.input : argv.output}`.replace(/(\.d)?\.ts$/, '');

describe: 'File to read from',
default: false
})

@@ -41,0 +40,0 @@ .option('output', {

@@ -6,9 +6,2 @@ "use strict";

exports.Formatter = Formatter;
class OperationFormatter extends Formatter {
constructor(operation) {
super();
this.operation = operation;
}
}
exports.OperationFormatter = OperationFormatter;
//# sourceMappingURL=formatter.js.map

@@ -5,44 +5,48 @@ "use strict";

const formatter_1 = require("../formatter");
class FetchClientFormatter extends formatter_1.OperationFormatter {
static async renderBoilerplate(apiSchema) {
return [
`const fetch = require('node-fetch')`,
`const pick = (obj:any, keys:string[]) => keys.reduce((picked, key) => obj[key] !== undefined ? Object.assign(picked, {[key]: obj[key]}) : picked, {})`,
`const encodeQuery = (obj:any, keys:string[]) => require('querystring').encode(pick(obj, keys))`,
`const API_URL = ${JSON.stringify(lodash_1.get(apiSchema, 'servers[0].url'))}`,
].join('\n');
const withoutIndentation = (s) => s.replace(/(\s*[\n]+)\s*/g, '\n').trim();
const withoutEmptyLines = (s) => s.replace(/\n+/g, '\n');
class FetchClientFormatter extends formatter_1.Formatter {
constructor({ url } = {}) {
super();
this.url = url;
}
async render() {
const { operationTypeName } = this.names();
return {
[operationTypeName]: this.renderActionType(),
};
async renderBoilerplate(apiSchema) {
const url = this.url || lodash_1.get(apiSchema, 'servers[0].url');
return withoutIndentation(`
const fetch = require('node-fetch')
const pick = (obj:any, keys:string[]) => keys.reduce((picked, key) => obj[key] !== undefined ? Object.assign(picked, {[key]: obj[key]}) : picked, {})
const substitutePath = (pathName:string, body:any) => pathName.split('/').map(dir => dir.startsWith('{') ? body[dir.slice(1,-1)] : dir).join('/')
const encodeQuery = (obj:any, keys:string[]) => require('querystring').encode(pick(obj, keys))
const API_URL = ${JSON.stringify(url)}
`);
}
renderActionType() {
const { operationName, requestTypeName, responseTypeName } = this.names();
return `export type ${operationName} = (payload: ${requestTypeName}) => Promise<${responseTypeName}>;`;
async render(operation) {
const { operationTypeName, operationName, requestTypeName, responseTypeName } = this.names(operation);
const typedef = `export type ${operationName} = (payload: ${requestTypeName}) => Promise<${responseTypeName}>;`;
return { [operationTypeName]: typedef };
}
async renderAction() {
const { operationName, requestTypeName, responseTypeName } = this.names();
const queryParameterNames = this.operation.route.parameters
.filter(param => param.in === 'query')
.map(param => param.name);
const urlCode = queryParameterNames.length ?
`[API_URL, encodeQuery(body, ${JSON.stringify(queryParameterNames)})].filter(x=>x).join('?')` :
'API_URL';
const fetchWrapper = `const ${operationName} =
async renderAction(operation) {
const { operationName, requestTypeName, responseTypeName } = this.names(operation);
const fetchWrapper = withoutEmptyLines(`const ${operationName} =
async (body:${requestTypeName}, options:any):Promise<${responseTypeName}> => {
return fetch(${urlCode}, {
return fetch(${this.urlSnippet(operation)}, {
...options,
method: ${JSON.stringify(this.operation.method)},
body: JSON.stringify(body)
method: ${JSON.stringify(operation.method)},
${operation.route.requestBody ? 'body: JSON.stringify(body),' : ''}
}).then((res:any) => res.json())
}`;
return {
[operationName]: fetchWrapper
};
}`);
return { [operationName]: fetchWrapper };
}
names() {
const operationName = this.operation.name;
const operationTypeName = this.operation.name + 'OperationType';
urlSnippet(operation) {
const queryParameterNames = operation.parameterNamesIn('query');
const endpointURL = operation.hasAnyParametersIn('path') ?
`API_URL + substitutePath(${JSON.stringify(operation.pathName)}, body)` :
`API_URL`;
return queryParameterNames.length ?
`[${endpointURL}, encodeQuery(body, ${JSON.stringify(queryParameterNames)})].filter(x=>x).join('?')` :
endpointURL;
}
names(operation) {
const operationName = operation.name;
const operationTypeName = operation.name + 'OperationType';
const requestTypeName = operationName + 'Request';

@@ -49,0 +53,0 @@ const responseTypeName = operationName + 'Result';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const request_1 = require("./request");
const response_1 = require("./response");
var request_1 = require("./request");
exports.RequestTypeFormatter = request_1.RequestTypeFormatter;
var response_1 = require("./response");
exports.ResultTypeFormatter = response_1.ResultTypeFormatter;
var schema_1 = require("./schema");
exports.SchemaFormatter = schema_1.SchemaFormatter;
exports.defaultOperationFormatters = [
request_1.RequestTypeFormatter,
response_1.ResultTypeFormatter
];
var fetch_1 = require("./fetch");
exports.FetchClientFormatter = fetch_1.FetchClientFormatter;
//# sourceMappingURL=index.js.map

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

const compile_1 = require("../compile");
class RequestTypeFormatter extends formatter_1.OperationFormatter {
async render() {
const typeName = `${this.operation.name}Request`;
const parameters = this.operation.route.parameters || [];
class RequestTypeFormatter extends formatter_1.Formatter {
async render(operation) {
const typeName = `${operation.name}Request`;
const parameters = operation.route.parameters || [];
return {
[typeName]: await this.toTypescriptInterface(typeName, parameters)
[typeName]: await this.toTypescriptInterface(operation, typeName, parameters)
};
}
async toTypescriptInterface(typeName, parameters) {
const requestSchema = lodash_1.get(this.operation.route, 'requestBody.content["application/json"].schema');
async toTypescriptInterface(operation, typeName, parameters) {
const requestSchema = lodash_1.get(operation.route, 'requestBody.content["application/json"].schema');
const aliasedType = requestSchema && requestSchema.$ref && compile_1.getSchemaNameByRef(requestSchema.$ref);

@@ -18,0 +18,0 @@ if (aliasedType)

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

const compile_1 = require("../compile");
class ResultTypeFormatter extends formatter_1.OperationFormatter {
class ResultTypeFormatter extends formatter_1.Formatter {
constructor() {

@@ -12,4 +12,4 @@ super(...arguments);

}
async render() {
const definitions = this.getResponseSchemaDefinitions();
async render(operation) {
const definitions = this.getResponseSchemaDefinitions(operation);
const compilations = await Promise.all(definitions.map(({ schema, typeName }) => this.compileDefinition(schema, typeName)));

@@ -25,9 +25,9 @@ return definitions.reduce((typeDefs, definition, index) => Object.assign(typeDefs, {

}
getResponseSchemaDefinitions() {
const responsesByStatusCode = lodash_1.get(this.operation.route, 'responses', {});
getResponseSchemaDefinitions(operation) {
const responsesByStatusCode = lodash_1.get(operation.route, 'responses', {});
const statusCodes = this.getStatusCodes(responsesByStatusCode);
return statusCodes.map(((statusCode, index) => {
const key = `responses['${statusCode}'].content[${this.contentType}].schema`;
const typeName = this.typeNameFor(index === 0 ? 'Result' : statusCode);
const schema = lodash_1.get(this.operation.route, key);
const typeName = this.typeNameFor(operation, index === 0 ? 'Result' : statusCode);
const schema = lodash_1.get(operation.route, key);
return { schema, statusCode, typeName };

@@ -43,5 +43,5 @@ }));

}
typeNameFor(suffix) {
typeNameFor(operation, suffix) {
return lodash_1.upperFirst(lodash_1.camelCase(`
${this.operation.name}
${operation.name}
${suffix === 'default' ? 'fallback' : suffix.toString()}

@@ -48,0 +48,0 @@ `));

@@ -6,10 +6,9 @@ "use strict";

class SchemaFormatter extends formatter_1.Formatter {
constructor(schema, name) {
constructor(name) {
super();
this.schema = schema;
this.name = name;
}
async render() {
async render(schema) {
return {
[this.name]: await compile_1.compileSchema(this.schema, this.name)
[this.name]: await compile_1.compileSchema(schema, this.name)
};

@@ -16,0 +15,0 @@ }

@@ -14,31 +14,30 @@ "use strict";

const clientStore = new store_1.Store();
const stores = { typeStore, clientStore };
new refs_1.InternalRefRewriter().rewrite(schemas);
new refs_1.InternalRefRewriter().rewrite(paths);
for (const schemaName of Object.keys(schemas)) {
typeStore.assign(await new formatters_1.SchemaFormatter(schemas[schemaName], schemaName).render());
typeStore.assign(await new formatters_1.SchemaFormatter(schemaName).render(schemas[schemaName]));
}
const formatters = [...formatters_1.defaultOperationFormatters, ...operationFormatters];
for (let formatter of formatters) {
if (typeof formatter.renderBoilerplate === 'function') {
clientStore.assign({
[formatters.indexOf(formatter)]: await formatter.renderBoilerplate(apiSchema)
});
}
const formatters = [
new formatters_1.RequestTypeFormatter,
new formatters_1.ResultTypeFormatter,
...operationFormatters
];
const hasBoilerplate = (formatter) => typeof formatter.renderBoilerplate === 'function';
for (let formatter of formatters.filter(hasBoilerplate))
clientStore.assign({
[formatters.indexOf(formatter)]: await formatter.renderBoilerplate(apiSchema)
});
for (const operation of operation_1.eachOperation(paths)) {
await applyFormatters(operation, formatters, stores);
}
for (const pathName of Object.keys(paths)) {
for (const method of Object.keys(paths[pathName])) {
const operation = new operation_1.Operation(paths[pathName][method], { pathName, method });
for (const OperationFormatter of formatters) {
const formatter = new OperationFormatter(operation);
typeStore.assign(await formatter.render());
if (typeof formatter.renderAction === 'function')
clientStore.assign(await formatter.renderAction());
}
}
return stores;
};
async function applyFormatters(operation, formatters, { typeStore, clientStore }) {
for (const formatter of formatters) {
typeStore.assign(await formatter.render(operation));
if (typeof formatter.renderAction === 'function')
clientStore.assign(await formatter.renderAction(operation));
}
return {
typeStore,
clientStore,
};
};
}
//# sourceMappingURL=index.js.map

@@ -10,5 +10,27 @@ "use strict";

this.method = method;
this.pathName = pathName;
}
hasAnyParametersIn(parameterLocation) {
return !!(this.route.parameters || []).find((param) => param.in === parameterLocation);
}
parametersIn(parameterLocation) {
return (this.route.parameters || []).filter(param => param.in === parameterLocation);
}
parameterNamesIn(parameterLocation) {
return this.parametersIn(parameterLocation).map(param => param.name);
}
}
exports.Operation = Operation;
function eachOperation(paths) {
return {
*[Symbol.iterator]() {
for (const pathName of Object.keys(paths)) {
for (const method of Object.keys(paths[pathName])) {
yield new Operation(paths[pathName][method], { pathName, method });
}
}
}
};
}
exports.eachOperation = eachOperation;
//# sourceMappingURL=operation.js.map
{
"name": "openapi-to-typescript",
"version": "3.1.0",
"version": "3.2.0",
"description": "Generate TypeScript typings based on an OpenAPI schema object.",

@@ -16,3 +16,5 @@ "main": "dist/index.js",

"build": "rimraf dist && tsc",
"cli": "ts-node ./lib/cli",
"commit": "git-cz",
"cz": "git-cz",
"test": "jest"

@@ -19,0 +21,0 @@ },

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