From 272f77ceb17a659b431b8d60cb1203a1321e4c7a Mon Sep 17 00:00:00 2001 From: allburov Date: Tue, 20 Oct 2020 18:00:39 +0700 Subject: [PATCH] Add opepapi\swagger scaffolding --- nest-cli.json | 9 +++- package-lock.json | 57 +++++++++++++++++++++- package.json | 5 +- src/api/all.dto.ts | 10 ++++ src/{app.service.ts => api/api.service.ts} | 4 +- src/api/chattingController.ts | 23 +++++++++ src/api/device.controller.ts | 21 ++++++++ src/app.controller.spec.ts | 22 --------- src/app.controller.ts | 12 ----- src/app.module.ts | 16 +++--- src/main.ts | 27 ++++++++-- test/app.e2e-spec.ts | 6 +-- 12 files changed, 157 insertions(+), 55 deletions(-) create mode 100644 src/api/all.dto.ts rename src/{app.service.ts => api/api.service.ts} (50%) create mode 100644 src/api/chattingController.ts create mode 100644 src/api/device.controller.ts delete mode 100644 src/app.controller.spec.ts delete mode 100644 src/app.controller.ts diff --git a/nest-cli.json b/nest-cli.json index 56167b36..46eceee2 100644 --- a/nest-cli.json +++ b/nest-cli.json @@ -1,4 +1,9 @@ { "collection": "@nestjs/schematics", - "sourceRoot": "src" -} + "sourceRoot": "src", + "compilerOptions": { + "plugins": [ + "@nestjs/swagger/plugin" + ] + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 407920f6..feecd2b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1664,6 +1664,11 @@ "uuid": "8.3.0" } }, + "@nestjs/mapped-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-0.1.0.tgz", + "integrity": "sha512-FfQsZK5K1OvvGqjPHCJtrNTLlKLg7bLuphtCRTFb5K2P98JTfslauMbT7bS8huOoK/86HMNmNoHR/EVLAd4FzA==" + }, "@nestjs/platform-express": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-7.4.4.tgz", @@ -1794,6 +1799,16 @@ } } }, + "@nestjs/swagger": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-4.6.1.tgz", + "integrity": "sha512-ClJmY7w70fhS0ET3O84IGTyFzKult9T0BlwjyfFeyd9Y02bsX4vYNuJ3YXoOgiHJYsFPUBqpc8DAi4k6AkCdfw==", + "requires": { + "@nestjs/mapped-types": "0.1.0", + "lodash": "4.17.20", + "path-to-regexp": "3.2.0" + } + }, "@nestjs/testing": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-7.4.4.tgz", @@ -2105,6 +2120,11 @@ } } }, + "@types/validator": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.0.0.tgz", + "integrity": "sha512-WAy5txG7aFX8Vw3sloEKp5p/t/Xt8jD3GRD9DacnFv6Vo8ubudAsRTXgxpQwU0mpzY/H8U4db3roDuCMjShBmw==" + }, "@types/webpack": { "version": "4.41.21", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.21.tgz", @@ -3415,6 +3435,17 @@ } } }, + "class-validator": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.12.2.tgz", + "integrity": "sha512-TDzPzp8BmpsbPhQpccB3jMUE/3pK0TyqamrK0kcx+ZeFytMA+O6q87JZZGObHHnoo9GM8vl/JppIyKWeEA/EVw==", + "requires": { + "@types/validator": "13.0.0", + "google-libphonenumber": "^3.2.8", + "tslib": ">=1.9.0", + "validator": "13.0.0" + } + }, "cli-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.0.tgz", @@ -5587,6 +5618,11 @@ } } }, + "google-libphonenumber": { + "version": "3.2.14", + "resolved": "https://registry.npmjs.org/google-libphonenumber/-/google-libphonenumber-3.2.14.tgz", + "integrity": "sha512-4r7mQRbk7EUYV1gyfP1SInYuQsjuDtRXCGLSotxeYDJaj/aF1xFO5PV/GSQeIxXWhIw050DujROICvWpZ1XYRw==" + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -8983,8 +9019,7 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.memoize": { "version": "4.1.2", @@ -11640,6 +11675,19 @@ } } }, + "swagger-ui-dist": { + "version": "3.35.2", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.35.2.tgz", + "integrity": "sha512-19oRW6ZVCTY7JnaMFnIUoxkqI+xhBOGzSFVQTMLDB9KTNASP82v/0SkNpY2T4zbjwZF2Y5bcty9E6rhLGAj0Gg==" + }, + "swagger-ui-express": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.1.4.tgz", + "integrity": "sha512-Ea96ecpC+Iq9GUqkeD/LFR32xSs8gYqmTW1gXCuKg81c26WV6ZC2FsBSPVExQP6WkyUuz5HEiR0sEv/HCC343g==", + "requires": { + "swagger-ui-dist": "^3.18.1" + } + }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", @@ -12354,6 +12402,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "validator": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.0.0.tgz", + "integrity": "sha512-anYx5fURbgF04lQV18nEQWZ/3wHGnxiKdG4aL8J+jEDsm98n/sU/bey+tYk6tnGJzm7ioh5FoqrAiQ6m03IgaA==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index c9d33ff4..18717c16 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,12 @@ "@nestjs/common": "^7.0.0", "@nestjs/core": "^7.0.0", "@nestjs/platform-express": "^7.0.0", + "@nestjs/swagger": "^4.6.1", + "class-validator": "^0.12.2", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", - "rxjs": "^6.5.4" + "rxjs": "^6.5.4", + "swagger-ui-express": "^4.1.4" }, "devDependencies": { "@nestjs/cli": "^7.0.0", diff --git a/src/api/all.dto.ts b/src/api/all.dto.ts new file mode 100644 index 00000000..a81e9fe3 --- /dev/null +++ b/src/api/all.dto.ts @@ -0,0 +1,10 @@ +export class Message { + readonly chatId: string; + readonly text: string; +} + +export class MessageReply { + readonly chatId: string; + readonly text: string; + readonly reply_to: string; +} diff --git a/src/app.service.ts b/src/api/api.service.ts similarity index 50% rename from src/app.service.ts rename to src/api/api.service.ts index 927d7cca..041790d8 100644 --- a/src/app.service.ts +++ b/src/api/api.service.ts @@ -1,7 +1,7 @@ -import { Injectable } from '@nestjs/common'; +import {Injectable} from '@nestjs/common'; @Injectable() -export class AppService { +export class ApiService { getHello(): string { return 'Hello World!'; } diff --git a/src/api/chattingController.ts b/src/api/chattingController.ts new file mode 100644 index 00000000..514058f5 --- /dev/null +++ b/src/api/chattingController.ts @@ -0,0 +1,23 @@ +import {Body, Controller, Post} from '@nestjs/common'; +import {ApiService} from './api.service'; +import {ApiOperation, ApiTags} from "@nestjs/swagger"; +import {Message, MessageReply} from "./all.dto"; + +@Controller('api') +@ApiTags('chatting') +export class ChattingController { + constructor(private readonly apiService: ApiService) { + } + + @Post('/sendText') + @ApiOperation({summary: 'Send a text message'}) + sendText(@Body() message: Message) { + return `You've sent: ${message.chatId} - ${message.text}` + } + + @Post('/reply') + @ApiOperation({summary: 'Reply to a text message'}) + reply(@Body() message: MessageReply) { + return `You've sent: ${message.chatId} - ${message.text} - ${message.reply_to}` + } +} diff --git a/src/api/device.controller.ts b/src/api/device.controller.ts new file mode 100644 index 00000000..e0cb85ad --- /dev/null +++ b/src/api/device.controller.ts @@ -0,0 +1,21 @@ +import {Controller, Get} from '@nestjs/common'; +import {ApiTags} from "@nestjs/swagger"; + +@Controller('api') +@ApiTags('device') +export class DeviceController { + @Get('/getHostDevice') + getHostDevice(): string { + return 'hostDevice' + } + + @Get('/getConnectionState') + getConnectionState(): string { + return 'getConnectionState' + } + + @Get('/getWAVersion') + getWAVersion(): string { + return 'getWAVersion' + } +} diff --git a/src/app.controller.spec.ts b/src/app.controller.spec.ts deleted file mode 100644 index d22f3890..00000000 --- a/src/app.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; - -describe('AppController', () => { - let appController: AppController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [AppController], - providers: [AppService], - }).compile(); - - appController = app.get(AppController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(appController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/src/app.controller.ts b/src/app.controller.ts deleted file mode 100644 index cce879ee..00000000 --- a/src/app.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { AppService } from './app.service'; - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get() - getHello(): string { - return this.appService.getHello(); - } -} diff --git a/src/app.module.ts b/src/app.module.ts index 86628031..d9095c08 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,10 +1,12 @@ -import { Module } from '@nestjs/common'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; +import {Module} from '@nestjs/common'; +import {ChattingController} from './api/chattingController'; +import {ApiService} from './api/api.service'; +import {DeviceController} from "./api/device.controller"; @Module({ - imports: [], - controllers: [AppController], - providers: [AppService], + imports: [], + controllers: [ChattingController, DeviceController], + providers: [ApiService], }) -export class AppModule {} +export class AppModule { +} diff --git a/src/main.ts b/src/main.ts index 13cad38c..ae8a36d3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,27 @@ -import { NestFactory } from '@nestjs/core'; -import { AppModule } from './app.module'; +import {NestFactory} from '@nestjs/core'; +import {AppModule} from './app.module'; +import {DocumentBuilder, SwaggerModule} from "@nestjs/swagger"; async function bootstrap() { - const app = await NestFactory.create(AppModule); - await app.listen(3000); + const app = await NestFactory.create(AppModule); + const options = new DocumentBuilder() + .setTitle('WhatsApp HTTP API') + .setDescription('WhatsApp HTTP API that you can configure in a click') + .setVersion('1.0') + .addTag('device', 'Device information') + .addTag('chatting', 'Chat methods') + .addApiKey({ + type: 'apiKey', + description: 'Your secret key', + name: 'X-VENOM-TOKEN' + } + ) + .build(); + const document = SwaggerModule.createDocument(app, options); + SwaggerModule.setup('', app, document); + + await app.listen(3000); + console.log(`Application is running on: ${await app.getUrl()}`); } + bootstrap(); diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts index 50cda623..3019efdb 100644 --- a/test/app.e2e-spec.ts +++ b/test/app.e2e-spec.ts @@ -1,7 +1,7 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; +import {Test, TestingModule} from '@nestjs/testing'; +import {INestApplication} from '@nestjs/common'; import * as request from 'supertest'; -import { AppModule } from './../src/app.module'; +import {AppModule} from '../src/app.module'; describe('AppController (e2e)', () => { let app: INestApplication;