nestjs-openapi-next 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +25 -0
- package/README.md +247 -90
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/decorators/api-tag-group.decorator.d.ts +8 -4
- package/dist/decorators/api-tag-group.decorator.js +5 -1
- package/dist/decorators/api-webhook.decorator.d.ts +1 -0
- package/dist/decorators/api-webhook.decorator.js +8 -0
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +1 -0
- package/dist/document-builder.d.ts +5 -1
- package/dist/document-builder.js +28 -3
- package/dist/explorers/api-parameters.explorer.d.ts +25 -2
- package/dist/extra/swagger-shim.d.ts +2 -0
- package/dist/extra/swagger-shim.js +8 -0
- package/dist/interfaces/denormalized-doc.interface.d.ts +2 -0
- package/dist/interfaces/open-api-spec.interface.d.ts +40 -4
- package/dist/interfaces/schema-object-metadata.interface.d.ts +1 -1
- package/dist/services/schema-object-factory.d.ts +58 -8
- package/dist/services/schema-object-factory.js +2 -1
- package/dist/services/swagger-types-mapper.d.ts +127 -12
- package/dist/swagger-explorer.js +10 -1
- package/dist/swagger-module.d.ts +2 -0
- package/dist/swagger-module.js +376 -7
- package/dist/swagger-scanner.js +8 -1
- package/dist/swagger-transformer.d.ts +1 -1
- package/dist/swagger-transformer.js +13 -5
- package/package.json +10 -10
- package/bun.lock +0 -2154
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"WebSearch",
|
|
5
|
+
"WebFetch(domain:spec.openapis.org)",
|
|
6
|
+
"WebFetch(domain:www.openapis.org)",
|
|
7
|
+
"WebFetch(domain:blog.stoplight.io)",
|
|
8
|
+
"WebFetch(domain:apisyouwonthate.com)",
|
|
9
|
+
"WebFetch(domain:github.com)",
|
|
10
|
+
"Bash(gh auth status:*)",
|
|
11
|
+
"Bash(gh issue create:*)",
|
|
12
|
+
"Bash(gh issue view:*)",
|
|
13
|
+
"Bash(gh issue edit:*)",
|
|
14
|
+
"Bash(npm test)",
|
|
15
|
+
"Bash(npm install)",
|
|
16
|
+
"Bash(npm test:*)",
|
|
17
|
+
"Bash(gh pr view:*)",
|
|
18
|
+
"Bash(git checkout:*)",
|
|
19
|
+
"Bash(git add:*)",
|
|
20
|
+
"Bash(git commit -m \"$\\(cat <<''EOF''\ndocs: update README with OAS 3.1/3.2 features\n\nAdd documentation for newly implemented OpenAPI 3.1/3.2 features:\n- JSON Schema Draft 2020-12 alignment\n- type as array support \\(replaces nullable\\)\n- LicenseObject.identifier\n- ServerObject.pathPrefix\n- InfoObject.tags\n- ReferenceObject summary/description override\n- exclusiveMinimum/exclusiveMaximum type change\n\nCloses #7\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
21
|
+
"Bash(git push:*)",
|
|
22
|
+
"Bash(gh pr create:*)"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
package/README.md
CHANGED
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
# nestjs-openapi-next
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
3
|
+
`nestjs-openapi-next` is a fork of `@nestjs/swagger` (upstream: `nestjs/swagger`).
|
|
4
|
+
The goal is to keep upstream behavior as compatible as possible while adding a set of **OpenAPI 3.1/3.2** features and widely-used **OpenAPI extension fields** (`x-`) that are commonly consumed by tools like Redoc.
|
|
5
|
+
|
|
6
|
+
## Key differences from upstream
|
|
7
|
+
|
|
8
|
+
- **Richer OpenAPI 3.1/3.2 typings**
|
|
9
|
+
- e.g. `TagObject.summary`, `OAuthFlowsObject.deviceAuthorization`, `LicenseObject.identifier`, etc.
|
|
10
|
+
- **Enhanced tag support**
|
|
11
|
+
- `@ApiTag(options)` (class/controller-level): defines tag metadata (`summary`, `x-displayName`, `description`, `parent`, `kind`, ...) and merges it into the top-level `document.tags`.
|
|
12
|
+
- `x-displayName` support for tags, mirrored with `summary` (setting either results in both fields being written with the same value).
|
|
13
|
+
- Root-level `x-tagGroups` support (commonly used by Redoc). If you use `parent` to form relationships, `x-tagGroups` is auto-derived; you can also set it explicitly via `DocumentBuilder`.
|
|
14
|
+
- **OAS 3.1 features**
|
|
15
|
+
- JSON Schema Draft 2020-12 alignment (e.g. `$defs`, `prefixItems`, `const`, `contentEncoding`, `contentMediaType`, `contentSchema`).
|
|
16
|
+
- `type` as array support (e.g. `type: ['string', 'null']`) with automatic `nullable` removal.
|
|
17
|
+
- `LicenseObject.identifier` field support via `DocumentBuilder.setLicense()`.
|
|
18
|
+
- `ReferenceObject` with `summary` and `description` override support.
|
|
19
|
+
- `exclusiveMinimum` / `exclusiveMaximum` as number type (changed from boolean in OAS 3.0).
|
|
20
|
+
- **OAS 3.2 features**
|
|
21
|
+
- HTTP `QUERY` method via `@ApiQueryMethod()` (emits `paths['/x'].query`).
|
|
22
|
+
- Streaming responses via `@ApiStreamingResponse()` (`itemSchema`, e.g. SSE `text/event-stream`).
|
|
23
|
+
- OAuth2 Device Authorization Flow typing + `@ApiSecurityDeviceFlow()` helper.
|
|
24
|
+
- `ServerObject.pathPrefix` field support via `DocumentBuilder.addServer()`.
|
|
25
|
+
- `InfoObject.tags` field support via `DocumentBuilder.setInfoTags()`.
|
|
26
|
+
- **Convenience APIs**
|
|
27
|
+
- `DocumentBuilder.addServerWithName()` for a non-standard-but-common `server.name`.
|
|
28
|
+
|
|
29
|
+
Test coverage: `test/openapi-3-1.spec.ts`, `test/openapi-3-2.spec.ts`.
|
|
23
30
|
|
|
24
31
|
## Compatibility
|
|
25
32
|
|
|
26
33
|
- **NestJS**: peerDependencies target `@nestjs/common` / `@nestjs/core` `^11.0.1`
|
|
27
|
-
- **Runtime deps**:
|
|
34
|
+
- **Runtime deps**: aligned with upstream `@nestjs/swagger` (`reflect-metadata`, optional `class-validator` / `class-transformer`, etc.)
|
|
28
35
|
|
|
29
36
|
## Installation
|
|
30
37
|
|
|
31
|
-
### Install from this fork (recommended for OAS 3.2 extensions)
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
npm i --save github:undownding/nestjs-openapi-next
|
|
35
|
-
```
|
|
36
|
-
|
|
37
38
|
### Install from npm
|
|
38
39
|
|
|
39
40
|
```bash
|
|
@@ -44,98 +45,121 @@ npm i --save nestjs-openapi-next
|
|
|
44
45
|
|
|
45
46
|
See the official Nest OpenAPI tutorial: `https://docs.nestjs.com/openapi/introduction`
|
|
46
47
|
|
|
47
|
-
Typical setup (minimal skeleton):
|
|
48
|
-
|
|
49
48
|
```ts
|
|
50
49
|
import { NestFactory } from '@nestjs/core';
|
|
51
|
-
import { DocumentBuilder, SwaggerModule } from '
|
|
50
|
+
import { DocumentBuilder, SwaggerModule } from 'nestjs-openapi-next';
|
|
52
51
|
|
|
53
|
-
// ...
|
|
54
52
|
const app = await NestFactory.create(AppModule);
|
|
55
53
|
|
|
56
54
|
const config = new DocumentBuilder()
|
|
57
55
|
.setTitle('Example')
|
|
58
56
|
.setDescription('API description')
|
|
59
57
|
.setVersion('1.0')
|
|
60
|
-
// If you want to declare OAS 3.2
|
|
58
|
+
// If you want the document to declare OAS 3.2, set it explicitly:
|
|
61
59
|
.setOpenAPIVersion('3.2.0')
|
|
62
60
|
.build();
|
|
63
61
|
|
|
64
62
|
const document = SwaggerModule.createDocument(app, config);
|
|
65
63
|
SwaggerModule.setup('api', app, document);
|
|
66
|
-
|
|
67
|
-
await app.listen(3000);
|
|
68
64
|
```
|
|
69
65
|
|
|
70
|
-
##
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
### 1) `@ApiTag(options)` (recommended) and deprecation of `@ApiTagGroup()`
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
`@ApiTag(options)` is the primary decorator for defining tag metadata at the controller level.
|
|
73
71
|
|
|
74
|
-
|
|
72
|
+
`@ApiTagGroup(options)` is kept as a backward-compatible alias, but is **deprecated** and may be removed in a future major version.
|
|
75
73
|
|
|
76
74
|
```ts
|
|
77
|
-
import { Controller,
|
|
78
|
-
import {
|
|
75
|
+
import { Controller, Get } from '@nestjs/common';
|
|
76
|
+
import { ApiTag } from 'nestjs-openapi-next';
|
|
79
77
|
|
|
80
|
-
@
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
@ApiTag({
|
|
79
|
+
name: 'Customers',
|
|
80
|
+
summary: 'Customers'
|
|
81
|
+
// you may also set: 'x-displayName': 'Customers'
|
|
82
|
+
})
|
|
83
|
+
@Controller('customers')
|
|
84
|
+
export class CustomersController {
|
|
85
|
+
@Get()
|
|
86
|
+
list() {
|
|
87
|
+
return [];
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
```
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
- Important: this does **not** change Nest routing at runtime — it only affects the generated OpenAPI document.
|
|
92
|
+
### 2) Tag `x-displayName` (mirrored with `summary`)
|
|
92
93
|
|
|
93
|
-
|
|
94
|
+
This fork treats tag `summary` and `x-displayName` as equivalent display fields:
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
- set either one;
|
|
97
|
+
- the generated `document.tags` will contain **both** `summary` and `x-displayName` with the same value.
|
|
98
|
+
|
|
99
|
+
### 3) Root-level `x-tagGroups` (tag grouping)
|
|
100
|
+
|
|
101
|
+
#### Auto-derived (recommended)
|
|
102
|
+
|
|
103
|
+
If you use tag `parent` relationships (via `@ApiTag()`), the root-level `x-tagGroups` will be derived automatically:
|
|
96
104
|
|
|
97
105
|
```ts
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
parent: 'Admin',
|
|
106
|
-
kind: 'nav'
|
|
107
|
-
})
|
|
108
|
-
@Controller('cats')
|
|
109
|
-
export class CatsController {
|
|
110
|
-
@Get()
|
|
111
|
-
list() {
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
}
|
|
106
|
+
@ApiTag({ name: 'Customers' })
|
|
107
|
+
@Controller('customers')
|
|
108
|
+
export class CustomersController {}
|
|
109
|
+
|
|
110
|
+
@ApiTag({ name: 'Customer Authentication', parent: 'Customers' })
|
|
111
|
+
@Controller('auth')
|
|
112
|
+
export class AuthController {}
|
|
115
113
|
```
|
|
116
114
|
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
Illustrative output:
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
tags:
|
|
119
|
+
- name: Customers
|
|
120
|
+
- name: Customer Authentication
|
|
121
|
+
x-tagGroups:
|
|
122
|
+
- name: Customers
|
|
123
|
+
tags:
|
|
124
|
+
- Customers
|
|
125
|
+
- Customer Authentication
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Manual configuration
|
|
119
129
|
|
|
120
|
-
|
|
130
|
+
You can also set `x-tagGroups` explicitly via `DocumentBuilder.addTagGroup()`:
|
|
121
131
|
|
|
122
132
|
```ts
|
|
123
|
-
new DocumentBuilder()
|
|
124
|
-
.
|
|
133
|
+
const config = new DocumentBuilder()
|
|
134
|
+
.setTitle('t')
|
|
135
|
+
.setVersion('1')
|
|
136
|
+
.addTag('Customers')
|
|
137
|
+
.addTag('Customer Authentication')
|
|
138
|
+
.addTagGroup('Customers', ['Customers', 'Customer Authentication'])
|
|
125
139
|
.build();
|
|
126
140
|
```
|
|
127
141
|
|
|
128
|
-
|
|
142
|
+
### 4) HTTP `QUERY` method: `@ApiQueryMethod()`
|
|
129
143
|
|
|
130
|
-
|
|
144
|
+
```ts
|
|
145
|
+
import { Controller, Post } from '@nestjs/common';
|
|
146
|
+
import { ApiQueryMethod } from 'nestjs-openapi-next';
|
|
131
147
|
|
|
132
|
-
|
|
148
|
+
@Controller()
|
|
149
|
+
export class QueryController {
|
|
150
|
+
@Post('search')
|
|
151
|
+
@ApiQueryMethod()
|
|
152
|
+
search() {
|
|
153
|
+
return { ok: true };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
133
157
|
|
|
134
|
-
|
|
158
|
+
### 5) Streaming responses: `@ApiStreamingResponse()` (`itemSchema`)
|
|
135
159
|
|
|
136
160
|
```ts
|
|
137
161
|
import { Controller, Get } from '@nestjs/common';
|
|
138
|
-
import { ApiProperty, ApiStreamingResponse } from '
|
|
162
|
+
import { ApiProperty, ApiStreamingResponse } from 'nestjs-openapi-next';
|
|
139
163
|
|
|
140
164
|
class SseItemDto {
|
|
141
165
|
@ApiProperty()
|
|
@@ -156,17 +180,11 @@ export class EventsController {
|
|
|
156
180
|
}
|
|
157
181
|
```
|
|
158
182
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
- `responses['200'].content['text/event-stream'].itemSchema` -> `#/components/schemas/SseItemDto`
|
|
162
|
-
|
|
163
|
-
### 4) OAuth2 Device Authorization Flow: `flows.deviceAuthorization` + `@ApiSecurityDeviceFlow()`
|
|
164
|
-
|
|
165
|
-
Define the OAuth2 scheme (with `flows.deviceAuthorization`) via `DocumentBuilder.addOAuth2()`, then declare per-operation requirements with the decorator.
|
|
183
|
+
### 6) OAuth2 Device Authorization Flow: `flows.deviceAuthorization` + `@ApiSecurityDeviceFlow()`
|
|
166
184
|
|
|
167
185
|
```ts
|
|
168
186
|
import { Controller, Get } from '@nestjs/common';
|
|
169
|
-
import { ApiSecurityDeviceFlow, DocumentBuilder } from '
|
|
187
|
+
import { ApiSecurityDeviceFlow, DocumentBuilder } from 'nestjs-openapi-next';
|
|
170
188
|
|
|
171
189
|
@Controller()
|
|
172
190
|
export class SecuredController {
|
|
@@ -196,15 +214,154 @@ const config = new DocumentBuilder()
|
|
|
196
214
|
.build();
|
|
197
215
|
```
|
|
198
216
|
|
|
199
|
-
|
|
217
|
+
### 7) OpenAPI 3.1 Webhooks: `@ApiWebhook()`
|
|
218
|
+
|
|
219
|
+
OpenAPI 3.1 introduces a root-level `webhooks` object for out-of-band callbacks
|
|
220
|
+
initiated by the API provider.
|
|
221
|
+
|
|
222
|
+
This fork supports emitting webhook operations via a decorator:
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { Controller, Post } from '@nestjs/common';
|
|
226
|
+
import { ApiWebhook } from '@nestjs/swagger';
|
|
227
|
+
|
|
228
|
+
@Controller()
|
|
229
|
+
export class StripeWebhooksController {
|
|
230
|
+
@Post('stripe')
|
|
231
|
+
@ApiWebhook('stripeEvent')
|
|
232
|
+
stripe() {
|
|
233
|
+
return { ok: true };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
The generated document will contain `document.webhooks.stripeEvent.post`, and the
|
|
239
|
+
corresponding route will **not** be emitted under `document.paths`.
|
|
240
|
+
|
|
241
|
+
### 8) `LicenseObject.identifier` (OAS 3.1)
|
|
242
|
+
|
|
243
|
+
OAS 3.1 added an `identifier` field to `LicenseObject` for SPDX license identifiers:
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
const config = new DocumentBuilder()
|
|
247
|
+
.setTitle('Example')
|
|
248
|
+
.setVersion('1.0')
|
|
249
|
+
.setLicense('MIT', 'https://opensource.org/licenses/MIT', 'MIT')
|
|
250
|
+
.build();
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
This produces:
|
|
254
|
+
|
|
255
|
+
```yaml
|
|
256
|
+
info:
|
|
257
|
+
license:
|
|
258
|
+
name: MIT
|
|
259
|
+
url: https://opensource.org/licenses/MIT
|
|
260
|
+
identifier: MIT
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### 9) `ServerObject.pathPrefix` (OAS 3.2)
|
|
264
|
+
|
|
265
|
+
OAS 3.2 added a `pathPrefix` field to `ServerObject`:
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
const config = new DocumentBuilder()
|
|
269
|
+
.setTitle('Example')
|
|
270
|
+
.setVersion('1.0')
|
|
271
|
+
.addServer('https://api.example.com', 'Production', {}, '/v1')
|
|
272
|
+
.build();
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
This produces:
|
|
276
|
+
|
|
277
|
+
```yaml
|
|
278
|
+
servers:
|
|
279
|
+
- url: https://api.example.com
|
|
280
|
+
description: Production
|
|
281
|
+
pathPrefix: /v1
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### 10) `InfoObject.tags` (OAS 3.2)
|
|
285
|
+
|
|
286
|
+
OAS 3.2 added a `tags` field to `InfoObject` for categorizing the API itself:
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
const config = new DocumentBuilder()
|
|
290
|
+
.setTitle('Example')
|
|
291
|
+
.setVersion('1.0')
|
|
292
|
+
.setInfoTags(['payments', 'commerce'])
|
|
293
|
+
.build();
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
This produces:
|
|
297
|
+
|
|
298
|
+
```yaml
|
|
299
|
+
info:
|
|
300
|
+
title: Example
|
|
301
|
+
version: '1.0'
|
|
302
|
+
tags:
|
|
303
|
+
- payments
|
|
304
|
+
- commerce
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### 11) `ReferenceObject` with `summary` / `description` override (OAS 3.1)
|
|
200
308
|
|
|
201
|
-
|
|
202
|
-
|
|
309
|
+
OAS 3.1 allows `$ref` objects to include `summary` and `description` fields that override the referenced schema's values:
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
import { ApiProperty } from 'nestjs-openapi-next';
|
|
313
|
+
|
|
314
|
+
class CreateUserDto {
|
|
315
|
+
@ApiProperty({
|
|
316
|
+
allOf: [
|
|
317
|
+
{
|
|
318
|
+
$ref: '#/components/schemas/BaseUser',
|
|
319
|
+
summary: 'User base fields',
|
|
320
|
+
description: 'Contains the common user properties'
|
|
321
|
+
}
|
|
322
|
+
]
|
|
323
|
+
})
|
|
324
|
+
user: BaseUser;
|
|
325
|
+
}
|
|
326
|
+
```
|
|
203
327
|
|
|
204
|
-
|
|
328
|
+
### 12) `type` as array (OAS 3.1)
|
|
205
329
|
|
|
206
|
-
|
|
207
|
-
|
|
330
|
+
OAS 3.1 supports `type` as an array for union types. This replaces the `nullable` keyword:
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
import { ApiProperty } from 'nestjs-openapi-next';
|
|
334
|
+
|
|
335
|
+
class UserDto {
|
|
336
|
+
@ApiProperty({ type: ['string', 'null'] })
|
|
337
|
+
nickname: string | null;
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
This produces `type: ['string', 'null']` instead of `type: 'string', nullable: true`.
|
|
342
|
+
|
|
343
|
+
### 13) JSON Schema Draft 2020-12 keywords (OAS 3.1)
|
|
344
|
+
|
|
345
|
+
OAS 3.1 aligns with JSON Schema Draft 2020-12, adding support for:
|
|
346
|
+
|
|
347
|
+
- `$defs` - local schema definitions
|
|
348
|
+
- `prefixItems` - tuple validation (replaces `items` array form)
|
|
349
|
+
- `const` - exact value matching
|
|
350
|
+
- `contentEncoding` - encoding for string content (e.g., `base64`)
|
|
351
|
+
- `contentMediaType` - media type for string content
|
|
352
|
+
- `contentSchema` - schema for decoded content
|
|
353
|
+
|
|
354
|
+
```ts
|
|
355
|
+
import { ApiProperty } from 'nestjs-openapi-next';
|
|
356
|
+
|
|
357
|
+
class FileDto {
|
|
358
|
+
@ApiProperty({
|
|
359
|
+
contentEncoding: 'base64',
|
|
360
|
+
contentMediaType: 'image/png'
|
|
361
|
+
})
|
|
362
|
+
data: string;
|
|
363
|
+
}
|
|
364
|
+
```
|
|
208
365
|
|
|
209
366
|
## License
|
|
210
367
|
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.DECORATORS = {
|
|
|
10
10
|
API_TAGS: `${exports.DECORATORS_PREFIX}/apiUseTags`,
|
|
11
11
|
API_TAG_GROUP: `${exports.DECORATORS_PREFIX}/apiTagGroup`,
|
|
12
12
|
API_QUERY_METHOD: `${exports.DECORATORS_PREFIX}/apiQueryMethod`,
|
|
13
|
+
API_WEBHOOK: `${exports.DECORATORS_PREFIX}/apiWebhook`,
|
|
13
14
|
API_CALLBACKS: `${exports.DECORATORS_PREFIX}/apiCallbacks`,
|
|
14
15
|
API_PARAMETERS: `${exports.DECORATORS_PREFIX}/apiParameters`,
|
|
15
16
|
API_HEADERS: `${exports.DECORATORS_PREFIX}/apiHeaders`,
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { TagObject } from '../interfaces/open-api-spec.interface';
|
|
2
|
-
export type
|
|
3
|
-
export
|
|
2
|
+
export type ApiTagKind = 'audience' | 'badge' | 'nav' | (string & {});
|
|
3
|
+
export type ApiTagGroupKind = ApiTagKind;
|
|
4
|
+
export interface ApiTagOptions extends Pick<TagObject, 'name' | 'summary' | 'x-displayName' | 'description' | 'externalDocs' | 'parent' | 'kind'> {
|
|
4
5
|
name: string;
|
|
5
6
|
summary?: string;
|
|
7
|
+
'x-displayName'?: string;
|
|
6
8
|
description?: string;
|
|
7
9
|
externalDocs?: TagObject['externalDocs'];
|
|
8
10
|
parent?: string;
|
|
9
|
-
kind?:
|
|
11
|
+
kind?: ApiTagKind;
|
|
10
12
|
}
|
|
11
|
-
export declare function
|
|
13
|
+
export declare function ApiTag(options: ApiTagOptions): ClassDecorator;
|
|
14
|
+
export declare function ApiTagGroup(options: ApiTagOptions): ClassDecorator;
|
|
15
|
+
export type ApiTagGroupOptions = ApiTagOptions;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiTag = ApiTag;
|
|
3
4
|
exports.ApiTagGroup = ApiTagGroup;
|
|
4
5
|
const constants_1 = require("../constants");
|
|
5
6
|
const api_use_tags_decorator_1 = require("./api-use-tags.decorator");
|
|
6
|
-
function
|
|
7
|
+
function ApiTag(options) {
|
|
7
8
|
return (target) => {
|
|
8
9
|
const previous = Reflect.getMetadata(constants_1.DECORATORS.API_TAG_GROUP, target) || [];
|
|
9
10
|
Reflect.defineMetadata(constants_1.DECORATORS.API_TAG_GROUP, [...previous, options], target);
|
|
@@ -11,3 +12,6 @@ function ApiTagGroup(options) {
|
|
|
11
12
|
return target;
|
|
12
13
|
};
|
|
13
14
|
}
|
|
15
|
+
function ApiTagGroup(options) {
|
|
16
|
+
return ApiTag(options);
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function ApiWebhook(name?: string): MethodDecorator;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiWebhook = ApiWebhook;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
const helpers_1 = require("./helpers");
|
|
6
|
+
function ApiWebhook(name) {
|
|
7
|
+
return (0, helpers_1.createMethodDecorator)(constants_1.DECORATORS.API_WEBHOOK, name !== null && name !== void 0 ? name : true);
|
|
8
|
+
}
|
|
@@ -17,6 +17,7 @@ export * from './api-produces.decorator';
|
|
|
17
17
|
export { ApiProperty, ApiPropertyOptional, ApiPropertyOptions, ApiResponseProperty } from './api-property.decorator';
|
|
18
18
|
export * from './api-query.decorator';
|
|
19
19
|
export * from './api-query-method.decorator';
|
|
20
|
+
export * from './api-webhook.decorator';
|
|
20
21
|
export * from './api-response.decorator';
|
|
21
22
|
export * from './api-streaming-response.decorator';
|
|
22
23
|
export * from './api-security.decorator';
|
package/dist/decorators/index.js
CHANGED
|
@@ -37,6 +37,7 @@ Object.defineProperty(exports, "ApiPropertyOptional", { enumerable: true, get: f
|
|
|
37
37
|
Object.defineProperty(exports, "ApiResponseProperty", { enumerable: true, get: function () { return api_property_decorator_1.ApiResponseProperty; } });
|
|
38
38
|
__exportStar(require("./api-query.decorator"), exports);
|
|
39
39
|
__exportStar(require("./api-query-method.decorator"), exports);
|
|
40
|
+
__exportStar(require("./api-webhook.decorator"), exports);
|
|
40
41
|
__exportStar(require("./api-response.decorator"), exports);
|
|
41
42
|
__exportStar(require("./api-streaming-response.decorator"), exports);
|
|
42
43
|
__exportStar(require("./api-security.decorator"), exports);
|
|
@@ -8,13 +8,17 @@ export declare class DocumentBuilder {
|
|
|
8
8
|
setDescription(description: string): this;
|
|
9
9
|
setVersion(version: string): this;
|
|
10
10
|
setTermsOfService(termsOfService: string): this;
|
|
11
|
+
setInfoTags(tags: string[]): this;
|
|
11
12
|
setContact(name: string, url: string, email: string): this;
|
|
12
13
|
setLicense(name: string, url: string): this;
|
|
14
|
+
setLicenseWithIdentifier(name: string, identifier: string): this;
|
|
13
15
|
setOpenAPIVersion(version: string): this;
|
|
14
|
-
addServer(url: string, description?: string, variables?: Record<string, ServerVariableObject>): this;
|
|
16
|
+
addServer(url: string, description?: string, pathPrefix?: string, variables?: Record<string, ServerVariableObject>): this;
|
|
17
|
+
addServerWithName(name: string, url: string, description?: string, pathPrefix?: string, variables?: Record<string, ServerVariableObject>): this;
|
|
15
18
|
setExternalDoc(description: string, url: string): this;
|
|
16
19
|
setBasePath(path: string): this;
|
|
17
20
|
addTag(name: string, description?: string, externalDocs?: ExternalDocumentationObject, summary?: string): this;
|
|
21
|
+
addTagGroup(name: string, tags: string[]): this;
|
|
18
22
|
addExtension(extensionKey: string, extensionProperties: any, location?: ExtensionLocation): this;
|
|
19
23
|
addSecurity(name: string, options: SecuritySchemeObject): this;
|
|
20
24
|
addGlobalResponse(...respones: ApiResponseOptions[]): this;
|
package/dist/document-builder.js
CHANGED
|
@@ -27,6 +27,10 @@ class DocumentBuilder {
|
|
|
27
27
|
this.document.info.termsOfService = termsOfService;
|
|
28
28
|
return this;
|
|
29
29
|
}
|
|
30
|
+
setInfoTags(tags) {
|
|
31
|
+
this.document.info.tags = tags;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
30
34
|
setContact(name, url, email) {
|
|
31
35
|
this.document.info.contact = { name, url, email };
|
|
32
36
|
return this;
|
|
@@ -35,6 +39,10 @@ class DocumentBuilder {
|
|
|
35
39
|
this.document.info.license = { name, url };
|
|
36
40
|
return this;
|
|
37
41
|
}
|
|
42
|
+
setLicenseWithIdentifier(name, identifier) {
|
|
43
|
+
this.document.info.license = { name, identifier };
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
38
46
|
setOpenAPIVersion(version) {
|
|
39
47
|
if (version.match(/^\d\.\d\.\d$/)) {
|
|
40
48
|
this.document.openapi = version;
|
|
@@ -44,8 +52,18 @@ class DocumentBuilder {
|
|
|
44
52
|
}
|
|
45
53
|
return this;
|
|
46
54
|
}
|
|
47
|
-
addServer(url, description, variables) {
|
|
48
|
-
this.document.servers.push({ url, description, variables });
|
|
55
|
+
addServer(url, description, pathPrefix, variables) {
|
|
56
|
+
this.document.servers.push({ url, description, variables, pathPrefix });
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
addServerWithName(name, url, description, pathPrefix, variables) {
|
|
60
|
+
this.document.servers.push({
|
|
61
|
+
name,
|
|
62
|
+
url,
|
|
63
|
+
description,
|
|
64
|
+
variables,
|
|
65
|
+
pathPrefix
|
|
66
|
+
});
|
|
49
67
|
return this;
|
|
50
68
|
}
|
|
51
69
|
setExternalDoc(description, url) {
|
|
@@ -57,14 +75,21 @@ class DocumentBuilder {
|
|
|
57
75
|
return this;
|
|
58
76
|
}
|
|
59
77
|
addTag(name, description = '', externalDocs, summary) {
|
|
78
|
+
const normalizedSummary = summary;
|
|
60
79
|
this.document.tags = this.document.tags.concat((0, lodash_1.pickBy)({
|
|
61
80
|
name,
|
|
62
|
-
summary,
|
|
81
|
+
summary: normalizedSummary,
|
|
82
|
+
'x-displayName': normalizedSummary,
|
|
63
83
|
description,
|
|
64
84
|
externalDocs
|
|
65
85
|
}, (0, lodash_1.negate)(lodash_1.isUndefined)));
|
|
66
86
|
return this;
|
|
67
87
|
}
|
|
88
|
+
addTagGroup(name, tags) {
|
|
89
|
+
const existing = this.document['x-tagGroups'] || [];
|
|
90
|
+
this.document['x-tagGroups'] = existing.concat({ name, tags });
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
68
93
|
addExtension(extensionKey, extensionProperties, location = 'root') {
|
|
69
94
|
if (!extensionKey.startsWith('x-')) {
|
|
70
95
|
throw new Error('Extension key is not prefixed. Please ensure you prefix it with `x-`.');
|
|
@@ -6,6 +6,29 @@ export declare const exploreApiParametersMetadata: (schemas: Record<string, Sche
|
|
|
6
6
|
schema: {
|
|
7
7
|
type: string;
|
|
8
8
|
items: any;
|
|
9
|
+
$schema?: string;
|
|
10
|
+
$id?: string;
|
|
11
|
+
$defs?: Record<string, SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject>;
|
|
12
|
+
$dynamicAnchor?: string;
|
|
13
|
+
$dynamicRef?: string;
|
|
14
|
+
$anchor?: string;
|
|
15
|
+
const?: any;
|
|
16
|
+
contentMediaType?: string;
|
|
17
|
+
contentEncoding?: string;
|
|
18
|
+
contentSchema?: SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject;
|
|
19
|
+
if?: SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject;
|
|
20
|
+
then?: SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject;
|
|
21
|
+
else?: SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject;
|
|
22
|
+
dependentSchemas?: Record<string, SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject>;
|
|
23
|
+
dependentRequired?: Record<string, string[]>;
|
|
24
|
+
prefixItems?: (SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject)[];
|
|
25
|
+
unevaluatedProperties?: SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject | boolean;
|
|
26
|
+
unevaluatedItems?: SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject | boolean;
|
|
27
|
+
contains?: SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject;
|
|
28
|
+
minContains?: number;
|
|
29
|
+
maxContains?: number;
|
|
30
|
+
$comment?: string;
|
|
31
|
+
propertyNames?: SchemaObject | import("../interfaces/open-api-spec.interface").ReferenceObject;
|
|
9
32
|
nullable?: boolean;
|
|
10
33
|
discriminator?: import("../interfaces/open-api-spec.interface").DiscriminatorObject;
|
|
11
34
|
readOnly?: boolean;
|
|
@@ -28,9 +51,9 @@ export declare const exploreApiParametersMetadata: (schemas: Record<string, Sche
|
|
|
28
51
|
title?: string;
|
|
29
52
|
multipleOf?: number;
|
|
30
53
|
maximum?: number;
|
|
31
|
-
exclusiveMaximum?: boolean;
|
|
54
|
+
exclusiveMaximum?: boolean | number;
|
|
32
55
|
minimum?: number;
|
|
33
|
-
exclusiveMinimum?: boolean;
|
|
56
|
+
exclusiveMinimum?: boolean | number;
|
|
34
57
|
maxLength?: number;
|
|
35
58
|
minLength?: number;
|
|
36
59
|
pattern?: string;
|