Skip to content

Commit bfe51e3

Browse files
authored
Resolve remote schemas (#602)
* Absorb schema loading/parsing into Node API * Load remote schemas
1 parent fd37dd1 commit bfe51e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1129
-354
lines changed

README.md

+21-11
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010

1111
🚀 Convert [OpenAPI 3.0][openapi3] and [2.0 (Swagger)][openapi2] schemas to TypeScript interfaces using Node.js.
1212

13-
💅 The output is prettified with [Prettier][prettier] (and can be customized!).
13+
**Features**
1414

15-
👉 Works for both local and remote resources (filesystem and HTTP).
15+
- Convert [Open API 3.x][openapi3] and [Swagger 2.x][openapi2] to TypeScript types
16+
- Load schemas either from local `.yaml` or `.json` files, or from a remote URL (simple authentication supported with the `--auth` flag)
17+
- Supports remote `$ref`s using [json-schema-ref-parser][json-schema-ref-parser]
18+
- Formats output using [Prettier][prettier]
19+
- Uses the latest TypeScript 4.0 syntax
1620

17-
View examples:
21+
**Examples**
1822

1923
- [Stripe, OpenAPI 2.0](./examples/stripe-openapi2.ts)
2024
- [Stripe, OpenAPI 3.0](./examples/stripe-openapi3.ts)
@@ -106,19 +110,24 @@ npm i --save-dev openapi-typescript
106110
```
107111

108112
```js
109-
const { readFileSync } = require("fs");
113+
const fs = require("fs");
110114
const openapiTS = require("openapi-typescript").default;
111115

112-
const input = JSON.parse(readFileSync("spec.json", "utf8")); // Input can be any JS object (OpenAPI format)
113-
const output = openapiTS(input); // Outputs TypeScript defs as a string (to be parsed, or written to a file)
116+
// option 1: load [object] as schema (JSON only)
117+
const schema = await fs.promises.readFile("spec.json", "utf8") // must be OpenAPI JSON
118+
const output = await openapiTS(JSON.parse(schema));
119+
120+
// option 2: load [string] as local file (YAML or JSON; released in v3.3)
121+
const localPath = path.join(__dirname, 'spec.yaml'); // may be YAML or JSON format
122+
const output = await openapiTS(localPath);
123+
124+
// option 3: load [string] as remote URL (YAML or JSON; released in v3.3)
125+
const output = await openapiTS('https://myurl.com/v1/openapi.yaml');
114126
```
115127

116-
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
117-
definitions. This lets you pull from any source (a Swagger server, local files, etc.), and similarly lets you parse,
118-
post-process, and save the output anywhere.
128+
The Node API may be useful if dealing with dynamically-created schemas, or you’re using within context of a larger application. Pass in either a JSON-friendly object to load a schema from memory, or a string to load a schema from a local file or remote URL (it will load the file quickly using built-in Node methods). Note that a YAML string isn’t supported in the Node.js API; either use the CLI or convert to JSON using [js-yaml][js-yaml] first.
119129

120-
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
121-
you’re batching large folders of specs, [glob][glob] may also come in handy.
130+
⚠️ As of `v3.3`, this is an async function.
122131

123132
#### Custom Formatter
124133

@@ -164,6 +173,7 @@ encouraged but not required.
164173

165174
[glob]: https://www.npmjs.com/package/glob
166175
[js-yaml]: https://www.npmjs.com/package/js-yaml
176+
[json-schema-ref-parser]: https://github.com/APIDevTools/json-schema-ref-parser
167177
[namespace]: https://www.typescriptlang.org/docs/handbook/namespaces.html
168178
[npm-run-all]: https://www.npmjs.com/package/npm-run-all
169179
[openapi-format]: https://swagger.io/specification/#data-types

bin/cli.js

+7-17
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const path = require("path");
66
const meow = require("meow");
77
const glob = require("tiny-glob");
88
const { default: openapiTS } = require("../dist/cjs/index.js");
9-
const { loadSpec } = require("./loaders");
109

1110
const cli = meow(
1211
`Usage
@@ -70,25 +69,15 @@ function errorAndExit(errorMessage) {
7069
async function generateSchema(pathToSpec) {
7170
const output = cli.flags.output ? OUTPUT_FILE : OUTPUT_STDOUT; // FILE or STDOUT
7271

73-
// load spec
74-
let spec = undefined;
75-
try {
76-
spec = await loadSpec(pathToSpec, {
77-
auth: cli.flags.auth,
78-
log: output !== OUTPUT_STDOUT,
79-
});
80-
} catch (err) {
81-
errorAndExit(`❌ ${err}`);
82-
}
83-
8472
// generate schema
85-
const result = openapiTS(spec, {
86-
auth: cli.flags.auth,
73+
const result = await openapiTS(pathToSpec, {
8774
additionalProperties: cli.flags.additionalProperties,
88-
immutableTypes: cli.flags.immutableTypes,
75+
auth: cli.flags.auth,
8976
defaultNonNullable: cli.flags.defaultNonNullable,
77+
immutableTypes: cli.flags.immutableTypes,
9078
prettierConfig: cli.flags.prettierConfig,
9179
rawSchema: cli.flags.rawSchema,
80+
silent: output === OUTPUT_STDOUT,
9281
version: cli.flags.version,
9382
});
9483

@@ -108,13 +97,14 @@ async function generateSchema(pathToSpec) {
10897
console.log(green(`🚀 ${pathToSpec} -> ${bold(outputFile)} [${time}ms]`));
10998
} else {
11099
process.stdout.write(result);
100+
// if stdout, (still) don’t log anything to console!
111101
}
112102

113103
return result;
114104
}
115105

116106
async function main() {
117-
const output = cli.flags.output ? OUTPUT_FILE : OUTPUT_STDOUT; // FILE or STDOUT
107+
let output = cli.flags.output ? OUTPUT_FILE : OUTPUT_STDOUT; // FILE or STDOUT
118108
const pathToSpec = cli.input[0];
119109

120110
if (output === OUTPUT_FILE) {
@@ -148,7 +138,7 @@ async function main() {
148138
errorAndExit(`❌ Expected directory for --output if using glob patterns. Received "${cli.flags.output}".`);
149139
}
150140

151-
// generate schema(s)
141+
// generate schema(s) in parallel
152142
await Promise.all(
153143
inputSpecPaths.map(async (specPath) => {
154144
if (cli.flags.output !== "." && output === OUTPUT_FILE) {

bin/loaders/index.js

-69
This file was deleted.

bin/loaders/loadFromFs.js

-14
This file was deleted.

bin/loaders/loadFromHttp.js

-57
This file was deleted.

0 commit comments

Comments
 (0)