Skip to content
This repository has been archived by the owner on Feb 7, 2025. It is now read-only.

Commit

Permalink
feat(breaking): dropping support for callback handling
Browse files Browse the repository at this point in the history
  • Loading branch information
erunion committed Jan 30, 2025
1 parent b824ac6 commit d86c1df
Show file tree
Hide file tree
Showing 15 changed files with 155 additions and 347 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

- Parses Swagger specs in **JSON** or **YAML** format
- Validates against the [Swagger 2.0 schema](https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v2.0/schema.json), [OpenAPI 3.0 Schema](https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.0/schema.json), or [OpenAPI 3.1 Schema](https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.1/schema.json)
- [Resolves](https://apitools.dev/swagger-parser/docs/swagger-parser.html#resolveapi-options-callback) all `$ref` pointers, including external files and URLs
- Can [bundle](https://apitools.dev/swagger-parser/docs/swagger-parser.html#bundleapi-options-callback) all your Swagger files into a single file that only has _internal_ `$ref` pointers
- Can [dereference](https://apitools.dev/swagger-parser/docs/swagger-parser.html#dereferenceapi-options-callback) all `$ref` pointers, giving you a normal JavaScript object that's easy to work with
- [Resolves](https://github.com/readmeio/openapi-parser/blob/main/docs/openapi-parser.md#resolveapi-options-callback) all `$ref` pointers, including external files and URLs
- Can [bundle](https://github.com/readmeio/openapi-parser/blob/main/docs/openapi-parser.md#bundleapi-options-callback) all your Swagger files into a single file that only has _internal_ `$ref` pointers
- Can [dereference](https://github.com/readmeio/openapi-parser/blob/main/docs/openapi-parser.md#dereferenceapi-options-callback) all `$ref` pointers, giving you a normal JavaScript object that's easy to work with
- **[Tested](https://github.com/readmeio/openapi-parser/actions)** in Node.js and all modern web browsers on Mac, Windows, and Linux
- Tested on **[over 1,500 real-world APIs](https://apis.guru/browse-apis/)** from Google, Microsoft, Facebook, Spotify, etc.
- Supports [circular references](https://apitools.dev/swagger-parser/docs/#circular-refs), nested references, back-references, and cross-references
Expand Down Expand Up @@ -71,6 +71,10 @@ import OpenAPIParser from '@readme/openapi-parser';

## Differences from `@apidevtools/swagger-parser`

The methods on `@readme/openapi-parser`, unlike `@apidevtools/swagger-parser`, do not support callbacks.

### Error messages

`@apidevtools/swagger-parser` returns schema validation errors as the raw error stack from Ajv. For example:

<img src="https://user-images.githubusercontent.com/33762/137796620-cd7de717-6492-4cff-b291-8629ed5dcd6e.png" width="600" />
Expand Down
45 changes: 7 additions & 38 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
## Things to Know

- [Class methods vs. Instance methods](#class-methods-vs-instance-methods)
- [Callbacks vs. Promises](#callbacks-vs-promises)
- [Circular references](#circular-refs)

## Classes & Methods
Expand All @@ -12,11 +11,11 @@

- [`api` property](openapi-parser.md#api)
- [`$refs` property](openapi-parser.md#refs)
- [`validate()` method](openapi-parser.md#validateapi-options-callback)
- [`dereference()` method](openapi-parser.md#dereferenceapi-options-callback)
- [`bundle()` method](openapi-parser.md#bundleapi-options-callback)
- [`parse()` method](openapi-parser.md#parseapi-options-callback)
- [`resolve()` method](openapi-parser.md#resolveapi-options-callback)
- [`validate()` method](openapi-parser.md#validateapi-options)
- [`dereference()` method](openapi-parser.md#dereferenceapi-options)
- [`bundle()` method](openapi-parser.md#bundleapi-options)
- [`parse()` method](openapi-parser.md#parseapi-options)
- [`resolve()` method](openapi-parser.md#resolveapi-options)

#### [The `$Refs` class](refs.md)

Expand Down Expand Up @@ -44,37 +43,7 @@ let parser = new OpenAPIParser();
parser.validate('my-api.yaml');
```

The difference is that in the second example you now have a reference to `parser`, which means you can access the results ([`parser.api`](openapi-parser.md#api-object) and [`parser.$refs`](openapi-parser.md#refs)) anytime you want, rather than just in the callback function.

### Callbacks vs. Promises

Many people prefer `async`/`await` or [Promise](http://javascriptplayground.com/blog/2015/02/promises/) syntax instead of callbacks. Swagger Parser allows you to use whichever one you prefer.

If you pass a callback function to any method, then the method will call the callback using the Node.js error-first convention. If you do _not_ pass a callback function, then the method will return a Promise.

The following two examples are equivalent:

```javascript
// Callback syntax
OpenAPIParser.validate(mySchema, (err, api) => {
if (err) {
// Error
} else {
// Success
}
});
```

```javascript
try {
// async/await syntax
let api = await OpenAPIParser.validate(mySchema);

// Success
} catch (err) {
// Error
}
```
The difference is that in the second example you now have a reference to `parser`, which means you can access the results ([`parser.api`](openapi-parser.md#api-object) and [`parser.$refs`](openapi-parser.md#refs)) anytime you want.

### Circular $Refs

Expand All @@ -84,7 +53,7 @@ You can disable circular references by setting the [`dereference.circular`](opti

Or you can choose to just ignore circular references altogether by setting the [`dereference.circular`](options.md) option to `"ignore"`. In this case, all non-circular references will still be dereferenced as normal, but any circular references will remain in the schema.

Another option is to use the [`bundle`](openapi-parser.md#bundleapi-options-callback) method rather than the [`dereference`](openapi-parser.md#dereferenceapi-options-callback) method. Bundling does _not_ result in circular references, because it simply converts _external_ `$ref` pointers to _internal_ ones.
Another option is to use the [`bundle`](openapi-parser.md#bundleapi-options) method rather than the [`dereference`](openapi-parser.md#dereferenceapi-options) method. Bundling does _not_ result in circular references, because it simply converts _external_ `$ref` pointers to _internal_ ones.

```javascript
"person": {
Expand Down
71 changes: 28 additions & 43 deletions docs/openapi-parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ This is the default export of Swagger Parser. You can create instances of this c

##### Methods

- [`validate()`](#validateapi-options-callback)
- [`dereference()`](#dereferenceapi-options-callback)
- [`bundle()`](#bundleapi-options-callback)
- [`parse()`](#parseapi-options-callback)
- [`resolve()`](#resolveapi-options-callback)
- [`validate()`](#validateapi-options)
- [`dereference()`](#dereferenceapi-options)
- [`bundle()`](#bundleapi-options)
- [`parse()`](#parseapi-options)
- [`resolve()`](#resolveapi-options)

### `api`

The `api` property is the parsed/bundled/dereferenced Swagger API object. This is the same value that is passed to the callback function (or Promise) when calling the [`parse`](#parseapi-options-callback), [`bundle`](#bundleapi-options-callback), or [`dereference`](#dereferenceapi-options-callback) methods.
The `api` property is the parsed/bundled/dereferenced Swagger API object. This is the same value that is passed when calling the [`parse`](#parseapi-options), [`bundle`](#bundleapi-options), or [`dereference`](#dereferenceapi-options) methods.

```javascript
let parser = new SwaggerParser();
Expand All @@ -35,7 +35,7 @@ api === parser.api; // => true

The `$refs` property is a [`$Refs`](refs.md) object, which lets you access all of the externally-referenced files in the API, as well as easily get and set specific values in the schema using JSON pointers.

This is the same value that is passed to the callback function (or Promise) when calling the [`resolve`](#resolveapi-options-callback) method.
This is the same value that is passed when calling the [`resolve`](#resolveapi-options) method.

```javascript
let parser = new SwaggerParser();
Expand All @@ -47,27 +47,24 @@ await parser.dereference('my-api.json');
parser.$refs.paths(); // => ["my-api.json"]
```

### `validate(api, [options], [callback])`
### `validate(api, [options])`

- **api** (_required_) - `string` or `object`<br>
A [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or the file path or URL of your Swagger API. See the [`parse`](#parseapi-options-callback) method for more info.
A [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or the file path or URL of your Swagger API. See the [`parse`](#parseapi-options) method for more info.

- **options** (_optional_) - `object`<br>
See [options](options.md) for the full list of options

- **callback** (_optional_) - `function(err, api)`<br>
A callback that will receive the dereferenced and validated [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object).

- **Return Value:** `Promise`<br>
See [Callbacks vs. Promises](README.md#callbacks-vs-promises)
The dereferenced and validated [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object).

Validates the Swagger API against the [Swagger 2.0 schema](https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v2.0/schema.json), [OpenAPI 3.0 Schema](https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.0/schema.json), or [OpenAPI 3.1 Schema](https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.1/schema.json).

If [the `validate.spec` option](options.md#validate-options) is enabled, then this method also validates against the [Swagger 2.0 spec](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md). The specification validator will catch some things that aren't covered by the Swagger 2.0 Schema, such as duplicate parameters, invalid MIME types, etc.

If validation fails, then an error will be passed to the callback function, or the Promise will reject. Either way, the error will contain information about why the API is invalid.
If validation fails, then the Promise will be rejected. Either way, the error will contain information about why the API is invalid.

This method calls [`dereference`](#dereferenceapi-options-callback) internally, so the returned [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object) is fully dereferenced.
This method calls [`dereference`](#dereferenceapi-options) internally, so the returned [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object) is fully dereferenced.

```javascript
try {
Expand All @@ -78,23 +75,20 @@ try {
}
```

### `dereference(api, [options], [callback])`
### `dereference(api, [options])`

- **api** (_required_) - `string` or `object`<br>
A [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or the file path or URL of your Swagger API. See the [`parse`](#parseapi-options-callback) method for more info.
A [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or the file path or URL of your Swagger API. See the [`parse`](#parseapi-options) method for more info.

- **options** (_optional_) - `object`<br>
See [options](options.md) for the full list of options

- **callback** (_optional_) - `function(err, api)`<br>
A callback that will receive the dereferenced [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object).

- **Return Value:** `Promise`<br>
See [Callbacks vs. Promises](README.md#callbacks-vs-promises)
The dereferenced [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object).

Dereferences all `$ref` pointers in the Swagger API, replacing each reference with its resolved value. This results in a [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object) that does not contain _any_ `$ref` pointers. Instead, it's a normal JavaScript object tree that can easily be crawled and used just like any other JavaScript object. This is great for programmatic usage, especially when using tools that don't understand JSON references.

The `dereference` method maintains object reference equality, meaning that all `$ref` pointers that point to the same object will be replaced with references to the same object. Again, this is great for programmatic usage, but it does introduce the risk of [circular references](README.md#circular-refs), so be careful if you intend to serialize the API using [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Consider using the [`bundle`](#bundleapi-options-callback) method instead, which does not create circular references.
The `dereference` method maintains object reference equality, meaning that all `$ref` pointers that point to the same object will be replaced with references to the same object. Again, this is great for programmatic usage, but it does introduce the risk of [circular references](README.md#circular-refs), so be careful if you intend to serialize the API using [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Consider using the [`bundle`](#bundleapi-options) method instead, which does not create circular references.

```javascript
let api = await SwaggerParser.dereference('my-api.yaml');
Expand All @@ -104,21 +98,18 @@ let api = await SwaggerParser.dereference('my-api.yaml');
console.log(api.definitions.person.properties.firstName); // => {type: "string"}
```

### `bundle(api, [options], [callback])`
### `bundle(api, [options])`

- **api** (_required_) - `string` or `object`<br>
A [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or the file path or URL of your Swagger API. See the [`parse`](#parseapi-options-callback) method for more info.
A [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or the file path or URL of your Swagger API. See the [`parse`](#parseapi-options) method for more info.

- **options** (_optional_) - `object`<br>
See [options](options.md) for the full list of options

- **callback** (_optional_) - `function(err, api)`<br>
A callback that will receive the bundled [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object).

- **Return Value:** `Promise`<br>
See [Callbacks vs. Promises](README.md#callbacks-vs-promises)
- **Return Value:** `Promise<api>`<br>
The bundled [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object).

Bundles all referenced files/URLs into a single api that only has _internal_ `$ref` pointers. This lets you split-up your API however you want while you're building it, but easily combine all those files together when it's time to package or distribute the API to other people. The resulting API size will be small, since it will still contain _internal_ JSON references rather than being [fully-dereferenced](#dereferenceapi-options-callback).
Bundles all referenced files/URLs into a single api that only has _internal_ `$ref` pointers. This lets you split-up your API however you want while you're building it, but easily combine all those files together when it's time to package or distribute the API to other people. The resulting API size will be small, since it will still contain _internal_ JSON references rather than being [fully-dereferenced](#dereferenceapi-options).

This also eliminates the risk of [circular references](README.md#circular-refs), so the API can be safely serialized using [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).

Expand All @@ -127,7 +118,7 @@ let api = await SwaggerParser.bundle('my-api.yaml');
console.log(api.definitions.person); // => {$ref: "#/definitions/schemas~1person.yaml"}
```

### `parse(api, [options], [callback])`
### `parse(api, [options])`

- **api** (_required_) - `string` or `object`<br>
A [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or the file path or URL of your Swagger API.
Expand All @@ -137,13 +128,10 @@ console.log(api.definitions.person); // => {$ref: "#/definitions/schemas~1person
- **options** (_optional_) - `object`<br>
See [options](options.md) for the full list of options

- **callback** (_optional_) - `function(err, api)`<br>
A callback that will receive the parsed [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or an error.

- **Return Value:** `Promise`<br>
See [Callbacks vs. Promises](README.md#callbacks-vs-promises)
The parsed [Swagger object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or a rejected error.

> This method is used internally by other methods, such as [`bundle`](#bundleapi-options-callback) and [`dereference`](#dereferenceapi-options-callback). You probably won't need to call this method yourself.
> This method is used internally by other methods, such as [`bundle`](#bundleapi-options) and [`dereference`](#dereferenceapi-options). You probably won't need to call this method yourself.
Parses the given Swagger API (in JSON or YAML format), and returns it as a JavaScript object. This method **does not** resolve `$ref` pointers or dereference anything. It simply parses _one_ file and returns it.

Expand All @@ -152,21 +140,18 @@ let api = await SwaggerParser.parse('my-api.yaml');
console.log('API name: %s, Version: %s', api.info.title, api.info.version);
```

### `resolve(api, [options], [callback])`
### `resolve(api, [options])`

- **api** (_required_) - `string` or `object`<br>
A [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or the file path or URL of your Swagger API. See the [`parse`](#parseapi-options-callback) method for more info.
A [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#swagger-object), or the file path or URL of your Swagger API. See the [`parse`](#parseapi-options) method for more info.

- **options** (_optional_) - `object`<br>
See [options](options.md) for the full list of options

- **callback** (_optional_) - `function(err, $refs)`<br>
A callback that will receive a [`$Refs`](refs.yaml) object.

- **Return Value:** `Promise`<br>
See [Callbacks vs. Promises](README.md#callbacks-vs-promises)
A [`$Refs`](refs.yaml) object.

> This method is used internally by other methods, such as [`bundle`](#bundleapi-options-callback) and [`dereference`](#dereferenceapi-options-callback). You probably won't need to call this method yourself.
> This method is used internally by other methods, such as [`bundle`](#bundleapi-options) and [`dereference`](#dereferenceapi-options). You probably won't need to call this method yourself.
Resolves all JSON references (`$ref` pointers) in the given Swagger API. If it references any other files/URLs, then they will be downloaded and resolved as well (unless `options.$refs.external` is false). This method **does not** dereference anything. It simply gives you a [`$Refs`](refs.yaml) object, which is a map of all the resolved references and their values.

Expand Down
2 changes: 1 addition & 1 deletion docs/refs.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `$Refs` class

When you call the [`resolve`](openapi-parser.md#resolveschema-options-callback) method, the value that gets passed to the callback function (or Promise) is a `$Refs` object. This same object is accessible via the [`parser.$refs`](openapi-parser.md#refs) property of `OpenAPIParser` objects.
When you call the [`resolve`](openapi-parser.md#resolveschema-options) method, the value that is returned is a `$Refs` object. This same object is accessible via the [`parser.$refs`](openapi-parser.md#refs) property of `OpenAPIParser` objects.

This object is a map of JSON References and their resolved values. It also has several convenient helper methods that make it easy for you to navigate and manipulate the JSON References.

Expand Down
Loading

0 comments on commit d86c1df

Please sign in to comment.