🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@eggjs/router

Package Overview
Dependencies
Maintainers
10
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@eggjs/router - npm Package Compare versions

Comparing version
1.0.0
to
1.1.0
+10
index.js
'use strict';
const KoaRouter = require('./lib/router');
const EggRouter = require('./lib/egg_router');
// for compact
module.exports = KoaRouter;
module.exports.KoaRouter = KoaRouter;
module.exports.EggRouter = EggRouter;
'use strict';
const is = require('is-type-of');
const Router = require('./router');
const utility = require('utility');
const inflection = require('inflection');
const assert = require('assert');
const utils = require('./utils');
const METHODS = [ 'head', 'options', 'get', 'put', 'patch', 'post', 'delete' ];
const REST_MAP = {
index: {
suffix: '',
method: 'GET',
},
new: {
namePrefix: 'new_',
member: true,
suffix: 'new',
method: 'GET',
},
create: {
suffix: '',
method: 'POST',
},
show: {
member: true,
suffix: ':id',
method: 'GET',
},
edit: {
member: true,
namePrefix: 'edit_',
suffix: ':id/edit',
method: 'GET',
},
update: {
member: true,
namePrefix: '',
suffix: ':id',
method: ['PATCH', 'PUT'],
},
destroy: {
member: true,
namePrefix: 'destroy_',
suffix: ':id',
method: 'DELETE',
},
};
/**
* FIXME: move these patch into @eggjs/router
*/
class EggRouter extends Router {
/**
* @constructor
* @param {Object} opts - Router options.
* @param {Application} app - Application object.
*/
constructor(opts, app) {
super(opts);
this.app = app;
this.patchRouterMethod();
}
patchRouterMethod() {
// patch router methods to support generator function middleware and string controller
METHODS.concat(['all']).forEach(method => {
this[method] = (...args) => {
const splited = spliteAndResolveRouterParams({ args, app: this.app });
// format and rebuild params
args = splited.prefix.concat(splited.middlewares);
return super[method](...args);
};
});
}
/**
* Create and register a route.
* @param {String} path - url path
* @param {Array} methods - Array of HTTP verbs
* @param {Array} middlewares -
* @param {Object} opts -
* @return {Route} this
*/
register(path, methods, middlewares, opts) {
// patch register to support generator function middleware and string controller
middlewares = Array.isArray(middlewares) ? middlewares : [middlewares];
middlewares = convertMiddlewares(middlewares, this.app);
path = Array.isArray(path) ? path : [path];
path.forEach(p => super.register(p, methods, middlewares, opts));
return this;
}
/**
* restful router api
* @param {String} name - Router name
* @param {String} prefix - url prefix
* @param {Function} middleware - middleware or controller
* @example
* ```js
* app.resources('/posts', 'posts')
* app.resources('posts', '/posts', 'posts')
* app.resources('posts', '/posts', app.role.can('user'), app.controller.posts)
* ```
*
* Examples:
*
* ```js
* app.resources('/posts', 'posts')
* ```
*
* yield router mapping
*
* Method | Path | Route Name | Controller.Action
* -------|-----------------|----------------|-----------------------------
* GET | /posts | posts | app.controller.posts.index
* GET | /posts/new | new_post | app.controller.posts.new
* GET | /posts/:id | post | app.controller.posts.show
* GET | /posts/:id/edit | edit_post | app.controller.posts.edit
* POST | /posts | posts | app.controller.posts.create
* PATCH | /posts/:id | post | app.controller.posts.update
* DELETE | /posts/:id | post | app.controller.posts.destroy
*
* app.router.url can generate url based on arguments
* ```js
* app.router.url('posts')
* => /posts
* app.router.url('post', { id: 1 })
* => /posts/1
* app.router.url('new_post')
* => /posts/new
* app.router.url('edit_post', { id: 1 })
* => /posts/1/edit
* ```
* @return {Router} return route object.
* @since 1.0.0
*/
resources(...args) {
const splited = spliteAndResolveRouterParams({ args, app: this.app });
const middlewares = splited.middlewares;
// last argument is Controller object
const controller = splited.middlewares.pop();
let name = '';
let prefix = '';
if (splited.prefix.length === 2) {
// router.get('users', '/users')
name = splited.prefix[0];
prefix = splited.prefix[1];
} else {
// router.get('/users')
prefix = splited.prefix[0];
}
for (const key in REST_MAP) {
const action = controller[key];
if (!action) continue;
const opts = REST_MAP[key];
let formatedName;
if (opts.member) {
formatedName = inflection.singularize(name);
} else {
formatedName = inflection.pluralize(name);
}
if (opts.namePrefix) {
formatedName = opts.namePrefix + formatedName;
}
prefix = prefix.replace(/\/$/, '');
const path = opts.suffix ? `${prefix}/${opts.suffix}` : prefix;
const method = Array.isArray(opts.method) ? opts.method : [opts.method];
this.register(path, method, middlewares.concat(action), { name: formatedName });
}
return this;
}
/**
* @param {String} name - Router name
* @param {Object} params - more parameters
* @example
* ```js
* router.url('edit_post', { id: 1, name: 'foo', page: 2 })
* => /posts/1/edit?name=foo&page=2
* router.url('posts', { name: 'foo&1', page: 2 })
* => /posts?name=foo%261&page=2
* ```
* @return {String} url by path name and query params.
* @since 1.0.0
*/
url(name, params) {
const route = this.route(name);
if (!route) return '';
const args = params;
let url = route.path;
assert(!is.regExp(url), `Can't get the url for regExp ${url} for by name '${name}'`);
const queries = [];
if (typeof args === 'object' && args !== null) {
const replacedParams = [];
url = url.replace(/:([a-zA-Z_]\w*)/g, function ($0, key) {
if (utility.has(args, key)) {
const values = args[key];
replacedParams.push(key);
return utility.encodeURIComponent(Array.isArray(values) ? values[0] : values);
}
return $0;
});
for (const key in args) {
if (replacedParams.includes(key)) {
continue;
}
const values = args[key];
const encodedKey = utility.encodeURIComponent(key);
if (Array.isArray(values)) {
for (const val of values) {
queries.push(`${encodedKey}=${utility.encodeURIComponent(val)}`);
}
} else {
queries.push(`${encodedKey}=${utility.encodeURIComponent(values)}`);
}
}
}
if (queries.length > 0) {
const queryStr = queries.join('&');
if (!url.includes('?')) {
url = `${url}?${queryStr}`;
} else {
url = `${url}&${queryStr}`;
}
}
return url;
}
pathFor(name, params) {
return this.url(name, params);
}
}
/**
* 1. split (name, url, ...middleware, controller) to
* {
* prefix: [name, url]
* middlewares [...middleware, controller]
* }
*
* 2. resolve controller from string to function
*
* @param {Object} options inputs
* @param {Object} options.args router params
* @param {Object} options.app egg application instance
* @return {Object} prefix and middlewares
*/
function spliteAndResolveRouterParams({ args, app }) {
let prefix;
let middlewares;
if (args.length >= 3 && (is.string(args[1]) || is.regExp(args[1]))) {
// app.get(name, url, [...middleware], controller)
prefix = args.slice(0, 2);
middlewares = args.slice(2);
} else {
// app.get(url, [...middleware], controller)
prefix = args.slice(0, 1);
middlewares = args.slice(1);
}
// resolve controller
const controller = middlewares.pop();
middlewares.push(resolveController(controller, app));
return { prefix, middlewares };
}
/**
* resolve controller from string to function
* @param {String|Function} controller input controller
* @param {Application} app egg application instance
* @return {Function} controller function
*/
function resolveController(controller, app) {
if (is.string(controller)) {
const actions = controller.split('.');
let obj = app.controller;
actions.forEach(key => {
obj = obj[key];
if (!obj) throw new Error(`controller '${controller}' not exists`);
});
controller = obj;
}
// ensure controller is exists
if (!controller) throw new Error('controller not exists');
return controller;
}
/**
* 1. ensure controller(last argument) support string
* - [url, controller]: app.get('/home', 'home');
* - [name, url, controller(string)]: app.get('posts', '/posts', 'posts.list');
* - [name, url, controller]: app.get('posts', '/posts', app.controller.posts.list);
* - [name, url(regexp), controller]: app.get('regRouter', /\/home\/index/, 'home.index');
* - [name, url, middleware, [...], controller]: `app.get(/user/:id', hasLogin, canGetUser, 'user.show');`
*
* 2. make middleware support generator function
*
* @param {Array} middlewares middlewares and controller(last middleware)
* @param {Application} app egg application instance
* @return {Array} middlewares
*/
function convertMiddlewares(middlewares, app) {
// ensure controller is resolved
const controller = resolveController(middlewares.pop(), app);
// make middleware support generator function
middlewares = middlewares.map(utils.middleware);
const wrappedController = (ctx, next) => {
return utils.callFn(controller, [ctx, next], ctx);
};
return middlewares.concat([wrappedController]);
}
module.exports = EggRouter;
'use strict';
const convert = require('koa-convert');
const is = require('is-type-of');
const co = require('co');
module.exports = {
async callFn(fn, args, ctx) {
args = args || [];
if (!is.function(fn)) return;
if (is.generatorFunction(fn)) fn = co.wrap(fn);
return ctx ? fn.call(ctx, ...args) : fn(...args);
},
middleware(fn) {
return is.generatorFunction(fn) ? convert(fn) : fn;
},
};
+11
-2
1.0.0 / 2019-01-30
1.1.0 / 2019-01-30
==================
**features**
* [[`b318dd5`](http://github.com/eggjs/egg-router/commit/b318dd5ff2eea60013ed62b2a435f803c12bf20f)] - feat: add egg-router (dead-horse <<dead_horse@qq.com>>)
**fixes**
* [[`b3db7b4`](http://github.com/eggjs/egg-router/commit/b3db7b41988d3bf1b4e885ed76b3a8165c1d3b1d)] - fix: add missing dependencies koa-convert (dead-horse <<dead_horse@qq.com>>)
* [[`c280336`](http://github.com/eggjs/egg-router/commit/c2803368a8256bc9504ae3c821eefeb9d1fcbc4d)] - fix: only support node@8 (dead-horse <<dead_horse@qq.com>>)
* [[`7a887a2`](http://github.com/eggjs/egg-router/commit/7a887a252445e602c2ea7e1c6f4cde52a433644d)] - fix: update license (dead-horse <<dead_horse@qq.com>>)
**others**
* [[`ae40168`](http://github.com/eggjs/egg-router/commit/ae4016862fb8bdaf30e730a9278fbb1455d8b75d)] - docs: clean doc (dead-horse <<dead_horse@qq.com>>)
* [[`e4f21a8`](http://github.com/eggjs/egg-router/commit/e4f21a8ed6dfd72c4d6f4a13bbda9a4e90b0401c)] - chore: fix history (dead-horse <<dead_horse@qq.com>>)
1.0.0 / 2019-01-30

@@ -9,0 +18,0 @@ ==================

+1
-1

@@ -1,2 +0,2 @@

var debug = require('debug')('koa-router');
var debug = require('debug')('egg-router');
var pathToRegExp = require('path-to-regexp');

@@ -3,0 +3,0 @@ var uri = require('urijs');

/**
* RESTful resource routing middleware for koa.
*
* @author Alex Mingoia <talk@alexmingoia.com>
* @link https://github.com/alexmingoia/koa-router
* RESTful resource routing middleware for eggjs.
*/
var debug = require('debug')('koa-router');
var debug = require('debug')('egg-router');
var compose = require('koa-compose');

@@ -10,0 +7,0 @@ var HttpError = require('http-errors');

The MIT License (MIT)
Copyright (c) 2015 Alexander C. Mingoia
Copyright (c) 2019 eggjs

@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -8,8 +8,8 @@ {

},
"main": "lib/router.js",
"files": [
"lib"
"lib",
"index.js"
],
"author": "eggjs",
"version": "1.0.0",
"version": "1.1.0",
"keywords": [

@@ -22,12 +22,18 @@ "koa",

"dependencies": {
"co": "^4.6.0",
"debug": "^3.1.0",
"http-errors": "^1.3.1",
"inflection": "^1.12.0",
"is-type-of": "^1.2.1",
"koa-compose": "^3.0.0",
"koa-convert": "^1.2.0",
"methods": "^1.0.1",
"path-to-regexp": "^1.1.1",
"urijs": "^1.19.0"
"urijs": "^1.19.0",
"utility": "^1.15.0"
},
"devDependencies": {
"egg-bin": "^4.10.0",
"egg-ci": "^1.11.0",
"expect.js": "^0.3.1",
"jsdoc-to-markdown": "^1.1.1",
"koa": "2.2.0",

@@ -39,9 +45,12 @@ "mocha": "^2.0.1",

"scripts": {
"test": "NODE_ENV=test mocha test/**/*.js",
"docs": "NODE_ENV=test jsdoc2md -t ./lib/README_tpl.hbs --src ./lib/*.js >| README.md"
"test": "egg-bin test",
"ci": "egg-bin cov"
},
"ci": {
"version": "8, 10"
},
"engines": {
"node": ">= 4"
"node": ">= 8"
},
"license": "MIT"
}

@@ -411,12 +411,5 @@ # @eggjs/router

```
## Contributing
Please submit all issues and pull requests to the [alexmingoia/egg-router](http://github.com/alexmingoia/egg-router) repository!
## Tests
Run tests using `npm test`.
## Support
If you have any problem or suggestion please open an issue [here](https://github.com/alexmingoia/egg-router/issues).
# koa-router
[![NPM version](https://img.shields.io/npm/v/koa-router.svg?style=flat)](https://npmjs.org/package/koa-router) [![NPM Downloads](https://img.shields.io/npm/dm/koa-router.svg?style=flat)](https://npmjs.org/package/koa-router) [![Node.js Version](https://img.shields.io/node/v/koa-router.svg?style=flat)](http://nodejs.org/download/) [![Build Status](https://img.shields.io/travis/alexmingoia/koa-router.svg?style=flat)](http://travis-ci.org/alexmingoia/koa-router) [![Tips](https://img.shields.io/gratipay/alexmingoia.svg?style=flat)](https://www.gratipay.com/alexmingoia/) [![Gitter Chat](https://img.shields.io/badge/gitter-join%20chat-1dce73.svg?style=flat)](https://gitter.im/alexmingoia/koa-router/)
> Router middleware for [koa](https://github.com/koajs/koa)
* Express-style routing using `app.get`, `app.put`, `app.post`, etc.
* Named URL parameters.
* Named routes with URL generation.
* Responds to `OPTIONS` requests with allowed methods.
* Support for `405 Method Not Allowed` and `501 Not Implemented`.
* Multiple route middleware.
* Multiple routers.
* Nestable routers.
* ES7 async/await support.
{{#module name="koa-router"}}{{>body}}{{/module}}## Migrating to 7 / Koa 2
- The API has changed to match the new promise-based middleware
signature of koa 2. See the
[koa 2.x readme](https://github.com/koajs/koa/tree/2.0.0-alpha.3) for more
information.
- Middleware is now always run in the order declared by `.use()` (or `.get()`,
etc.), which matches Express 4 API.
## Installation
Install using [npm](https://www.npmjs.org/):
```sh
npm install koa-router
```
## API Reference
{{#module name="koa-router"~}}
{{>body~}}
{{>member-index~}}
{{>members~}}
{{/module~}}
## Contributing
Please submit all issues and pull requests to the [alexmingoia/koa-router](http://github.com/alexmingoia/koa-router) repository!
## Tests
Run tests using `npm test`.
## Support
If you have any problem or suggestion please open an issue [here](https://github.com/alexmingoia/koa-router/issues).