nestjs-openapi-next 1.0.0 → 1.0.1
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/.idea/codeStyles/Project.xml +70 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/compiler.xml +6 -0
- package/.idea/copilot.data.migration.agent.xml +6 -0
- package/.idea/copilot.data.migration.ask2agent.xml +6 -0
- package/.idea/copilot.data.migration.edit.xml +6 -0
- package/.idea/easycode.ignore +13 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/nestjs-openapi-next.iml +8 -0
- package/.idea/prettier.xml +6 -0
- package/.idea/vcs.xml +6 -0
- package/README.md +112 -88
- 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 +2 -0
- package/dist/document-builder.js +12 -1
- 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 +8 -0
- package/dist/swagger-explorer.js +8 -1
- package/dist/swagger-module.d.ts +2 -0
- package/dist/swagger-module.js +67 -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 +4 -4
- package/bun.lock +0 -2154
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<component name="ProjectCodeStyleConfiguration">
|
|
2
|
+
<code_scheme name="Project" version="173">
|
|
3
|
+
<HTMLCodeStyleSettings>
|
|
4
|
+
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
|
5
|
+
</HTMLCodeStyleSettings>
|
|
6
|
+
<JSCodeStyleSettings version="0">
|
|
7
|
+
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
8
|
+
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
|
9
|
+
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
10
|
+
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
|
11
|
+
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
12
|
+
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
13
|
+
</JSCodeStyleSettings>
|
|
14
|
+
<JetCodeStyleSettings>
|
|
15
|
+
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
|
16
|
+
</JetCodeStyleSettings>
|
|
17
|
+
<TypeScriptCodeStyleSettings version="0">
|
|
18
|
+
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
19
|
+
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
|
20
|
+
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
21
|
+
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
|
22
|
+
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
23
|
+
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
24
|
+
</TypeScriptCodeStyleSettings>
|
|
25
|
+
<VueCodeStyleSettings>
|
|
26
|
+
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
|
|
27
|
+
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
|
|
28
|
+
</VueCodeStyleSettings>
|
|
29
|
+
<codeStyleSettings language="HTML">
|
|
30
|
+
<option name="SOFT_MARGINS" value="80" />
|
|
31
|
+
<indentOptions>
|
|
32
|
+
<option name="INDENT_SIZE" value="2" />
|
|
33
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
34
|
+
<option name="TAB_SIZE" value="2" />
|
|
35
|
+
</indentOptions>
|
|
36
|
+
</codeStyleSettings>
|
|
37
|
+
<codeStyleSettings language="JAVA">
|
|
38
|
+
<indentOptions>
|
|
39
|
+
<option name="USE_TAB_CHARACTER" value="true" />
|
|
40
|
+
<option name="SMART_TABS" value="true" />
|
|
41
|
+
</indentOptions>
|
|
42
|
+
</codeStyleSettings>
|
|
43
|
+
<codeStyleSettings language="JavaScript">
|
|
44
|
+
<option name="SOFT_MARGINS" value="80" />
|
|
45
|
+
<indentOptions>
|
|
46
|
+
<option name="INDENT_SIZE" value="2" />
|
|
47
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
48
|
+
<option name="TAB_SIZE" value="2" />
|
|
49
|
+
</indentOptions>
|
|
50
|
+
</codeStyleSettings>
|
|
51
|
+
<codeStyleSettings language="TypeScript">
|
|
52
|
+
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
|
53
|
+
<option name="SOFT_MARGINS" value="80" />
|
|
54
|
+
<indentOptions>
|
|
55
|
+
<option name="INDENT_SIZE" value="2" />
|
|
56
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
57
|
+
<option name="TAB_SIZE" value="2" />
|
|
58
|
+
</indentOptions>
|
|
59
|
+
</codeStyleSettings>
|
|
60
|
+
<codeStyleSettings language="Vue">
|
|
61
|
+
<option name="SOFT_MARGINS" value="80" />
|
|
62
|
+
<indentOptions>
|
|
63
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
64
|
+
</indentOptions>
|
|
65
|
+
</codeStyleSettings>
|
|
66
|
+
<codeStyleSettings language="kotlin">
|
|
67
|
+
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
|
68
|
+
</codeStyleSettings>
|
|
69
|
+
</code_scheme>
|
|
70
|
+
</component>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/nestjs-openapi-next.iml" filepath="$PROJECT_DIR$/.idea/nestjs-openapi-next.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$" />
|
|
5
|
+
<orderEntry type="inheritedJdk" />
|
|
6
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
7
|
+
</component>
|
|
8
|
+
</module>
|
package/.idea/vcs.xml
ADDED
package/README.md
CHANGED
|
@@ -1,39 +1,32 @@
|
|
|
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
|
-
- `@ApiSecurityDeviceFlow()` convenience decorator for security requirements.
|
|
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.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.2 typings**
|
|
9
|
+
- e.g. `TagObject.summary`, `OAuthFlowsObject.deviceAuthorization`, 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
|
+
- **Additional OAS 3.2 behaviors**
|
|
15
|
+
- HTTP `QUERY` method via `@ApiQueryMethod()` (emits `paths['/x'].query`).
|
|
16
|
+
- Streaming responses via `@ApiStreamingResponse()` (`itemSchema`, e.g. SSE `text/event-stream`).
|
|
17
|
+
- OAuth2 Device Authorization Flow typing + `@ApiSecurityDeviceFlow()` helper.
|
|
18
|
+
- **Convenience APIs**
|
|
19
|
+
- `DocumentBuilder.addServerWithName()` for a non-standard-but-common `server.name`.
|
|
21
20
|
|
|
22
21
|
Test coverage: `test/openapi-3-2.spec.ts`.
|
|
23
22
|
|
|
24
23
|
## Compatibility
|
|
25
24
|
|
|
26
25
|
- **NestJS**: peerDependencies target `@nestjs/common` / `@nestjs/core` `^11.0.1`
|
|
27
|
-
- **Runtime deps**:
|
|
26
|
+
- **Runtime deps**: aligned with upstream `@nestjs/swagger` (`reflect-metadata`, optional `class-validator` / `class-transformer`, etc.)
|
|
28
27
|
|
|
29
28
|
## Installation
|
|
30
29
|
|
|
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
30
|
### Install from npm
|
|
38
31
|
|
|
39
32
|
```bash
|
|
@@ -44,98 +37,121 @@ npm i --save nestjs-openapi-next
|
|
|
44
37
|
|
|
45
38
|
See the official Nest OpenAPI tutorial: `https://docs.nestjs.com/openapi/introduction`
|
|
46
39
|
|
|
47
|
-
Typical setup (minimal skeleton):
|
|
48
|
-
|
|
49
40
|
```ts
|
|
50
41
|
import { NestFactory } from '@nestjs/core';
|
|
51
|
-
import { DocumentBuilder, SwaggerModule } from '
|
|
42
|
+
import { DocumentBuilder, SwaggerModule } from 'nestjs-openapi-next';
|
|
52
43
|
|
|
53
|
-
// ...
|
|
54
44
|
const app = await NestFactory.create(AppModule);
|
|
55
45
|
|
|
56
46
|
const config = new DocumentBuilder()
|
|
57
47
|
.setTitle('Example')
|
|
58
48
|
.setDescription('API description')
|
|
59
49
|
.setVersion('1.0')
|
|
60
|
-
// If you want to declare OAS 3.2
|
|
50
|
+
// If you want the document to declare OAS 3.2, set it explicitly:
|
|
61
51
|
.setOpenAPIVersion('3.2.0')
|
|
62
52
|
.build();
|
|
63
53
|
|
|
64
54
|
const document = SwaggerModule.createDocument(app, config);
|
|
65
55
|
SwaggerModule.setup('api', app, document);
|
|
66
|
-
|
|
67
|
-
await app.listen(3000);
|
|
68
56
|
```
|
|
69
57
|
|
|
70
|
-
##
|
|
58
|
+
## Usage
|
|
71
59
|
|
|
72
|
-
### 1)
|
|
60
|
+
### 1) `@ApiTag(options)` (recommended) and deprecation of `@ApiTagGroup()`
|
|
73
61
|
|
|
74
|
-
|
|
62
|
+
`@ApiTag(options)` is the primary decorator for defining tag metadata at the controller level.
|
|
63
|
+
|
|
64
|
+
`@ApiTagGroup(options)` is kept as a backward-compatible alias, but is **deprecated** and may be removed in a future major version.
|
|
75
65
|
|
|
76
66
|
```ts
|
|
77
|
-
import { Controller,
|
|
78
|
-
import {
|
|
67
|
+
import { Controller, Get } from '@nestjs/common';
|
|
68
|
+
import { ApiTag } from 'nestjs-openapi-next';
|
|
79
69
|
|
|
80
|
-
@
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
70
|
+
@ApiTag({
|
|
71
|
+
name: 'Customers',
|
|
72
|
+
summary: 'Customers'
|
|
73
|
+
// you may also set: 'x-displayName': 'Customers'
|
|
74
|
+
})
|
|
75
|
+
@Controller('customers')
|
|
76
|
+
export class CustomersController {
|
|
77
|
+
@Get()
|
|
78
|
+
list() {
|
|
79
|
+
return [];
|
|
86
80
|
}
|
|
87
81
|
}
|
|
88
82
|
```
|
|
89
83
|
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
### 2) Tag `x-displayName` (mirrored with `summary`)
|
|
85
|
+
|
|
86
|
+
This fork treats tag `summary` and `x-displayName` as equivalent display fields:
|
|
92
87
|
|
|
93
|
-
|
|
88
|
+
- set either one;
|
|
89
|
+
- the generated `document.tags` will contain **both** `summary` and `x-displayName` with the same value.
|
|
94
90
|
|
|
95
|
-
|
|
91
|
+
### 3) Root-level `x-tagGroups` (tag grouping)
|
|
92
|
+
|
|
93
|
+
#### Auto-derived (recommended)
|
|
94
|
+
|
|
95
|
+
If you use tag `parent` relationships (via `@ApiTag()`), the root-level `x-tagGroups` will be derived automatically:
|
|
96
96
|
|
|
97
97
|
```ts
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
98
|
+
@ApiTag({ name: 'Customers' })
|
|
99
|
+
@Controller('customers')
|
|
100
|
+
export class CustomersController {}
|
|
101
|
+
|
|
102
|
+
@ApiTag({ name: 'Customer Authentication', parent: 'Customers' })
|
|
103
|
+
@Controller('auth')
|
|
104
|
+
export class AuthController {}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Illustrative output:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
tags:
|
|
111
|
+
- name: Customers
|
|
112
|
+
- name: Customer Authentication
|
|
113
|
+
x-tagGroups:
|
|
114
|
+
- name: Customers
|
|
115
|
+
tags:
|
|
116
|
+
- Customers
|
|
117
|
+
- Customer Authentication
|
|
115
118
|
```
|
|
116
119
|
|
|
117
|
-
|
|
118
|
-
- During scanning, tag group metadata is merged into top-level `document.tags` and then merged with tags coming from `DocumentBuilder`.
|
|
120
|
+
#### Manual configuration
|
|
119
121
|
|
|
120
|
-
|
|
122
|
+
You can also set `x-tagGroups` explicitly via `DocumentBuilder.addTagGroup()`:
|
|
121
123
|
|
|
122
124
|
```ts
|
|
123
|
-
new DocumentBuilder()
|
|
124
|
-
.
|
|
125
|
+
const config = new DocumentBuilder()
|
|
126
|
+
.setTitle('t')
|
|
127
|
+
.setVersion('1')
|
|
128
|
+
.addTag('Customers')
|
|
129
|
+
.addTag('Customer Authentication')
|
|
130
|
+
.addTagGroup('Customers', ['Customers', 'Customer Authentication'])
|
|
125
131
|
.build();
|
|
126
132
|
```
|
|
127
133
|
|
|
128
|
-
|
|
134
|
+
### 4) HTTP `QUERY` method: `@ApiQueryMethod()`
|
|
129
135
|
|
|
130
|
-
|
|
136
|
+
```ts
|
|
137
|
+
import { Controller, Post } from '@nestjs/common';
|
|
138
|
+
import { ApiQueryMethod } from 'nestjs-openapi-next';
|
|
131
139
|
|
|
132
|
-
|
|
140
|
+
@Controller()
|
|
141
|
+
export class QueryController {
|
|
142
|
+
@Post('search')
|
|
143
|
+
@ApiQueryMethod()
|
|
144
|
+
search() {
|
|
145
|
+
return { ok: true };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
133
149
|
|
|
134
|
-
|
|
150
|
+
### 5) Streaming responses: `@ApiStreamingResponse()` (`itemSchema`)
|
|
135
151
|
|
|
136
152
|
```ts
|
|
137
153
|
import { Controller, Get } from '@nestjs/common';
|
|
138
|
-
import { ApiProperty, ApiStreamingResponse } from '
|
|
154
|
+
import { ApiProperty, ApiStreamingResponse } from 'nestjs-openapi-next';
|
|
139
155
|
|
|
140
156
|
class SseItemDto {
|
|
141
157
|
@ApiProperty()
|
|
@@ -156,17 +172,11 @@ export class EventsController {
|
|
|
156
172
|
}
|
|
157
173
|
```
|
|
158
174
|
|
|
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.
|
|
175
|
+
### 6) OAuth2 Device Authorization Flow: `flows.deviceAuthorization` + `@ApiSecurityDeviceFlow()`
|
|
166
176
|
|
|
167
177
|
```ts
|
|
168
178
|
import { Controller, Get } from '@nestjs/common';
|
|
169
|
-
import { ApiSecurityDeviceFlow, DocumentBuilder } from '
|
|
179
|
+
import { ApiSecurityDeviceFlow, DocumentBuilder } from 'nestjs-openapi-next';
|
|
170
180
|
|
|
171
181
|
@Controller()
|
|
172
182
|
export class SecuredController {
|
|
@@ -196,15 +206,29 @@ const config = new DocumentBuilder()
|
|
|
196
206
|
.build();
|
|
197
207
|
```
|
|
198
208
|
|
|
199
|
-
|
|
209
|
+
### 7) OpenAPI 3.1 Webhooks: `@ApiWebhook()`
|
|
200
210
|
|
|
201
|
-
|
|
202
|
-
|
|
211
|
+
OpenAPI 3.1 introduces a root-level `webhooks` object for out-of-band callbacks
|
|
212
|
+
initiated by the API provider.
|
|
203
213
|
|
|
204
|
-
|
|
214
|
+
This fork supports emitting webhook operations via a decorator:
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
import { Controller, Post } from '@nestjs/common';
|
|
218
|
+
import { ApiWebhook } from '@nestjs/swagger';
|
|
219
|
+
|
|
220
|
+
@Controller()
|
|
221
|
+
export class StripeWebhooksController {
|
|
222
|
+
@Post('stripe')
|
|
223
|
+
@ApiWebhook('stripeEvent')
|
|
224
|
+
stripe() {
|
|
225
|
+
return { ok: true };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
205
229
|
|
|
206
|
-
|
|
207
|
-
|
|
230
|
+
The generated document will contain `document.webhooks.stripeEvent.post`, and the
|
|
231
|
+
corresponding route will **not** be emitted under `document.paths`.
|
|
208
232
|
|
|
209
233
|
## License
|
|
210
234
|
|
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);
|
|
@@ -12,9 +12,11 @@ export declare class DocumentBuilder {
|
|
|
12
12
|
setLicense(name: string, url: string): this;
|
|
13
13
|
setOpenAPIVersion(version: string): this;
|
|
14
14
|
addServer(url: string, description?: string, variables?: Record<string, ServerVariableObject>): this;
|
|
15
|
+
addServerWithName(name: string, url: string, description?: string, variables?: Record<string, ServerVariableObject>): this;
|
|
15
16
|
setExternalDoc(description: string, url: string): this;
|
|
16
17
|
setBasePath(path: string): this;
|
|
17
18
|
addTag(name: string, description?: string, externalDocs?: ExternalDocumentationObject, summary?: string): this;
|
|
19
|
+
addTagGroup(name: string, tags: string[]): this;
|
|
18
20
|
addExtension(extensionKey: string, extensionProperties: any, location?: ExtensionLocation): this;
|
|
19
21
|
addSecurity(name: string, options: SecuritySchemeObject): this;
|
|
20
22
|
addGlobalResponse(...respones: ApiResponseOptions[]): this;
|
package/dist/document-builder.js
CHANGED
|
@@ -48,6 +48,10 @@ class DocumentBuilder {
|
|
|
48
48
|
this.document.servers.push({ url, description, variables });
|
|
49
49
|
return this;
|
|
50
50
|
}
|
|
51
|
+
addServerWithName(name, url, description, variables) {
|
|
52
|
+
this.document.servers.push({ name, url, description, variables });
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
51
55
|
setExternalDoc(description, url) {
|
|
52
56
|
this.document.externalDocs = { description, url };
|
|
53
57
|
return this;
|
|
@@ -57,14 +61,21 @@ class DocumentBuilder {
|
|
|
57
61
|
return this;
|
|
58
62
|
}
|
|
59
63
|
addTag(name, description = '', externalDocs, summary) {
|
|
64
|
+
const normalizedSummary = summary;
|
|
60
65
|
this.document.tags = this.document.tags.concat((0, lodash_1.pickBy)({
|
|
61
66
|
name,
|
|
62
|
-
summary,
|
|
67
|
+
summary: normalizedSummary,
|
|
68
|
+
'x-displayName': normalizedSummary,
|
|
63
69
|
description,
|
|
64
70
|
externalDocs
|
|
65
71
|
}, (0, lodash_1.negate)(lodash_1.isUndefined)));
|
|
66
72
|
return this;
|
|
67
73
|
}
|
|
74
|
+
addTagGroup(name, tags) {
|
|
75
|
+
const existing = this.document['x-tagGroups'] || [];
|
|
76
|
+
this.document['x-tagGroups'] = existing.concat({ name, tags });
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
68
79
|
addExtension(extensionKey, extensionProperties, location = 'root') {
|
|
69
80
|
if (!extensionKey.startsWith('x-')) {
|
|
70
81
|
throw new Error('Extension key is not prefixed. Please ensure you prefix it with `x-`.');
|
|
@@ -71,9 +71,11 @@ export declare function ApiSchema(): () => void;
|
|
|
71
71
|
export declare function ApiSecurity(): () => void;
|
|
72
72
|
export declare function ApiSecurityDeviceFlow(): () => void;
|
|
73
73
|
export declare function ApiTags(): () => void;
|
|
74
|
+
export declare function ApiTag(): () => void;
|
|
74
75
|
export declare function ApiTagGroup(): () => void;
|
|
75
76
|
export declare function ApiCallbacks(): () => void;
|
|
76
77
|
export declare function ApiQueryMethod(): () => void;
|
|
78
|
+
export declare function ApiWebhook(): () => void;
|
|
77
79
|
export declare function ApiStreamingResponse(): () => void;
|
|
78
80
|
export declare function ApiLink(): () => void;
|
|
79
81
|
export declare function ApiDefaultGetter(): () => void;
|
|
@@ -73,9 +73,11 @@ exports.ApiSchema = ApiSchema;
|
|
|
73
73
|
exports.ApiSecurity = ApiSecurity;
|
|
74
74
|
exports.ApiSecurityDeviceFlow = ApiSecurityDeviceFlow;
|
|
75
75
|
exports.ApiTags = ApiTags;
|
|
76
|
+
exports.ApiTag = ApiTag;
|
|
76
77
|
exports.ApiTagGroup = ApiTagGroup;
|
|
77
78
|
exports.ApiCallbacks = ApiCallbacks;
|
|
78
79
|
exports.ApiQueryMethod = ApiQueryMethod;
|
|
80
|
+
exports.ApiWebhook = ApiWebhook;
|
|
79
81
|
exports.ApiStreamingResponse = ApiStreamingResponse;
|
|
80
82
|
exports.ApiLink = ApiLink;
|
|
81
83
|
exports.ApiDefaultGetter = ApiDefaultGetter;
|
|
@@ -309,6 +311,9 @@ function ApiSecurityDeviceFlow() {
|
|
|
309
311
|
function ApiTags() {
|
|
310
312
|
return () => { };
|
|
311
313
|
}
|
|
314
|
+
function ApiTag() {
|
|
315
|
+
return () => { };
|
|
316
|
+
}
|
|
312
317
|
function ApiTagGroup() {
|
|
313
318
|
return () => { };
|
|
314
319
|
}
|
|
@@ -318,6 +323,9 @@ function ApiCallbacks() {
|
|
|
318
323
|
function ApiQueryMethod() {
|
|
319
324
|
return () => { };
|
|
320
325
|
}
|
|
326
|
+
function ApiWebhook() {
|
|
327
|
+
return () => { };
|
|
328
|
+
}
|
|
321
329
|
function ApiStreamingResponse() {
|
|
322
330
|
return () => { };
|
|
323
331
|
}
|