RestrictionsPlugin.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Ivan Kopeykin @vankop
  4. */
  5. "use strict";
  6. /** @typedef {import("./Resolver")} Resolver */
  7. /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
  8. const slashCode = "/".charCodeAt(0);
  9. const backslashCode = "\\".charCodeAt(0);
  10. /**
  11. * @param {string} path path
  12. * @param {string} parent parent path
  13. * @returns {boolean} true, if path is inside of parent
  14. */
  15. const isInside = (path, parent) => {
  16. if (!path.startsWith(parent)) return false;
  17. if (path.length === parent.length) return true;
  18. const charCode = path.charCodeAt(parent.length);
  19. return charCode === slashCode || charCode === backslashCode;
  20. };
  21. module.exports = class RestrictionsPlugin {
  22. /**
  23. * @param {string | ResolveStepHook} source source
  24. * @param {Set<string | RegExp>} restrictions restrictions
  25. */
  26. constructor(source, restrictions) {
  27. this.source = source;
  28. this.restrictions = restrictions;
  29. }
  30. /**
  31. * @param {Resolver} resolver the resolver
  32. * @returns {void}
  33. */
  34. apply(resolver) {
  35. resolver
  36. .getHook(this.source)
  37. .tapAsync("RestrictionsPlugin", (request, resolveContext, callback) => {
  38. if (typeof request.path === "string") {
  39. const path = request.path;
  40. for (const rule of this.restrictions) {
  41. if (typeof rule === "string") {
  42. if (!isInside(path, rule)) {
  43. if (resolveContext.log) {
  44. resolveContext.log(
  45. `${path} is not inside of the restriction ${rule}`
  46. );
  47. }
  48. return callback(null, null);
  49. }
  50. } else if (!rule.test(path)) {
  51. if (resolveContext.log) {
  52. resolveContext.log(
  53. `${path} doesn't match the restriction ${rule}`
  54. );
  55. }
  56. return callback(null, null);
  57. }
  58. }
  59. }
  60. callback();
  61. });
  62. }
  63. };