diff --git a/lib/exports-helper.js b/lib/exports-helper.js index 4199ee1d..65bd40e5 100644 --- a/lib/exports-helper.js +++ b/lib/exports-helper.js @@ -12,7 +12,7 @@ var debug = require('debug')('strong-remoting:exports-helper'); /*! * Constants */ -var PASSTHROUGH_OPTIONS = ['http', 'description']; +var PASSTHROUGH_OPTIONS = ['http', 'description', 'notes']; /** * @class A wrapper to make manipulating the exports object easier. @@ -112,6 +112,7 @@ function method(fn, options) { var path = options.path || options.name || fn.name || null; var accepts = options.accepts || null; var returns = options.returns || null; + var errors = options.errors || null; if (!path) { // TODO: Error. @@ -122,6 +123,7 @@ function method(fn, options) { fn.shared = true; fn.accepts = accepts; fn.returns = returns; + fn.errors = errors; PASSTHROUGH_OPTIONS.forEach(function (key) { if (options[key]) { diff --git a/lib/http-context.js b/lib/http-context.js index a0a09430..6451bd8b 100644 --- a/lib/http-context.js +++ b/lib/http-context.js @@ -47,6 +47,7 @@ HttpContext.prototype.buildArgs = function (method) { var ctx = this; var accepts = method.accepts; var returns = method.returns; + var errors = method.errors; // build arguments from req and method options accepts.forEach(function (o) { diff --git a/lib/http-invocation.js b/lib/http-invocation.js index 081baa38..c59df7aa 100644 --- a/lib/http-invocation.js +++ b/lib/http-invocation.js @@ -81,6 +81,7 @@ HttpInvocation.prototype.createRequest = function () { var req = {json: true, method: verb || 'GET'}; var accepts = method.accepts; var returns = method.returns; + var errors = method.errors; var query; // initial url is the format @@ -176,6 +177,7 @@ HttpInvocation.prototype.transformResponse = function(res, body, callback) { var callbackArgs = [null]; // null => placeholder for err var method = this.method; var returns = method.returns; + var errors = method.errors; var isObject = typeof body === 'object'; var err; var hasError = res.statusCode >= 400; diff --git a/lib/jsonrpc-adapter.js b/lib/jsonrpc-adapter.js index e68bf651..3f4228b7 100644 --- a/lib/jsonrpc-adapter.js +++ b/lib/jsonrpc-adapter.js @@ -204,9 +204,11 @@ JsonRpcAdapter.prototype.allRoutes = function () { verb: verb, path: path, description: method.description, + notes: method.notes, method: method.stringName, accepts: (method.accepts && method.accepts.length) ? method.accepts : undefined, - returns: (method.returns && method.returns.length) ? method.returns : undefined + returns: (method.returns && method.returns.length) ? method.returns : undefined, + errors: (method.errors && method.errors.length) ? method.errors : undefined }); } }; diff --git a/lib/remote-objects.js b/lib/remote-objects.js index 2ac629ca..541958a9 100644 --- a/lib/remote-objects.js +++ b/lib/remote-objects.js @@ -205,7 +205,8 @@ RemoteObjects.prototype.toJSON = function () { result[sharedMethod.stringName] = { http: sharedMethod.fn && sharedMethod.fn.http, accepts: sharedMethod.accepts, - returns: sharedMethod.returns + returns: sharedMethod.returns, + errors: sharedMethod.errors }; }); diff --git a/lib/rest-adapter.js b/lib/rest-adapter.js index 596e90e4..d04438a1 100644 --- a/lib/rest-adapter.js +++ b/lib/rest-adapter.js @@ -367,9 +367,11 @@ RestAdapter.prototype.allRoutes = function () { verb: verb, path: path, description: method.description, + notes: method.notes, method: method.stringName, accepts: (method.accepts && method.accepts.length) ? method.accepts : undefined, - returns: (method.returns && method.returns.length) ? method.returns : undefined + returns: (method.returns && method.returns.length) ? method.returns : undefined, + errors: (method.errors && method.errors.length) ? method.errors : undefined }); } } @@ -420,7 +422,9 @@ function RestMethod(restClass, sharedMethod) { this.accepts = sharedMethod.accepts; this.returns = sharedMethod.returns; + this.errors = sharedMethod.errors; this.description = sharedMethod.description; + this.notes = sharedMethod.notes; var methodRoutes = getRoutes(sharedMethod); if (sharedMethod.isStatic || !restClass.ctor) { diff --git a/lib/shared-class.js b/lib/shared-class.js index 4c05ee76..5649fef4 100644 --- a/lib/shared-class.js +++ b/lib/shared-class.js @@ -126,6 +126,7 @@ function define(methods, name, options, fn) { * define('myMethod', { * accepts: {arg: 'str', type: 'string'}, * returns: {arg: 'str', type: 'string'} + * errors: [ { code: 404, message: 'Not Found', responseModel: 'Error' } ] * }, myMethod); * }); * function myMethod(str, cb) { diff --git a/lib/shared-method.js b/lib/shared-method.js index 7bc7c27e..9ebb949e 100644 --- a/lib/shared-method.js +++ b/lib/shared-method.js @@ -18,11 +18,12 @@ var EventEmitter = require('events').EventEmitter /** * Create a new `SharedMethod` with the given `fn`. * - * @param {Function} fn + * @param {Function} fn The `Function` to be invoked when the method is invoked * @param {Function} name - * @param {SharedClass} SharedClass + * @param {SharedClass} sharedClass The `SharedClass` the method will be + * attached to * @param {Boolean} isStatic - * @class + * @class SharedMethod */ function SharedMethod(fn, name, sc, options) { @@ -38,7 +39,9 @@ function SharedMethod(fn, name, sc, options) { var isStatic = this.isStatic = options.isStatic || false; this.accepts = options.accepts || fn.accepts || []; this.returns = options.returns || fn.returns || []; + this.errors = options.errors || fn.errors || []; this.description = options.description || fn.description; + this.notes = options.notes || fn.notes; this.http = options.http || fn.http || {}; this.rest = options.rest || fn.rest || {}; this.shared = options.shared; @@ -64,6 +67,9 @@ function SharedMethod(fn, name, sc, options) { if(this.returns && !Array.isArray(this.returns)) { this.returns = [this.returns]; } + if(this.errors && !Array.isArray(this.errors)) { + this.errors = [this.errors]; + } this.stringName = (sc ? sc.name : '') + (isStatic ? '.' : '.prototype.') + name; } @@ -83,7 +89,9 @@ SharedMethod.fromFunction = function(fn, name, sharedClass, isStatic) { isStatic: isStatic, accepts: fn.accepts, returns: fn.returns, + errors: fn.errors, description: fn.description, + notes: fn.notes, http: fn.http, rest: fn.rest }); @@ -99,6 +107,7 @@ SharedMethod.fromFunction = function(fn, name, sharedClass, isStatic) { SharedMethod.prototype.invoke = function (scope, args, fn) { var accepts = this.accepts; var returns = this.returns; + var errors = this.errors; var method = this.getFunction(); var sharedMethod = this; var formattedArgs = []; diff --git a/lib/socket-io-context.js b/lib/socket-io-context.js index 09deb6b0..ccbe36c7 100644 --- a/lib/socket-io-context.js +++ b/lib/socket-io-context.js @@ -85,6 +85,7 @@ SocketIOContext.prototype.invoke = function (scope, method, fn) { var args = method.isSharedCtor ? this.ctorArgs : this.args; var accepts = method.accepts; var returns = method.returns; + var errors = method.errors; var scope; var result; diff --git a/test/rest-adapter.test.js b/test/rest-adapter.test.js index a01c6121..3e2246d2 100644 --- a/test/rest-adapter.test.js +++ b/test/rest-adapter.test.js @@ -105,11 +105,21 @@ describe('RestAdapter', function() { expect(method.returns).to.eql([anArg]); }); + it('has `errors`', function() { + var method = givenRestStaticMethod({ errors: anArg }); + expect(method.errors).to.eql([anArg]); + }); + it('has `description`', function() { var method = givenRestStaticMethod({ description: 'a-desc' }); expect(method.description).to.equal('a-desc'); }); + it('has `notes`', function() { + var method = givenRestStaticMethod({ notes: 'some-notes' }); + expect(method.notes).to.equal('some-notes'); + }); + describe('isReturningArray()', function() { it('returns true when there is single root Array arg', function() { var method = givenRestStaticMethod({ diff --git a/test/rest.test.js b/test/rest.test.js index 94e8cfa3..0c5ba112 100644 --- a/test/rest.test.js +++ b/test/rest.test.js @@ -618,6 +618,7 @@ describe('strong-remoting-rest', function(){ { arg: 'a', type: 'number', http: {source: 'path'} } ], returns: { arg: 'n', type: 'number', root: true}, + errors: [], http: { path: '/:a' } } );