Skip to content

Commit 2a4de7a

Browse files
Merge pull request #3424 from daniseijo/extensions-info-section
feat(document-builder): add support for setting extensions inside the info object
2 parents 5943508 + 9a0745e commit 2a4de7a

File tree

4 files changed

+48
-6
lines changed

4 files changed

+48
-6
lines changed

e2e/api-spec.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,7 +1684,10 @@
16841684
"title": "Cats example",
16851685
"description": "The cats API description",
16861686
"version": "1.0",
1687-
"contact": {}
1687+
"contact": {},
1688+
"x-logo": {
1689+
"url": "https://example.com/logo.png"
1690+
}
16881691
},
16891692
"tags": [
16901693
{
@@ -2114,5 +2117,8 @@
21142117
"basic": [],
21152118
"cookie": []
21162119
}
2117-
]
2120+
],
2121+
"x-test": {
2122+
"test": "test"
2123+
}
21182124
}

e2e/validate-schema.e2e-spec.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ describe('Validate OpenAPI schema', () => {
6464
in: 'header',
6565
schema: { type: 'string' }
6666
})
67+
.addExtension('x-test', { test: 'test' })
68+
.addExtension('x-logo', { url: 'https://example.com/logo.png' }, 'info')
6769
.build();
6870
});
6971

@@ -219,7 +221,7 @@ describe('Validate OpenAPI schema', () => {
219221
expect(api.components.schemas).toHaveProperty('Cat');
220222
});
221223

222-
it('should consider explicit config over auto-detected schema', async () => {
224+
it('should consider explicit config over auto-detected schema', () => {
223225
const document = SwaggerModule.createDocument(app, options);
224226
expect(document.paths['/api/cats/download'].get.responses).toEqual({
225227
'200': {
@@ -234,10 +236,30 @@ describe('Validate OpenAPI schema', () => {
234236
});
235237
});
236238

237-
it('should not add optional properties to required list', async () => {
239+
it('should not add optional properties to required list', () => {
238240
const document = SwaggerModule.createDocument(app, options);
239241
const required = (document.components?.schemas?.Cat as SchemaObject)
240242
?.required;
241243
expect(required).not.toContain('optionalRawDefinition');
242244
});
245+
246+
it('should fail if extension is not prefixed with x-', () => {
247+
expect(() =>
248+
new DocumentBuilder().addExtension('test', { test: 'test' }).build()
249+
).toThrow(
250+
'Extension key is not prefixed. Please ensure you prefix it with `x-`.'
251+
);
252+
});
253+
254+
it('should add extension to root', () => {
255+
const document = SwaggerModule.createDocument(app, options);
256+
expect(document['x-test']).toEqual({ test: 'test' });
257+
});
258+
259+
it('should add extension to info', () => {
260+
const document = SwaggerModule.createDocument(app, options);
261+
expect(document.info['x-logo']).toEqual({
262+
url: 'https://example.com/logo.png'
263+
});
264+
});
243265
});

lib/document-builder.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ApiResponseOptions } from './decorators/api-response.decorator';
44
import { buildDocumentBase } from './fixtures/document.base';
55
import { OpenAPIObject } from './interfaces';
66
import {
7+
ExtensionLocation,
78
ExternalDocumentationObject,
89
ParameterObject,
910
SecurityRequirementObject,
@@ -76,6 +77,9 @@ export class DocumentBuilder {
7677
return this;
7778
}
7879

80+
/**
81+
* @deprecated Use `addServer` method to set up multiple different paths. The `setBasePath` method has been deprecated. Now, a global prefix is populated automatically. If you want to ignore it, take a look here: https://docs.nestjs.com/recipes/swagger#global-prefix.
82+
*/
7983
public setBasePath(path: string) {
8084
this.logger.warn(
8185
'The "setBasePath" method has been deprecated. Now, a global prefix is populated automatically. If you want to ignore it, take a look here: https://docs.nestjs.com/recipes/swagger#global-prefix. Alternatively, you can use "addServer" method to set up multiple different paths.'
@@ -101,14 +105,22 @@ export class DocumentBuilder {
101105
return this;
102106
}
103107

104-
public addExtension(extensionKey: string, extensionProperties: any): this {
108+
public addExtension(
109+
extensionKey: string,
110+
extensionProperties: any,
111+
location: ExtensionLocation = 'root'
112+
): this {
105113
if (!extensionKey.startsWith('x-')) {
106114
throw new Error(
107115
'Extension key is not prefixed. Please ensure you prefix it with `x-`.'
108116
);
109117
}
110118

111-
this.document[extensionKey] = clone(extensionProperties);
119+
if (location === 'root') {
120+
this.document[extensionKey] = clone(extensionProperties);
121+
} else {
122+
this.document[location][extensionKey] = clone(extensionProperties);
123+
}
112124

113125
return this;
114126
}

lib/interfaces/open-api-spec.interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,5 @@ export interface OAuthFlowObject {
287287

288288
export type ScopesObject = Record<string, any>;
289289
export type SecurityRequirementObject = Record<string, string[]>;
290+
291+
export type ExtensionLocation = 'root' | 'info';

0 commit comments

Comments
 (0)