144 lines
16 KiB
JavaScript
144 lines
16 KiB
JavaScript
|
'use strict';var _minimatch = require('minimatch');var _minimatch2 = _interopRequireDefault(_minimatch);
|
||
|
|
||
|
var _resolve = require('eslint-module-utils/resolve');var _resolve2 = _interopRequireDefault(_resolve);
|
||
|
var _importType = require('../core/importType');var _importType2 = _interopRequireDefault(_importType);
|
||
|
var _moduleVisitor = require('eslint-module-utils/moduleVisitor');var _moduleVisitor2 = _interopRequireDefault(_moduleVisitor);
|
||
|
var _docsUrl = require('../docsUrl');var _docsUrl2 = _interopRequireDefault(_docsUrl);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { 'default': obj };}
|
||
|
|
||
|
module.exports = {
|
||
|
meta: {
|
||
|
type: 'suggestion',
|
||
|
docs: {
|
||
|
category: 'Static analysis',
|
||
|
description: 'Forbid importing the submodules of other modules.',
|
||
|
url: (0, _docsUrl2['default'])('no-internal-modules') },
|
||
|
|
||
|
|
||
|
schema: [
|
||
|
{
|
||
|
anyOf: [
|
||
|
{
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
allow: {
|
||
|
type: 'array',
|
||
|
items: {
|
||
|
type: 'string' } } },
|
||
|
|
||
|
|
||
|
|
||
|
additionalProperties: false },
|
||
|
|
||
|
{
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
forbid: {
|
||
|
type: 'array',
|
||
|
items: {
|
||
|
type: 'string' } } },
|
||
|
|
||
|
|
||
|
|
||
|
additionalProperties: false }] }] },
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
create: function () {function noReachingInside(context) {
|
||
|
var options = context.options[0] || {};
|
||
|
var allowRegexps = (options.allow || []).map(function (p) {return _minimatch2['default'].makeRe(p);});
|
||
|
var forbidRegexps = (options.forbid || []).map(function (p) {return _minimatch2['default'].makeRe(p);});
|
||
|
|
||
|
// minimatch patterns are expected to use / path separators, like import
|
||
|
// statements, so normalize paths to use the same
|
||
|
function normalizeSep(somePath) {
|
||
|
return somePath.split('\\').join('/');
|
||
|
}
|
||
|
|
||
|
function toSteps(somePath) {
|
||
|
return normalizeSep(somePath).
|
||
|
split('/').
|
||
|
filter(function (step) {return step && step !== '.';}).
|
||
|
reduce(function (acc, step) {
|
||
|
if (step === '..') {
|
||
|
return acc.slice(0, -1);
|
||
|
}
|
||
|
return acc.concat(step);
|
||
|
}, []);
|
||
|
}
|
||
|
|
||
|
// test if reaching to this destination is allowed
|
||
|
function reachingAllowed(importPath) {
|
||
|
return allowRegexps.some(function (re) {return re.test(importPath);});
|
||
|
}
|
||
|
|
||
|
// test if reaching to this destination is forbidden
|
||
|
function reachingForbidden(importPath) {
|
||
|
return forbidRegexps.some(function (re) {return re.test(importPath);});
|
||
|
}
|
||
|
|
||
|
function isAllowViolation(importPath) {
|
||
|
var steps = toSteps(importPath);
|
||
|
|
||
|
var nonScopeSteps = steps.filter(function (step) {return step.indexOf('@') !== 0;});
|
||
|
if (nonScopeSteps.length <= 1) {return false;}
|
||
|
|
||
|
// before trying to resolve, see if the raw import (with relative
|
||
|
// segments resolved) matches an allowed pattern
|
||
|
var justSteps = steps.join('/');
|
||
|
if (reachingAllowed(justSteps) || reachingAllowed('/' + String(justSteps))) {return false;}
|
||
|
|
||
|
// if the import statement doesn't match directly, try to match the
|
||
|
// resolved path if the import is resolvable
|
||
|
var resolved = (0, _resolve2['default'])(importPath, context);
|
||
|
if (!resolved || reachingAllowed(normalizeSep(resolved))) {return false;}
|
||
|
|
||
|
// this import was not allowed by the allowed paths, and reaches
|
||
|
// so it is a violation
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function isForbidViolation(importPath) {
|
||
|
var steps = toSteps(importPath);
|
||
|
|
||
|
// before trying to resolve, see if the raw import (with relative
|
||
|
// segments resolved) matches a forbidden pattern
|
||
|
var justSteps = steps.join('/');
|
||
|
|
||
|
if (reachingForbidden(justSteps) || reachingForbidden('/' + String(justSteps))) {return true;}
|
||
|
|
||
|
// if the import statement doesn't match directly, try to match the
|
||
|
// resolved path if the import is resolvable
|
||
|
var resolved = (0, _resolve2['default'])(importPath, context);
|
||
|
if (resolved && reachingForbidden(normalizeSep(resolved))) {return true;}
|
||
|
|
||
|
// this import was not forbidden by the forbidden paths so it is not a violation
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// find a directory that is being reached into, but which shouldn't be
|
||
|
var isReachViolation = options.forbid ? isForbidViolation : isAllowViolation;
|
||
|
|
||
|
function checkImportForReaching(importPath, node) {
|
||
|
var potentialViolationTypes = ['parent', 'index', 'sibling', 'external', 'internal'];
|
||
|
if (
|
||
|
potentialViolationTypes.indexOf((0, _importType2['default'])(importPath, context)) !== -1 &&
|
||
|
isReachViolation(importPath))
|
||
|
{
|
||
|
context.report({
|
||
|
node: node,
|
||
|
message: 'Reaching to "' + String(importPath) + '" is not allowed.' });
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (0, _moduleVisitor2['default'])(
|
||
|
function (source) {
|
||
|
checkImportForReaching(source.value, source);
|
||
|
},
|
||
|
{ commonjs: true });
|
||
|
|
||
|
}return noReachingInside;}() };
|
||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1pbnRlcm5hbC1tb2R1bGVzLmpzIl0sIm5hbWVzIjpbIm1vZHVsZSIsImV4cG9ydHMiLCJtZXRhIiwidHlwZSIsImRvY3MiLCJjYXRlZ29yeSIsImRlc2NyaXB0aW9uIiwidXJsIiwic2NoZW1hIiwiYW55T2YiLCJwcm9wZXJ0aWVzIiwiYWxsb3ciLCJpdGVtcyIsImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiwiZm9yYmlkIiwiY3JlYXRlIiwibm9SZWFjaGluZ0luc2lkZSIsImNvbnRleHQiLCJvcHRpb25zIiwiYWxsb3dSZWdleHBzIiwibWFwIiwicCIsIm1pbmltYXRjaCIsIm1ha2VSZSIsImZvcmJpZFJlZ2V4cHMiLCJub3JtYWxpemVTZXAiLCJzb21lUGF0aCIsInNwbGl0Iiwiam9pbiIsInRvU3RlcHMiLCJmaWx0ZXIiLCJzdGVwIiwicmVkdWNlIiwiYWNjIiwic2xpY2UiLCJjb25jYXQiLCJyZWFjaGluZ0FsbG93ZWQiLCJpbXBvcnRQYXRoIiwic29tZSIsInJlIiwidGVzdCIsInJlYWNoaW5nRm9yYmlkZGVuIiwiaXNBbGxvd1Zpb2xhdGlvbiIsInN0ZXBzIiwibm9uU2NvcGVTdGVwcyIsImluZGV4T2YiLCJsZW5ndGgiLCJqdXN0U3RlcHMiLCJyZXNvbHZlZCIsImlzRm9yYmlkVmlvbGF0aW9uIiwiaXNSZWFjaFZpb2xhdGlvbiIsImNoZWNrSW1wb3J0Rm9yUmVhY2hpbmciLCJub2RlIiwicG90ZW50aWFsVmlvbGF0aW9uVHlwZXMiLCJyZXBvcnQiLCJtZXNzYWdlIiwic291cmNlIiwidmFsdWUiLCJjb21tb25qcyJdLCJtYXBwaW5ncyI6ImFBQUEsc0M7O0FBRUEsc0Q7QUFDQSxnRDtBQUNBLGtFO0FBQ0EscUM7O0FBRUFBLE9BQU9DLE9BQVAsR0FBaUI7QUFDZkMsUUFBTTtBQUNKQyxVQUFNLFlBREY7QUFFSkMsVUFBTTtBQUNKQyxnQkFBVSxpQkFETjtBQUVKQyxtQkFBYSxtREFGVDtBQUdKQyxXQUFLLDBCQUFR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
|