Skip to content

Commit

Permalink
fix(linter): rule no-restricted-imports support missing options
Browse files Browse the repository at this point in the history
  • Loading branch information
Sysix committed Dec 23, 2024
1 parent 0a19f9a commit 5296bb4
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 54 deletions.
142 changes: 88 additions & 54 deletions crates/oxc_linter/src/rules/eslint/no_restricted_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct RestrictedPattern {
import_names: Option<Vec<CompactStr>>,
import_name_pattern: Option<CompactStr>,
allow_import_names: Option<Vec<CompactStr>>,
allow_import_name_pattern: Option<CompactStr>,
case_sensitive: Option<bool>,
message: Option<CompactStr>,
}
Expand Down Expand Up @@ -150,11 +151,31 @@ fn add_configuration_patterns_from_object(
add_configuration_patterns_from_string(patterns, module_name);
}
Value::Object(_) => {
if let Ok(path) = serde_json::from_value::<RestrictedPattern>(path_value.clone()) {
if path.group.is_some() && path.regex.is_some() {
if let Ok(pattern) = serde_json::from_value::<RestrictedPattern>(path_value.clone())
{
if pattern.group.is_some() && pattern.regex.is_some() {
// ToDo: not allowed
}

// allowImportNames cannot be used in combination with importNames, importNamePattern or allowImportNamePattern.
if pattern.allow_import_names.is_some() && (
pattern.import_names.is_some()
|| pattern.import_name_pattern.is_some()
|| pattern.allow_import_name_pattern.is_some()
) {
// ToDo: not allowed
}

// allowImportNamePattern cannot be used in combination with importNames, importNamePattern or allowImportNames.
if pattern.allow_import_name_pattern.is_some()
&& (pattern.import_names.is_some()
|| pattern.import_name_pattern.is_some()
|| pattern.allow_import_names.is_some())
{
// ToDo: not allowed
}
patterns.push(path);

patterns.push(pattern);
}
}
_ => (),
Expand All @@ -169,6 +190,7 @@ fn add_configuration_patterns_from_string(paths: &mut Vec<RestrictedPattern>, mo
import_names: None,
import_name_pattern: None,
allow_import_names: None,
allow_import_name_pattern: None,
case_sensitive: None,
message: None,
});
Expand Down Expand Up @@ -200,6 +222,11 @@ fn is_name_span_allowed_in_pattern(name: &CompactStr, pattern: &RestrictedPatter
return true;
}

// fast check if this name is allowed
if pattern.get_allow_import_name_pattern_result(name) {
return true;
}

// when no importNames or importNamePattern option is provided, no import in general is allowed
if pattern.import_names.as_ref().is_none() && pattern.import_name_pattern.is_none() {
return false;
Expand Down Expand Up @@ -313,12 +340,19 @@ impl RestrictedPattern {
return false;
};

let flags = match self.case_sensitive {
Some(case_sensitive) if case_sensitive => "u",
_ => "iu",
let Ok(reg_exp) = Regex::with_flags(import_name_pattern.as_str(), "u") else {
return false;
};

let Ok(reg_exp) = Regex::with_flags(import_name_pattern.as_str(), flags) else {
reg_exp.find(name).is_some()
}

fn get_allow_import_name_pattern_result(&self, name: &CompactStr) -> bool {
let Some(allow_import_names) = &self.allow_import_name_pattern else {
return false;
};

let Ok(reg_exp) = Regex::with_flags(allow_import_names.as_str(), "u") else {
return false;
};

Expand Down Expand Up @@ -911,15 +945,15 @@ fn test() {
}]
}])),
),
// (
// "import { Foo } from 'foo';",
// Some(serde_json::json!([{
// "patterns": [{
// "group": ["foo"],
// "allowImportNamePattern": "^Foo"
// }]
// }])),
// ),
(
"import { Foo } from 'foo';",
Some(serde_json::json!([{
"patterns": [{
"group": ["foo"],
"allowImportNamePattern": "^Foo"
}]
}])),
),
(
r#"import withPatterns from "foo/bar";"#,
Some(
Expand Down Expand Up @@ -1726,25 +1760,25 @@ fn test() {
}]
}])),
),
// (
// "export { Bar } from 'foo';",
// Some(serde_json::json!([{
// "patterns": [{
// "group": ["foo"],
// "allowImportNamePattern": "^Foo"
// }]
// }])),
// ),
// (
// "export { Bar } from 'foo';",
// Some(serde_json::json!([{
// "patterns": [{
// "group": ["foo"],
// "allowImportNamePattern": "^Foo",
// "message": r#"Only imports that match the pattern "/^Foo/u" are allowed to be imported from "foo"."#
// }]
// }])),
// ),
(
"export { Bar } from 'foo';",
Some(serde_json::json!([{
"patterns": [{
"group": ["foo"],
"allowImportNamePattern": "^Foo"
}]
}])),
),
(
"export { Bar } from 'foo';",
Some(serde_json::json!([{
"patterns": [{
"group": ["foo"],
"allowImportNamePattern": "^Foo",
"message": r#"Only imports that match the pattern "/^Foo/u" are allowed to be imported from "foo"."#
}]
}])),
),
(
r#"import { AllowedObject, DisallowedObject } from "foo";"#,
Some(serde_json::json!([{
Expand Down Expand Up @@ -1821,25 +1855,25 @@ fn test() {
}]
}])),
),
// (
// r#"import * as AllowedObject from "foo/bar";"#,
// Some(serde_json::json!([{
// "patterns": [{
// "group": ["foo/*"],
// "allowImportNamePattern": "^Allow"
// }]
// }])),
// ),
// (
// r#"import * as AllowedObject from "foo/bar";"#,
// Some(serde_json::json!([{
// "patterns": [{
// "group": ["foo/*"],
// "allowImportNamePattern": "^Allow",
// "message": r#"Only import names starting with "Allow" are allowed to be imported from "foo"."#
// }]
// }])),
// ),
(
r#"import * as AllowedObject from "foo/bar";"#,
Some(serde_json::json!([{
"patterns": [{
"group": ["foo/*"],
"allowImportNamePattern": "^Allow"
}]
}])),
),
(
r#"import * as AllowedObject from "foo/bar";"#,
Some(serde_json::json!([{
"patterns": [{
"group": ["foo/*"],
"allowImportNamePattern": "^Allow",
"message": r#"Only import names starting with "Allow" are allowed to be imported from "foo"."#
}]
}])),
),
(
r#"import withPatterns from "foo/baz";"#,
Some(
Expand Down
28 changes: 28 additions & 0 deletions crates/oxc_linter/src/snapshots/eslint_no_restricted_imports.snap
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,20 @@ snapshot_kind: text
╰────
help: Remove the import statement.

eslint(no-restricted-imports): 'foo' import is restricted from being used.
╭─[no_restricted_imports.tsx:1:21]
1export { Bar } from 'foo';
· ─────
╰────
help: Remove the import statement.

eslint(no-restricted-imports): Only imports that match the pattern "/^Foo/u" are allowed to be imported from "foo".
╭─[no_restricted_imports.tsx:1:21]
1export { Bar } from 'foo';
· ─────
╰────
help: Remove the import statement.

eslint(no-restricted-imports): 'foo' import is restricted from being used.
╭─[no_restricted_imports.tsx:1:49]
1import { AllowedObject, DisallowedObject } from "foo";
Expand Down Expand Up @@ -807,6 +821,20 @@ snapshot_kind: text
╰────
help: Remove the import statement.

eslint(no-restricted-imports): 'foo/bar' import is restricted from being used.
╭─[no_restricted_imports.tsx:1:32]
1import * as AllowedObject from "foo/bar";
· ─────────
╰────
help: Remove the import statement.

eslint(no-restricted-imports): Only import names starting with "Allow" are allowed to be imported from "foo".
╭─[no_restricted_imports.tsx:1:32]
1import * as AllowedObject from "foo/bar";
· ─────────
╰────
help: Remove the import statement.

eslint(no-restricted-imports): foo is forbidden, use bar instead
╭─[no_restricted_imports.tsx:1:26]
1import withPatterns from "foo/baz";
Expand Down

0 comments on commit 5296bb4

Please sign in to comment.