Comparing version 0.6.9 to 0.6.10
@@ -19,3 +19,2 @@ // __Dependencies__ | ||
var controller = express(); | ||
var initialized = false; | ||
var model = mongoose.model(options.singular); | ||
@@ -43,4 +42,4 @@ var findByPath; | ||
// Mixins | ||
mixins.middleware.call(controller); | ||
mixins.swagger.call(controller); | ||
mixins.middleware.apply(controller); | ||
mixins.swagger.apply(controller); | ||
@@ -52,10 +51,2 @@ // Return the array of active verbs | ||
}); | ||
} | ||
// A method used to intialize the controller and activate user middleware. It | ||
// may be called multiple times, but will trigger intialization only once. | ||
controller.initialize = function () { | ||
if (initialized) return controller; | ||
controller.activate(); | ||
return controller; | ||
}; | ||
@@ -62,0 +53,0 @@ |
119
index.js
@@ -10,24 +10,12 @@ // __Dependencies__ | ||
function swaggerTypeFor (type) { | ||
if (type === String) return 'string'; | ||
if (type === Number) return 'double'; | ||
if (type === Date) return 'Date'; | ||
if (type === mongoose.Schema.Types.Buffer) throw new Error('Not implemented'); | ||
if (type === Boolean) return 'boolean'; | ||
if (type === mongoose.Schema.Types.Mixed) throw new Error('Not implemented'); | ||
if (type === mongoose.Schema.Types.ObjectId) return 'string'; | ||
if (type === mongoose.Schema.Types.Oid) return 'string'; | ||
if (type === mongoose.Schema.Types.Array) return 'Array'; | ||
throw new Error('Unrecognized type:' + type); | ||
}; | ||
// 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); | ||
// Figure out the basePath for Swagger API definition | ||
function getBase (request, extra) { | ||
var url = request.originalUrl; | ||
var split = url.split('/'); | ||
while (extra) extra--, split.pop(); | ||
return request.protocol + '://' + request.headers.host + split.join('/'); | ||
} | ||
// A method for generating a Swagger resource listing | ||
function generateResourceListing () { | ||
function generateResourceListing (options) { | ||
var plurals = this.get('controllers').map(function (controller) { | ||
@@ -37,5 +25,5 @@ return controller.get('plural'); | ||
var listing = { | ||
apiVersion: '0.0.1', // TODO | ||
apiVersion: options.version, | ||
swaggerVersion: '1.1', | ||
basePath: 'http://127.0.0.1:8012/api/v1', // TODO | ||
basePath: options.basePath, | ||
apis: plurals.map(function (plural) { | ||
@@ -49,89 +37,6 @@ return { path: '/api-docs/' + plural, description: 'Operations about ' + plural + '.' }; | ||
// A method used to generate a Swagger model definition for a controller | ||
function generateModelDefinition (controller) { | ||
var definition = {}; | ||
var schema = controller.get('schema'); | ||
definition.id = capitalize(controller.get('singular')); | ||
definition.properties = {}; | ||
Object.keys(schema.paths).forEach(function (name) { | ||
var property = {}; | ||
var path = schema.paths[name]; | ||
if (path.selected === false) return; | ||
// TODO also check controller options | ||
property.type = swaggerTypeFor(path.options.type); | ||
property.required = path.options.required || (name === '_id'); | ||
// Set enum values if applicable | ||
if (path.enumValues && path.enumValues.length > 0) { | ||
property.allowableValues = { valueType: 'LIST', values: path.enumValues }; | ||
} | ||
// Set allowable values range if min or max is present | ||
if (!isNaN(path.options.min) || !isNaN(path.options.max)) { | ||
property.allowableValues = { valueType: 'RANGE' }; | ||
} | ||
if (!isNaN(path.options.min)) { | ||
property.allowableValues.min = path.options.min; | ||
} | ||
if (!isNaN(path.options.max)) { | ||
property.allowableValues.max = path.options.max; | ||
} | ||
definition.properties[name] = property; | ||
}); | ||
return definition; | ||
} | ||
// A method used to generate a Swagger API definition for a controller | ||
function generateApiDefinition (controller, plural) { | ||
var definition = {}; | ||
definition.path = '/' + controller.get('plural'); | ||
if (plural) definition.path += '/{id}'; | ||
if (plural) definition.description = 'Operations about a given ' + controller.get('singular'); | ||
else definition.description = 'Operations about ' + controller.get('plural'); | ||
definition.operations = []; | ||
controller.activeVerbs().forEach(function (verb) { | ||
var operation = {}; | ||
var titlePlural = capitalize(controller.get('plural')); | ||
var titleSingular = capitalize(controller.get('singular')); | ||
// Don't do post/put for single/plural | ||
if (verb === 'post' && !plural) return; | ||
if (verb === 'put' && plural) return; | ||
operation.httpMethod = verb.toUpperCase(); | ||
if (plural) operation.nickname = verb + titlePlural; | ||
else operation.nickname = verb + titleSingular + 'ById'; | ||
if (plural) operation.responseClass = [ titleSingular ]; | ||
else operation.responseClass = titleSingular; | ||
operation.parameters = []; // TODO | ||
if (plural) operation.summary = capitalize(verb) + ' some ' + controller.get('plural'); | ||
else operation.summary = capitalize(verb) + ' a ' + controller.get('singular') + ' by its unique ID'; | ||
operation.errorResponses = []; // TODO 404 | ||
definition.operations.push(operation); | ||
}); | ||
return definition; | ||
} | ||
// __Module Definition__ | ||
var baucis = module.exports = function (options) { | ||
options || (options = {}); | ||
options.version = options.version || '0.0.1'; | ||
@@ -152,3 +57,3 @@ var app = express(); | ||
app.get('/api-docs', function (request, response, next) { | ||
response.json(app.generateResourceListing()); | ||
response.json(app.generateResourceListing({ version: options.version, basePath: getBase(request, 1) })); | ||
}); | ||
@@ -164,3 +69,3 @@ } | ||
app.get('/api-docs' + route, function (request, response, next) { | ||
response.json(controller.generateApiDefinition()); | ||
response.json(controller.generateApiDefinition({ version: options.version, basePath: getBase(request, 2) })); | ||
}); | ||
@@ -167,0 +72,0 @@ } |
@@ -25,3 +25,3 @@ // This is a Controller mixin for adding methods to manage middleware creation. | ||
// Parse middleware | ||
// Parse middleware into an array of middleware definitions for each howMany and verb | ||
function factor (stage, options) { | ||
@@ -75,3 +75,3 @@ if (!stage) throw new Error('Must supply stage.'); | ||
// Flags whether the custom middleware has been activated | ||
var activated = false; | ||
var initialized = false; | ||
// A hash for storing user middleware | ||
@@ -95,3 +95,3 @@ var custom = { | ||
function register (stage, howMany, verbs, middleware) { | ||
if (activated) { | ||
if (initialized) { | ||
throw new Error("Can't add middleware after the controller has been activated."); | ||
@@ -119,3 +119,3 @@ } | ||
function activate (stage, howMany, verbs, middleware) { | ||
if (activated) throw new Error("Can't activate middleware after the controller has been activated."); | ||
if (initialized) throw new Error("Can't activate middleware after the controller has been activated."); | ||
@@ -163,4 +163,4 @@ var options = last(1, ['howMany', 'verbs', 'middleware'], arguments); | ||
// may be called multiple times, but will trigger intialization only once. | ||
controller.activate = function () { | ||
if (activated) return controller; | ||
controller.initialize = function () { | ||
if (initialized) return controller; | ||
@@ -221,5 +221,5 @@ // __Request-Stage Middleware__ | ||
delete custom; | ||
activated = true; | ||
initialized = true; | ||
return controller; | ||
}; | ||
}; |
@@ -257,8 +257,8 @@ // This is a Controller mixin to add methods for generating Swagger data. | ||
// A method used to generate a Swagger API definition for a controller | ||
this.generateApiDefinition = function () { | ||
this.generateApiDefinition = function (options) { | ||
var modelName = capitalize(this.get('singular')); | ||
var definition = { | ||
apiVersion: '0.0.1', // TODO | ||
apiVersion: options.version, | ||
swaggerVersion: '1.1', | ||
basePath: 'http://127.0.0.1:8012/api/v1', // TODO | ||
basePath: options.basePath, | ||
resourcePath: '/' + this.get('plural'), | ||
@@ -265,0 +265,0 @@ apis: [], |
@@ -5,3 +5,3 @@ { | ||
"homepage": "https://github.com/wprl/baucis", | ||
"version": "0.6.9", | ||
"version": "0.6.10", | ||
"main": "index.js", | ||
@@ -8,0 +8,0 @@ "scripts": { |
@@ -1,3 +0,3 @@ | ||
baucis v0.6.9 | ||
============= | ||
baucis v0.6.10 | ||
============== | ||
@@ -4,0 +4,0 @@ Baucis is Express middleware that creates configurable REST APIs using Mongoose schemata. |
@@ -27,3 +27,3 @@ var expect = require('expect.js'); | ||
var options = { | ||
url: 'http://localhost:8012/api/v1/api-docs', | ||
url: 'http://127.0.0.1:8012/api/v1/api-docs', | ||
json: true | ||
@@ -52,3 +52,3 @@ }; | ||
var options = { | ||
url: 'http://localhost:8012/api/v1/api-docs/vegetables', | ||
url: 'http://127.0.0.1:8012/api/v1/api-docs/vegetables', | ||
json: true | ||
@@ -99,4 +99,7 @@ }; | ||
it('should generate models correctly'); | ||
it('should generate documentation for each controller'); | ||
it('should keep paths deselected in the schema private'); | ||
it('should keep paths deselected in the controller private'); | ||
}); |
465747
2494