|
| 1 | +import { Body, Controller, Delete, Get, Param, Post, Req, Res, UseInterceptors } from '@nestjs/common'; |
| 2 | +import { ApiTags, ApiResponse, ApiOperation, ApiParam, ApiBody, ApiConsumes, ApiProduces } from '@nestjs/swagger'; |
| 3 | +import { ScenarioService } from './scenario.service'; |
| 4 | +import { ScenarioSummary } from './scenario.dto'; |
| 5 | +import { Request, Response } from 'express'; |
| 6 | +import { Scenario, validate, yaml } from '@letsflow/api'; |
| 7 | +import Negotiator from 'negotiator'; |
| 8 | + |
| 9 | +//const scenarioSchema = 'https://schemas.letsflow.io/v1.0.0/scenario'; |
| 10 | + |
| 11 | +@ApiTags('Scenario') |
| 12 | +@Controller('scenarios') |
| 13 | +export class ScenarioController { |
| 14 | + constructor(private service: ScenarioService) {} |
| 15 | + |
| 16 | + @ApiOperation({ summary: 'Get all scenarios' }) |
| 17 | + @ApiResponse({ status: 200, description: 'Success', type: ScenarioSummary, isArray: true }) |
| 18 | + @Get() |
| 19 | + list(): ScenarioSummary[] { |
| 20 | + return this.service.list(); |
| 21 | + } |
| 22 | + |
| 23 | + private contentNegotiation(req: Request, ext?: string): string | null { |
| 24 | + if (ext === 'json') return 'application/json'; |
| 25 | + if (ext === 'yaml') return 'application/yaml'; |
| 26 | + if (!ext) return new Negotiator(req).mediaType(['application/json', 'application/yaml']); |
| 27 | + |
| 28 | + return null; |
| 29 | + } |
| 30 | + |
| 31 | + @ApiOperation({ summary: 'Get scenario by ID' }) |
| 32 | + @ApiParam({ name: 'id', description: 'Scenario ID', format: 'uuid' }) |
| 33 | + @ApiResponse({ status: 200, description: 'Success' }) |
| 34 | + @ApiProduces('application/json', 'application/x-yaml') |
| 35 | + @Get(':filename') |
| 36 | + get(@Param('filename') filename: string, @Req() req: Request, @Res() res: Response): void { |
| 37 | + const [id, ext] = filename.split('.'); |
| 38 | + |
| 39 | + if (!this.service.has(id)) { |
| 40 | + res.status(404).send('Scenario not found'); |
| 41 | + return; |
| 42 | + } |
| 43 | + |
| 44 | + const scenario = this.service.get(id); |
| 45 | + |
| 46 | + if (this.contentNegotiation(req, ext) === 'application/yaml') { |
| 47 | + res.status(200).header('Content-Type', 'application/yaml').send(yaml.stringify(scenario)); |
| 48 | + } else { |
| 49 | + res.status(200).json(scenario); |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + @ApiOperation({ summary: 'Store a scenario' }) |
| 54 | + @ApiConsumes('application/json', 'application/yaml') |
| 55 | + @ApiBody({ required: true, schema: { type: 'object' } }) |
| 56 | + @ApiResponse({ status: 201, description: 'Created' }) |
| 57 | + @Post() |
| 58 | + async store(@Body() scenario: Scenario, @Req() req: Request, @Res() res: Response): Promise<void> { |
| 59 | + if (!validate(scenario)) { |
| 60 | + res.status(400).json(validate.errors); |
| 61 | + return; |
| 62 | + } |
| 63 | + |
| 64 | + const id = await this.service.store(scenario); |
| 65 | + |
| 66 | + res.status(201).setHeader('Location', `${req.url}/${id}`).send(); |
| 67 | + } |
| 68 | + |
| 69 | + @ApiOperation({ summary: 'Disable a scenario' }) |
| 70 | + @ApiParam({ name: 'id', description: 'Scenario ID', format: 'uuid' }) |
| 71 | + @ApiResponse({ status: 204, description: 'No Content' }) |
| 72 | + @Delete() |
| 73 | + async disable(@Param('id') id: string, @Res() res: Response): Promise<void> { |
| 74 | + await this.service.disable(id); |
| 75 | + res.status(201).send(); |
| 76 | + } |
| 77 | +} |
0 commit comments