@rsdk/http.server 6.0.0-next.6 → 6.0.0-next.8

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.
@@ -20,14 +20,14 @@ let HttpConfig = class HttpConfig extends core_1.Config {
20
20
  };
21
21
  exports.HttpConfig = HttpConfig;
22
22
  __decorate([
23
- (0, core_1.Property)('HTTP_HOST', new core_1.StringParser(), {
23
+ (0, core_1.Property)('HTTP_HOST', new common_1.StringParser(), {
24
24
  defaultValue: '0.0.0.0',
25
25
  description: 'HTTP host',
26
26
  }),
27
27
  __metadata("design:type", String)
28
28
  ], HttpConfig.prototype, "host", void 0);
29
29
  __decorate([
30
- (0, core_1.Property)('HTTP_PORT', new core_1.IntParser(), {
30
+ (0, core_1.Property)('HTTP_PORT', new common_1.IntParser(), {
31
31
  // eslint-disable-next-line unicorn/numeric-separators-style
32
32
  defaultValue: 50050,
33
33
  description: 'HTTP port',
@@ -35,16 +35,16 @@ __decorate([
35
35
  __metadata("design:type", Number)
36
36
  ], HttpConfig.prototype, "port", void 0);
37
37
  __decorate([
38
- (0, core_1.Property)('HTTP_BODY_LIMIT', new core_1.SizeParser(), {
38
+ (0, core_1.Property)('HTTP_BODY_LIMIT', new common_1.SizeParser(), {
39
39
  defaultValue: new common_1.Size(100, 'kb'),
40
40
  description: 'Max HTTP body size',
41
41
  }),
42
42
  __metadata("design:type", common_1.Size)
43
43
  ], HttpConfig.prototype, "bodyLimit", void 0);
44
44
  __decorate([
45
- (0, core_1.Property)('HTTP_SWAGGER_UI_ENABLED', new core_1.BoolParser(), {
45
+ (0, core_1.Property)('HTTP_SWAGGER_UI_ENABLED', new common_1.BoolParser(), {
46
46
  defaultValue: true,
47
- description: 'Enable swagger UI on /swagger endpoint',
47
+ description: 'Enable swagger UI on /swagger (can be configured) endpoint',
48
48
  }),
49
49
  __metadata("design:type", Boolean)
50
50
  ], HttpConfig.prototype, "swaggerUI", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"http.config.js","sourceRoot":"","sources":["../src/http.config.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAoC;AACpC,qCASoB;AAKb,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,aAAM;IAK3B,IAAI,CAAU;IAOd,IAAI,CAAU;IAMd,SAAS,CAAQ;IAMjB,SAAS,CAAW;CAC9B,CAAA;AAzBY,gCAAU;AAKZ;IAJR,IAAA,eAAQ,EAAC,WAAW,EAAE,IAAI,mBAAY,EAAE,EAAE;QACzC,YAAY,EAAE,SAAS;QACvB,WAAW,EAAE,WAAW;KACzB,CAAC;;wCACqB;AAOd;IALR,IAAA,eAAQ,EAAC,WAAW,EAAE,IAAI,gBAAS,EAAE,EAAE;QACtC,4DAA4D;QAC5D,YAAY,EAAE,KAAK;QACnB,WAAW,EAAE,WAAW;KACzB,CAAC;;wCACqB;AAMd;IAJR,IAAA,eAAQ,EAAC,iBAAiB,EAAE,IAAI,iBAAU,EAAE,EAAE;QAC7C,YAAY,EAAE,IAAI,aAAI,CAAC,GAAG,EAAE,IAAI,CAAC;QACjC,WAAW,EAAE,oBAAoB;KAClC,CAAC;8BACmB,aAAI;6CAAC;AAMjB;IAJR,IAAA,eAAQ,EAAC,yBAAyB,EAAE,IAAI,iBAAU,EAAE,EAAE;QACrD,YAAY,EAAE,IAAI;QAClB,WAAW,EAAE,wCAAwC;KACtD,CAAC;;6CAC2B;qBAxBlB,UAAU;IAHtB,IAAA,oBAAa,EAAC;QACb,IAAI,EAAE,CAAC,gBAAS,CAAC,cAAc,EAAE,gBAAS,CAAC,SAAS,EAAE,gBAAS,CAAC,IAAI,CAAC;KACtE,CAAC;GACW,UAAU,CAyBtB"}
1
+ {"version":3,"file":"http.config.js","sourceRoot":"","sources":["../src/http.config.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAMsB;AACtB,qCAAwE;AAKjE,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,aAAM;IAK3B,IAAI,CAAU;IAOd,IAAI,CAAU;IAMd,SAAS,CAAQ;IAMjB,SAAS,CAAW;CAC9B,CAAA;AAzBY,gCAAU;AAKZ;IAJR,IAAA,eAAQ,EAAC,WAAW,EAAE,IAAI,qBAAY,EAAE,EAAE;QACzC,YAAY,EAAE,SAAS;QACvB,WAAW,EAAE,WAAW;KACzB,CAAC;;wCACqB;AAOd;IALR,IAAA,eAAQ,EAAC,WAAW,EAAE,IAAI,kBAAS,EAAE,EAAE;QACtC,4DAA4D;QAC5D,YAAY,EAAE,KAAK;QACnB,WAAW,EAAE,WAAW;KACzB,CAAC;;wCACqB;AAMd;IAJR,IAAA,eAAQ,EAAC,iBAAiB,EAAE,IAAI,mBAAU,EAAE,EAAE;QAC7C,YAAY,EAAE,IAAI,aAAI,CAAC,GAAG,EAAE,IAAI,CAAC;QACjC,WAAW,EAAE,oBAAoB;KAClC,CAAC;8BACmB,aAAI;6CAAC;AAMjB;IAJR,IAAA,eAAQ,EAAC,yBAAyB,EAAE,IAAI,mBAAU,EAAE,EAAE;QACrD,YAAY,EAAE,IAAI;QAClB,WAAW,EAAE,4DAA4D;KAC1E,CAAC;;6CAC2B;qBAxBlB,UAAU;IAHtB,IAAA,oBAAa,EAAC;QACb,IAAI,EAAE,CAAC,gBAAS,CAAC,cAAc,EAAE,gBAAS,CAAC,SAAS,EAAE,gBAAS,CAAC,IAAI,CAAC;KACtE,CAAC;GACW,UAAU,CAyBtB"}
@@ -2,9 +2,9 @@ import { type ExecutionContext } from '@nestjs/common';
2
2
  import type { Controller, INestApplication } from '@nestjs/common/interfaces';
3
3
  import type { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
4
4
  import type { AbstractHttpAdapter } from '@nestjs/core';
5
- import { DocumentBuilder as OriginalDocumentBuilder } from '@nestjs/swagger';
6
5
  import type { Constructor, DeepPartial } from '@rsdk/common';
7
- import type { ConfigContext, GenericHeaders, HttpOptions, IErrorsFormatter, IErrorsSender, IErrorsTransformer, IHttpTransport, LogFormatter } from '@rsdk/core';
6
+ import type { ConfigContext, GenericHeaders, HttpOptions, IErrorsFormatter, IErrorsSender, IErrorsTransformer, IHttpTransport, LogFormatter, PlatformContext } from '@rsdk/core';
7
+ import type { OpenApiOptions } from '@rsdk/http.openapi';
8
8
  import { HttpConfig } from './http.config';
9
9
  export interface ParsersConfig {
10
10
  body: {
@@ -13,11 +13,9 @@ export interface ParsersConfig {
13
13
  };
14
14
  cookie: boolean;
15
15
  }
16
- export type DocumentBuilder = Omit<OriginalDocumentBuilder, 'build' | 'setTitle' | 'setDescription' | 'setVersion'>;
17
- export interface SwaggerOptions {
18
- url: string;
19
- file: string;
20
- configure(builder: DocumentBuilder): void;
16
+ export interface SwaggerOptions extends Partial<OpenApiOptions> {
17
+ /** URL path for Swagger UI */
18
+ url?: string;
21
19
  }
22
20
  export interface HttpTransportOptions {
23
21
  /**
@@ -30,7 +28,6 @@ export interface HttpTransportOptions {
30
28
  globalPrefix?: string;
31
29
  /**
32
30
  * Configuration of body and cookie parsers
33
- // NOTE: This fields is actually is handled in transport specific way
34
31
  */
35
32
  parsers?: DeepPartial<ParsersConfig>;
36
33
  /**
@@ -40,11 +37,11 @@ export interface HttpTransportOptions {
40
37
  * NOTE: SwaggerUI is enabled or disabled by HTTP_SWAGGER_UI_ENABLED
41
38
  * (true by default).
42
39
  */
43
- swagger?: DeepPartial<SwaggerOptions>;
40
+ swagger?: SwaggerOptions | SwaggerOptions[];
44
41
  }
45
42
  export declare abstract class AbstractHttpTransport implements IHttpTransport {
46
- protected readonly options?: HttpTransportOptions | undefined;
47
- constructor(options?: HttpTransportOptions | undefined);
43
+ protected readonly options: HttpTransportOptions;
44
+ constructor(options?: HttpTransportOptions);
48
45
  extractHeaders(ctx: ExecutionContext): GenericHeaders;
49
46
  matchByContext(ctx: ExecutionContext): boolean;
50
47
  errorFormatter(): IErrorsFormatter;
@@ -55,7 +52,7 @@ export declare abstract class AbstractHttpTransport implements IHttpTransport {
55
52
  getMetricsController(): Constructor<Controller>;
56
53
  createHttpOptions(configContext: ConfigContext): HttpOptions;
57
54
  createAdapter(configContext: ConfigContext): AbstractHttpAdapter;
58
- configureApp(app: INestApplication, configContext: ConfigContext): Promise<void> | void;
55
+ configureApp(app: INestApplication, context: PlatformContext): Promise<void>;
59
56
  abstract createHttpAdapter(config: HttpConfig): AbstractHttpAdapter;
60
57
  abstract logFormatter(): LogFormatter;
61
58
  }
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AbstractHttpTransport = void 0;
4
4
  const swagger_1 = require("@nestjs/swagger");
5
5
  const core_1 = require("@rsdk/core");
6
- const node_fs_1 = require("node:fs");
6
+ const http_openapi_1 = require("@rsdk/http.openapi");
7
7
  const controllers_1 = require("./controllers");
8
8
  const error_handling_1 = require("./error-handling");
9
9
  const http_config_1 = require("./http.config");
10
10
  const http_headers_1 = require("./http.headers");
11
11
  class AbstractHttpTransport {
12
12
  options;
13
- constructor(options) {
13
+ constructor(options = {}) {
14
14
  this.options = options;
15
15
  }
16
16
  extractHeaders(ctx) {
@@ -39,38 +39,34 @@ class AbstractHttpTransport {
39
39
  }
40
40
  createHttpOptions(configContext) {
41
41
  const { host, port } = configContext.resolve(http_config_1.HttpConfig);
42
- return {
43
- host,
44
- port,
45
- };
42
+ return { host, port };
46
43
  }
47
44
  createAdapter(configContext) {
48
45
  return this.createHttpAdapter(configContext.resolve(http_config_1.HttpConfig));
49
46
  }
50
- configureApp(app, configContext) {
47
+ async configureApp(app, context) {
48
+ const configContext = await context.getConfigContext();
51
49
  const { swaggerUI } = configContext.resolve(http_config_1.HttpConfig);
52
- const { globalPrefix, swagger, cors } = this.options ?? {};
50
+ const { globalPrefix, swagger, cors } = this.options;
53
51
  if (globalPrefix) {
54
52
  app.setGlobalPrefix(globalPrefix);
55
53
  }
56
54
  if (cors) {
57
55
  app.enableCors(cors);
58
56
  }
59
- if (swaggerUI || swagger?.file) {
60
- const builder = new swagger_1.DocumentBuilder()
61
- .setTitle(app.get(core_1.APP_NAME))
62
- .setVersion(app.get(core_1.APP_VERSION))
63
- .setDescription(app.get(core_1.APP_DESCRIPTION));
64
- // Applies additional configuration from user
65
- swagger?.configure?.(builder);
66
- const openApiConfig = builder.build();
67
- const spec = swagger_1.SwaggerModule.createDocument(app, openApiConfig);
68
- if (swagger?.file) {
69
- (0, node_fs_1.writeFileSync)(swagger.file, JSON.stringify(spec));
70
- }
71
- if (swaggerUI) {
72
- swagger_1.SwaggerModule.setup(swagger?.url ?? '/swagger', app, spec);
73
- }
57
+ if (!swaggerUI) {
58
+ return;
59
+ }
60
+ const configs = Array.isArray(swagger) ? swagger : [swagger ?? {}];
61
+ for (const config of configs) {
62
+ const generator = new http_openapi_1.OpenApiGenerator(context, {
63
+ title: app.get(core_1.APP_NAME),
64
+ version: app.get(core_1.APP_VERSION),
65
+ description: app.get(core_1.APP_DESCRIPTION),
66
+ ...config,
67
+ });
68
+ const document = await generator.generate();
69
+ swagger_1.SwaggerModule.setup(config.url ?? '/swagger', app, document);
74
70
  }
75
71
  }
76
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"http.transport.js","sourceRoot":"","sources":["../src/http.transport.ts"],"names":[],"mappings":";;;AAIA,6CAGyB;AAYzB,qCAAoE;AACpE,qCAAwC;AAExC,+CAA4E;AAC5E,qDAI0B;AAC1B,+CAA2C;AAC3C,iDAA6C;AAiD7C,MAAsB,qBAAqB;IACV;IAA/B,YAA+B,OAA8B;QAA9B,YAAO,GAAP,OAAO,CAAuB;IAAG,CAAC;IAEjE,cAAc,CAAC,GAAqB;QAClC,OAAO,IAAI,0BAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,cAAc,CAAC,GAAqB;QAClC,OAAO,GAAG,CAAC,OAAO,EAAE,KAAK,MAAM,CAAC;IAClC,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,oCAAmB,EAAE,CAAC;IACnC,CAAC;IAED,WAAW;QACT,OAAO,IAAI,iCAAgB,EAAE,CAAC;IAChC,CAAC;IAED,iBAAiB;QACf,OAAO,CAAC,IAAI,sCAAqB,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,WAAW;QACT,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,mBAAmB;QACjB,OAAO,kCAAoB,CAAC;IAC9B,CAAC;IAED,oBAAoB;QAClB,OAAO,mCAAqB,CAAC;IAC/B,CAAC;IAED,iBAAiB,CAAC,aAA4B;QAC5C,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,wBAAU,CAAC,CAAC;QAEzD,OAAO;YACL,IAAI;YACJ,IAAI;SACL,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,aAA4B;QACxC,OAAO,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,OAAO,CAAC,wBAAU,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,YAAY,CACV,GAAqB,EACrB,aAA4B;QAE5B,MAAM,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,wBAAU,CAAC,CAAC;QACxD,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QAC3D,IAAI,YAAY,EAAE,CAAC;YACjB,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QAED,IAAI,SAAS,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,IAAI,yBAAuB,EAAE;iBAC1C,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,eAAQ,CAAC,CAAC;iBAC3B,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,kBAAW,CAAC,CAAC;iBAChC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,sBAAe,CAAC,CAAC,CAAC;YAE5C,6CAA6C;YAC7C,OAAO,EAAE,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC;YAE9B,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,uBAAa,CAAC,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;YAE9D,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;gBAClB,IAAA,uBAAa,EAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YACpD,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,uBAAa,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;IACH,CAAC;CAKF;AAtFD,sDAsFC"}
1
+ {"version":3,"file":"http.transport.js","sourceRoot":"","sources":["../src/http.transport.ts"],"names":[],"mappings":";;;AAKA,6CAAgD;AAahD,qCAAoE;AAEpE,qDAAsD;AAGtD,+CAA4E;AAC5E,qDAI0B;AAC1B,+CAA2C;AAC3C,iDAA6C;AAyC7C,MAAsB,qBAAqB;IACV;IAA/B,YAA+B,UAAgC,EAAE;QAAlC,YAAO,GAAP,OAAO,CAA2B;IAAG,CAAC;IAErE,cAAc,CAAC,GAAqB;QAClC,OAAO,IAAI,0BAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,cAAc,CAAC,GAAqB;QAClC,OAAO,GAAG,CAAC,OAAO,EAAE,KAAK,MAAM,CAAC;IAClC,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,oCAAmB,EAAE,CAAC;IACnC,CAAC;IAED,WAAW;QACT,OAAO,IAAI,iCAAgB,EAAE,CAAC;IAChC,CAAC;IAED,iBAAiB;QACf,OAAO,CAAC,IAAI,sCAAqB,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,WAAW;QACT,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,mBAAmB;QACjB,OAAO,kCAAoB,CAAC;IAC9B,CAAC;IAED,oBAAoB;QAClB,OAAO,mCAAqB,CAAC;IAC/B,CAAC;IAED,iBAAiB,CAAC,aAA4B;QAC5C,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,wBAAU,CAAC,CAAC;QAEzD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IAED,aAAa,CAAC,aAA4B;QACxC,OAAO,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,OAAO,CAAC,wBAAU,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,GAAqB,EACrB,OAAwB;QAExB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC;QACvD,MAAM,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,wBAAU,CAAC,CAAC;QACxD,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAErD,IAAI,YAAY,EAAE,CAAC;YACjB,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,IAAI,EAAE,CAAC;YACT,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAEnE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,IAAI,+BAAgB,CAAC,OAAO,EAAE;gBAC9C,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,eAAQ,CAAC;gBACxB,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,kBAAW,CAAC;gBAC7B,WAAW,EAAE,GAAG,CAAC,GAAG,CAAC,sBAAe,CAAC;gBACrC,GAAG,MAAM;aACV,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;YAE5C,uBAAa,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;CAKF;AApFD,sDAoFC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsdk/http.server",
3
- "version": "6.0.0-next.6",
3
+ "version": "6.0.0-next.8",
4
4
  "description": "HTTP transport for rsdk apps (needs some of HTTP adapters)",
5
5
  "license": "Apache License 2.0",
6
6
  "publishConfig": {
@@ -16,12 +16,14 @@
16
16
  "@nestjs/swagger": "^7.0.0 || ^8.0.0",
17
17
  "@rsdk/common": "*",
18
18
  "@rsdk/core": "*",
19
+ "@rsdk/http.openapi": "*",
19
20
  "@rsdk/logging": "*",
20
21
  "@rsdk/zones": "*",
21
22
  "body-parser": "^1.20.1",
22
23
  "cookie-parser": "^1.4.6",
24
+ "lodash": "^4.17.21",
23
25
  "reflect-metadata": "^0.1.12 || ^0.2.0",
24
26
  "rxjs": "^7.8.1"
25
27
  },
26
- "gitHead": "e322e01c1824cc5a0d5ce4cdd7272a484fcb099f"
28
+ "gitHead": "320e0f477ca338642e2237fdbed869c01615855b"
27
29
  }
@@ -1,14 +1,11 @@
1
- import { Size } from '@rsdk/common';
2
1
  import {
3
2
  BoolParser,
4
- Config,
5
- ConfigSection,
6
- ConfigTag,
7
3
  IntParser,
8
- Property,
4
+ Size,
9
5
  SizeParser,
10
6
  StringParser,
11
- } from '@rsdk/core';
7
+ } from '@rsdk/common';
8
+ import { Config, ConfigSection, ConfigTag, Property } from '@rsdk/core';
12
9
 
13
10
  @ConfigSection({
14
11
  tags: [ConfigTag.infrastructure, ConfigTag.transport, ConfigTag.http],
@@ -35,7 +32,7 @@ export class HttpConfig extends Config {
35
32
 
36
33
  @Property('HTTP_SWAGGER_UI_ENABLED', new BoolParser(), {
37
34
  defaultValue: true,
38
- description: 'Enable swagger UI on /swagger endpoint',
35
+ description: 'Enable swagger UI on /swagger (can be configured) endpoint',
39
36
  })
40
37
  readonly swaggerUI!: boolean;
41
38
  }
@@ -1,11 +1,9 @@
1
+ /* eslint-disable unicorn/no-nested-ternary */
1
2
  import { type ExecutionContext } from '@nestjs/common';
2
3
  import type { Controller, INestApplication } from '@nestjs/common/interfaces';
3
4
  import type { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
4
5
  import type { AbstractHttpAdapter } from '@nestjs/core';
5
- import {
6
- DocumentBuilder as OriginalDocumentBuilder,
7
- SwaggerModule,
8
- } from '@nestjs/swagger';
6
+ import { SwaggerModule } from '@nestjs/swagger';
9
7
  import type { Constructor, DeepPartial } from '@rsdk/common';
10
8
  import type {
11
9
  ConfigContext,
@@ -16,9 +14,12 @@ import type {
16
14
  IErrorsTransformer,
17
15
  IHttpTransport,
18
16
  LogFormatter,
17
+ PlatformContext,
19
18
  } from '@rsdk/core';
20
19
  import { APP_DESCRIPTION, APP_NAME, APP_VERSION } from '@rsdk/core';
21
- import { writeFileSync } from 'node:fs';
20
+ import type { OpenApiOptions } from '@rsdk/http.openapi';
21
+ import { OpenApiGenerator } from '@rsdk/http.openapi';
22
+ import _ from 'lodash';
22
23
 
23
24
  import { HealthHttpController, MetricsHttpController } from './controllers';
24
25
  import {
@@ -37,16 +38,9 @@ export interface ParsersConfig {
37
38
  cookie: boolean;
38
39
  }
39
40
 
40
- export type DocumentBuilder = Omit<
41
- OriginalDocumentBuilder,
42
- 'build' | 'setTitle' | 'setDescription' | 'setVersion'
43
- >;
44
-
45
- export interface SwaggerOptions {
46
- url: string;
47
- file: string;
48
-
49
- configure(builder: DocumentBuilder): void;
41
+ export interface SwaggerOptions extends Partial<OpenApiOptions> {
42
+ /** URL path for Swagger UI */
43
+ url?: string;
50
44
  }
51
45
 
52
46
  export interface HttpTransportOptions {
@@ -62,7 +56,6 @@ export interface HttpTransportOptions {
62
56
 
63
57
  /**
64
58
  * Configuration of body and cookie parsers
65
- // NOTE: This fields is actually is handled in transport specific way
66
59
  */
67
60
  parsers?: DeepPartial<ParsersConfig>;
68
61
 
@@ -73,11 +66,11 @@ export interface HttpTransportOptions {
73
66
  * NOTE: SwaggerUI is enabled or disabled by HTTP_SWAGGER_UI_ENABLED
74
67
  * (true by default).
75
68
  */
76
- swagger?: DeepPartial<SwaggerOptions>;
69
+ swagger?: SwaggerOptions | SwaggerOptions[];
77
70
  }
78
71
 
79
72
  export abstract class AbstractHttpTransport implements IHttpTransport {
80
- constructor(protected readonly options?: HttpTransportOptions) {}
73
+ constructor(protected readonly options: HttpTransportOptions = {}) {}
81
74
 
82
75
  extractHeaders(ctx: ExecutionContext): GenericHeaders {
83
76
  return new HttpHeaders(ctx);
@@ -114,48 +107,46 @@ export abstract class AbstractHttpTransport implements IHttpTransport {
114
107
  createHttpOptions(configContext: ConfigContext): HttpOptions {
115
108
  const { host, port } = configContext.resolve(HttpConfig);
116
109
 
117
- return {
118
- host,
119
- port,
120
- };
110
+ return { host, port };
121
111
  }
122
112
 
123
113
  createAdapter(configContext: ConfigContext): AbstractHttpAdapter {
124
114
  return this.createHttpAdapter(configContext.resolve(HttpConfig));
125
115
  }
126
116
 
127
- configureApp(
117
+ async configureApp(
128
118
  app: INestApplication,
129
- configContext: ConfigContext,
130
- ): Promise<void> | void {
119
+ context: PlatformContext,
120
+ ): Promise<void> {
121
+ const configContext = await context.getConfigContext();
131
122
  const { swaggerUI } = configContext.resolve(HttpConfig);
132
- const { globalPrefix, swagger, cors } = this.options ?? {};
123
+ const { globalPrefix, swagger, cors } = this.options;
124
+
133
125
  if (globalPrefix) {
134
126
  app.setGlobalPrefix(globalPrefix);
135
127
  }
128
+
136
129
  if (cors) {
137
130
  app.enableCors(cors);
138
131
  }
139
132
 
140
- if (swaggerUI || swagger?.file) {
141
- const builder = new OriginalDocumentBuilder()
142
- .setTitle(app.get(APP_NAME))
143
- .setVersion(app.get(APP_VERSION))
144
- .setDescription(app.get(APP_DESCRIPTION));
133
+ if (!swaggerUI) {
134
+ return;
135
+ }
145
136
 
146
- // Applies additional configuration from user
147
- swagger?.configure?.(builder);
137
+ const configs = Array.isArray(swagger) ? swagger : [swagger ?? {}];
148
138
 
149
- const openApiConfig = builder.build();
150
- const spec = SwaggerModule.createDocument(app, openApiConfig);
139
+ for (const config of configs) {
140
+ const generator = new OpenApiGenerator(context, {
141
+ title: app.get(APP_NAME),
142
+ version: app.get(APP_VERSION),
143
+ description: app.get(APP_DESCRIPTION),
144
+ ...config,
145
+ });
151
146
 
152
- if (swagger?.file) {
153
- writeFileSync(swagger.file, JSON.stringify(spec));
154
- }
147
+ const document = await generator.generate();
155
148
 
156
- if (swaggerUI) {
157
- SwaggerModule.setup(swagger?.url ?? '/swagger', app, spec);
158
- }
149
+ SwaggerModule.setup(config.url ?? '/swagger', app, document);
159
150
  }
160
151
  }
161
152