router.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. 'use strict';
  2. const is = require('is-type-of');
  3. const assert = require('assert');
  4. const methods = [ 'head', 'options', 'get', 'put', 'patch', 'post', 'delete', 'del', 'all', 'resources' ];
  5. class RouterPlus {
  6. constructor(app) {
  7. this.app = app;
  8. }
  9. /**
  10. * get sub router
  11. *
  12. * @method Router#namespace
  13. * @param {String} prefix - sub router prefix
  14. * @param {...Function} [middlewares] - optional middlewares
  15. * @return {Router} Return sub router with special prefix
  16. */
  17. namespace(prefix, ...middlewares) {
  18. assert(is.string(prefix), `only support prefix with string, but got ${prefix}`);
  19. assert(prefix !== '/', 'namespace / is not supported');
  20. const fnCache = {};
  21. // mock router
  22. const proxy = new Proxy(this.app.router, {
  23. get(target, property) {
  24. if (methods.includes(property)) {
  25. if (!fnCache[property]) {
  26. fnCache[property] = proxyFn(target, property, prefix, middlewares, proxy);
  27. }
  28. return fnCache[property];
  29. }
  30. return target[property];
  31. },
  32. });
  33. return proxy;
  34. }
  35. }
  36. module.exports = RouterPlus;
  37. function proxyFn(target, property, prefix, middlewares, routerProxy) {
  38. const fn = target[property];
  39. const proxy = new Proxy(fn, {
  40. apply(targetFn, ctx, args) {
  41. if (args.length >= 3 && (is.string(args[1]) || is.regExp(args[1]))) {
  42. // app.get(name, url, [...middleware], controller)
  43. args[1] = addPrefix(prefix, args[1]);
  44. args.splice(2, 0, ...middlewares);
  45. } else {
  46. // app.get(url, [...middleware], controller)
  47. args[0] = addPrefix(prefix, args[0]);
  48. args.splice(1, 0, ...middlewares);
  49. }
  50. Reflect.apply(targetFn, ctx, args);
  51. return routerProxy;
  52. },
  53. });
  54. return proxy;
  55. }
  56. function addPrefix(prefix, path) {
  57. assert(is.string(path), `only support path with string, but got ${path}`);
  58. return prefix + path;
  59. }