Repository navigation
Expand file tree
/
Copy patheslint-plugin-local.js
More file actions
103 lines (98 loc) · 3.65 KB
/
Copy patheslint-plugin-local.js
File metadata and controls
103 lines (98 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// @ts-check
import path from 'node:path';
/**
* @type {{[ruleName: string]: import('eslint').Rule.RuleModule}}
*/
export const localRules = {
'jsx-uses-m-pragma': {
create(context) {
const pragma = 'm';
const usePragma = () => context.markVariableAsUsed(pragma);
return {
JSXOpeningElement: usePragma,
JSXOpeningFragment: usePragma,
};
},
},
'jsx-uses-vars': {
create(context) {
return {
/**
* @param {{ name: any; }} node
*/
JSXOpeningElement(node) {
let variable;
const jsxTag = node.name;
if (jsxTag.type === 'JSXIdentifier') {
variable = jsxTag.name;
} else if (jsxTag.type === 'JSXMemberExpression') {
variable = jsxTag.object.name;
} else {
console.warn('Unsupported JSX identifier', jsxTag);
}
context.markVariableAsUsed(variable);
},
};
},
},
'no-restricted-paths': {
meta: {
type: 'problem',
schema: [
{
type: 'object',
properties: {
zones: {
type: 'array',
items: {
type: 'object',
properties: {
target: {type: 'string'},
from: {type: 'string'},
},
required: ['target', 'from'],
additionalProperties: false,
},
},
},
additionalProperties: false,
},
],
},
create(context) {
const cwd = context.cwd;
const filename = context.filename;
const zones = (context.options[0] && context.options[0].zones) || [];
const absoluteZones = zones.map((/** @type {{target: string; from: string}} */zone) => ({
target: path.resolve(cwd, zone.target),
from: path.resolve(cwd, zone.from),
}));
/** @type {(dir: string, file: string) => boolean} */
function isWithin(dir, file) {
const rel = path.relative(dir, file);
return rel !== '' && !rel.startsWith('..') && !path.isAbsolute(rel);
}
function check(/** @type {any} */node) {
const source = node.source;
if (!source || typeof source.value !== 'string' || !source.value.startsWith('.')) {
return;
}
const resolved = path.resolve(path.dirname(filename), source.value);
for (const zone of absoluteZones) {
if (isWithin(zone.target, filename) && isWithin(zone.from, resolved)) {
context.report({
node: source,
message: `Importing from "${path.relative(cwd, zone.from)}" is not allowed in "${path.relative(cwd, zone.target)}"`,
});
return;
}
}
}
return {
ImportDeclaration: check,
ExportNamedDeclaration: check,
ExportAllDeclaration: check,
};
},
},
};