Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve remote schemas #602

Merged
merged 2 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 21 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@

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

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

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

View examples:
**Examples**

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

```js
const { readFileSync } = require("fs");
const fs = require("fs");
const openapiTS = require("openapi-typescript").default;

const input = JSON.parse(readFileSync("spec.json", "utf8")); // Input can be any JS object (OpenAPI format)
const output = openapiTS(input); // Outputs TypeScript defs as a string (to be parsed, or written to a file)
// option 1: load [object] as schema (JSON only)
const schema = await fs.promises.readFile("spec.json", "utf8") // must be OpenAPI JSON
const output = await openapiTS(JSON.parse(schema));

// option 2: load [string] as local file (YAML or JSON; released in v3.3)
const localPath = path.join(__dirname, 'spec.yaml'); // may be YAML or JSON format
const output = await openapiTS(localPath);

// option 3: load [string] as remote URL (YAML or JSON; released in v3.3)
const output = await openapiTS('https://myurl.com/v1/openapi.yaml');
```

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
definitions. This lets you pull from any source (a Swagger server, local files, etc.), and similarly lets you parse,
post-process, and save the output anywhere.
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.

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

#### Custom Formatter

Expand Down Expand Up @@ -164,6 +173,7 @@ encouraged but not required.

[glob]: https://www.npmjs.com/package/glob
[js-yaml]: https://www.npmjs.com/package/js-yaml
[json-schema-ref-parser]: https://github.com/APIDevTools/json-schema-ref-parser
[namespace]: https://www.typescriptlang.org/docs/handbook/namespaces.html
[npm-run-all]: https://www.npmjs.com/package/npm-run-all
[openapi-format]: https://swagger.io/specification/#data-types
Expand Down
24 changes: 7 additions & 17 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const path = require("path");
const meow = require("meow");
const glob = require("tiny-glob");
const { default: openapiTS } = require("../dist/cjs/index.js");
const { loadSpec } = require("./loaders");

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

// load spec
let spec = undefined;
try {
spec = await loadSpec(pathToSpec, {
auth: cli.flags.auth,
log: output !== OUTPUT_STDOUT,
});
} catch (err) {
errorAndExit(`❌ ${err}`);
}

// generate schema
const result = openapiTS(spec, {
auth: cli.flags.auth,
const result = await openapiTS(pathToSpec, {
additionalProperties: cli.flags.additionalProperties,
immutableTypes: cli.flags.immutableTypes,
auth: cli.flags.auth,
defaultNonNullable: cli.flags.defaultNonNullable,
immutableTypes: cli.flags.immutableTypes,
prettierConfig: cli.flags.prettierConfig,
rawSchema: cli.flags.rawSchema,
silent: output === OUTPUT_STDOUT,
version: cli.flags.version,
});

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

return result;
}

async function main() {
const output = cli.flags.output ? OUTPUT_FILE : OUTPUT_STDOUT; // FILE or STDOUT
let output = cli.flags.output ? OUTPUT_FILE : OUTPUT_STDOUT; // FILE or STDOUT
const pathToSpec = cli.input[0];

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

// generate schema(s)
// generate schema(s) in parallel
await Promise.all(
inputSpecPaths.map(async (specPath) => {
if (cli.flags.output !== "." && output === OUTPUT_FILE) {
Expand Down
69 changes: 0 additions & 69 deletions bin/loaders/index.js

This file was deleted.

14 changes: 0 additions & 14 deletions bin/loaders/loadFromFs.js

This file was deleted.

57 changes: 0 additions & 57 deletions bin/loaders/loadFromHttp.js

This file was deleted.