baucis-swagger2
Version:
Generate customizable swagger version 2.0 definitions for your Baucis REST API.
208 lines (186 loc) • 5.3 kB
JavaScript
// __Dependencies__
var utils = require('./utils');
var params = require('./parameters');
// __Private Module Members__
//Follows Swagger 2.0: as described in https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md
// Figure out the basePath for Swagger API definition
function getBase (request, extra) {
var parts = request.originalUrl.split('/');
// Remove extra path parts.
parts.splice(-extra, extra);
var base = parts.join('/');
return base;
}
function generateValidationErrorDefinition() {
var def = {
required: ['message', 'name', 'kind', 'path'],
properties: {
properties: {
'$ref': '#/definitions/ValidationErrorProperties'
},
message: {
type: 'string'
},
name: {
type: 'string'
},
kind: {
type: 'string'
},
path: {
type: 'string'
}
}
};
return def;
}
function generateValidationErrorPropertiesDefinition() {
var def = {
required: ['type', 'message', 'path'],
properties: {
type: {
type: 'string'
},
message: {
type: 'string'
},
path: {
type: 'string'
}
}
};
return def;
}
function buildTags(options) {
var tags = [];
options.controllers.forEach(function (controller) {
tags.push({
name: controller.model().singular(),
description: utils.capitalize(controller.model().singular()) + ' resource.',
'x-resource': true //custom extension to state this tag represent a resource
});
});
return tags;
}
function buildPaths(controllers) {
var paths = {};
controllers.forEach(function (controller) {
controller.generateSwagger2();
var collection = controller.swagger2.paths;
for (var path in collection) {
if (collection.hasOwnProperty(path)) {
paths[path] = collection[path];
}
}
});
return paths;
}
function buildDefinitions(controllers) {
var definitions = {};
controllers.forEach(function (controller) {
controller.generateSwagger2();
var collection = controller.swagger2.definitions;
for (var def in collection) {
if (collection.hasOwnProperty(def)) {
definitions[def] = collection[def];
}
}
definitions.ValidationError = generateValidationErrorDefinition();
definitions.ValidationErrorProperties = generateValidationErrorPropertiesDefinition();
});
return definitions;
}
// A method for generating a Swagger resource listing
function generateResourceListing (options) {
var controllers = options.controllers;
var opts = options.options || {};
var paths = buildPaths(controllers);
var definitions = buildDefinitions(controllers);
var listing = {
swagger: '2.0',
info: {
description: 'Baucis generated API',
version: options.version,
title: 'api',
//termsOfService: 'TOS: to be defined.',
//contact: {
// email: 'me@address.com'
//},
//license: {
// name: 'TBD',
// url: 'http://license.com'
//}
},
//host: null,
basePath: options.basePath,
tags: buildTags(options),
schemes: ['http', 'https'],
consumes: ['application/json'],
produces: ['application/json', 'text/html'],
paths: paths,
definitions: definitions,
parameters: params.generateCommonParams()
//responses: getReusableResponses(),
//securityDefinitions: {},
//security: [] // Must be added via extensions
//externalDocs: null
};
if (opts.security) {
listing.security = opts.security;
}
if (opts.securityDefinitions) {
listing.securityDefinitions = opts.securityDefinitions;
}
return listing;
}
//build an specific spec based on options and filtered controllers
function generateResourceListingForVersion(options) {
var clone = JSON.parse(JSON.stringify(options.rootDocument));
clone.info.version = options.version;
clone.basePath = options.basePath;
clone.paths = clone.paths || {};
clone.definitions = clone.definitions || {};
mergeIn(clone.paths, buildPaths(options.controllers));
mergeIn(clone.definitions, buildDefinitions(options.controllers));
return clone;
}
function mergeIn(container, items) {
if (!items) {
return;
}
for(var key in items) {
if (items.hasOwnProperty(key)) {
container[key] = items[key];
}
}
}
// __Module Definition__
module.exports = function (options, protect) {
var api = this;
api.generateSwagger2 = function() {
//user can extend this swagger2Document
api.swagger2Document = generateResourceListing({
version: null,
controllers: protect.controllers('0.0.1'),
basePath: null,
options: options
});
return api;
};
// Middleware for the documentation index.
api.get('/swagger.json', function (request, response) {
if (!api.swagger2Document) {
api.generateSwagger2();
}
//Customize a swagger2Document copy by requested version
var versionedApi = generateResourceListingForVersion({
rootDocument: api.swagger2Document,
version: request.baucis.release,
controllers: protect.controllers(request.baucis.release),
basePath: getBase(request, 1),
options: options
});
response.json(versionedApi);
});
return api;
};