Skip to content

Commit 3ea8d8f

Browse files
committed
Absorb schema loading/parsing into Node API
1 parent 84fe190 commit 3ea8d8f

File tree

13 files changed

+238
-252
lines changed

13 files changed

+238
-252
lines changed

README.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,19 +121,26 @@ npm i --save-dev openapi-typescript
121121
```
122122

123123
```js
124-
const { readFileSync } = require("fs");
124+
const fs = require("fs");
125125
const openapiTS = require("openapi-typescript").default;
126126

127-
const input = JSON.parse(readFileSync("spec.json", "utf8")); // Input can be any JS object (OpenAPI format)
128-
const output = openapiTS(input); // Outputs TypeScript defs as a string (to be parsed, or written to a file)
127+
// option 1: load JS object, write to local file
128+
const schema = await fs.promises.readFile("spec.json", "utf8") // must be OpenAPI JSON
129+
const output = await openapiTS(JSON.parse(schema));
130+
131+
// option 2 (new in v3.3): load local path
132+
const localPath = path.join(__dirname, 'spec.yaml'); // may be YAML or JSON format
133+
const output = await openapiTS(localPath);
134+
135+
// option 3 (new in v3.3): load remote URL
136+
const output = await openapiTS('https://myurl.com/v1/openapi.yaml');
129137
```
130138

131-
The Node API is a bit more flexible: it will only take a JS object as input (OpenAPI format), and return a string of TS
132-
definitions. This lets you pull from any source (a Swagger server, local files, etc.), and similarly lets you parse,
133-
post-process, and save the output anywhere.
139+
The Node API may be useful if dealing with dynamically-created schemas, or you’re using within context of a larger application. It
140+
141+
⚠️ As of `v3.3`, this is an async function.
134142

135-
If your specs are in YAML, you’ll have to convert them to JS objects using a library such as [js-yaml][js-yaml]. If
136-
you’re batching large folders of specs, [glob][glob] may also come in handy.
143+
It’s important to note that options 2 and 3 are triggered by passing in a `string` rather than an `object`.
137144

138145
#### Custom Formatter
139146

bin/cli.js

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const { bold, green, red } = require("kleur");
55
const path = require("path");
66
const meow = require("meow");
77
const { default: openapiTS } = require("../dist/cjs/index.js");
8-
const { loadSpec } = require("./loaders");
98

109
const cli = meow(
1110
`Usage
@@ -51,56 +50,36 @@ async function main() {
5150
let output = "FILE"; // FILE or STDOUT
5251
const pathToSpec = cli.input[0];
5352

54-
// 0. setup
5553
if (!cli.flags.output) {
5654
output = "STDOUT"; // if --output not specified, fall back to stdout
5755
}
5856
if (output === "FILE") {
59-
console.info(bold(`✨ openapi-typescript ${require("../package.json").version}`)); // only log if we’re NOT writing to stdout
57+
console.info(bold(`✨ openapi-typescript ${require("../package.json").version}`)); // don’t log anything to console!
6058
}
6159

62-
// 1. input
63-
let spec = undefined;
64-
try {
65-
spec = await loadSpec(pathToSpec, {
66-
auth: cli.flags.auth,
67-
log: output !== "STDOUT",
68-
});
69-
} catch (err) {
70-
process.exitCode = 1; // needed for async functions
71-
throw new Error(red(`❌ ${err}`));
72-
}
73-
74-
// 2. generate schema (the main part!)
75-
const result = openapiTS(spec, {
60+
const result = await openapiTS(pathToSpec, {
61+
auth: cli.flags.auth,
62+
silent: output === "STDOUT",
7663
immutableTypes: cli.flags.immutableTypes,
7764
prettierConfig: cli.flags.prettierConfig,
7865
rawSchema: cli.flags.rawSchema,
7966
version: cli.flags.version,
8067
});
8168

82-
// 3. output
8369
if (output === "FILE") {
8470
// output option 1: file
8571
const outputFile = path.resolve(process.cwd(), cli.flags.output);
8672

87-
// recursively create parent directories if they don’t exist
88-
const parentDirs = cli.flags.output.split(path.sep);
89-
for (var i = 1; i < parentDirs.length; i++) {
90-
const dir = path.resolve(process.cwd(), ...parentDirs.slice(0, i));
91-
if (!fs.existsSync(dir)) {
92-
fs.mkdirSync(dir);
93-
}
94-
}
95-
96-
fs.writeFileSync(outputFile, result, "utf8");
73+
await fs.promises.mkdir(path.dirname(outputFile), { recursive: true });
74+
await fs.promises.writeFile(outputFile, result, "utf8");
9775

9876
const timeEnd = process.hrtime(timeStart);
9977
const time = timeEnd[0] + Math.round(timeEnd[1] / 1e6);
10078
console.log(green(`🚀 ${pathToSpec} -> ${bold(cli.flags.output)} [${time}ms]`));
10179
} else {
10280
// output option 2: stdout
10381
process.stdout.write(result);
82+
// (still) don’t log anything to console!
10483
}
10584

10685
return result;

bin/loaders/index.js

Lines changed: 0 additions & 69 deletions
This file was deleted.

bin/loaders/loadFromFs.js

Lines changed: 0 additions & 14 deletions
This file was deleted.

bin/loaders/loadFromHttp.js

Lines changed: 0 additions & 57 deletions
This file was deleted.

package-lock.json

Lines changed: 26 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,24 @@
5454
"version": "npm run build"
5555
},
5656
"dependencies": {
57-
"js-yaml": "^4.0.0",
58-
"kleur": "^4.1.3",
57+
"js-yaml": "^4.1.0",
58+
"kleur": "^4.1.4",
5959
"meow": "^9.0.0",
6060
"mime": "^2.5.2",
6161
"prettier": "^2.2.1"
6262
},
6363
"devDependencies": {
64-
"@types/jest": "^26.0.14",
65-
"@types/js-yaml": "^4.0.0",
66-
"@typescript-eslint/eslint-plugin": "^4.4.1",
67-
"@typescript-eslint/parser": "^4.4.1",
68-
"codecov": "^3.8.1",
69-
"eslint": "^7.11.0",
70-
"eslint-config-prettier": "^8.1.0",
71-
"eslint-plugin-prettier": "^3.1.4",
72-
"jest": "^26.5.3",
73-
"ts-jest": "^26.4.1",
74-
"typescript": "^4.1.3"
64+
"@types/jest": "^26.0.23",
65+
"@types/js-yaml": "^4.0.1",
66+
"@types/mime": "^2.0.3",
67+
"@typescript-eslint/eslint-plugin": "^4.22.0",
68+
"@typescript-eslint/parser": "^4.22.0",
69+
"codecov": "^3.8.2",
70+
"eslint": "^7.25.0",
71+
"eslint-config-prettier": "^8.3.0",
72+
"eslint-plugin-prettier": "^3.4.0",
73+
"jest": "^26.6.3",
74+
"ts-jest": "^26.5.5",
75+
"typescript": "^4.2.4"
7576
}
7677
}

src/index.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import path from "path";
22
import prettier from "prettier";
33
import parserTypescript from "prettier/parser-typescript";
4+
import load from "./load";
45
import { swaggerVersion } from "./utils";
56
import { transformAll } from "./transform/index";
67
import { OpenAPI2, OpenAPI3, SchemaObject, SwaggerToTSOptions } from "./types";
@@ -14,24 +15,27 @@ export const WARNING_MESSAGE = `/**
1415
1516
`;
1617

17-
export default function openapiTS(
18-
schema: OpenAPI2 | OpenAPI3 | Record<string, SchemaObject>,
18+
export default async function openapiTS(
19+
schema: string | OpenAPI2 | OpenAPI3 | Record<string, SchemaObject>,
1920
options?: SwaggerToTSOptions
20-
): string {
21-
// 1. determine version
22-
const version = (options && options.version) || swaggerVersion(schema as OpenAPI2 | OpenAPI3);
21+
): Promise<string> {
22+
// 1. load schema
23+
const schemaObj = await load(schema, { auth: options?.auth, silent: options?.silent || false });
2324

24-
// 2. generate output
25+
// 2. determine version
26+
const version = options?.version || swaggerVersion(schemaObj as OpenAPI2 | OpenAPI3);
27+
28+
// 3. generate output
2529
let output = `${WARNING_MESSAGE}
26-
${transformAll(schema, {
30+
${transformAll(schemaObj, {
2731
formatter: options && typeof options.formatter === "function" ? options.formatter : undefined,
2832
immutableTypes: (options && options.immutableTypes) || false,
2933
rawSchema: options && options.rawSchema,
3034
version,
3135
})}
3236
`;
3337

34-
// 3. Prettify output
38+
// 4. Prettify output
3539
let prettierOptions: prettier.Options = {
3640
parser: "typescript",
3741
plugins: [parserTypescript],

0 commit comments

Comments
 (0)