Skip to content

Instantly share code, notes, and snippets.

@htunnicliff
Created September 16, 2021 21:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save htunnicliff/fe654b500c2ae896873f6458efdb2eb3 to your computer and use it in GitHub Desktop.
Save htunnicliff/fe654b500c2ae896873f6458efdb2eb3 to your computer and use it in GitHub Desktop.
CLI script for generaterating TypeScript declaration files using an OpenAPI spec
#!/usr/bin/env node
import NextEnv from "@next/env";
import axios from "axios";
import chalk from "chalk";
import dtsgenerator from "dtsgenerator";
import fs from "node:fs/promises";
import path from "node:path";
import { oraPromise } from "ora";
import prettier from "prettier";
const { default: generateTypes, parseSchema, ts } = dtsgenerator;
const { loadEnvConfig } = NextEnv;
const { format, resolveConfig } = prettier;
// Inject environment variables into `process.env`
loadEnvConfig(process.cwd(), true, {
error: console.error,
info: () => {
// no-op
},
});
/**
* @param {string} url
* @param {string} namespace
* @param {string} outFile
*/
async function main(url, namespace, outFile) {
if (!url || !url.startsWith("http")) {
throw new Error("URL is required.");
}
if (!outFile) {
throw new Error("outFile is required.");
}
const schemaURL = url + "/openapi.json";
// Get OpenAPI schema
const { data: schema } = await oraPromise(
axios.get(schemaURL),
`Downloading schema from ${chalk.yellow(schemaURL)}`
);
// Generate types from schema
const rawTypes = await oraPromise(
generateTypes({
contents: [parseSchema(schema)],
config: {
target: ts.ScriptTarget.ES2020,
plugins: {
"@dtsgenerator/replace-namespace": {
map: [
{
from: ["Paths"],
to: [`${namespace}Paths`],
},
{
from: ["Components"],
to: [namespace],
},
],
},
},
},
}),
"Generating types"
);
// Format raw types
const formattedTypes = await oraPromise(
resolveConfig(process.cwd()).then((config) => {
return format(rawTypes, {
...config,
parser: "typescript",
});
}),
"Format types with Prettier"
);
// Save output
await oraPromise(
fs.writeFile(path.resolve(process.cwd(), outFile), formattedTypes),
`Saving to ${chalk.green(outFile)}`
);
}
const apis = [
{
baseURL: "https://foo-api.com",
namespace: "Foo",
outFile: "./types/foo-api.d.ts",
},
{
baseURL: "https://bar-api.com",
namespace: "Bar",
outFile: "./types/bar-api.d.ts",
},
];
for (const { baseURL, namespace, outFile } of apis) {
await main(baseURL, namespace, outFile);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment