swaxios
Version:
Swagger API client generator based on axios and TypeScript.
166 lines • 7.29 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeClient = exports.generateClient = exports.exportServices = void 0;
const axios_1 = __importDefault(require("axios"));
const ci_info_1 = require("ci-info");
const cli_interact_1 = require("cli-interact");
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const yamljs_1 = __importDefault(require("yamljs"));
const generators_1 = require("./generators");
const InterfaceGenerator_1 = require("./generators/InterfaceGenerator");
const FileUtil_1 = require("./util/FileUtil");
const StringUtil = __importStar(require("./util/StringUtil"));
const SwaggerValidator_1 = require("./validator/SwaggerValidator");
async function exportServices(swaggerJson) {
const resources = [];
const recordedUrls = {};
for (const url of Object.keys(swaggerJson.paths)) {
const normalizedUrl = StringUtil.normalizeUrl(url);
const directory = normalizedUrl.substr(0, normalizedUrl.lastIndexOf('/'));
const serviceName = StringUtil.generateServiceName(normalizedUrl);
const fullyQualifiedName = `rest${directory}/${serviceName}`;
recordedUrls[fullyQualifiedName] = {
...recordedUrls[fullyQualifiedName],
[url]: swaggerJson.paths[url],
};
}
for (const [fullyQualifiedName, resourceDefinitions] of Object.entries(recordedUrls)) {
const restResource = new generators_1.ResourceGenerator(fullyQualifiedName, resourceDefinitions, swaggerJson);
resources.push(restResource);
}
return resources;
}
exports.exportServices = exportServices;
async function buildIndexFiles(fileIndex) {
const filesAndDirs = Object.keys(fileIndex.files).concat(Object.keys(fileIndex.directories).map(dir => `${dir}/`));
await new generators_1.IndexFileGenerator(filesAndDirs, fileIndex.fullPath).write();
for (const dir of Object.values(fileIndex.directories)) {
await buildIndexFiles(dir);
}
}
async function generateClient(swaggerJson, outputDirectory) {
const resources = await exportServices(swaggerJson);
for (const restResource of resources) {
const renderedResource = await restResource.toString();
await fs_extra_1.default.outputFile(path_1.default.join(outputDirectory, restResource.filePath), renderedResource, 'utf-8');
}
const fileIndex = await (0, FileUtil_1.generateFileIndex)(outputDirectory);
await new generators_1.APIClientGenerator(fileIndex, outputDirectory, swaggerJson).write();
fileIndex.files.APIClient = {
alternativeName: null,
fullPath: path_1.default.resolve(outputDirectory, 'APIClient'),
name: 'APIClient',
};
fileIndex.directories.interfaces = {
directories: {},
files: {},
fullPath: path_1.default.resolve(outputDirectory, 'interfaces'),
name: 'interfaces',
};
await buildIndexFiles(fileIndex);
await generateInterfaces(swaggerJson, outputDirectory);
}
exports.generateClient = generateClient;
async function generateInterfaces(spec, outputDirectory) {
if (!spec.definitions) {
console.info('Spec has no definitions.');
return;
}
const interfaceDirectory = path_1.default.join(outputDirectory, 'interfaces');
for (const [definitionName, definition] of Object.entries(spec.definitions)) {
await new InterfaceGenerator_1.InterfaceGenerator(definitionName, definition, spec, interfaceDirectory).write();
}
await new generators_1.IndexFileGenerator(Object.keys(spec.definitions), interfaceDirectory).write();
}
function parseInputFile(inputFile) {
try {
return JSON.parse(inputFile);
}
catch (error) {
try {
return yamljs_1.default.parse(inputFile);
}
catch (error) {
throw new Error(`Input file "${inputFile}" is neither valid JSON nor valid YAML.`);
}
}
}
function hasErrorCode(error) {
return typeof (error && error.code) === 'string';
}
async function readInputFile(inputFile) {
console.log(`Reading OpenAPI specification from file "${inputFile}" ...`);
try {
const data = await fs_extra_1.default.readFile(inputFile, 'utf-8');
return parseInputFile(data);
}
catch (error) {
if (hasErrorCode(error) && error.code === 'ENOENT') {
throw new Error(`Input file "${inputFile}" could not be found or is not readable`);
}
throw error;
}
}
async function readInputURL(inputUrl) {
console.log(`Reading OpenAPI specification from URL "${inputUrl}" ...`);
try {
const { data } = await axios_1.default.get(inputUrl, { transformResponse: data => data });
return parseInputFile(data);
}
catch (error) {
throw error;
}
}
async function checkOutputDirectory(outputDirectory, forceDeletion) {
const directoryExists = await fs_extra_1.default.pathExists(outputDirectory);
function shouldDelete() {
const question = `The output directory "${outputDirectory}" exists already. Would you like to delete it?\nNOTE: Without deletion, Swaxios can generate unexpected results.`;
return forceDeletion || (!ci_info_1.isCI && (0, cli_interact_1.getYesNo)(question));
}
if (directoryExists) {
if (shouldDelete()) {
console.info(`Deleting "${outputDirectory}" ...`);
await fs_extra_1.default.remove(outputDirectory);
return;
}
if (ci_info_1.isCI) {
throw new Error(`Output directory "${outputDirectory}" exists already`);
}
}
}
async function writeClient(inputFile, outputDirectory, forceDeletion) {
await checkOutputDirectory(outputDirectory, forceDeletion);
const isUrl = /^(https?|ftps?):\/\//.test(inputFile);
const swaggerJson = isUrl ? await readInputURL(inputFile) : await readInputFile(inputFile);
await (0, SwaggerValidator_1.validateConfig)(swaggerJson);
return generateClient(swaggerJson, outputDirectory);
}
exports.writeClient = writeClient;
//# sourceMappingURL=Swaxios.js.map