Skip to content

Commit

Permalink
Merge branch 'master' of github.com:atsid/express-jefferson
Browse files Browse the repository at this point in the history
* 'master' of github.com:atsid/express-jefferson:
  #17 - readability cleanup
  #17 - Adding an 'aliases' config section
  • Loading branch information
Chris Trevino committed Mar 25, 2015
2 parents 22e6e2c + e434566 commit 62f865b
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -8,7 +8,7 @@
# express-jefferson
Declarative Express Application Wiring

express-jefferson is a microlibrary for declaratively describing RESTful services. Currently, it allows you to describe your service routes as a map.
express-jefferson is a microlibrary for declaratively describing RESTful services.

```js
// main.js
Expand Down Expand Up @@ -58,6 +58,7 @@ jefferson(app, conf);

## Configuration
* routes - An map of routes by name. Each object in the map describes an endpoint to be wired. These endpoints must contain an HTTP method, a path, and an array of middleware functions.
* aliases: (optional) - A map of alias-name to handler chain. Routes may use these aliases in lieu of repeated function groups.
* proxies: (optional) - An array of proxy objects invoked around all middleware functions in order. Each proxy object should have an init() function that accepts a delegate middleware function and returns a new middleware function.
* params: (optional) - A map of path-parameter name to resolver functions.

Expand Down
29 changes: 29 additions & 0 deletions src/jefferson.js
Expand Up @@ -34,12 +34,41 @@ module.exports = (app, conf) => {
return lastProxy;
};

/**
* Resolves an alias reference
* @param aliasName
* @param middlewareChain
*/
let resolveAlias = (aliasName) => {
if (!conf.aliases) {
throw new Error(`no aliases defined, cannot find ${aliasName}`);
}
if (!conf.aliases[aliasName]) {
throw new Error(`could not find handler chain with alias ${aliasName}`);
}
return conf.aliases[aliasName];
};

/**
* Resolves alias references in a middleware cahin
* @param middleware
*/
let resolveAliases = (middleware) => {
let isAlias = (x) => typeof x === 'string';
for (let i = middleware.length -1; i >= 0; i--) {
if (isAlias(middleware[i])) {
middleware.splice(i, 1, resolveAlias(middleware[i]));
}
}
};

/**
* Configures a middleware chain
* @param middleware An array of middleware functions
* @returns {*} An array of middleware functions
*/
let configureMiddleware = (middleware) => {
resolveAliases(middleware);
return middleware.map(wrapInProxies);
};

Expand Down
85 changes: 85 additions & 0 deletions src/jefferson.test.js
Expand Up @@ -221,4 +221,89 @@ describe('Jefferson', () => {
done();
});
});

it('throws if a subchain reference is undefined', () => {
let conf = {
aliases: {
'derp': []
},
routes: {
'getUser': {
method: 'GET',
path: '/test-item',
middleware: [
(req, res, next) => {
req.entity = {id: 1};
next();
},
'processAndReturn'
]
}
}
};

let app = express();
expect(() => jefferson(app, conf)).to.throw();
});

it('throws if a alias section is undefined and an alias is referenced', () => {
let conf = {
routes: {
'getUser': {
method: 'GET',
path: '/test-item',
middleware: [
(req, res, next) => {
req.entity = {id: 1};
next();
},
'processAndReturn'
]
}
}
};

let app = express();
expect(() => jefferson(app, conf)).to.throw();
});

it('can reference subchain aliases', (done) => {
let conf = {
aliases: {
processAndReturn: [
(req, res, next) => {
req.entity.herp = 'derp';
next();
},
(req, res) => { res.json(req.entity); }
]
},
routes: {
'getUser': {
method: 'GET',
path: '/test-item',
middleware: [
(req, res, next) => {
req.entity = {id: 1};
next();
},
'processAndReturn'
]
}
}
};

let app = express();
jefferson(app, conf);

request(app)
.get('/test-item')
.expect(200)
.end((err, res) => {
if (err) { return done(err); }
expect(res.body.id).to.equal(1);
expect(res.body.herp).to.equal('derp');
done();
});
});
});

0 comments on commit 62f865b

Please sign in to comment.