import { HttpMethod } from '../http'; import { SwaggerParameter } from './SwaggerParameterType'; import { SwaggerRequestBody } from './SwaggerRequestBodyType'; import { SwaggerResponse } from './SwaggerResponseType'; import { SwaggerSchema } from './SwaggerSchemaType'; class SwaggerDoc { private method: HttpMethod; private route?: string; private summary?: string; private description?: string; private requestBody?: SwaggerRequestBody; private parameters: SwaggerParameter[] = []; private responses: SwaggerResponse[] = []; public static get(route: string): SwaggerDoc { return new SwaggerDoc(HttpMethod.GET).setRoute(route); } public static post(route: string): SwaggerDoc { return new SwaggerDoc(HttpMethod.POST).setRoute(route); } private constructor(method: HttpMethod) { this.method = method; } private setRoute(route: string): SwaggerDoc { this.route = route; return this; } public setSummary(summary: string): SwaggerDoc { this.summary = summary; return this; } public setDescription(description: string): SwaggerDoc { this.description = description; return this; } public setRequestBody(requestBody: SwaggerRequestBody): SwaggerDoc { this.requestBody = requestBody; return this; } public addParameter(param: SwaggerParameter): SwaggerDoc { this.parameters.push(param); return this; } public addResponse(res: SwaggerResponse): SwaggerDoc { this.responses.push(res); return this; } public toAnnotation(): string { let annotation = '/**\n'; annotation += ' *\t@swagger\n'; annotation += ` *\t${this.route}:\n`; annotation += ` *\t\t${this.getMethod()}:\n`; if(this.summary) annotation += ` *\t\t\tsummary: ${this.summary}\n`; if(this.description) annotation += ` *\t\t\tdescription: ${this.description}\n`; if(this.parameters.length > 0) { annotation += ' *\t\t\tparameters:\n'; for(const param of this.parameters) { annotation += ` *\t\t\t- in: ${param.in}\n`; annotation += ` *\t\t\t name: ${param.name}\n`; annotation += ` *\t\t\t required: ${param.required}\n`; annotation += ` *\t\t\t description: ${param.description}\n`; if(param.schema) { annotation += ' *\t\t\t schema:\n'; annotation += this.deserializeSchema(param.schema, 4); } } } if(this.requestBody) { annotation += ' *\t\t\trequestBody:\n'; annotation += ` *\t\t\t\trequired: ${this.requestBody.required}`; annotation += ` *\t\t\t\tdescription: ${this.requestBody.description}\n`; annotation += ' *\t\t\t\tcontent:\n'; annotation += ` *\t\t\t\t\t${this.requestBody.content.mediaType}:\n`; annotation += ' *\t\t\t\t\t\tschema:\n'; annotation += this.deserializeSchema(this.requestBody.content.schema, 6); } if(this.responses.length > 0) { annotation += ' *\t\t\tresponses:\n'; for(const res of this.responses) { annotation += ` *\t\t\t\t${res.code}:\n`; annotation += ` *\t\t\t\t\tdescription: ${res.description}\n`; if(res.content) { annotation += ' *\t\t\t\t\tcontent:\n'; annotation += ` *\t\t\t\t\t\t${res.content.mediaType}:\n`; annotation += ' *\t\t\t\t\t\t\tschema:\n'; annotation += this.deserializeSchema(res.content.schema, 7); } } } annotation += ' */\n'; return annotation.replace(/\t/g, ' '); } private getMethod(): string { switch(this.method) { case HttpMethod.GET: return 'get'; case HttpMethod.POST: return 'post'; default: return 'undefined'; } } private deserializeSchema(schema: SwaggerSchema, level: number): string { let res = ''; const indent = ' *' + this.repeatStr('\t', level + 1); res += indent + `type: ${schema.type}\n`; if(schema.description) res += indent + `description: ${schema.description}\n`; if(schema.example) res += indent + `example: ${schema.example}\n`; if(schema.items && schema.items.length > 0) { res += indent + 'items:\n'; for(const item of schema.items) { res += this.deserializeSchema(item, level + 2); } } if(schema.properties && Object.keys(schema.properties).length > 0) { res += indent + 'properties:\n'; for(const key of Object.keys(schema.properties)) { res += indent + '\t' + `${key}:\n`; res += this.deserializeSchema(schema.properties[key], level + 3); } } return res; } private repeatStr(str: string, n: number): string { let res = ''; for(let i = 0; i < n; i++) res += str; return res; } } export { SwaggerDoc };