Skip to content

Update docs #962

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

Merged
merged 1 commit into from
Oct 30, 2022
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Changes

_What does this PR change? Link to any related issue(s)._

## How to Review

_How can a reviewer review your changes? What should be kept in mind for this review?_

## Checklist

- [ ] Unit tests updated
- [ ] README updated
- [ ] `examples/` directory updated (if applicable)
130 changes: 70 additions & 60 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,98 +1,108 @@
# Contributing

Thanks for being willing to contribute!
Thanks for being willing to contribute! 🙏

**Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source
Project on GitHub][egghead]
**Working on your first Pull Request (PR)?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)

## Project setup
## Open issues

Please check out the [the open issues](https://github.com/drwpow/openapi-typescript/issues). Issues labelled [**Help Wanted**](https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and [**Good First Issue**](https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) are especially good to help with.

Contributing doesn’t have to be in code! Simply answering questions in open issues, or providing workarounds, is just as important a contribution as making pull requests.

## Setup

### Dependencies

1. Install [pnpm](https://pnpm.io/)
2. Fork and clone the repo
3. Run `pnpm i` to install dependencies
4. Create a branch for your PR with `git checkout -b pr/your-branch-name`

It’s also recommended you have [ESLint][eslint] installed and set up correctly. You may also run the command
`npm run lint` to see lint errors.
### VS Code setup

> Tip: Keep your `main` branch pointing at the original repository and make pull requests from branches on your fork. To
> do this, run:
>
> ```
> git remote add upstream https://github.com/drwpow/openapi-typescript.git
> git fetch upstream
> git branch --set-upstream-to=upstream/main main
> ```
>
> This will add the original repository as a "remote" called "upstream," Then fetch the git information from that
> remote, then set your local `main` branch to use the upstream main branch whenever you run `git pull`. Then you can
> make all of your pull request branches based on this `main` branch. Whenever you want to update your version of
> `main`, do a regular `git pull`.
If using VS Code, the following extensions are recommended (or their equivalent extensions if using another editor)

## Committing and pushing changes
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)

Please make sure to run the tests (`npm test`) before you commit your changes.
## Workflow

### Local schemas
When working locally, run:

This repo supports OpenAPI 2.0 and 3.0. There are some real-world examples located in `tests/v2/specs/*.yaml` and
`tests/v3/specs/*.yaml`, respectively. Testing large, real schemas was a major goal of this project. Many libraries only
test the “Petstore” example from Swagger, which is contrived and is missing much complexity from companies’ production
schemas.
```bash
npm run dev
```

_Note: don’t update the `yaml` schemas with your own custom additions (but if the official versions have updated, then
it’s fine to update them here). If you’d like to add your schema for testing, then please add them as a new schema, and
add them to `./expected/*.ts`._
This will compile the code as you change automatically.

#### Regenerating schemas
### TDD

If you’ve added a feature or fixed a bug and need to update the generated schemas, run the following:
This library is a great usecase for [test-driven development (TDD)](https://en.wikipedia.org/wiki/Test-driven_development). If you’re new to this, the basic workflow is:

```
# 1. re-build the package
npm run build
# 2. run the local CLI (not the npm one!)
./bin/cli.js tests/v3/specs/github.yaml -o tests/v3/expected/github.ts
# NOTE: on Windows, try running the script on WSL if getting errors
```
1. First, write a [test](#testing) that fully outlines what you’d _like_ the output to be.
2. Make sure this test **fails** when you run `npm test` (yes, _fails!_)
3. Then, make changes to `src/` until the tests pass.

_Code generation is hard!_ And for that reason, starting with a very clear expectation of your end-goal can make working easier.

### Unit tests or snapshot tests?

This library has both unit tests (tests that test a tiny part of a schema) and snapshot tests (tests that run over an entire, complete schema). When opening a PR, the former are more valuable than the latter, and are always required. However, updating snapshot tests can help with the following:

- Fixing bugs that deal with multiple schemas with remote `$ref`s
- Fixing Node.js or OS-related bugs
- Adding a CLI option that changes the entire output

For most PRs, **snapshot tests can be avoided.** But for scenarios similar to the ones mentioned, they can ensure everything is working as expected.

### Generating types

It may be surprising to hear, but _generating TypeScript types from OpenAPI is opinionated!_ Even though TypeScript and OpenAPI are very close relatives, both being JavaScript/JSON-based, they are nonetheless 2 different languages and thus there is always some room for interpretation. Likewise, some parts of the OpenAPI specification can be ambiguous on how they’re used, and what the expected type outcomes may be (though this is generally for more advanced usecasees, such as specific implementations of `anyOf` as well as [discriminator](https://spec.openapis.org/oas/latest.html#discriminatorObject) and complex polymorphism).

This should update the expected TypeScript definiton.
All that said, this library should strive to generate _the most predictable_ TypeScript output for a given schema. And to achieve that, it always helps to open an [issue](https://github.com/drwpow/openapi-typescript/issues) or [discussion](https://github.com/drwpow/openapi-typescript/discussions) to gather feedback.

_Also if this appears in `examples/` feel free to update that, too!_
### Opening a PR

When opening a pull request, make sure all of the following is done:

- [x] Tests are added
- [x] Build passes (`npm run build`)
- [x] Tests pass (`npm test`)
- [x] Linting passes (`npm run lint`)

Lastly, be sure to fill out the complete PR template!

## Testing

Tests use [Vitest](https://vitest.dev), a modern test-runner based on Jest. To run the tests locally, run:
This library uses [Vitest](https://vitest.dev/) for testing. There’s a great [VS Code extension](https://marketplace.visualstudio.com/items?itemName=ZixuanChen.vitest-explorer) you can optionally use if you’d like in-editor debugging tools.

```
### Running tests

💡 The tests test **the production build** in `dist/`. Be sure to run `npm run build` before running tests (or keep `npm run dev` running in the background, which compiles as-you-work)!

To run the entire test suite once, run:


```bash
npm test
```

To run an individual test:

```
npx vitest [part of filename]
```bash
npx vitest [partial filename]
```

Or to start all tests in watch mode:
To start the entire test suite in watch mode:

```
```bash
npx vitest
```

[See docs](https://vitest.dev)
### Running linting

## Help needed
To run ESLint on the project:

Please check out the [the open issues][issues]. Issues labelled [**Help Wanted**][help-wanted] and [**Good First
Issue**][good-first-issue] are especially good to help with.

Also, please watch the repo and respond to questions/bug reports/feature requests! Thanks!

[all-contributors]: https://github.com/all-contributors/all-contributors
[egghead]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github
[eslint]: https://eslint.org/
[good-first-issue]:
https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22
[help-wanted]: https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22
[issues]: https://github.com/drwpow/openapi-typescript/issues
```bash
npm run lint
```
60 changes: 20 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,18 @@

# 📘️ openapi-typescript

🚀 Convert [OpenAPI 3.0][openapi3] and [2.0 (Swagger)][openapi2] schemas to TypeScript interfaces using Node.js.
🚀 Convert [OpenAPI](https://spec.openapis.org/oas/latest.html) schemas to TypeScript interfaces painlessly using pure Node.js. No Java, node-gyp, or running OpenAPI servers necessary. Uses [Prettier](https://npmjs.com/prettier) to format the output.

**Features**

- ✅ [OpenAPI 3.0][openapi3]
- ✅ [Swagger 2.0][openapi2]
- ✅ Supports YAML and JSON schema formats
- ✅ Supports YAML and JSON
- ✅ Supports loading via remote URL (simple authentication supported with the `--auth` flag)
- ✅ Supports remote references: `$ref: "external.yaml#components/schemas/User"`
- ✅ Formats using [Prettier][prettier]
- ✅ TypeScript 4.0 features
- ✅ Prettier formatting is fully customizable to match your existing code style.

**Examples**

- [Stripe, OpenAPI 2.0](./examples/stripe-openapi2.ts)
- [Stripe, OpenAPI 3.0](./examples/stripe-openapi3.ts)
[See examples](./examples/)

## Usage

Expand Down Expand Up @@ -54,14 +50,12 @@ _Thanks to [@sharmarajdaksh](https://github.com/sharmarajdaksh) for the glob fea
#### ☁️ Reading specs from remote resource

```bash
npx openapi-typescript https://petstore.swagger.io/v2/swagger.json --output petstore.ts
npx openapi-typescript https://petstore3.swagger.io/api/v3/openapi.yaml --output petstore.d.ts

# 🔭 Loading spec from https://petstore.swagger.io/v2/swagger.json
# 🚀 https://petstore.swagger.io/v2/swagger.json -> petstore.ts [650ms]
# 🔭 Loading spec from https://petstore3.swagger.io/api/v3/openapi.yaml
# 🚀 https://petstore3.swagger.io/api/v3/openapi.yaml -> petstore.d.ts [650ms]
```

_Note: globbing doesn’t work for remote schemas because there is no reliable way to determine a list of files to select from a remote file system._

_Thanks to [@psmyrdek](https://github.com/psmyrdek) for the remote spec feature!_

#### Using in TypeScript
Expand All @@ -76,16 +70,16 @@ type APIResponse = components["schemas"]["APIResponse"];

Because OpenAPI schemas may have invalid TypeScript characters as names, the square brackets are a safe way to access every property.

Also note that there’s a special `operations` interface that you can import `OperationObjects` by their [operationId][openapi-operationid]:
##### Operations

Operations can be imported directly by their [operationId](https://spec.openapis.org/oas/latest.html#operation-object):

```ts
import { operations } from "./generated-schema.ts";

type getUsersById = operations["getUsersById"];
```

Even though `operations` isn’t present in your original schema, it’s a simple convenience and won’t disrupt any of your other types.

_Thanks to [@gr2m](https://github.com/gr2m) for the operations feature!_

#### openapi-typescript-fetch
Expand All @@ -94,7 +88,6 @@ The generated spec can also be used with [openapi-typescript-fetch](https://www.

```ts
import { paths } from "./petstore";

import { Fetcher } from "openapi-typescript-fetch";

// declare fetcher for paths
Expand Down Expand Up @@ -163,7 +156,6 @@ npx openapi-typescript schema.yaml
| `--make-paths-enum` | `-pe` | `false` | (optional) Generate an enum of endpoint paths |
| `--path-params-as-types` | | `false` | (optional) Substitute path parameter names with their respective types |
| `--raw-schema` | | `false` | Generate TS types from partial schema (e.g. having `components.schema` at the top level) |
| `--version` | | | Force OpenAPI version with `--version 3` or `--version 2` (required for `--raw-schema` when version is unknown) |

### 🐢 Node

Expand All @@ -172,7 +164,7 @@ npm i --save-dev openapi-typescript
```

```js
import fs from "fs";
import fs from "node:fs";
import openapiTS from "openapi-typescript";

// example 1: load [object] as schema (JSON only)
Expand All @@ -187,9 +179,7 @@ const output = await openapiTS(localPath);
const output = await openapiTS("https://myurl.com/v1/openapi.yaml");
```

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.

⚠️ As of `v4.0`, `openapiTS()` is an async function.
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](https://www.npmjs.com/package/js-yaml) first.

#### Custom Formatter

Expand Down Expand Up @@ -222,26 +212,16 @@ _Note: you don’t have to use `.format`—this is just an example! You can use

## 🏅 Project Goals

1. Support converting any OpenAPI 3.0 or 2.0 (Swagger) schema to TypeScript types, no matter how complicated
1. The generated TypeScript types **must** match your schema as closely as possible (i.e. don’t convert names to
`PascalCase` or follow any TypeScript-isms; faithfully reproduce your schema as closely as possible, capitalization
and all)
1. This library is a TypeScript generator, not a schema validator.
1. Support converting any valid OpenAPI schema to TypeScript types, no matter how complicated.
1. This library does **NOT** validate your schema, there are other libraries for that.
1. The generated TypeScript types **must** match your schema as closely as possible (e.g. no renaming to
`PascalCase`)
1. This library should never require Java, node-gyp, or some other complex environment to work. This should require Node.js and nothing else.
1. This library will never require a running OpenAPI server to work.

## 🤝 Contributing

PRs are welcome! Please see our [CONTRIBUTING.md](./CONTRIBUTING.md) guide. Opening an issue beforehand to discuss is
encouraged but not required.

[glob]: https://www.npmjs.com/package/glob
[js-yaml]: https://www.npmjs.com/package/js-yaml
[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
[openapi-operationid]: https://swagger.io/specification/#operation-object
[openapi2]: https://swagger.io/specification/v2/
[openapi3]: https://swagger.io/specification
[prettier]: https://npmjs.com/prettier
PRs are welcome! Please see our [CONTRIBUTING.md](./CONTRIBUTING.md) guide.

### Contributors ✨

Expand Down Expand Up @@ -323,7 +303,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
</tr>
</tbody>
<tfoot>

</tfoot>
</table>

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"homepage": "https://github.com/drwpow/openapi-typescript#readme",
"scripts": {
"build": "del dist && tsc",
"dev": "tsc --watch",
"format": "npm run prettier -w .",
"lint": "eslint .",
"prepare": "npm run build",
Expand Down