@ethalium/nestjs-openapi 0.0.1 → 0.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/README.md
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
<p align="center" style="font-size: 40px;">NestJS Swagger/OpenAPI - Extended Decorators</p>
|
|
2
|
+
|
|
3
|
+
<p align="center">Extended functionalities/decorators for the official <a href="https://github.com/nestjs/swagger">@nestjs/swagger</a> package</p>
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="https://www.npmjs.com/package/@ethalium/nestjs-openapi" target="_blank"><img src="https://img.shields.io/npm/v/@ethalium/nestjs-openapi.svg" alt="NPM Version" /></a>
|
|
6
|
+
<a href="https://www.npmjs.com/package/@ethalium/nestjs-openapi" target="_blank"><img src="https://img.shields.io/npm/l/@ethalium/nestjs-openapi.svg" alt="Package License" /></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/@ethalium/nestjs-openapi" target="_blank"><img src="https://img.shields.io/npm/dm/@ethalium/nestjs-openapi.svg" alt="NPM Downloads" /></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/@ethalium/nestjs-openapi" target="_blank"><img src="https://img.shields.io/bundlephobia/min/@ethalium/nestjs-openapi?label=size" alt="Package Size" /></a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
To begin using it, we first install the required dependencies:
|
|
13
|
+
```
|
|
14
|
+
npm install --save @ethalium/nestjs-openapi @nestjs/swagger
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Bootstrap
|
|
18
|
+
Once the installation is done, we need to initialize the OpenAPI wrapper using the `OpenApiModule`:
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { NestFactory } from '@nestjs/core';
|
|
22
|
+
import { SwaggerModule } from "@nestjs/swagger";
|
|
23
|
+
import { OpenApiModule } from '@ethalium/nestjs-openapi';
|
|
24
|
+
import { AppModule } from './app.module';
|
|
25
|
+
|
|
26
|
+
async function bootstrap() {
|
|
27
|
+
|
|
28
|
+
// create application
|
|
29
|
+
const app = await NestFactory.create(AppModule);
|
|
30
|
+
|
|
31
|
+
// create document builder
|
|
32
|
+
const config = OpenApiModule.createDocumentBuilder({
|
|
33
|
+
title: 'Cats example',
|
|
34
|
+
description: 'The cats API description',
|
|
35
|
+
version: '1.0',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// create document from builder
|
|
39
|
+
const document = OpenApiModule.createDocument(app, config.build(), {
|
|
40
|
+
...
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// setup swagger
|
|
44
|
+
SwaggerModule.setup('api', app, document);
|
|
45
|
+
|
|
46
|
+
// start server
|
|
47
|
+
await app.listen(process.env.PORT ?? 3000);
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
bootstrap();
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Function: `OpenApi.createDocumentBuilder`
|
|
56
|
+
The DocumentBuilder class is used to configure the OpenAPI document. It extends the `DocumentBuilder` class from `@nestjs/swagger` package and gives you the ability to define the properties while constructing the class.
|
|
57
|
+
|
|
58
|
+
## Function: `OpenApi.createDocument`
|
|
59
|
+
The `createDocument` method is used to create the OpenAPI document. It runs the custom OpenAPI builder to build additional schema's like `TagGroups`, `TagNames`, `ResponseOverrides`, ect.
|
|
60
|
+
|
|
61
|
+
### Options
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
#### `uniqueTagGroupTags`: boolean
|
|
65
|
+
Indicates if the tags in a tagGroup should be unique for this group.
|
|
66
|
+
* If set to `true`, all tags in a specific tagGroup will have the group name as a prefix and the original name will be set as 'x-displayName' to avoid duplicate tags in the generated OpenAPI document.
|
|
67
|
+
* If set to `false` or undefined, the tags will be added to the groups without transforming the name.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
#### `uniqueTagGroupTagNameFactory`: (groupName: string, tagName: string) => string
|
|
71
|
+
A factory function that generates a custom model name for a tag in a tag group. It allows customization of naming conventions for tags programmatically. By default, the groupName and tagName will be joined together and put
|
|
72
|
+
through a `pascalCase` function.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
#### `tagGroupUngrouped`: boolean|string|Omit<IOpenApiTagGroupMetadata, 'tags'>
|
|
76
|
+
Represents either a string or an object containing tag group metadata. If set to string or object, it will be used to define the default tag group for all endpoints that have no explicit tag group assigned. If true, it will add all ungrouped tags to the group "Ungrouped". If false or empty, endpoints that have no tag group will not be grouped.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
#### `responseOverrides`: IOpenApiDocumentOverrideResponses
|
|
80
|
+
Represents optional response overrides that can be applied to refine or replace the OpenAPI response behavior for specific API request status codes.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
{
|
|
84
|
+
responseOverrides: {
|
|
85
|
+
|
|
86
|
+
// wrapps a response in the success response model. The original response will be stored under the 'data' key.
|
|
87
|
+
'2XX': {
|
|
88
|
+
type: HttpSuccessResponse,
|
|
89
|
+
subKey: 'data'
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
// overrides the default error response model (4XX and 5XX).
|
|
93
|
+
'error': HttpErrorResponse,
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
#### `responseOverrideModelNameFactory`: (overrideName: string, responseType: string) => string
|
|
101
|
+
A factory function that generates a custom model name for a response override. It allows customization of naming conventions for response overrides programmatically. Only applicable when using the `responseOverrides` option, for overrides that have a `subKey` defined, and if the `responseType` does either have a type or schema with `type` defined.
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
## Decorators
|
|
105
|
+
Decorators are used to add additional metadata to the controllers and endpoints. Some decorators are not documented here, because they're mainly used internally.
|
|
106
|
+
|
|
107
|
+
### `@OAController()` *Controller*
|
|
108
|
+
Invokes the `@Controller` decorator and adds the possibility to define OpenAPI metadata for the controller like `tags`, `tagGroups`, `headers`, `query parameters`, ect.
|
|
109
|
+
|
|
110
|
+
#### Schemas
|
|
111
|
+
* `@OAController(options?: OAControllerOptions)`
|
|
112
|
+
* `@OAController(path: string, options?: OAControllerOptions)`
|
|
113
|
+
* `@OAController(path: string, exclude?: false)`
|
|
114
|
+
|
|
115
|
+
#### Example
|
|
116
|
+
```typescript
|
|
117
|
+
@OAController('/', {...})
|
|
118
|
+
export class CatsController {
|
|
119
|
+
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
### `@OARoute` `@OAGet` `@OAPost` `@OAPut` `@OAPatch` `@OADelete` *Method*
|
|
125
|
+
Invokes the corresponding `@Get`, `@Post`, `@Put`, `@Patch`, `@Delete` decorators and adds the possibility to define OpenAPI metadata for the endpoint like `summary`, `description`, `parameters`, `responses`, ect.`
|
|
126
|
+
|
|
127
|
+
#### Schemas
|
|
128
|
+
* `@OAGet(options?: OARouteOptions)`
|
|
129
|
+
* `@OAGet(path: string, options?: OARouteOptions)`
|
|
130
|
+
* `@OAGet(path: string, exclude?: false)`
|
|
131
|
+
* ...
|
|
132
|
+
|
|
133
|
+
#### Example
|
|
134
|
+
```typescript
|
|
135
|
+
@OAController('/')
|
|
136
|
+
export class CatsController {
|
|
137
|
+
|
|
138
|
+
@OAGet('/', {
|
|
139
|
+
summary: 'Find all cats',
|
|
140
|
+
description: 'Returns all cats from the database',
|
|
141
|
+
response: [Cats]
|
|
142
|
+
})
|
|
143
|
+
findAll(): Cats[] {
|
|
144
|
+
return this.catsService.findAll();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
### `@OAError` *Controller, Method*
|
|
152
|
+
Adds the `responses` metadata to the endpoint to define the OpenAPI response model for the specified error status code.
|
|
153
|
+
|
|
154
|
+
#### Schemas
|
|
155
|
+
* `@OABadRequest(options?: IOpenApiErrorOptions)`
|
|
156
|
+
* `@OABadRequest(description?: string, options?: IOpenApiErrorOptions)`
|
|
157
|
+
* `@OABadRequest(type: IOpenApiErrorType, description?: string, options?: IOpenApiErrorOptions)`
|
|
158
|
+
|
|
159
|
+
#### Example
|
|
160
|
+
```typescript
|
|
161
|
+
@OAController('/')
|
|
162
|
+
export class CatsController {
|
|
163
|
+
|
|
164
|
+
@OAGet('/', {
|
|
165
|
+
summary: 'Find all cats',
|
|
166
|
+
description: 'Returns all cats from the database',
|
|
167
|
+
response: [Cats]
|
|
168
|
+
})
|
|
169
|
+
@OAUnauthorized(HttpErrorResponse, "You're not authorized to access this resource.")
|
|
170
|
+
findAll(): Cats[] {
|
|
171
|
+
throw new BadRequestException('Invalid request');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
### `@OAProperty` *Property*
|
|
179
|
+
Adds properties to the OpenAPI schema for the specified class property. Invokes the `@ApiProperty` decorator from `@nestjs/swagger` package.
|
|
180
|
+
The library provides various decorators to add additional metadata to the OpenAPI schema. Every decorator looks like `@OA*Property` and `@OA*PropertyOptionsl`.
|
|
181
|
+
|
|
182
|
+
* `@OAStringProperty`, `@OAStringPropertyOptional`: Adds a string property to the OpenAPI schema.
|
|
183
|
+
* `@OANumberProperty`, `@OANumberPropertyOptional`: Adds a number property to the OpenAPI schema.
|
|
184
|
+
* `@OABooleanProperty`, `@OABooleanPropertyOptional`: Adds a boolean property to the OpenAPI schema.
|
|
185
|
+
* `@OATypeProperty`, `@OATypePropertyOptional`: Adds a nested classRef property to the OpenAPI schema.
|
|
186
|
+
* `@OAObjectProperty`, `@OAObjectPropertyOptional`: Adds an object property to the OpenAPI schema.
|
|
187
|
+
* `@OAEnumProperty`, `@OAEnumPropertyOptional`: Adds an enum property to the OpenAPI schema.
|
|
188
|
+
* `@OAAnyOfProperty`, `@OAAnyOfPropertyOptional`: Adds an anyOf property to the OpenAPI schema.`
|
|
189
|
+
* `@OAAllOfProperty`, `@OAAllOfPropertyOptional`: Adds an oneOf property to the OpenAPI schema.`
|
|
190
|
+
* `@OAOneOfProperty`, `@OAOneOfPropertyOptional`: Adds an oneOf property to the OpenAPI schema.`
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
### `@OATag`, `@OATags` *Controller*, *Method*
|
|
194
|
+
Adds the `tags` metadata to the endpoint to define the OpenAPI tag for the specified controller or method. Additional options like displayName and trait are available to set.
|
|
195
|
+
|
|
196
|
+
#### Example
|
|
197
|
+
```typescript
|
|
198
|
+
@OATag('Cats')
|
|
199
|
+
@OAController('/')
|
|
200
|
+
export class CatsController {
|
|
201
|
+
|
|
202
|
+
@OATag('Find all cats')
|
|
203
|
+
@OAGet('/', {
|
|
204
|
+
summary: 'Find all cats',
|
|
205
|
+
description: 'Returns all cats from the database',
|
|
206
|
+
response: [Cats]
|
|
207
|
+
})
|
|
208
|
+
@OAUnauthorized(HttpErrorResponse, "You're not authorized to access this resource.")
|
|
209
|
+
findAll(): Cats[] {
|
|
210
|
+
throw new BadRequestException('Invalid request');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### `@OATagGroup` *Module*, *Controller*, *Method*
|
|
217
|
+
Adds the `tagGroups` metadata to the controller or method to define the OpenAPI tag group for the specified controller or method.
|
|
218
|
+
* *Module*: Adds the tag group to the entire controllers in the module.
|
|
219
|
+
* *Controller*: Adds the tag group to the controller.
|
|
220
|
+
* *Method*: Adds the tag group to the method.
|
|
221
|
+
|
|
222
|
+
#### Example:
|
|
223
|
+
```typescript
|
|
224
|
+
@OATagGroup('Cats API')
|
|
225
|
+
@Module({...})
|
|
226
|
+
export class CatsModule {}
|
|
227
|
+
```
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OAProperty = OAProperty;
|
|
3
4
|
exports.OACreateProperty = OACreateProperty;
|
|
4
5
|
const decorator_utils_1 = require("../utils/decorator.utils");
|
|
5
6
|
const type_utils_1 = require("../utils/type.utils");
|
|
6
7
|
const swagger_1 = require("@nestjs/swagger");
|
|
8
|
+
function OAProperty(options) {
|
|
9
|
+
return OACreateProperty({
|
|
10
|
+
args: [options]
|
|
11
|
+
});
|
|
12
|
+
}
|
|
7
13
|
function OACreateProperty(data) {
|
|
8
14
|
return (0, decorator_utils_1.createPropertyDecorator)({
|
|
9
15
|
transform: (ctx) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"property.decorator.js","sourceRoot":"","sources":["../../../lib/decorators/property.decorator.ts"],"names":[],"mappings":";;AAKA,4CAgBC;
|
|
1
|
+
{"version":3,"file":"property.decorator.js","sourceRoot":"","sources":["../../../lib/decorators/property.decorator.ts"],"names":[],"mappings":";;AAKA,gCAIC;AAGD,4CAgBC;AA5BD,8DAAiE;AAEjE,oDAAiE;AACjE,6CAA4C;AAE5C,SAAgB,UAAU,CAAC,OAAgC;IACzD,OAAO,gBAAgB,CAAC;QACtB,IAAI,EAAE,CAAC,OAAO,CAAC;KAChB,CAAC,CAAC;AACL,CAAC;AAGD,SAAgB,gBAAgB,CAAC,IAIhC;IACC,OAAO,IAAA,yCAAuB,EAAiC;QAC7D,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;YACjB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAA,0BAAa,EAA0B,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YAC1G,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAA,0BAAa,EAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;YAClF,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,UAAU,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACzB,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,KAAc,CAAC,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,IAAA,qBAAW,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,CAAC;KACF,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|