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