restrict-imports-loader
Version:
A Webpack loader to restrict imports in ES and TypeScript
54 lines • 2.02 kB
JavaScript
import * as path from "path";
const UP_ONE_LEVEL_LENGTH = 3;
const REGEX_UP_LEVELS = new RegExp(String.raw `(?:\.\.\/)+`, "g");
export function everythingInPackage(packageName) {
return matchedBy(new RegExp(String.raw `^${packageName}(\/.*)?$`));
}
export function matchedBy(r) {
return importPath => Promise.resolve({ restricted: r.test(importPath) });
}
export function climbingUpwardsMoreThan(levels) {
return importPath => {
const maxLength = lengthOfLongestMatch(normalize(importPath).match(REGEX_UP_LEVELS));
const maxClimbs = maxLength / UP_ONE_LEVEL_LENGTH;
const s = maxClimbs === 1 ? "" : "s";
return Promise.resolve({
restricted: maxClimbs > levels,
info: `(contains ${maxClimbs} consecutive occurrence${s} of "../"; max ${levels} allowed)`,
});
};
}
function lengthOfLongestMatch(matches) {
return (matches === null
? 0
: matches.reduce((acc, m) => Math.max(acc, m.length), 0));
}
function normalize(importPath) {
return importPath.replace(/\/+/g, "/").replace(/\/\.\//g, "/");
}
export const everythingInside = everything(true);
export const everythingOutside = everything(false);
function everything(insideIsRestricted) {
return dirs => {
return (importPath, loaderContext) => new Promise((resolve, reject) => {
loaderContext.resolve(loaderContext.context, importPath, (err, result) => {
if (err === null) {
resolve({
restricted: insideIsRestricted === dirs.some(contains(result)),
info: `(resolved: ${result})`,
});
}
else {
reject(err.message);
}
});
});
};
}
function contains(contained) {
return dir => {
const relative = path.relative(dir, contained);
return !relative.startsWith("..") && !path.isAbsolute(relative);
};
}
//# sourceMappingURL=deciders.js.map