UNPKG

swaxios

Version:

Swagger API client generator based on axios and TypeScript.

162 lines 7.74 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InterfaceGenerator = exports.TypeScriptType = exports.SwaggerType = void 0; const fs_extra_1 = __importDefault(require("fs-extra")); const path_1 = __importDefault(require("path")); const util_1 = require("util"); const TemplateGenerator_1 = require("./TemplateGenerator"); var SwaggerType; (function (SwaggerType) { SwaggerType["ARRAY"] = "array"; SwaggerType["BOOLEAN"] = "boolean"; SwaggerType["INTEGER"] = "integer"; SwaggerType["NUMBER"] = "number"; SwaggerType["OBJECT"] = "object"; SwaggerType["STRING"] = "string"; })(SwaggerType || (exports.SwaggerType = SwaggerType = {})); var TypeScriptType; (function (TypeScriptType) { TypeScriptType["ANY"] = "any"; TypeScriptType["ARRAY"] = "Array"; TypeScriptType["BOOLEAN"] = "boolean"; TypeScriptType["EMPTY_OBJECT"] = "{}"; TypeScriptType["NUMBER"] = "number"; TypeScriptType["STRING"] = "string"; TypeScriptType["INTERFACE"] = "interface"; TypeScriptType["TYPE"] = "type"; })(TypeScriptType || (exports.TypeScriptType = TypeScriptType = {})); class InterfaceGenerator extends TemplateGenerator_1.TemplateGenerator { name; templateFile; spec; definition; outputDirectory; constructor(definitionName, definition, spec, outputDirectory) { super(); this.name = definitionName; this.templateFile = 'Interface.hbs'; this.spec = spec; this.definition = definition; this.outputDirectory = outputDirectory; fs_extra_1.default.ensureDirSync(this.outputDirectory); } static buildInterface(spec, schema, schemaName, imports = [], basicType = TypeScriptType.TYPE) { const reference = schema.$ref; if (reference && reference.startsWith('#/definitions')) { if (!spec.definitions) { console.info('Spec has no definitions.'); return { type: TypeScriptType.EMPTY_OBJECT, imports }; } const definition = reference.replace('#/definitions/', '').replace(/[^\w\/-]/gm, '_'); if (!imports.includes(definition)) { imports.push(definition); } return { type: definition, imports }; } const schemaObject = schema; const { allOf: multipleSchemas, required: requiredProperties, properties } = schemaObject; if (multipleSchemas) { const multipleTypes = multipleSchemas.map(itemSchema => InterfaceGenerator.buildInterface(spec, itemSchema, schemaName, imports, basicType)); const schemas = multipleTypes.map(item => item.type).join('&'); for (const itemType of multipleTypes) { for (const itemImport of itemType.imports) { if (!imports.includes(itemImport)) { imports.push(itemImport); } } } return { basicType, type: schemas, imports }; } let schemaType = schemaObject.type || SwaggerType.OBJECT; if (Array.isArray(schemaType) && schemaType[0]) { schemaType = schemaType[0]; } switch (schemaType.toLowerCase()) { case SwaggerType.BOOLEAN: { return { basicType, type: TypeScriptType.BOOLEAN, imports }; } case SwaggerType.STRING: { return { basicType, type: TypeScriptType.STRING, imports }; } case SwaggerType.NUMBER: case SwaggerType.INTEGER: { return { basicType, type: TypeScriptType.NUMBER, imports }; } case SwaggerType.OBJECT: { if (!properties) { console.info(`Schema type for "${schemaName}" is "object" but has no properties.`); return { basicType: TypeScriptType.INTERFACE, type: TypeScriptType.EMPTY_OBJECT, imports }; } const schema = {}; for (const [property, propertyOptions] of Object.entries(properties)) { const isRequired = requiredProperties && requiredProperties.includes(property); const safeProperty = property.replace(/\W/gm, '_'); const isReadOnly = !!propertyOptions.readOnly; const propertyName = `${isReadOnly ? 'readonly ' : ''}${safeProperty}${isRequired ? '' : '?'}`; const { type: propertyType, imports: propertyImports } = InterfaceGenerator.buildInterface(spec, propertyOptions, safeProperty, imports); schema[propertyName] = propertyType; for (const propertyImport of propertyImports) { if (!imports.includes(propertyImport)) { imports.push(propertyImport); } } } const type = (0, util_1.inspect)(schema, { breakLength: Infinity, depth: Infinity }) .replace(/'/gm, '') .replace(',', ';') .replace(new RegExp('\\n', 'g'), ''); return { basicType: TypeScriptType.INTERFACE, type, imports }; } case SwaggerType.ARRAY: { if (!schemaObject.items) { console.info(`Schema type for "${schemaName}" is "array" but has no items.`); return { basicType, type: `${TypeScriptType.ARRAY}<${TypeScriptType.ANY}>`, imports }; } if (!(schemaObject.items instanceof Array)) { const { imports: itemImports, type: itemType } = InterfaceGenerator.buildInterface(spec, schemaObject.items, schemaName, imports); for (const itemImport of itemImports) { if (!imports.includes(itemImport)) { imports.push(itemImport); } } return { basicType, type: `${TypeScriptType.ARRAY}<${itemType}>`, imports }; } const itemTypes = schemaObject.items.map(itemSchema => InterfaceGenerator.buildInterface(spec, itemSchema, schemaName, imports, basicType)); const schemas = itemTypes.map(item => item.type).join('|'); for (const itemType of itemTypes) { for (const itemImport of itemType.imports) { if (!imports.includes(itemImport)) { imports.push(itemImport); } } } return { basicType, type: `${TypeScriptType.ARRAY}<${schemas}>`, imports }; } default: { return { basicType, type: TypeScriptType.EMPTY_OBJECT, imports }; } } } generateInterface() { return InterfaceGenerator.buildInterface(this.spec, this.definition, this.name); } async write() { const renderedIndex = await this.toString(); const outputFile = path_1.default.join(this.outputDirectory, this.filePath); return fs_extra_1.default.outputFile(outputFile, renderedIndex, 'utf-8'); } async getContext() { const { basicType, imports, type: typeData } = this.generateInterface(); return { basicType: basicType || '', imports, name: this.name, typeData, }; } } exports.InterfaceGenerator = InterfaceGenerator; //# sourceMappingURL=InterfaceGenerator.js.map