UNPKG

swagger-parser-mock

Version:

一个简单的 Swagger 文档解析器,支持生成演示数据与数据实体类

174 lines (151 loc) 4.66 kB
var URL = require('url') var memoizee = require('memoizee') var swagger = require('swagger-client') var swaggerTools = require('swagger-tools').specs.v1 var utils = require('./utils') var primitives = require('./primitives') function primitive (schema) { schema = utils.objectify(schema) var type = schema.type var format = schema.format var value = primitives[type + '_' + format] || primitives[type] if (typeof schema.example === 'undefined') { return value || 'Unknown Type: ' + schema.type } return schema.example } function sampleFromSchema (schema) { schema = utils.objectify(schema) var type = schema.type var properties = schema.properties var additionalProperties = schema.additionalProperties var items = schema.items if (!type) { if (properties) { type = 'object' } else if (items) { type = 'array' } else { return } } if (type === 'object') { var props = utils.objectify(properties) var obj = {} for (var name in props) { obj[name] = sampleFromSchema(props[name]) } if (additionalProperties === true) { obj.additionalProp1 = {} } else if (additionalProperties) { var additionalProps = utils.objectify(additionalProperties) var additionalPropVal = sampleFromSchema(additionalProps) for (var i = 1; i < 4; i++) { obj['additionalProp' + i] = additionalPropVal } } return obj } if (type === 'array') { return [sampleFromSchema(items)] } if (schema['enum']) { if (schema['default']) return schema['default'] return utils.normalizeArray(schema['enum'])[0] } if (type === 'file') { return } return primitive(schema) } var memoizedSampleFromSchema = memoizee(sampleFromSchema) function getSampleSchema (schema) { return JSON.stringify(memoizedSampleFromSchema(schema), null, 2) } /** * 处理 1.x 文档中,array 类型下 items.type 无法解析 model 的问题 * * { a: { type: 'array', items: { type: 'Pet' } }, models: { Pet: {} } } * => * { a: { type: 'array', items: { $ref: 'Pet' } }, models: { Pet: {} } } * * @param {*} obj * @param {*} models */ function renameTypeKey (obj, models) { models = models || {} if (!obj || (obj && typeof obj !== 'object')) return Object.keys(obj).forEach(key => { const value = obj[key] if (value && typeof value === 'object') { renameTypeKey(value, models) } if (key === 'type' && value === 'array' && obj.items && obj.items.type && models[obj.items.type]) { obj.items.$ref = obj.items.type delete obj.items.type } }) } var parser = module.exports = function (url, opts) { opts = opts || {} if (typeof url === 'string') { opts.url = url } else { opts = url } return swagger(opts).then(function (res) { var spec = res.spec var isOAS3 = spec.openapi && spec.openapi === '3.0.0' if (spec.swaggerVersion) { // v1 var paths = spec.apis.map(function (api) { var baseUrl = res.url if (!/\.json$/.test(baseUrl)) { baseUrl += '/' } opts.url = URL.resolve(baseUrl, api.path.replace(/^\//, '')) return swagger(opts) }) return Promise.all(paths).then(function (apis) { var specs = apis.map(function (o) { return o.spec }) return new Promise(function (resolve, reject) { for (let spec of specs) { renameTypeKey(spec, spec.models) } swaggerTools.convert(spec, specs, true, function (error, docs) { if (error) return reject(error) resolve(parser({ spec: docs })) }) }) }) } else { for (var path in spec.paths) { for (var method in spec.paths[path]) { var api = spec.paths[path][method] var schema for (var code in api.responses) { var response = api.responses[code] if (isOAS3) { schema = response.content && response.content['application/json'] && utils.inferSchema(response.content['application/json']) response.example = schema ? getSampleSchema(schema) : null } else { schema = utils.inferSchema(response) response.example = schema ? getSampleSchema(schema) : null } } if (!api.parameters) continue for (var parameter of api.parameters) { schema = utils.inferSchema(parameter) parameter.example = schema ? getSampleSchema(schema) : null } } } } return spec }) }