Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

baucis-swagger2

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

baucis-swagger2 - npm Package Compare versions

Comparing version 0.1.2 to 0.1.3

test/utils.js

38

Api.js
// __Dependencies__
var url = require('url');
var deco = require('deco');
var utils = require('./utils');

@@ -9,12 +8,2 @@ // __Private Module Members__

// A method for capitalizing the first letter of a string
function capitalize (s) {
if (!s) {
return s;
}
if (s.length === 1) {
return s.toUpperCase();
}
return s[0].toUpperCase() + s.substring(1);
}

@@ -51,3 +40,3 @@ // Figure out the basePath for Swagger API definition

name: controller.model().singular(),
description: capitalize(controller.model().singular()) + ' resource.',
description: utils.capitalize(controller.model().singular()) + ' resource.',
'x-resource': true //custom extension to state this tag represent a resource

@@ -58,2 +47,3 @@ });

}
/* TODO. Move general params to a unique point of definition accordingly to Swagger 2.0
function getReusableParameters() {

@@ -65,11 +55,12 @@ return [];

}
*/
function buildPaths(controllers) {
var paths = {};
controllers.forEach(function (controller) {
var resourcePath = '/' + controller.model().plural();
controller.generateSwagger2();
for(var path in controller.swagger2.paths) {
paths[path] = controller.swagger2.paths[path];
var collection = controller.swagger2.paths;
for (var path in collection) {
if (collection.hasOwnProperty(path)) {
paths[path] = collection[path];
}
}

@@ -82,7 +73,8 @@ });

controllers.forEach(function (controller) {
var resourcePath = '/' + controller.model().plural();
controller.generateSwagger2();
for(var def in controller.swagger2.definitions) {
definitions[def] = controller.swagger2.definitions[def];
var collection = controller.swagger2.definitions;
for (var def in collection) {
if (collection.hasOwnProperty(def)) {
definitions[def] = collection[def];
}
}

@@ -147,3 +139,3 @@ definitions.ErrorModel = generateErrorModelDefinition();

// __Module Definition__
var decorator = module.exports = function (options, protect) {
module.exports = function (options, protect) {
var api = this;

@@ -150,0 +142,0 @@

@@ -5,18 +5,8 @@ // This is a Controller mixin to add methods for generating Swagger data.

var mongoose = require('mongoose');
var utils = require('./utils');
// __Private Members__
// A method for capitalizing the first letter of a string
function capitalize (s) {
if (!s) {
return s;
}
if (s.length === 1) {
return s.toUpperCase();
}
return s[0].toUpperCase() + s.substring(1);
}
// __Module Definition__
var decorator = module.exports = function () {
module.exports = function () {
var controller = this;

@@ -26,9 +16,4 @@

// Generate parameter list for operations
function generateParameters(isInstance, verb) {
var parameters = [];
// Parameters available for singular routes
if (isInstance) {
parameters.push({
function getParamId() {
return {
name: 'id',

@@ -39,5 +24,6 @@ in: 'path',

required: true
});
parameters.push({
};
}
function getParamXBaucisUpdateOperator() {
return {
name: 'X-Baucis-Update-Operator',

@@ -48,8 +34,6 @@ in: 'header',

required: false
});
}
// Parameters available for plural routes
if (!isInstance) {
parameters.push({
};
}
function getParamSkip() {
return {
name: 'skip',

@@ -61,5 +45,6 @@ in: 'query',

required: false
});
parameters.push({
};
}
function getParamLimit() {
return {
name: 'limit',

@@ -71,5 +56,6 @@ in: 'query',

required: false
});
parameters.push({
};
}
function getParamCount() {
return {
name: 'count',

@@ -80,5 +66,6 @@ in: 'query',

required: false
});
parameters.push({
};
}
function getParamConditions() {
return {
name: 'conditions',

@@ -89,5 +76,6 @@ in: 'query',

required: false
});
parameters.push({
};
}
function getParamSort() {
return {
name: 'sort',

@@ -98,7 +86,6 @@ in: 'query',

required: false
});
}
// Parameters available for singular and plural routes
parameters.push({
};
}
function getParamSelect() {
return {
name: 'select',

@@ -109,5 +96,6 @@ in: 'query',

required: false
});
parameters.push({
};
}
function getParamPopulate() {
return {
name: 'populate',

@@ -118,57 +106,48 @@ in: 'query',

required: false
});
if (verb === 'post') {
// TODO post body can be single or array
parameters.push({
};
}
function getParamDocument(isPost) {
// TODO post body can be single or array
return {
name: 'document',
in: 'body',
description: 'Create a document by sending the paths to be updated in the request body.',
description: (isPost) ?
'Create a document by sending the paths to be updated in the request body.' :
'Update a document by sending the paths to be updated in the request body.',
schema: {
$ref: '#/definitions/' + capitalize(controller.model().singular()),
$ref: '#/definitions/' + utils.capitalize(controller.model().singular()),
},
required: true
});
};
}
// Generate parameter list for operations
function generateParameters(isInstance, verb) {
var parameters = [];
// Parameters available for singular and plural routes
parameters.push(getParamSelect(),
getParamPopulate());
if (isInstance) {
// Parameters available for singular routes
parameters.push(getParamId(),
getParamXBaucisUpdateOperator());
}
else {
// Parameters available for plural routes
parameters.push(getParamSkip(),
getParamLimit(),
getParamCount(),
getParamConditions(),
getParamSort());
}
if (verb === 'post') {
parameters.push(getParamDocument(true));
}
if (verb === 'put') {
parameters.push({
name: 'document',
in: 'body',
description: 'Update a document by sending the paths to be updated in the request body.',
schema: {
$ref: '#/definitions/' + capitalize(controller.model().singular()),
},
required: true
});
parameters.push(getParamDocument(false));
}
return parameters;
}
function buildSemanticLabel(verb) {
if ("get"===verb || "head"===verb) {
return "query";
}
else if ("put"===verb || "patch"===verb) {
return "modify";
}
else if ("post"===verb) {
return "create";
}
else if ("delete"===verb) {
return "delete";
}
else if ("options"===verb) {
return "info";
}
else if ("trace"===verb) {
return "trace";
}
return null;
}
function buildTags(resourceName) {
var res = [
resourceName ];
return res;
return [ resourceName ];
}

@@ -188,3 +167,3 @@

schema: {
'$ref': '#/definitions/' + capitalize(resourceName)
'$ref': '#/definitions/' + utils.capitalize(resourceName)
}

@@ -213,3 +192,3 @@ };

function buildSecurityFor(isInstance, verb, resourceName) {
function buildSecurityFor() {
var security = [];

@@ -219,3 +198,8 @@ // TODO

}
function buildOperationInfo(res, operationId, summary, description) {
res.operationId = operationId;
res.summary = summary;
res.description = description;
return res;
}
function buildBaseOperation(mode, verb, resourceName, pluralName) {

@@ -228,22 +212,22 @@ var isInstance = (mode === 'instance');

responses: buildResponsesFor(isInstance, verb, resourceName, pluralName),
security: buildSecurityFor(isInstance, verb, resourceName),
security: buildSecurityFor(),
};
if (isInstance) {
if ('get' === verb) {
res.operationId = 'getById';
res.summary = 'Get a ' + resourceName + ' by its unique ID';
res.description = 'Retrieve a ' + resourceName + ' by its ID' + '.';
return res;
return buildOperationInfo(res,
'getById',
'Get a ' + resourceName + ' by its unique ID',
'Retrieve a ' + resourceName + ' by its ID' + '.');
}
else if ('put' === verb) {
res.operationId = 'update';
res.summary = 'Modify a ' + resourceName + ' by its unique ID';
res.description = 'Update an existing ' + resourceName + ' by its ID' + '.';
return res;
return buildOperationInfo(res,
'update',
'Modify a ' + resourceName + ' by its unique ID',
'Update an existing ' + resourceName + ' by its ID' + '.');
}
else if ('delete' === verb) {
res.operationId = 'deleteById';
res.summary = 'Delete a ' + resourceName + ' by its unique ID';
res.description = 'Deletes an existing ' + resourceName + ' by its ID' + '.';
return res;
return buildOperationInfo(res,
'deleteById',
'Delete a ' + resourceName + ' by its unique ID',
'Deletes an existing ' + resourceName + ' by its ID' + '.');
}

@@ -253,18 +237,18 @@ } else {

if ('get' === verb) {
res.operationId = 'query';
res.summary = 'Query some ' + pluralName;
res.description = 'Query over ' + pluralName + '.';
return res;
return buildOperationInfo(res,
'query',
'Query some ' + pluralName,
'Query over ' + pluralName + '.');
}
else if ('post' === verb) {
res.operationId = 'create';
res.summary = 'Create some ' + pluralName;
res.description = 'Create one or more ' + pluralName + '.';
return res;
return buildOperationInfo(res,
'create',
'Create some ' + pluralName,
'Create one or more ' + pluralName + '.');
}
else if ('delete' === verb) {
res.operationId = 'deleteByQuery';
res.summary = 'Delete some ' + pluralName + ' by query';
res.description = 'Delete all ' + pluralName + ' matching the specified query.';
return res;
return buildOperationInfo(res,
'deleteByQuery',
'Delete some ' + pluralName + ' by query',
'Delete all ' + pluralName + ' matching the specified query.');
}

@@ -275,5 +259,9 @@ }

function buildOperation(mode, verb, resourceName, pluralName) {
function buildOperation(containerPath, mode, verb) {
var resourceName = controller.model().singular();
var pluralName = controller.model().plural();
var operation = buildBaseOperation(mode, verb, resourceName, pluralName);
operation.tags = buildTags(resourceName);
containerPath[verb] = operation;
return operation;

@@ -315,17 +303,11 @@ }

}
// A method used to generated a Swagger property for a model
function generatePropertyDefinition (name, path, definitionName) {
var property = {};
var schema = controller.model().schema;
function skipProperty(name, path, controller) {
var select = controller.select();
var type = path.options.type ? swagger20TypeFor(path.options.type) : 'string'; // virtuals don't have type
var mode = (select && select.match(/(?:^|\s)[-]/g)) ? 'exclusive' : 'inclusive';
var exclusiveNamePattern = new RegExp('\\B-' + name + '\\b', 'gi');
var inclusiveNamePattern = new RegExp('(?:\\B[+]|\\b)' + name + '\\b', 'gi');
// Keep deselected paths private
if (path.selected === false) {
return;
return true;
}
// TODO is _id always included unless explicitly excluded?

@@ -335,9 +317,18 @@

if (select && mode === 'exclusive' && select.match(exclusiveNamePattern)) {
return;
return true;
}
// If the mode is inclusive but the name is not present, skip this one.
if (select && mode === 'inclusive' && name !== '_id' && !select.match(inclusiveNamePattern)) {
return true;
}
return false;
}
// A method used to generated a Swagger property for a model
function generatePropertyDefinition(name, path, definitionName) {
var property = {};
var type = path.options.type ? swagger20TypeFor(path.options.type) : 'string'; // virtuals don't have type
if (skipProperty(name, path, controller)) {
return;
}
// Configure the property

@@ -349,3 +340,3 @@ if (path.options.type === mongoose.Schema.Types.ObjectId) {

else if (path.options.ref) {
property.$ref = '#/definitions/'+capitalize(path.options.ref);
property.$ref = '#/definitions/' + utils.capitalize(path.options.ref);
}

@@ -358,3 +349,3 @@ }

//2. reference
$ref: '#/definitions/'+ definitionName + capitalize(name)
$ref: '#/definitions/'+ definitionName + utils.capitalize(name)
};

@@ -373,2 +364,3 @@ }

/*
// Set enum values if applicable

@@ -378,3 +370,2 @@ if (path.enumValues && path.enumValues.length > 0) {

}
// Set allowable values range if min or max is present

@@ -384,30 +375,24 @@ if (!isNaN(path.options.min) || !isNaN(path.options.max)) {

}
if (!isNaN(path.options.min)) {
// TODO: property.allowableValues.min = path.options.min;
}
if (!isNaN(path.options.max)) {
// TODO: property.allowableValues.max = path.options.max;
}
*/
if (!property.type && !property.$ref) {
console.log('Warning: That field type is not yet supported in baucis Swagger definitions, using "string."');
console.log('Path name: %s.%s', capitalize(controller.model().singular()), name);
console.log('Mongoose type: %s', path.options.type);
warnInvalidType(name, path);
property.type = 'string';
}
return property;
}
// A method used to generate a Swagger model definition for a controller
function generateModelDefinition (schema, definitionName) {
var definition = {};
function warnInvalidType(name, path) {
console.log('Warning: That field type is not yet supported in baucis Swagger definitions, using "string."');
console.log('Path name: %s.%s', utils.capitalize(controller.model().singular()), name);
console.log('Mongoose type: %s', path.options.type);
}
definition.required = [];
definition.properties = {};
Object.keys(schema.paths).forEach(function (name) {
var path = schema.paths[name];
function mergePaths(definition, pathsCollection, definitionName) {
Object.keys(pathsCollection).forEach(function (name) {
var path = pathsCollection[name];
var property = generatePropertyDefinition(name, path, definitionName);

@@ -419,22 +404,20 @@ definition.properties[name] = property;

});
Object.keys(schema.virtuals).forEach(function (name) {
var path = schema.virtuals[name];
var property = generatePropertyDefinition(name, path, definitionName);
definition.properties[name] = property;
if (path.options.required) {
definition.required.push(name);
}
});
}
// A method used to generate a Swagger model definition for a controller
function generateModelDefinition (schema, definitionName) {
var definition = {
required: [],
properties: {}
};
mergePaths(definition, schema.paths, definitionName);
mergePaths(definition, schema.virtuals, definitionName);
return definition;
}
function addInnerModelDefinitions(defs, definitionName) {
var schema = controller.model().schema;
Object.keys(schema.paths).forEach(function (name) {
var path = schema.paths[name];
function mergePathsForInnerDef(defs, collectionPaths, definitionName) {
Object.keys(collectionPaths).forEach(function (name) {
var path = collectionPaths[name];
if (path.schema) {
var newdefinitionName = definitionName + capitalize(name); //<-- synthetic name (no info for this in input model)
var newdefinitionName = definitionName + utils.capitalize(name); //<-- synthetic name (no info for this in input model)
var def = generateModelDefinition(path.schema, newdefinitionName);

@@ -444,11 +427,8 @@ defs[newdefinitionName] = def;

});
}
Object.keys(schema.virtuals).forEach(function (name) {
var path = schema.virtuals[name];
if (path.schema) {
var newdefinitionName = definitionName + capitalize(name); //<-- synthetic name (no info for this in input model)
var def = generateModelDefinition(path.schema, newdefinitionName);
defs[newdefinitionName] = def;
}
});
function addInnerModelDefinitions(defs, definitionName) {
var schema = controller.model().schema;
mergePathsForInnerDef(defs, schema.paths, definitionName);
mergePathsForInnerDef(defs, schema.virtuals, definitionName);
}

@@ -462,3 +442,3 @@

var modelName = capitalize(controller.model().singular());
var modelName = utils.capitalize(controller.model().singular());

@@ -471,4 +451,3 @@ controller.swagger2 = { paths: {}, definitions: {} };

// Instance path
var resourceName = controller.model().singular();
// Paths
var pluralName = controller.model().plural();

@@ -480,12 +459,10 @@

var paths = {};
paths[instancePath] = {
'get': buildOperation('instance', 'get', resourceName, pluralName),
'put': buildOperation('instance', 'put', resourceName, pluralName),
'delete': buildOperation('instance', 'delete', resourceName, pluralName)
};
paths[collectionPath] = {
'get': buildOperation('collection', 'get', resourceName, pluralName),
'post': buildOperation('collection', 'post', resourceName, pluralName),
'delete': buildOperation('collection', 'delete', resourceName, pluralName),
};
paths[instancePath] = {};
paths[collectionPath] = {};
buildOperation(paths[instancePath], 'instance', 'get');
buildOperation(paths[instancePath], 'instance', 'put');
buildOperation(paths[instancePath], 'instance', 'delete');
buildOperation(paths[collectionPath], 'collection', 'get');
buildOperation(paths[collectionPath], 'collection', 'post');
buildOperation(paths[collectionPath], 'collection', 'delete');
controller.swagger2.paths = paths;

@@ -492,0 +469,0 @@

{
"name": "baucis-swagger2",
"version": "0.1.2",
"version": "0.1.3",
"description": "Generate customizable swagger version 2.0 definitions for your Baucis REST API.",

@@ -16,3 +16,3 @@ "homepage": "https://github.com/icinetic/baucis-swagger2",

"pretest": "npm install",
"test": "mocha --bail --timeout 5000 -R spec"
"test": "istanbul cover node_modules/mocha/bin/_mocha -- --bail --timeout 5000 -R spec"
},

@@ -47,4 +47,6 @@ "author": {

"baucis": "^1.1.1",
"codeclimate-test-reporter": "0.0.4",
"expect.js": "~0.3.1",
"express": "~4.12.3",
"istanbul": "^0.3.13",
"mocha": "~2.2.4",

@@ -51,0 +53,0 @@ "mongoose": "~3.8.23",

@@ -9,2 +9,5 @@ baucis-swagger2

[![NPM](https://nodei.co/npm/baucis-swagger2.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/baucis-swagger2/)
This module generates customizable swagger 2.0 definitions for your Baucis API.

@@ -11,0 +14,0 @@ Use this module in conjunction with [Baucis](https://github.com/wprl/baucis).

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc