UNPKG

fastify-openapi-glue

Version:

generate a fastify configuration from an openapi specification

161 lines (152 loc) 3.4 kB
// a class for parsing openapi V2 data into config data for fastify import { ParserBase } from "./ParserBase.js"; const paramSchemaProps = [ "type", "description", "format", "allowEmptyValue", "items", "collectionFormat", "default", "maximum", "exclusiveMaximum", "minimum", "exclusiveMinimum", "maxLength", "minLength", "pattern", "maxItems", "minItems", "uniqueItems", "enum", "multipleOf", ]; export class ParserV2 extends ParserBase { parseParams(data) { const params = { type: "object", properties: {}, }; const required = []; for (const item of data) { // item.type "file" breaks ajv, so treat is as a special here if (item.type === "file") { item.type = "string"; item.isFile = true; } // params.properties[item.name] = {}; this.copyProps(item, params.properties[item.name], paramSchemaProps); // ajv wants "required" to be an array, which seems to be too strict // see https://github.com/json-schema/json-schema/wiki/Properties-and-required if (item.required) { required.push(item.name); } } if (required.length > 0) { params.required = required; } return params; } parseParameters(schema, data) { const params = []; const querystring = []; const headers = []; const formData = []; for (const item of data) { switch (item.in) { case "body": { schema.body = item.schema; break; } case "formData": { formData.push(item); break; } case "path": { params.push(item); break; } case "query": { querystring.push(item); break; } case "header": { headers.push(item); break; } } } if (params.length > 0) { schema.params = this.parseParams(params); } if (querystring.length > 0) { schema.querystring = this.parseParams(querystring); } if (headers.length > 0) { schema.headers = this.parseParams(headers); } if (formData.length > 0) { schema.body = this.parseParams(formData); } } parseResponses(responses) { const result = {}; for (const httpCode in responses) { if (responses[httpCode].schema !== undefined) { result[httpCode] = responses[httpCode].schema; continue; } if (this.options.addEmptySchema) { result[httpCode] = {}; } } return result; } makeSchema(genericSchema, data) { const schema = Object.assign({}, genericSchema); const copyItems = [ "tags", "summary", "description", "operationId", "produces", "consumes", "deprecated", ]; this.copyProps(data, schema, copyItems, true); if (data.parameters) { this.parseParameters(schema, data.parameters); } const response = this.parseResponses(data.responses); if (Object.keys(response).length > 0) { schema.response = response; } // remove loops from the schema so fastify wont break this.removeRecursion(schema); return schema; } parse(spec, options) { this.spec = spec; this.options = { addEmptySchema: options.addEmptySchema ?? false, }; for (const item in spec) { switch (item) { case "paths": { this.processPaths(spec.paths); break; } case "basePath": this.config.prefix = spec[item]; break; case "securityDefinitions": this.config.securitySchemes = spec[item]; break; default: this.config.generic[item] = spec[item]; } } return this.config; } }