import { IocContract } from '@adonisjs/fold/build' import { ConfigContract } from '@ioc:Adonis/Core/Config' import mime from 'mime' import buildJsDocConfig from './Utils/buildJsDocConfig' import swaggerJSDoc from 'swagger-jsdoc' import * as fs from 'fs' import { promises as fsp } from 'fs' import { Application } from '@adonisjs/application' import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' import { join } from 'path' import { ReadStream } from 'fs' export class SwaggerController { private config: ConfigContract private app: Application constructor(protected IoC: IocContract) { this.config = IoC.use('Adonis/Core/Config') this.app = this.IoC.use('Adonis/Core/Application') } public async swaggerUI({ params, response }: HttpContextContract) { const swaggerUiAssetPath = this.config.get('swagger.swaggerUiDistPath') || require('swagger-ui-dist').getAbsoluteFSPath() if (!params.fileName) { const baseUrl = this.config.get('swagger.uiUrl', '/docs').replace('/', '') return response.redirect(`/${baseUrl}/index.html`) } const fileName = params.fileName ? params.fileName : 'index.html' const path = join(swaggerUiAssetPath, fileName) const contentType = mime.getType(path) if (fileName.includes('initializer')) { const initializer = await fsp.readFile(path, 'utf-8') return response .header('Content-Type', contentType) .send( initializer.replace( 'https://petstore.swagger.io/v2/swagger.json', this.config.get('swagger.specUrl') ) ) } else { return response.header('Content-Type', contentType).stream(fs.createReadStream(path)) } } public async swaggerFile({ response }: HttpContextContract): Promise<void> { const mode = this.config.get('swagger.mode', 'RUNTIME') if (mode === 'RUNTIME') { response.send(swaggerJSDoc(buildJsDocConfig(this.config.get('swagger.options', {})))) } else { response .safeHeader('Content-type', 'application/json') .stream(this.getSwaggerSpecFileContent(), () => { return ['Unable to find file', 404] }) } } protected getSwaggerSpecFileContent(): ReadStream { const filePath = join(this.app.appRoot, this.config.get('swagger.specFilePath')) return fs.createReadStream(filePath) } }