UNPKG

restrict-imports-loader

Version:

A Webpack loader to restrict imports in ES and TypeScript

54 lines 2.02 kB
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