@achinet/nestjs-async 0.0.1 → 0.1.0

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.
Files changed (246) hide show
  1. package/.eslintrc.js +31 -0
  2. package/CHANGELOG.md +6 -0
  3. package/dist/decorators/asyncapi-operation-for-meta-key.decorator.js +1 -2
  4. package/dist/decorators/asyncapi-operation-for-meta-key.decorator.js.map +1 -1
  5. package/dist/decorators/asyncapi-operation.decorator.js +1 -2
  6. package/dist/decorators/asyncapi-operation.decorator.js.map +1 -1
  7. package/dist/decorators/asyncapi-pub.decorator.js +1 -2
  8. package/dist/decorators/asyncapi-pub.decorator.js.map +1 -1
  9. package/dist/decorators/asyncapi-service.decorator.js +1 -2
  10. package/dist/decorators/asyncapi-service.decorator.js.map +1 -1
  11. package/dist/decorators/asyncapi-sub.decorator.js +1 -2
  12. package/dist/decorators/asyncapi-sub.decorator.js.map +1 -1
  13. package/dist/explorers/asyncapi-operation.explorer.d.ts +8 -8
  14. package/dist/sample/app.module.d.ts +2 -0
  15. package/dist/sample/app.module.js +20 -0
  16. package/dist/sample/app.module.js.map +1 -0
  17. package/dist/sample/common.d.ts +3 -0
  18. package/dist/sample/common.js +40 -0
  19. package/dist/sample/common.js.map +1 -0
  20. package/dist/sample/constants.d.ts +12 -0
  21. package/dist/sample/constants.js +16 -0
  22. package/dist/sample/constants.js.map +1 -0
  23. package/dist/sample/felines/class/cat.class.d.ts +4 -0
  24. package/dist/sample/felines/class/cat.class.js +24 -0
  25. package/dist/sample/felines/class/cat.class.js.map +1 -0
  26. package/dist/sample/felines/class/feline.class.d.ts +19 -0
  27. package/dist/sample/felines/class/feline.class.js +20 -0
  28. package/dist/sample/felines/class/feline.class.js.map +1 -0
  29. package/dist/sample/felines/class/index.d.ts +5 -0
  30. package/dist/sample/felines/class/index.js +22 -0
  31. package/dist/sample/felines/class/index.js.map +1 -0
  32. package/dist/sample/felines/class/lion.class.d.ts +4 -0
  33. package/dist/sample/felines/class/lion.class.js +8 -0
  34. package/dist/sample/felines/class/lion.class.js.map +1 -0
  35. package/dist/sample/felines/class/message.class.d.ts +7 -0
  36. package/dist/sample/felines/class/message.class.js +28 -0
  37. package/dist/sample/felines/class/message.class.js.map +1 -0
  38. package/dist/sample/felines/class/tiger.class.d.ts +4 -0
  39. package/dist/sample/felines/class/tiger.class.js +8 -0
  40. package/dist/sample/felines/class/tiger.class.js.map +1 -0
  41. package/dist/sample/felines/dto/create-feline.dto.d.ts +4 -0
  42. package/dist/sample/felines/dto/create-feline.dto.js +28 -0
  43. package/dist/sample/felines/dto/create-feline.dto.js.map +1 -0
  44. package/dist/sample/felines/dto/index.d.ts +2 -0
  45. package/dist/sample/felines/dto/index.js +19 -0
  46. package/dist/sample/felines/dto/index.js.map +1 -0
  47. package/dist/sample/felines/dto/journaling-data.dto.d.ts +4 -0
  48. package/dist/sample/felines/dto/journaling-data.dto.js +8 -0
  49. package/dist/sample/felines/dto/journaling-data.dto.js.map +1 -0
  50. package/dist/sample/felines/felines.constants.d.ts +1 -0
  51. package/dist/sample/felines/felines.constants.js +5 -0
  52. package/dist/sample/felines/felines.constants.js.map +1 -0
  53. package/dist/sample/felines/felines.controller.d.ts +15 -0
  54. package/dist/sample/felines/felines.controller.js +101 -0
  55. package/dist/sample/felines/felines.controller.js.map +1 -0
  56. package/dist/sample/felines/felines.gateway.d.ts +16 -0
  57. package/dist/sample/felines/felines.gateway.js +90 -0
  58. package/dist/sample/felines/felines.gateway.js.map +1 -0
  59. package/dist/sample/felines/felines.module.d.ts +2 -0
  60. package/dist/sample/felines/felines.module.js +28 -0
  61. package/dist/sample/felines/felines.module.js.map +1 -0
  62. package/dist/sample/felines/felines.service.d.ts +8 -0
  63. package/dist/sample/felines/felines.service.js +33 -0
  64. package/dist/sample/felines/felines.service.js.map +1 -0
  65. package/dist/sample/felines/rto/feline.rto.d.ts +7 -0
  66. package/dist/sample/felines/rto/feline.rto.js +31 -0
  67. package/dist/sample/felines/rto/feline.rto.js.map +1 -0
  68. package/dist/sample/felines/rto/index.d.ts +1 -0
  69. package/dist/sample/felines/rto/index.js +18 -0
  70. package/dist/sample/felines/rto/index.js.map +1 -0
  71. package/dist/sample/index.d.ts +3 -0
  72. package/dist/sample/index.js +20 -0
  73. package/dist/sample/index.js.map +1 -0
  74. package/dist/sample/main.d.ts +1 -0
  75. package/dist/sample/main.js +30 -0
  76. package/dist/sample/main.js.map +1 -0
  77. package/dist/src/asyncapi-document.builder.d.ts +27 -0
  78. package/dist/src/asyncapi-document.builder.js +110 -0
  79. package/dist/src/asyncapi-document.builder.js.map +1 -0
  80. package/dist/src/asyncapi.constants.d.ts +6 -0
  81. package/dist/src/asyncapi.constants.js +11 -0
  82. package/dist/src/asyncapi.constants.js.map +1 -0
  83. package/dist/src/asyncapi.module.d.ts +8 -0
  84. package/dist/src/asyncapi.module.js +47 -0
  85. package/dist/src/asyncapi.module.js.map +1 -0
  86. package/dist/src/binding/asyncapi.amqp.interfaces.d.ts +38 -0
  87. package/dist/src/binding/asyncapi.amqp.interfaces.js +3 -0
  88. package/dist/src/binding/asyncapi.amqp.interfaces.js.map +1 -0
  89. package/dist/src/binding/asyncapi.kafka.interfaces.d.ts +21 -0
  90. package/dist/src/binding/asyncapi.kafka.interfaces.js +3 -0
  91. package/dist/src/binding/asyncapi.kafka.interfaces.js.map +1 -0
  92. package/dist/src/binding/index.d.ts +2 -0
  93. package/dist/src/binding/index.js +19 -0
  94. package/dist/src/binding/index.js.map +1 -0
  95. package/dist/src/decorators/asyncapi-operation-for-meta-key.decorator.d.ts +2 -0
  96. package/dist/src/decorators/asyncapi-operation-for-meta-key.decorator.js +37 -0
  97. package/dist/src/decorators/asyncapi-operation-for-meta-key.decorator.js.map +1 -0
  98. package/dist/src/decorators/asyncapi-operation.decorator.d.ts +2 -0
  99. package/dist/src/decorators/asyncapi-operation.decorator.js +9 -0
  100. package/dist/src/decorators/asyncapi-operation.decorator.js.map +1 -0
  101. package/dist/src/decorators/asyncapi-pub.decorator.d.ts +2 -0
  102. package/dist/src/decorators/asyncapi-pub.decorator.js +10 -0
  103. package/dist/src/decorators/asyncapi-pub.decorator.js.map +1 -0
  104. package/dist/src/decorators/asyncapi-service.decorator.d.ts +1 -0
  105. package/dist/src/decorators/asyncapi-service.decorator.js +9 -0
  106. package/dist/src/decorators/asyncapi-service.decorator.js.map +1 -0
  107. package/dist/src/decorators/asyncapi-sub.decorator.d.ts +2 -0
  108. package/dist/src/decorators/asyncapi-sub.decorator.js +10 -0
  109. package/dist/src/decorators/asyncapi-sub.decorator.js.map +1 -0
  110. package/dist/src/decorators/index.d.ts +4 -0
  111. package/dist/src/decorators/index.js +21 -0
  112. package/dist/src/decorators/index.js.map +1 -0
  113. package/dist/src/explorers/asyncapi-class.explorer.d.ts +5 -0
  114. package/dist/src/explorers/asyncapi-class.explorer.js +27 -0
  115. package/dist/src/explorers/asyncapi-class.explorer.js.map +1 -0
  116. package/dist/src/explorers/asyncapi-operation.explorer.d.ts +17 -0
  117. package/dist/src/explorers/asyncapi-operation.explorer.js +26 -0
  118. package/dist/src/explorers/asyncapi-operation.explorer.js.map +1 -0
  119. package/dist/src/explorers/index.d.ts +2 -0
  120. package/dist/src/explorers/index.js +19 -0
  121. package/dist/src/explorers/index.js.map +1 -0
  122. package/dist/src/index.d.ts +4 -0
  123. package/dist/src/index.js +21 -0
  124. package/dist/src/index.js.map +1 -0
  125. package/dist/src/interface/asyncapi-common.interfaces.d.ts +126 -0
  126. package/dist/src/interface/asyncapi-common.interfaces.js +3 -0
  127. package/dist/src/interface/asyncapi-common.interfaces.js.map +1 -0
  128. package/dist/src/interface/asyncapi-document-options.interface.d.ts +3 -0
  129. package/dist/src/interface/asyncapi-document-options.interface.js +3 -0
  130. package/dist/src/interface/asyncapi-document-options.interface.js.map +1 -0
  131. package/dist/src/interface/asyncapi-message.interface.d.ts +8 -0
  132. package/dist/src/interface/asyncapi-message.interface.js +3 -0
  133. package/dist/src/interface/asyncapi-message.interface.js.map +1 -0
  134. package/dist/src/interface/asyncapi-operation-headers.interface.d.ts +6 -0
  135. package/dist/src/interface/asyncapi-operation-headers.interface.js +3 -0
  136. package/dist/src/interface/asyncapi-operation-headers.interface.js.map +1 -0
  137. package/dist/src/interface/asyncapi-operation-options-raw.interface.d.ts +21 -0
  138. package/dist/src/interface/asyncapi-operation-options-raw.interface.js +3 -0
  139. package/dist/src/interface/asyncapi-operation-options-raw.interface.js.map +1 -0
  140. package/dist/src/interface/asyncapi-operation-options.interface.d.ts +8 -0
  141. package/dist/src/interface/asyncapi-operation-options.interface.js +3 -0
  142. package/dist/src/interface/asyncapi-operation-options.interface.js.map +1 -0
  143. package/dist/src/interface/asyncapi-operation-payload.interface.d.ts +2 -0
  144. package/dist/src/interface/asyncapi-operation-payload.interface.js +3 -0
  145. package/dist/src/interface/asyncapi-operation-payload.interface.js.map +1 -0
  146. package/dist/src/interface/asyncapi-server.interface.d.ts +10 -0
  147. package/dist/src/interface/asyncapi-server.interface.js +3 -0
  148. package/dist/src/interface/asyncapi-server.interface.js.map +1 -0
  149. package/dist/src/interface/asyncapi-template-options.interface.d.ts +7 -0
  150. package/dist/src/interface/asyncapi-template-options.interface.js +3 -0
  151. package/dist/src/interface/asyncapi-template-options.interface.js.map +1 -0
  152. package/dist/src/interface/denormalized-doc-resolvers.interface.d.ts +6 -0
  153. package/dist/src/interface/denormalized-doc-resolvers.interface.js +3 -0
  154. package/dist/src/interface/denormalized-doc-resolvers.interface.js.map +1 -0
  155. package/dist/src/interface/denormalized-doc.interface.d.ts +10 -0
  156. package/dist/src/interface/denormalized-doc.interface.js +3 -0
  157. package/dist/src/interface/denormalized-doc.interface.js.map +1 -0
  158. package/dist/src/interface/generator-options.interface.d.ts +22 -0
  159. package/dist/src/interface/generator-options.interface.js +3 -0
  160. package/dist/src/interface/generator-options.interface.js.map +1 -0
  161. package/dist/src/interface/index.d.ts +11 -0
  162. package/dist/src/interface/index.js +28 -0
  163. package/dist/src/interface/index.js.map +1 -0
  164. package/dist/src/services/asyncapi.explorer.d.ts +12 -0
  165. package/dist/src/services/asyncapi.explorer.js +69 -0
  166. package/dist/src/services/asyncapi.explorer.js.map +1 -0
  167. package/dist/src/services/asyncapi.generator.d.ts +6 -0
  168. package/dist/src/services/asyncapi.generator.js +68 -0
  169. package/dist/src/services/asyncapi.generator.js.map +1 -0
  170. package/dist/src/services/asyncapi.scanner.d.ts +14 -0
  171. package/dist/src/services/asyncapi.scanner.js +71 -0
  172. package/dist/src/services/asyncapi.scanner.js.map +1 -0
  173. package/dist/src/services/asyncapi.transformer.d.ts +4 -0
  174. package/dist/src/services/asyncapi.transformer.js +33 -0
  175. package/dist/src/services/asyncapi.transformer.js.map +1 -0
  176. package/dist/src/services/index.d.ts +4 -0
  177. package/dist/src/services/index.js +21 -0
  178. package/dist/src/services/index.js.map +1 -0
  179. package/dist/src/services/operation-object.factory.d.ts +9 -0
  180. package/dist/src/services/operation-object.factory.js +37 -0
  181. package/dist/src/services/operation-object.factory.js.map +1 -0
  182. package/dist/test/configs/jest-base.config.d.ts +3 -0
  183. package/dist/test/configs/jest-base.config.js +20 -0
  184. package/dist/test/configs/jest-base.config.js.map +1 -0
  185. package/dist/test/configs/jest-e2e.config.d.ts +3 -0
  186. package/dist/test/configs/jest-e2e.config.js +16 -0
  187. package/dist/test/configs/jest-e2e.config.js.map +1 -0
  188. package/dist/test/express.e2e-spec.d.ts +1 -0
  189. package/dist/test/express.e2e-spec.js +89 -0
  190. package/dist/test/express.e2e-spec.js.map +1 -0
  191. package/dist/test/fastify.e2e-spec.d.ts +1 -0
  192. package/dist/test/fastify.e2e-spec.js +57 -0
  193. package/dist/test/fastify.e2e-spec.js.map +1 -0
  194. package/dist/tsconfig.tsbuildinfo +1 -1
  195. package/misc/references/ref.html +303 -0
  196. package/misc/references/ref.json +1 -0
  197. package/misc/references/ref.yaml +292 -0
  198. package/misc/take-snaphots.sh +8 -0
  199. package/package.json +18 -11
  200. package/sample/app.module.ts +7 -0
  201. package/sample/common.ts +49 -0
  202. package/sample/constants.ts +12 -0
  203. package/sample/felines/class/cat.class.ts +9 -0
  204. package/sample/felines/class/feline.class.ts +29 -0
  205. package/sample/felines/class/index.ts +5 -0
  206. package/sample/felines/class/lion.class.ts +5 -0
  207. package/sample/felines/class/message.class.ts +17 -0
  208. package/sample/felines/class/tiger.class.ts +5 -0
  209. package/sample/felines/dto/create-feline.dto.ts +13 -0
  210. package/sample/felines/dto/index.ts +2 -0
  211. package/sample/felines/dto/journaling-data.dto.ts +5 -0
  212. package/sample/felines/felines.constants.ts +1 -0
  213. package/sample/felines/felines.controller.ts +76 -0
  214. package/sample/felines/felines.gateway.ts +76 -0
  215. package/sample/felines/felines.module.ts +15 -0
  216. package/sample/felines/felines.service.ts +24 -0
  217. package/sample/felines/rto/feline.rto.ts +17 -0
  218. package/sample/felines/rto/index.ts +1 -0
  219. package/sample/index.ts +3 -0
  220. package/sample/main.ts +34 -0
  221. package/src/asyncapi-document.builder.ts +5 -19
  222. package/src/asyncapi.module.ts +5 -16
  223. package/src/decorators/asyncapi-operation-for-meta-key.decorator.ts +4 -16
  224. package/src/decorators/asyncapi-operation.decorator.ts +1 -3
  225. package/src/decorators/asyncapi-pub.decorator.ts +6 -13
  226. package/src/decorators/asyncapi-sub.decorator.ts +6 -13
  227. package/src/explorers/asyncapi-class.explorer.ts +2 -6
  228. package/src/explorers/asyncapi-operation.explorer.ts +3 -12
  229. package/src/interface/asyncapi-common.interfaces.ts +1 -4
  230. package/src/interface/asyncapi-operation-options.interface.ts +2 -4
  231. package/src/interface/asyncapi-operation-payload.interface.ts +1 -5
  232. package/src/interface/asyncapi-server.interface.ts +1 -4
  233. package/src/interface/asyncapi-template-options.interface.ts +5 -5
  234. package/src/interface/denormalized-doc.interface.ts +1 -5
  235. package/src/services/asyncapi.explorer.ts +25 -34
  236. package/src/services/asyncapi.generator.ts +28 -16
  237. package/src/services/asyncapi.scanner.ts +39 -89
  238. package/src/services/asyncapi.transformer.ts +2 -8
  239. package/src/services/index.ts +0 -1
  240. package/test/__mocks__/@asyncapi/generator.js +41 -0
  241. package/test/configs/jest-base.config.ts +19 -0
  242. package/test/configs/jest-e2e.config.js +7 -0
  243. package/test/configs/jest-e2e.config.ts +19 -0
  244. package/test/configs/jest-swagger-plugin.js +16 -0
  245. package/test/express.e2e-spec.ts +64 -0
  246. package/test/fastify.e2e-spec.ts +65 -0
@@ -0,0 +1,7 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { FelinesModule } from './felines/felines.module';
3
+
4
+ @Module({
5
+ imports: [FelinesModule],
6
+ })
7
+ export class AppModule {}
@@ -0,0 +1,49 @@
1
+ import { INestApplicationContext } from '@nestjs/common';
2
+ import { HOST, PORT, SERVER } from './constants';
3
+ import { Cat, Feline, Lion, Tiger } from './felines/class';
4
+ import { FelinesModule } from './felines/felines.module';
5
+ import {
6
+ AsyncApiDocument,
7
+ AsyncApiDocumentBuilder,
8
+ AsyncApiModule,
9
+ AsyncServerObject,
10
+ } from '../src';
11
+
12
+ export async function makeAsyncapiDocument(
13
+ app: INestApplicationContext,
14
+ ): Promise<AsyncApiDocument> {
15
+ const asyncApiServer: AsyncServerObject = {
16
+ url: `ws://${HOST}:${PORT}`,
17
+ protocol: 'socket.io',
18
+ protocolVersion: '4',
19
+ description:
20
+ 'Allows you to connect using the websocket protocol to our Socket.io server.',
21
+ security: [{ 'user-password': [] }],
22
+ variables: {
23
+ port: {
24
+ description: 'Secure connection (TLS) is available through port 443.',
25
+ default: '443',
26
+ },
27
+ },
28
+ bindings: {},
29
+ };
30
+
31
+ const servers = Object.keys(SERVER).map((i) => ({
32
+ name: SERVER[i],
33
+ server: asyncApiServer,
34
+ }));
35
+
36
+ const asyncApiOptions = new AsyncApiDocumentBuilder()
37
+ .setTitle('Feline')
38
+ .setDescription('Feline server description here')
39
+ .setVersion('1.0')
40
+ .setDefaultContentType('application/json')
41
+ .addSecurity('user-password', { type: 'userPassword' })
42
+ .addServers(servers)
43
+ .build();
44
+
45
+ return AsyncApiModule.createDocument(app, asyncApiOptions, {
46
+ include: [FelinesModule],
47
+ extraModels: [Cat, Lion, Tiger, Feline],
48
+ });
49
+ }
@@ -0,0 +1,12 @@
1
+ export const DOC_RELATIVE_PATH = '/async-api';
2
+ export const BOOTSTRAP = 'Bootstrap';
3
+ export const PORT = 4001;
4
+ export const HOST = '0.0.0.0';
5
+ export const SERVER = {
6
+ europe: 'europe',
7
+ asia: 'asia',
8
+ northAmerica: 'north-america',
9
+ southAmerica: 'south-america',
10
+ africa: 'africa',
11
+ australia: 'australia',
12
+ };
@@ -0,0 +1,9 @@
1
+ import { ApiProperty } from '@nestjs/swagger';
2
+ import { Feline } from './feline.class';
3
+
4
+ export class Cat extends Feline {
5
+ @ApiProperty({
6
+ example: 'Maine Coon',
7
+ })
8
+ breed: string;
9
+ }
@@ -0,0 +1,29 @@
1
+ enum PawsEnum {
2
+ left = 'left',
3
+ right = 'right',
4
+ }
5
+
6
+ enum GendersEnum {
7
+ male = 'male',
8
+ female = 'female',
9
+ }
10
+
11
+ export abstract class Feline {
12
+ id: number;
13
+
14
+ name: string;
15
+
16
+ age: number;
17
+
18
+ gender: GendersEnum;
19
+
20
+ dominantPaw: PawsEnum;
21
+
22
+ tags: string[];
23
+
24
+ birthDatetime: Date;
25
+
26
+ constructor(initializer: Record<string, unknown>) {
27
+ Object.assign(this, initializer);
28
+ }
29
+ }
@@ -0,0 +1,5 @@
1
+ export * from './feline.class';
2
+ export * from './cat.class';
3
+ export * from './lion.class';
4
+ export * from './tiger.class';
5
+ export * from './message.class';
@@ -0,0 +1,5 @@
1
+ import { Feline } from './feline.class';
2
+
3
+ export class Lion extends Feline {
4
+ roarVolume: number;
5
+ }
@@ -0,0 +1,17 @@
1
+ import { ApiProperty } from '@nestjs/swagger';
2
+
3
+ export abstract class Message<T extends Record<string, any>> {
4
+ @ApiProperty({ format: 'uuid' })
5
+ correlationId: string;
6
+
7
+ @ApiProperty({ format: 'x.y.z', example: '1.0.1' })
8
+ version: string;
9
+
10
+ timestamp: Date;
11
+
12
+ abstract payload: T;
13
+
14
+ constructor(partialData: Partial<Message<T>>) {
15
+ Object.assign(this, partialData);
16
+ }
17
+ }
@@ -0,0 +1,5 @@
1
+ import { Feline } from './feline.class';
2
+
3
+ export class Tiger extends Feline {
4
+ numberOfStripes: number;
5
+ }
@@ -0,0 +1,13 @@
1
+ import { ApiProperty, getSchemaPath } from '@nestjs/swagger';
2
+ import { Cat, Feline, Lion, Message, Tiger } from '../class';
3
+
4
+ export class CreateFelineDto extends Message<Feline> {
5
+ @ApiProperty({
6
+ oneOf: [
7
+ { $ref: getSchemaPath(Cat) },
8
+ { $ref: getSchemaPath(Lion) },
9
+ { $ref: getSchemaPath(Tiger) },
10
+ ],
11
+ })
12
+ payload: Feline;
13
+ }
@@ -0,0 +1,2 @@
1
+ export * from '../class/message.class';
2
+ export * from './create-feline.dto';
@@ -0,0 +1,5 @@
1
+ import { Message } from '../class';
2
+
3
+ export class JournalingDataDto extends Message<Record<string, unknown>> {
4
+ payload: Record<string, unknown>;
5
+ }
@@ -0,0 +1 @@
1
+ export const FELINES_MS = 'FELINES_MS';
@@ -0,0 +1,76 @@
1
+ import { Controller, Get, Inject, Logger } from '@nestjs/common';
2
+ import { ClientProxy, EventPattern } from '@nestjs/microservices';
3
+ import { CreateFelineDto } from './dto';
4
+ import { AsyncApiPub, AsyncApiSub } from '../../src';
5
+ import { Cat, Feline } from '../../sample/felines/class';
6
+ import { JournalingDataDto } from '../../sample/felines/dto/journaling-data.dto';
7
+ import { FELINES_MS } from '../../sample/felines/felines.constants';
8
+ import { FelinesService } from '../../sample/felines/felines.service';
9
+ import { FelineRto } from '../../sample/felines/rto';
10
+
11
+ const EventPatternsMS = {
12
+ createFeline: 'ms/create/feline',
13
+ journal: 'ms/journal',
14
+ };
15
+
16
+ /**
17
+ * How to use AsyncApi in a microservices
18
+ */
19
+ @Controller()
20
+ export class FelinesController {
21
+ private logger: Logger = new Logger(FelinesController.name);
22
+
23
+ constructor(
24
+ @Inject(FELINES_MS)
25
+ private readonly client: ClientProxy,
26
+ private readonly felinesService: FelinesService,
27
+ ) {}
28
+
29
+ @AsyncApiSub({
30
+ channel: EventPatternsMS.journal,
31
+ message: {
32
+ payload: JournalingDataDto,
33
+ },
34
+ })
35
+ @EventPattern(EventPatternsMS.journal)
36
+ async journal(dataForJournaling: JournalingDataDto) {
37
+ const dataForJournalingString = JSON.stringify(dataForJournaling, null, 4);
38
+ this.logger.log(`journaling:\n${dataForJournalingString}`);
39
+ }
40
+
41
+ @AsyncApiPub({
42
+ channel: EventPatternsMS.createFeline,
43
+ message: {
44
+ payload: CreateFelineDto,
45
+ },
46
+ })
47
+ @AsyncApiSub({
48
+ channel: EventPatternsMS.createFeline,
49
+ message: {
50
+ payload: FelineRto,
51
+ },
52
+ })
53
+ @EventPattern(EventPatternsMS.createFeline)
54
+ async createFeline(createFelineDto: CreateFelineDto) {
55
+ const feline = await this.felinesService.create(createFelineDto);
56
+ this.logger.debug(`feline created:\n${JSON.stringify(feline)}`);
57
+ this.publishCreatedFeline(feline);
58
+ }
59
+
60
+ publishCreatedFeline(feline: Feline) {
61
+ const felineRto = new FelineRto({ payload: feline });
62
+ return this.client.emit(EventPatternsMS.journal, felineRto);
63
+ }
64
+
65
+ @Get()
66
+ async do() {
67
+ const cat = new Cat({
68
+ id: 123,
69
+ name: 'demo',
70
+ });
71
+
72
+ const felineRto = new CreateFelineDto({ payload: cat });
73
+
74
+ await this.createFeline(felineRto);
75
+ }
76
+ }
@@ -0,0 +1,76 @@
1
+ import { Logger } from '@nestjs/common';
2
+ import {
3
+ ConnectedSocket,
4
+ MessageBody,
5
+ OnGatewayDisconnect,
6
+ OnGatewayInit,
7
+ SubscribeMessage,
8
+ WebSocketGateway,
9
+ WebSocketServer,
10
+ } from '@nestjs/websockets';
11
+ import { Namespace, Server } from 'socket.io';
12
+ import { Socket } from 'socket.io-client';
13
+ import { FelinesService } from './/felines.service';
14
+ import { CreateFelineDto } from './dto';
15
+ import { FelineExtendedRto, FelineRto } from './rto';
16
+ import { AsyncApiPub, AsyncApiSub } from '../../src';
17
+
18
+ const EventPatternsWS = {
19
+ createFeline: 'ws/create/feline',
20
+ };
21
+
22
+ /**
23
+ * How to use AsyncApi in a websockets
24
+ */
25
+ @WebSocketGateway({ transports: ['websocket'], namespace: 'ws' })
26
+ export class FelinesGateway implements OnGatewayInit, OnGatewayDisconnect {
27
+ @WebSocketServer()
28
+ private readonly server: Server;
29
+ private readonly logger: Logger = new Logger(FelinesGateway.name);
30
+
31
+ constructor(private readonly felinesService: FelinesService) {}
32
+
33
+ afterInit(nsp: Namespace) {
34
+ this.logger.log(`Gateway server init: ${nsp?.name}`);
35
+ }
36
+
37
+ handleDisconnect(client: Socket) {
38
+ this.logger.log(`Client disconnected: ${client.id}`);
39
+ }
40
+
41
+ @SubscribeMessage(EventPatternsWS.createFeline)
42
+ @AsyncApiPub({
43
+ channel: EventPatternsWS.createFeline,
44
+ message: {
45
+ payload: CreateFelineDto,
46
+ },
47
+ })
48
+ async createFeline(
49
+ @ConnectedSocket() client: Socket,
50
+ @MessageBody() createFelineDto: CreateFelineDto,
51
+ ) {
52
+ this.logger.log(
53
+ `data from client ${client.id} : ${JSON.stringify(createFelineDto)}`,
54
+ );
55
+
56
+ const feline = await this.felinesService.create(createFelineDto);
57
+ await this.emitCreatedFeline(new FelineRto({ payload: feline }));
58
+ }
59
+
60
+ @AsyncApiSub({
61
+ channel: EventPatternsWS.createFeline,
62
+ message: [
63
+ {
64
+ name: 'oneOf demo #1',
65
+ payload: FelineRto,
66
+ },
67
+ {
68
+ name: 'oneOf demo #2',
69
+ payload: FelineExtendedRto,
70
+ },
71
+ ],
72
+ })
73
+ async emitCreatedFeline(felineRto: FelineRto) {
74
+ this.server.emit(EventPatternsWS.createFeline, felineRto);
75
+ }
76
+ }
@@ -0,0 +1,15 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { ClientsModule, Transport } from '@nestjs/microservices';
3
+ import { FELINES_MS } from './felines.constants';
4
+ import { FelinesController } from './felines.controller';
5
+ import { FelinesGateway } from './felines.gateway';
6
+ import { FelinesService } from './felines.service';
7
+
8
+ @Module({
9
+ imports: [
10
+ ClientsModule.register([{ name: FELINES_MS, transport: Transport.TCP }]),
11
+ ],
12
+ providers: [FelinesService, FelinesGateway],
13
+ controllers: [FelinesController],
14
+ })
15
+ export class FelinesModule {}
@@ -0,0 +1,24 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { Feline } from './class';
3
+ import { CreateFelineDto } from './dto';
4
+
5
+ @Injectable()
6
+ export class FelinesService {
7
+ private readonly felines: Feline[] = [];
8
+
9
+ async get(id: number): Promise<Feline> {
10
+ return this.felines[id];
11
+ }
12
+
13
+ async delete(id: number): Promise<boolean> {
14
+ const felineToDelete = this.get(id);
15
+ delete this.felines[id];
16
+ return !!felineToDelete;
17
+ }
18
+
19
+ async create(createFelineDto: CreateFelineDto): Promise<Feline> {
20
+ const feline = createFelineDto.payload;
21
+ this.felines.push(feline);
22
+ return feline;
23
+ }
24
+ }
@@ -0,0 +1,17 @@
1
+ import { ApiProperty, getSchemaPath } from '@nestjs/swagger';
2
+ import { Cat, Feline, Lion, Message, Tiger } from '../class';
3
+
4
+ export class FelineRto extends Message<Feline> {
5
+ @ApiProperty({
6
+ oneOf: [
7
+ { $ref: getSchemaPath(Cat) },
8
+ { $ref: getSchemaPath(Lion) },
9
+ { $ref: getSchemaPath(Tiger) },
10
+ ],
11
+ })
12
+ payload: Feline;
13
+ }
14
+
15
+ export class FelineExtendedRto extends FelineRto {
16
+ extra: string;
17
+ }
@@ -0,0 +1 @@
1
+ export * from './feline.rto';
@@ -0,0 +1,3 @@
1
+ export * from './app.module';
2
+ export * from './common';
3
+ export * from './constants';
package/sample/main.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { INestApplication, Logger } from '@nestjs/common';
2
+ import { NestFactory } from '@nestjs/core';
3
+ import { MicroserviceOptions, Transport } from '@nestjs/microservices';
4
+ import { ExpressAdapter } from '@nestjs/platform-express';
5
+ import { FastifyAdapter } from '@nestjs/platform-fastify';
6
+ import { AppModule } from './app.module';
7
+ import { makeAsyncapiDocument } from './common';
8
+ import { BOOTSTRAP, DOC_RELATIVE_PATH, HOST, PORT } from './constants';
9
+ import { AsyncApiModule } from '../src';
10
+
11
+ const USE_FASTIFY = false;
12
+
13
+ const adapter = USE_FASTIFY
14
+ ? new FastifyAdapter({
15
+ ignoreTrailingSlash: false,
16
+ })
17
+ : new ExpressAdapter();
18
+
19
+ async function bootstrap(): Promise<void> {
20
+ const app = await NestFactory.create<INestApplication>(AppModule, adapter, {});
21
+ const asyncapiDocument = await makeAsyncapiDocument(app);
22
+ await AsyncApiModule.setup(DOC_RELATIVE_PATH, app, asyncapiDocument);
23
+
24
+ app.connectMicroservice<MicroserviceOptions>({ transport: Transport.TCP });
25
+
26
+ await app.startAllMicroservices();
27
+ await app.listen(PORT, HOST);
28
+
29
+ const baseUrl = `http://${HOST}:${PORT}`;
30
+ const docUrl = baseUrl + DOC_RELATIVE_PATH;
31
+ Logger.log(`Server started at ${baseUrl}; AsyncApi at ${docUrl};`, BOOTSTRAP);
32
+ }
33
+
34
+ bootstrap();
@@ -4,17 +4,10 @@ import {
4
4
  TagObject,
5
5
  } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';
6
6
  import { isUndefined, negate, pickBy } from 'lodash';
7
- import {
8
- AsyncApiDocument,
9
- AsyncSecuritySchemeObject,
10
- AsyncServerObject,
11
- } from './interface';
7
+ import { AsyncApiDocument, AsyncSecuritySchemeObject, AsyncServerObject } from './interface';
12
8
 
13
9
  export class AsyncApiDocumentBuilder {
14
- private readonly buildDocumentBase = (): Omit<
15
- AsyncApiDocument,
16
- 'channels'
17
- > => ({
10
+ private readonly buildDocumentBase = (): Omit<AsyncApiDocument, 'channels'> => ({
18
11
  asyncapi: '2.5.0',
19
12
  info: {
20
13
  title: '',
@@ -27,8 +20,7 @@ export class AsyncApiDocumentBuilder {
27
20
  components: {},
28
21
  });
29
22
 
30
- private readonly document: Omit<AsyncApiDocument, 'channels'> =
31
- this.buildDocumentBase();
23
+ private readonly document: Omit<AsyncApiDocument, 'channels'> = this.buildDocumentBase();
32
24
 
33
25
  public setTitle(title: string): this {
34
26
  this.document.info.title = title;
@@ -65,9 +57,7 @@ export class AsyncApiDocumentBuilder {
65
57
  return this;
66
58
  }
67
59
 
68
- public addServers(
69
- servers: { name: string; server: AsyncServerObject }[],
70
- ): this {
60
+ public addServers(servers: { name: string; server: AsyncServerObject }[]): this {
71
61
  for (const { name, server } of servers) {
72
62
  this.addServer(name, server);
73
63
  }
@@ -85,11 +75,7 @@ export class AsyncApiDocumentBuilder {
85
75
  return this;
86
76
  }
87
77
 
88
- public addTag(
89
- name: string,
90
- description = '',
91
- externalDocs?: ExternalDocumentationObject,
92
- ): this {
78
+ public addTag(name: string, description = '', externalDocs?: ExternalDocumentationObject): this {
93
79
  this.document.tags = this.document.tags!.concat(
94
80
  pickBy(
95
81
  {
@@ -1,15 +1,7 @@
1
- import {
2
- INestApplication,
3
- INestApplicationContext,
4
- Logger,
5
- } from '@nestjs/common';
1
+ import { INestApplication, INestApplicationContext, Logger } from '@nestjs/common';
6
2
  import { validatePath } from '@nestjs/swagger/dist/utils/validate-path.util';
7
3
  import jsyaml from 'js-yaml';
8
- import {
9
- AsyncApiDocument,
10
- AsyncApiDocumentOptions,
11
- AsyncApiTemplateOptions,
12
- } from './interface';
4
+ import { AsyncApiDocument, AsyncApiDocumentOptions, AsyncApiTemplateOptions } from './interface';
13
5
  import { AsyncapiGenerator, AsyncapiScanner } from './services';
14
6
 
15
7
  export class AsyncApiModule {
@@ -34,10 +26,7 @@ export class AsyncApiModule {
34
26
  };
35
27
  }
36
28
 
37
- static async composeHtml(
38
- contract: AsyncApiDocument,
39
- templateOptions?: AsyncApiTemplateOptions,
40
- ) {
29
+ static async composeHtml(contract: AsyncApiDocument, templateOptions?: AsyncApiTemplateOptions) {
41
30
  const generator = new AsyncapiGenerator(templateOptions);
42
31
  return generator.generate(contract).catch((err) => {
43
32
  this.logger.error(err);
@@ -63,12 +52,12 @@ export class AsyncApiModule {
63
52
  res.send(html);
64
53
  });
65
54
 
66
- httpAdapter.get(finalPath + '-json', (req, res) => {
55
+ httpAdapter.get(`${finalPath}-json`, (req, res) => {
67
56
  res.type('application/json');
68
57
  res.send(jsonDocument);
69
58
  });
70
59
 
71
- httpAdapter.get(finalPath + '-yaml', (req, res) => {
60
+ httpAdapter.get(`${finalPath}-yaml`, (req, res) => {
72
61
  res.type('text/yaml');
73
62
  res.send(yamlDocument);
74
63
  });
@@ -23,10 +23,7 @@ function makeHeaders(headers?: AsyncApiOperationHeaders) {
23
23
  : undefined;
24
24
  }
25
25
 
26
- function makeMessage(
27
- message: OneAsyncApiMessage,
28
- defaultName: string,
29
- ): AsyncMessageObject {
26
+ function makeMessage(message: OneAsyncApiMessage, defaultName: string): AsyncMessageObject {
30
27
  return {
31
28
  ...message,
32
29
  name: message.name || defaultName,
@@ -37,19 +34,14 @@ function makeMessage(
37
34
  };
38
35
  }
39
36
 
40
- export function AsyncApiOperationForMetaKey(
41
- metaKey: string,
42
- options: AsyncApiOperationOptions[],
43
- ): MethodDecorator {
37
+ export function AsyncApiOperationForMetaKey(metaKey: string, options: AsyncApiOperationOptions[]): MethodDecorator {
44
38
  return (target, propertyKey: string | symbol, descriptor) => {
45
39
  const methodName = `${target.constructor.name}#${String(propertyKey)}`;
46
40
 
47
41
  const transformedOptions: AsyncOperationObject[] = options.map((i) => {
48
42
  const message = Array.isArray(i.message)
49
43
  ? {
50
- oneOf: i.message.map((i, index) =>
51
- makeMessage(i, `${methodName}#${index}`),
52
- ),
44
+ oneOf: i.message.map((j, index) => makeMessage(j, `${methodName}#${index}`)),
53
45
  }
54
46
  : makeMessage(i.message, methodName);
55
47
 
@@ -61,10 +53,6 @@ export function AsyncApiOperationForMetaKey(
61
53
  return transformedOptionInstance;
62
54
  });
63
55
 
64
- return createMethodDecorator(metaKey, transformedOptions)(
65
- target,
66
- propertyKey,
67
- descriptor,
68
- );
56
+ return createMethodDecorator(metaKey, transformedOptions)(target, propertyKey, descriptor);
69
57
  };
70
58
  }
@@ -2,8 +2,6 @@ import { DECORATORS } from '../asyncapi.constants';
2
2
  import { AsyncApiOperationOptions } from '../interface';
3
3
  import { AsyncApiOperationForMetaKey } from './asyncapi-operation-for-meta-key.decorator';
4
4
 
5
- export function AsyncApiOperation(
6
- ...options: AsyncApiOperationOptions[]
7
- ): MethodDecorator {
5
+ export function AsyncApiOperation(...options: AsyncApiOperationOptions[]): MethodDecorator {
8
6
  return AsyncApiOperationForMetaKey(DECORATORS.AsyncApiOperation, options);
9
7
  }
@@ -1,18 +1,11 @@
1
1
  import { DECORATORS } from '../asyncapi.constants';
2
- import {
3
- AsyncApiOperationOptions,
4
- AsyncApiSpecificOperationOptions,
5
- } from '../interface';
2
+ import { AsyncApiOperationOptions, AsyncApiSpecificOperationOptions } from '../interface';
6
3
  import { AsyncApiOperationForMetaKey } from './asyncapi-operation-for-meta-key.decorator';
7
4
 
8
- export function AsyncApiPub(
9
- ...specificOperationOptions: AsyncApiSpecificOperationOptions[]
10
- ) {
11
- const options: AsyncApiOperationOptions[] = specificOperationOptions.map(
12
- (i) => ({
13
- ...i,
14
- type: 'pub',
15
- }),
16
- );
5
+ export function AsyncApiPub(...specificOperationOptions: AsyncApiSpecificOperationOptions[]) {
6
+ const options: AsyncApiOperationOptions[] = specificOperationOptions.map((i) => ({
7
+ ...i,
8
+ type: 'pub',
9
+ }));
17
10
  return AsyncApiOperationForMetaKey(DECORATORS.AsyncApiPub, options);
18
11
  }
@@ -1,18 +1,11 @@
1
1
  import { DECORATORS } from '../asyncapi.constants';
2
- import {
3
- AsyncApiOperationOptions,
4
- AsyncApiSpecificOperationOptions,
5
- } from '../interface';
2
+ import { AsyncApiOperationOptions, AsyncApiSpecificOperationOptions } from '../interface';
6
3
  import { AsyncApiOperationForMetaKey } from './asyncapi-operation-for-meta-key.decorator';
7
4
 
8
- export function AsyncApiSub(
9
- ...specificOperationOptions: AsyncApiSpecificOperationOptions[]
10
- ) {
11
- const options: AsyncApiOperationOptions[] = specificOperationOptions.map(
12
- (i) => ({
13
- ...i,
14
- type: 'sub',
15
- }),
16
- );
5
+ export function AsyncApiSub(...specificOperationOptions: AsyncApiSpecificOperationOptions[]) {
6
+ const options: AsyncApiOperationOptions[] = specificOperationOptions.map((i) => ({
7
+ ...i,
8
+ type: 'sub',
9
+ }));
17
10
  return AsyncApiOperationForMetaKey(DECORATORS.AsyncApiSub, options);
18
11
  }
@@ -4,18 +4,14 @@ import { DECORATORS } from '../asyncapi.constants';
4
4
 
5
5
  let GATEWAY_METADATA;
6
6
  try {
7
- // eslint-disable-next-line @typescript-eslint/no-var-requires
7
+ // eslint-disable-next-line
8
8
  const wsConstants = require('@nestjs/websockets/constants');
9
9
  GATEWAY_METADATA = wsConstants.GATEWAY_METADATA;
10
10
  } catch {
11
11
  GATEWAY_METADATA = '__gateway__'; // in case @nestjs/websockets is not installed GATEWAY_METADATA value is irrelevant
12
12
  }
13
13
 
14
- export const asyncApiClassAnnotationLabels = [
15
- DECORATORS.AsyncApiClass,
16
- CONTROLLER_WATERMARK,
17
- GATEWAY_METADATA,
18
- ];
14
+ export const asyncApiClassAnnotationLabels = [DECORATORS.AsyncApiClass, CONTROLLER_WATERMARK, GATEWAY_METADATA];
19
15
 
20
16
  export const exploreAsyncapiClassMetadata = (metatype: Type<unknown>) => {
21
17
  return Reflect.getMetadata(DECORATORS.AsyncApiClass, metatype);