Skip to content

Commit c107e55

Browse files
author
Brijesh Bittu
committed
Sync with changes in core
1 parent d420d80 commit c107e55

File tree

4 files changed

+105
-1
lines changed

4 files changed

+105
-1
lines changed

packages/mui-infra/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"eslint-config-airbnb": "^19.0.4",
3737
"eslint-config-prettier": "^10.1.5",
3838
"eslint-import-resolver-typescript": "^4.4.1",
39+
"eslint-module-utils": "^2.12.0",
3940
"eslint-plugin-import": "^2.31.0",
4041
"eslint-plugin-jsx-a11y": "^6.10.2",
4142
"eslint-plugin-mocha": "^11.1.0",
@@ -44,6 +45,7 @@
4445
"eslint-plugin-react-hooks": "^6.0.0",
4546
"eslint-plugin-testing-library": "^7.2.2",
4647
"globals": "^16.2.0",
48+
"minimatch": "^10.0.1",
4749
"typescript-eslint": "^8.33.0"
4850
},
4951
"peerDependencies": {

packages/mui-infra/src/eslint/material-ui/index.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import docgenIgnoreBeforeComment from './rules/docgen-ignore-before-comment.mjs'
44
import muiNameMatchesComponentName from './rules/mui-name-matches-component-name.mjs';
55
import noEmptyBox from './rules/no-empty-box.mjs';
66
import noHardcodedLabels from './rules/no-hardcoded-labels.mjs';
7+
import noRestrictedResolvedImports from './rules/no-restricted-resolved-imports.mjs';
78
import noStyledBox from './rules/no-styled-box.mjs';
89
import rulesOfUseThemeVariants from './rules/rules-of-use-theme-variants.mjs';
910
import straightQuotes from './rules/straight-quotes.mjs';
@@ -26,5 +27,6 @@ export default {
2627
'no-styled-box': noStyledBox,
2728
'straight-quotes': straightQuotes,
2829
'disallow-react-api-in-server-components': disallowReactApiInServerComponents,
30+
'no-restricted-resolved-imports': noRestrictedResolvedImports,
2931
},
3032
};
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import moduleVisitor from 'eslint-module-utils/moduleVisitor';
2+
import resolve from 'eslint-module-utils/resolve';
3+
import minimatch from 'minimatch';
4+
import * as path from 'node:path';
5+
6+
/**
7+
* @typedef {Object} PatternConfig
8+
* @property {string} pattern - The pattern to match against resolved imports
9+
* @property {string} [message] - Custom message to show when the pattern matches
10+
*/
11+
12+
/**
13+
* Creates an ESLint rule that restricts imports based on their resolved paths.
14+
* Works with both ESM (import) and CommonJS (require) imports.
15+
*
16+
* @type {import('eslint').Rule.RuleModule}
17+
*/
18+
export default {
19+
meta: {
20+
docs: {
21+
description: 'Disallow imports that resolve to certain patterns.',
22+
},
23+
messages: {
24+
restrictedResolvedImport:
25+
'Importing from "{{importSource}}" is restricted because it resolves to "{{resolvedPath}}", which matches the pattern "{{pattern}}".{{customMessage}}',
26+
},
27+
type: 'suggestion',
28+
schema: [
29+
{
30+
type: 'array',
31+
items: {
32+
type: 'object',
33+
properties: {
34+
pattern: { type: 'string' },
35+
message: { type: 'string' },
36+
},
37+
required: ['pattern'],
38+
additionalProperties: false,
39+
},
40+
},
41+
],
42+
},
43+
create(context) {
44+
const options = context.options[0] || [];
45+
46+
if (!Array.isArray(options) || options.length === 0) {
47+
return {};
48+
}
49+
50+
return moduleVisitor(
51+
(source, node) => {
52+
// Get the resolved path of the import
53+
const resolvedPath = resolve(source.value, context);
54+
55+
if (!resolvedPath) {
56+
return;
57+
}
58+
59+
// Normalize the resolved path to use forward slashes
60+
const normalizedPath = resolvedPath.split(path.sep).join('/');
61+
62+
// Check each pattern against the resolved path
63+
for (const option of options) {
64+
const { pattern, message = '' } = option;
65+
66+
if (minimatch(normalizedPath, pattern)) {
67+
context.report({
68+
node,
69+
messageId: 'restrictedResolvedImport',
70+
data: {
71+
importSource: source.value,
72+
resolvedPath: normalizedPath,
73+
pattern,
74+
customMessage: message ? ` ${message}` : '',
75+
},
76+
});
77+
78+
// Stop after first match
79+
break;
80+
}
81+
}
82+
},
83+
{ commonjs: true, es6: true },
84+
); // This handles both require() and import statements
85+
},
86+
};

pnpm-lock.yaml

Lines changed: 15 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)