@spec2ts/openapi-client
Version:
Utility to convert OpenAPI v3 specifications to Typescript HTTP client using TypeScript native compiler
169 lines (167 loc) • 6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = exports.builder = exports.describe = exports.usage = void 0;
const path = require("path");
const fs_1 = require("fs");
const core_1 = require("@spec2ts/core");
const openapi_generator_1 = require("../lib/openapi-generator");
exports.usage = "$0 <input..>";
exports.describe = "Generate TypeScript HTTP client from OpenAPI specification";
function builder(argv) {
return argv
.positional("input", {
array: true,
type: "string",
describe: "Path to OpenAPI Specification(s) to convert to TypeScript HTTP client",
demandOption: true
})
.option("output", {
type: "string",
alias: "o",
describe: "Output file for generated client"
})
.option("cwd", {
type: "string",
alias: "c",
describe: "Root directory for resolving $refs"
})
.option("baseUrl", {
type: "string",
describe: "Base url of the server"
})
.option("prefix", {
type: "string",
describe: "Only generate paths with this prefix"
})
.option("avoidAny", {
type: "boolean",
describe: "Avoid the `any` type and use `unknown` instead"
})
.option("enableDate", {
choices: [true, "strict", "lax"],
describe: "Build `Date` for format `date` and `date-time`"
})
.option("inlineRequired", {
type: "boolean",
describe: "Create a method argument for each required parameter"
})
.option("importFetch", {
choices: ["node-fetch", "cross-fetch", "isomorphic-fetch"],
describe: "Use a custom fetch implementation"
})
.option("typesPath", {
type: "string",
describe: "Generate client types in external file relative to the output file"
})
.option("importFetchVersion", {
type: "string",
describe: "Use a custom fetch implementation version"
})
.option("importFormDataVersion", {
type: "string",
describe: "Use a custom form-data implementation version"
})
.option("packageName", {
type: "string",
describe: "Generate a package.json with given name"
})
.option("packageVersion", {
type: "string",
describe: "Set the version of the package.json"
})
.option("packageAuthor", {
type: "string",
describe: "Set the author of the package.json"
})
.option("packageLicense", {
type: "string",
describe: "Set the license of the package.json"
})
.option("packagePrivate", {
type: "boolean",
describe: "Set the package.json private"
})
.option("packageBuildTarget", {
type: "string",
describe: "Set the TypeScript build target"
})
.option("packageBuildModule", {
type: "string",
describe: "Set the TypeScript build module"
})
.option("banner", {
type: "string",
alias: "b",
describe: "Comment prepended to the top of each generated file"
});
}
exports.builder = builder;
async function handler(options) {
const files = await core_1.cli.findFiles(options.input);
for (const file of files) {
const output = options.output || core_1.cli.getOutputPath(file, options);
await core_1.cli.mkdirp(output);
if (options.typesPath) {
if (!options.typesPath.startsWith(".")) {
options.typesPath = "./" + options.typesPath;
}
const res = await (0, openapi_generator_1.generateClientFromFile)(file, options);
printFile(res.client, output, options);
const outputTypes = path.resolve(path.dirname(output), options.typesPath + ".ts");
printFile(res.types, outputTypes, options);
}
else {
const sourceFile = await (0, openapi_generator_1.generateClientFromFile)(file, options);
printFile(sourceFile, output, options);
}
if (options.packageName) {
await generatePackage(output, options);
}
}
}
exports.handler = handler;
async function printFile(file, output, options) {
const content = core_1.printer.printFile(file);
await core_1.cli.mkdirp(output);
await core_1.cli.writeFile(output, (options.banner || defaultBanner()) +
"\n\n" +
content);
}
function defaultBanner() {
return `/**
* DO NOT MODIFY
* Generated using @spec2ts/openapi-client.
* See https://www.npmjs.com/package/@spec2ts/openapi-client
*/
/* eslint-disable */`;
}
async function generatePackage(output, options) {
const outputDir = path.dirname(output);
const main = path.relative(outputDir, output);
const pkg = {
name: options.packageName,
version: options.packageVersion || "1.0.0",
description: "OpenAPI v3 client for " + options.packageName,
author: options.packageAuthor || "@spec2ts/openapi-client",
license: options.packageLicense || "UNLICENSED",
main: main.replace(/\.ts$/, ".js"),
files: ["*.js", "*.d.ts"],
scripts: {
build: `tsc ${main} --strict --target ${options.packageBuildTarget || "ES2018"} --module ${options.packageBuildModule || "UMD"} --moduleResolution node --skipLibCheck`,
prepublishOnly: "npm run build"
},
dependencies: {},
devDependencies: {
typescript: "^4.2.0"
}
};
if (options.importFetch) {
pkg.dependencies[options.importFetch] = options.importFetchVersion || "*";
pkg.dependencies["form-data"] = options.importFormDataVersion || "*";
pkg.devDependencies["@types/node"] = "*";
}
if (options.packagePrivate) {
pkg.private = options.packagePrivate;
}
await fs_1.promises.writeFile(path.join(outputDir, "package.json"), JSON.stringify(pkg, null, 2), "utf8");
}