New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

express-enrouten

Package Overview
Dependencies
Maintainers
2
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-enrouten - npm Package Compare versions

Comparing version 0.3.0 to 1.0.0

coverage/coverage.json

210

index.js

@@ -20,67 +20,66 @@ /*───────────────────────────────────────────────────────────────────────────*\

var fs = require('fs'),
path = require('path'),
assert = require('assert'),
express = require('express');
var path = require('path');
var caller = require('caller');
var express = require('express');
var reverend = require('reverend');
var debug = require('debuglog')('enrouten');
var index = require('./lib/index');
var routes = require('./lib/routes');
var registry = require('./lib/registry');
var directory = require('./lib/directory');
/**
* Resolve and recursively scan the provided directory
* @param dir the directory to scan.
* @returns {Array} absolute file paths that are able to be loaded by Node code.
* Creates the onmount handler used to process teh middelwarez
* @param app the sacrificial express app to use.
* @param options the configuration settings to use when scanning
* @returns {Function}
*/
function loaddir(dir) {
return scan(resolve(dir));
}
function mount(app, options) {
return function onmount(parent) {
var router;
/**
* Returns true if `require` is able to load the provided file
* or false if not.
* http://nodejs.org/api/modules.html#modules_file_modules
* @param file the file for which to determine module-ness.
* @returns {boolean}
*/
function isFileModule(file) {
var ext = path.extname(file);
// Remove sacrificial express app and keep a
// copy of the currently registered items.
/// XXX: caveat emptor, private member
parent._router.stack.pop();
router = registry(app.mountpath);
try {
// remove the file extension and use require.resolve to resolve known
// file types eg. CoffeeScript. Will throw if not found/loadable by node.
file = ext ? file.slice(0, -ext.length) : file;
require.resolve(file);
return true;
} catch (err) {
return false;
}
}
// Process the configuration, adding to the stack
if (typeof options.index === 'string') {
options.index = resolve(options.basedir, options.index);
index(router, options.index);
}
if (typeof options.directory === 'string') {
options.directory = resolve(options.basedir, options.directory);
directory(router, options.directory);
}
/**
* Recursively (synchronously) scans the provided root directory, locating files which
* are able to be loaded by node.
* @param dir the root dir to begin scanning
* @param controllers an array containing the absolute file paths of all found controllers
* @returns {Array} the controllers array.
*/
function scan(dir, controllers) {
var stats;
if (typeof options.routes === 'object') {
routes(router, options.routes);
}
controllers = controllers || [];
// Setup app locals for use in handlers.
parent.locals.enrouten = {
stats = fs.statSync(dir);
routes: router.routes,
if (stats.isDirectory()) {
// recursively scan child files
fs.readdirSync(dir).forEach(function (child) {
scan(path.join(dir, child), controllers);
});
}
path: function path(name, data) {
var route;
route = this.routes[name];
if (typeof route === 'string') {
return reverend(route, data || {});
}
return undefined;
}
if (stats.isFile()) {
// add if valid
isFileModule(dir) && controllers.push(dir);
}
};
return controllers;
debug('mounting routes at', app.mountpath);
debug(router.routes);
parent.use(app.mountpath, router._router);
};
}

@@ -90,87 +89,52 @@

/**
* Helper for resolving a relative file path or array
* of path segments.
* @param file file path or array of path segments.
* @returns {String} the resolved file path
* Resolves the provide basedir and file, returning
* and absolute file path.
* @param basedir the base directory to use in path resolution
* @param file the absolute or relative file path to resolve.
* @returns {String} the resolved absolute file path.
*/
function resolve(file) {
if (!file) {
return undefined;
function resolve(basedir, file) {
if (path.resolve(file) === file) {
// absolute path
return file;
}
if (Array.isArray(file)) {
file = path.join.apply(undefined, file);
}
file = path.resolve(file);
return file;
return path.join(basedir, file);
}
module.exports = function (settings) {
/**
* The main entry point for this module. Creates middleware
* to be mounted to a parent application.
* @param options the configuration settings for this middleware instance
* @returns {Function} express middleware
*/
function enrouten(options) {
var app;
function initialize(app, settings) {
// If index specified, use it.
if (settings.index) {
require(resolve(settings.index))(app);
}
options = options || {};
options.basedir = options.basedir || path.dirname(caller());
// If directory specified, scan
if (settings.directory) {
loaddir(settings.directory).forEach(function (file) {
var controller = require(file);
if (typeof controller === 'function' && controller.length === 1) {
controller(app);
}
});
}
app = express();
app.once('mount', mount(app, options));
// Finally, try specified routes
if (Array.isArray(settings.routes)) {
settings.routes.forEach(function (def) {
var method;
return app;
}
assert.ok(def.path, 'path is required');
assert.ok(typeof def.handler === 'function', 'handler is required');
method = (def.method || 'get').toLowerCase();
app[method](def.path, def.handler);
});
}
/**
* Create a URL from a named route and data.
* @param app the express app for which to generate the named route
* @param name the name of the route to generate
* @param data the object containing keys and values for the named replacements.
* @returns {String} the generated URL or undefined if no named route exists.
*/
enrouten.path = function path(app, name, data) {
var locals = app.locals;
if (locals.enrouten && typeof locals.enrouten.path === 'function') {
return locals.enrouten.path(name, data);
}
return undefined;
};
function mount(settings) {
return function onmount(parent) {
// Remove sacrificial express app
parent.stack.pop();
// Process the configuration.
initialize(parent, settings);
// Reorganize stack to place router in correct place
// This could get out of whack if someone registers
// directly against express prior to calling enrouten.
// This is done *after* scanning so any middleware registered
// during scanning is correctly put before the router.
parent.stack.some(function (middleware, idx, stack) {
if (middleware.handle.name === 'router') {
// If a route was specified when mounting, update the
// router middleware to only respond to that route.
// e.g. app.use('/foo', enrouten()) is akin to app.use('/foo', app.router);
middleware.route = app.route !== '/' ? app.route : '';
// Reorder stack
stack.splice(idx, 1);
stack.push(middleware);
return true;
}
return false;
});
};
}
app = express();
app.once('mount', mount(settings));
return app;
};
module.exports = enrouten;
{
"name": "express-enrouten",
"version": "0.3.0",
"version": "1.0.0",
"description": "An express route initialization and configuration module.",
"main": "index.js",
"scripts": {
"test": "grunt test"
"test": "tape test/*.js",
"cover": "istanbul cover tape -- test/*.js",
"lint": "jshint -c .jshintrc index.js lib/*.js"
},
"repository": "git://github.com/paypal/express-enrouten.git",
"repository": "git://github.com/krakenjs/express-enrouten.git",
"publishConfig": {

@@ -28,10 +30,13 @@ "registry": "https://registry.npmjs.org"

"devDependencies": {
"mocha": "~1.9.0",
"chai": "~1.5.0",
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.7.0",
"grunt-mocha-test": "~0.7.0",
"express": "~3.4.6",
"supertest": "~0.8.2"
"express": "~4.0.0",
"supertest": "~0.8.2",
"tape": "~2.10.2",
"istanbul": "~0.2.6",
"jshint": "~2.4.4"
},
"dependencies": {
"caller": "~0.0.1",
"debuglog": "~1.0.1",
"reverend": "~0.2.0"
}
}

@@ -6,4 +6,7 @@ express-enrouten

Note: `express-enrouten >=1.0` is only compatible with `express >=4.0`.
For `express 3.x` support, please use `express-enrouten 0.3.x`.
[![Build Status](https://travis-ci.org/paypal/express-enrouten.png)](https://travis-ci.org/paypal/express-enrouten)
[![Build Status](https://travis-ci.org/krakenjs/express-enrouten.png)](https://travis-ci.org/krakenjs/express-enrouten)
[![NPM version](https://badge.fury.io/js/express-enrouten.png)](http://badge.fury.io/js/express-enrouten)

@@ -26,26 +29,60 @@

```javascript
app.use(enrouten({
routes: [{
method: 'GET',
path: '/foo',
handler: function (req, res) {
// ...
}
}]
}
});
app.use(enrouten({ directory: 'routes' }));
```
- `directory` (optional) - String or array of path segments. Specify a directory to have enrouten scan all files recursively
to find files that match the controller-spec API.
#### directory
The `directory` configuration option (optional) is the path to a directory.
Specify a directory to have enrouten scan all files recursively to find files
that match the controller-spec API. With this API, the directory structure
dictates the paths at which handlers will be mounted.
```text
controllers
|-user
|-create.js
|-list.js
```
```javascript
// create.js
module.exports = function (router) {
router.post('/', function (req, res) {
res.send('ok');
});
};
```
```javascript
app.use(enrouten({
directory: 'controllers'
});
}));
```
Routes are now:
```test
/user/create
/user/list
```
- `routes` (optional) An array of route definition objects. Each definition must have a `path` and `handler` property and
can have an optional `method` property (`method` defaults to 'GET').
#### index
The `index` configuration option (optional) is the path to the single file to
load (which acts as the route 'index' of the application).
```javascript
app.use(enrouten({
index: 'routes/'
}));
```
```javascript
// index.js
module.exports = function (router) {
router.get('/', index);
router.all(passport.protect).get('/account', account);
// etc...
};
```
#### routes
The `routes` configuration option (optional) is an array of route definition objects.
Each definition must have a `path` and `handler` property and can have an optional
`method` property (`method` defaults to 'GET').
```javascript

@@ -57,21 +94,31 @@ app.use(enrouten({

]
});
}));
```
- `index` (optional, overrides `directory` and disables scanning) - String path or array of path segments indicating
the file to load which acts as the route 'index' of the application.
### Named Routes
For `index` and `directory` configurations there is also support for named routes.
The normal express router that is passed in will always behave as such, but in addition
it can be used to name a route, adding the name and path to `app.locals.enrouten.routes`.
For example:
```javascript
// index.js
module.exports = function (app) {
'use strict';
app.get('/', index);
app.get('/account', passport.protect, account);
module.exports = function (router) {
// etc...
router({ path: '/user/:id', name: 'user-info' })
.get(function (req, res) {
res.send('ok');
});
};
```
### Controller Files
A 'controller' is defined as any `require`-able file which exports a function that accepts a single argument. Any files with an extension of `.js` (or `.coffee` if CoffeeScript is registered) will be loaded and if it exports a function that accepts a single argument then this function will be called. **NOTE: Any file in the directory tree that matches the API will be invoked/initialized with the express application object.**
A 'controller' is defined as any `require`-able file which exports a function
that accepts a single argument. Any files with an extension of `.js` (or `.coffee`
if CoffeeScript is registered) will be loaded and if it exports a function that
accepts a single argument then this function will be called. **NOTE: Any file in
the directory tree that matches the API will be invoked/initialized with the
express router object.**

@@ -81,4 +128,4 @@ ```javascript

// controllers/controller.js
module.exports = function (app) {
app.get('/', function (req, res) {
module.exports = function (router) {
router.get('/', function (req, res) {
// ...

@@ -90,3 +137,3 @@ });

// Function does not get returned when `require`-ed, use `module.exports`
exports = function (app) {
exports = function (router) {
// ...

@@ -98,3 +145,3 @@ };

modules.exports = function (config) {
// `config` will be the express application
// `config` will be an express Router
// ...

@@ -101,0 +148,0 @@ };

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