context-matcher.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.match = void 0;
  4. const isGlob = require("is-glob");
  5. const micromatch = require("micromatch");
  6. const url = require("url");
  7. const errors_1 = require("./errors");
  8. function match(context, uri, req) {
  9. // single path
  10. if (isStringPath(context)) {
  11. return matchSingleStringPath(context, uri);
  12. }
  13. // single glob path
  14. if (isGlobPath(context)) {
  15. return matchSingleGlobPath(context, uri);
  16. }
  17. // multi path
  18. if (Array.isArray(context)) {
  19. if (context.every(isStringPath)) {
  20. return matchMultiPath(context, uri);
  21. }
  22. if (context.every(isGlobPath)) {
  23. return matchMultiGlobPath(context, uri);
  24. }
  25. throw new Error(errors_1.ERRORS.ERR_CONTEXT_MATCHER_INVALID_ARRAY);
  26. }
  27. // custom matching
  28. if (typeof context === 'function') {
  29. const pathname = getUrlPathName(uri);
  30. return context(pathname, req);
  31. }
  32. throw new Error(errors_1.ERRORS.ERR_CONTEXT_MATCHER_GENERIC);
  33. }
  34. exports.match = match;
  35. /**
  36. * @param {String} context '/api'
  37. * @param {String} uri 'http://example.org/api/b/c/d.html'
  38. * @return {Boolean}
  39. */
  40. function matchSingleStringPath(context, uri) {
  41. const pathname = getUrlPathName(uri);
  42. return pathname.indexOf(context) === 0;
  43. }
  44. function matchSingleGlobPath(pattern, uri) {
  45. const pathname = getUrlPathName(uri);
  46. const matches = micromatch([pathname], pattern);
  47. return matches && matches.length > 0;
  48. }
  49. function matchMultiGlobPath(patternList, uri) {
  50. return matchSingleGlobPath(patternList, uri);
  51. }
  52. /**
  53. * @param {String} contextList ['/api', '/ajax']
  54. * @param {String} uri 'http://example.org/api/b/c/d.html'
  55. * @return {Boolean}
  56. */
  57. function matchMultiPath(contextList, uri) {
  58. let isMultiPath = false;
  59. for (const context of contextList) {
  60. if (matchSingleStringPath(context, uri)) {
  61. isMultiPath = true;
  62. break;
  63. }
  64. }
  65. return isMultiPath;
  66. }
  67. /**
  68. * Parses URI and returns RFC 3986 path
  69. *
  70. * @param {String} uri from req.url
  71. * @return {String} RFC 3986 path
  72. */
  73. function getUrlPathName(uri) {
  74. return uri && url.parse(uri).pathname;
  75. }
  76. function isStringPath(context) {
  77. return typeof context === 'string' && !isGlob(context);
  78. }
  79. function isGlobPath(context) {
  80. return isGlob(context);
  81. }