mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
fix(linter): rule no-restricted-imports support missing options (#8076)
> The regex property is used to specify the regex patterns for restricting modules. > Note: regex cannot be used in combination with group. _https://eslint.org/docs/latest/rules/no-restricted-imports#regex_ > This option allows you to use regex patterns to restrict import names: _https://eslint.org/docs/latest/rules/no-restricted-imports#importnamepattern_ > This is a string option. Inverse of importNamePattern, this option allows imports that matches the specified regex pattern. So it restricts all imports from a module, except specified allowed patterns. > Note: allowImportNamePattern cannot be used in combination with importNames, importNamePattern or allowImportNames. _https://eslint.org/docs/latest/rules/no-restricted-imports#allowimportnamepattern_ Needed to install `regress` to support JS Sntax like Lookaheads and Lookbehinds Next Goals: - https://github.com/oxc-project/oxc/pull/7894 - Improve spans - Error for wrong configurations - update documentation - Output messages like [eslint](https://github.com/eslint/eslint/blob/main/lib/rules/no-restricted-imports.js#L140-L184)
This commit is contained in:
parent
8c6e0a6fa3
commit
41f2070895
2 changed files with 659 additions and 367 deletions
|
|
@ -2,9 +2,11 @@ use ignore::gitignore::GitignoreBuilder;
|
|||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
use oxc_span::{CompactStr, Span};
|
||||
use regex::Regex;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::Deserialize;
|
||||
use serde::{de::Error, Deserialize, Deserializer};
|
||||
use serde_json::Value;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::{
|
||||
context::LintContext,
|
||||
|
|
@ -48,21 +50,51 @@ pub struct NoRestrictedImportsConfig {
|
|||
#[serde(rename_all = "camelCase")]
|
||||
struct RestrictedPath {
|
||||
name: CompactStr,
|
||||
import_names: Option<Box<[CompactStr]>>,
|
||||
allow_import_names: Option<Box<[CompactStr]>>,
|
||||
import_names: Option<Vec<CompactStr>>,
|
||||
allow_import_names: Option<Vec<CompactStr>>,
|
||||
message: Option<CompactStr>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct RestrictedPattern {
|
||||
group: Vec<CompactStr>,
|
||||
import_names: Option<Box<[CompactStr]>>,
|
||||
allow_import_names: Option<Box<[CompactStr]>>,
|
||||
group: Option<Vec<CompactStr>>,
|
||||
regex: Option<SerdeRegexWrapper<Regex>>,
|
||||
import_names: Option<Vec<CompactStr>>,
|
||||
import_name_pattern: Option<SerdeRegexWrapper<Regex>>,
|
||||
allow_import_names: Option<Vec<CompactStr>>,
|
||||
allow_import_name_pattern: Option<SerdeRegexWrapper<Regex>>,
|
||||
case_sensitive: Option<bool>,
|
||||
message: Option<CompactStr>,
|
||||
}
|
||||
|
||||
/// A wrapper type which implements `Serialize` and `Deserialize` for
|
||||
/// types involving `Regex`
|
||||
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
|
||||
pub struct SerdeRegexWrapper<T>(pub T);
|
||||
|
||||
impl std::ops::Deref for SerdeRegexWrapper<Regex> {
|
||||
type Target = Regex;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for SerdeRegexWrapper<Regex> {
|
||||
fn deserialize<D>(d: D) -> Result<SerdeRegexWrapper<Regex>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = <Cow<str>>::deserialize(d)?;
|
||||
|
||||
match s.parse() {
|
||||
Ok(regex) => Ok(SerdeRegexWrapper(regex)),
|
||||
Err(err) => Err(D::Error::custom(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum GlobResult {
|
||||
Found,
|
||||
|
|
@ -148,8 +180,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()) {
|
||||
patterns.push(path);
|
||||
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(pattern);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
|
|
@ -159,9 +214,12 @@ fn add_configuration_patterns_from_object(
|
|||
|
||||
fn add_configuration_patterns_from_string(paths: &mut Vec<RestrictedPattern>, module_name: &str) {
|
||||
paths.push(RestrictedPattern {
|
||||
group: vec![CompactStr::new(module_name)],
|
||||
group: Some(vec![CompactStr::new(module_name)]),
|
||||
regex: None,
|
||||
import_names: None,
|
||||
import_name_pattern: None,
|
||||
allow_import_names: None,
|
||||
allow_import_name_pattern: None,
|
||||
case_sensitive: None,
|
||||
message: None,
|
||||
});
|
||||
|
|
@ -193,8 +251,13 @@ fn is_name_span_allowed_in_pattern(name: &CompactStr, pattern: &RestrictedPatter
|
|||
return true;
|
||||
}
|
||||
|
||||
// when no importNames option is provided, no import in general is allowed
|
||||
if pattern.import_names.as_ref().is_none() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
@ -203,6 +266,11 @@ fn is_name_span_allowed_in_pattern(name: &CompactStr, pattern: &RestrictedPatter
|
|||
return false;
|
||||
}
|
||||
|
||||
// the name is found is the importNamePattern
|
||||
if pattern.get_import_name_pattern_result(name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// we allow it
|
||||
true
|
||||
}
|
||||
|
|
@ -246,12 +314,16 @@ impl RestrictedPattern {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_gitignore_glob_result(&self, name: &NameSpan) -> GlobResult {
|
||||
fn get_group_glob_result(&self, name: &NameSpan) -> GlobResult {
|
||||
let Some(groups) = &self.group else {
|
||||
return GlobResult::None;
|
||||
};
|
||||
|
||||
let mut builder = GitignoreBuilder::new("");
|
||||
// returns always OK, will be fixed in the next version
|
||||
let _ = builder.case_insensitive(!self.case_sensitive.unwrap_or(false));
|
||||
|
||||
for group in &self.group {
|
||||
for group in groups {
|
||||
// returns always OK
|
||||
let _ = builder.add_line(None, group.as_str());
|
||||
}
|
||||
|
|
@ -274,6 +346,18 @@ impl RestrictedPattern {
|
|||
|
||||
GlobResult::Found
|
||||
}
|
||||
|
||||
fn get_regex_result(&self, name: &NameSpan) -> bool {
|
||||
self.regex.as_ref().is_some_and(|regex| regex.is_match(name.name()))
|
||||
}
|
||||
|
||||
fn get_import_name_pattern_result(&self, name: &CompactStr) -> bool {
|
||||
self.import_name_pattern.as_ref().is_some_and(|regex| regex.is_match(name))
|
||||
}
|
||||
|
||||
fn get_allow_import_name_pattern_result(&self, name: &CompactStr) -> bool {
|
||||
self.allow_import_name_pattern.as_ref().is_some_and(|regex| regex.is_match(name))
|
||||
}
|
||||
}
|
||||
|
||||
impl Rule for NoRestrictedImports {
|
||||
|
|
@ -397,7 +481,7 @@ impl NoRestrictedImports {
|
|||
continue;
|
||||
}
|
||||
|
||||
match pattern.get_gitignore_glob_result(&entry.module_request) {
|
||||
match pattern.get_group_glob_result(&entry.module_request) {
|
||||
GlobResult::Whitelist => {
|
||||
whitelist_found = true;
|
||||
break;
|
||||
|
|
@ -409,6 +493,12 @@ impl NoRestrictedImports {
|
|||
}
|
||||
GlobResult::None => (),
|
||||
};
|
||||
|
||||
if pattern.get_regex_result(&entry.module_request) {
|
||||
let span = entry.module_request.span();
|
||||
|
||||
no_restricted_imports_diagnostic(ctx, span, pattern.message.clone(), source);
|
||||
}
|
||||
}
|
||||
|
||||
if !whitelist_found && !found_errors.is_empty() {
|
||||
|
|
@ -450,7 +540,7 @@ impl NoRestrictedImports {
|
|||
continue;
|
||||
};
|
||||
|
||||
match pattern.get_gitignore_glob_result(module_request) {
|
||||
match pattern.get_group_glob_result(module_request) {
|
||||
GlobResult::Whitelist => {
|
||||
whitelist_found = true;
|
||||
break;
|
||||
|
|
@ -462,6 +552,12 @@ impl NoRestrictedImports {
|
|||
}
|
||||
GlobResult::None => (),
|
||||
};
|
||||
|
||||
if pattern.get_regex_result(module_request) {
|
||||
let span = module_request.span();
|
||||
|
||||
no_restricted_imports_diagnostic(ctx, span, pattern.message.clone(), source);
|
||||
}
|
||||
}
|
||||
|
||||
if !whitelist_found && !found_errors.is_empty() {
|
||||
|
|
@ -710,99 +806,99 @@ fn test() {
|
|||
}]
|
||||
}])),
|
||||
),
|
||||
// (
|
||||
// "import Foo from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import Foo from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Foo"],
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import Foo from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Bar } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Bar as Foo } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Bar as Foo } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Foo"],
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import Foo, { Baz as Bar } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^(Foo|Bar)"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import Foo, { Baz as Bar } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Foo"],
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Bar"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "export { Bar } from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "export { Bar as Foo } from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
(
|
||||
"import Foo from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import Foo from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Foo"],
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import Foo from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Bar } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Bar as Foo } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Bar as Foo } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Foo"],
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import Foo, { Baz as Bar } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^(Foo|Bar)"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import Foo, { Baz as Bar } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Foo"],
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Bar"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"export { Bar } from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"export { Bar as Foo } from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
r#"import { AllowedObject } from "foo";"#,
|
||||
Some(serde_json::json!([{
|
||||
|
|
@ -849,21 +945,21 @@ fn test() {
|
|||
}]
|
||||
}])),
|
||||
),
|
||||
// (
|
||||
// "import { Foo } from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "allowImportNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
(
|
||||
r#"import withPatterns from "foo/bar";"#,
|
||||
Some(
|
||||
serde_json::json!([{ "patterns": [{ "regex": "foo/(?!bar)", "message": "foo is forbidden, use bar instead" }] }]),
|
||||
),
|
||||
"import { Foo } from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"allowImportNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
// (
|
||||
// r#"import withPatterns from "foo/bar";"#,
|
||||
// Some(
|
||||
// serde_json::json!([{ "patterns": [{ "regex": "foo/(?!bar)", "message": "foo is forbidden, use bar instead" }] }]),
|
||||
// ),
|
||||
// ),
|
||||
(
|
||||
"import withPatternsCaseSensitive from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
|
|
@ -1475,214 +1571,214 @@ fn test() {
|
|||
}]
|
||||
}])),
|
||||
),
|
||||
// (
|
||||
// "import { Foo } from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Foo as Bar } from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import Foo, { Bar } from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^(Foo|Bar)"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Foo } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { FooBar } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import Foo, { Bar } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo|^Bar"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Foo, Bar } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^(Foo|Bar)"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import * as Foo from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import * as All from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import * as AllWithCustomMessage from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo",
|
||||
// "message": "Import from @/utils instead."
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import * as AllWithCustomMessage from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Foo"],
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo",
|
||||
// "message": "Import from @/utils instead."
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Foo } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Foo"],
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Foo } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Foo", "Bar"],
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Foo } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Bar"],
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Foo } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Foo"],
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Bar"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Foo, Bar } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Foo"],
|
||||
// "group": ["**/my/relative-module"],
|
||||
// "importNamePattern": "^Bar"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "export { Foo } from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "export { Foo as Bar } from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "export { Foo } from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "importNames": ["Bar"],
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "export * from 'foo';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "group": ["foo"],
|
||||
// "importNamePattern": "^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"."#
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
(
|
||||
"import { Foo } from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Foo as Bar } from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import Foo, { Bar } from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^(Foo|Bar)"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Foo } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { FooBar } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import Foo, { Bar } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo|^Bar"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Foo, Bar } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^(Foo|Bar)"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import * as Foo from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import * as All from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import * as AllWithCustomMessage from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo",
|
||||
"message": "Import from @/utils instead."
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import * as AllWithCustomMessage from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Foo"],
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo",
|
||||
"message": "Import from @/utils instead."
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Foo } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Foo"],
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Foo } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Foo", "Bar"],
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Foo } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Bar"],
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Foo } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Foo"],
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Bar"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Foo, Bar } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Foo"],
|
||||
"group": ["**/my/relative-module"],
|
||||
"importNamePattern": "^Bar"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"export { Foo } from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"export { Foo as Bar } from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"export { Foo } from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"importNames": ["Bar"],
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"export * from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"group": ["foo"],
|
||||
"importNamePattern": "^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!([{
|
||||
|
|
@ -1759,50 +1855,50 @@ 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(
|
||||
// serde_json::json!([{ "patterns": [{ "regex": "foo/(?!bar)", "message": "foo is forbidden, use bar instead" }] }]),
|
||||
// ),
|
||||
// ),
|
||||
// (
|
||||
// "import withPatternsCaseSensitive from 'FOO';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "regex": "FOO",
|
||||
// "message": "foo is forbidden, use bar instead",
|
||||
// "caseSensitive": true
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
// (
|
||||
// "import { Foo } from '../../my/relative-module';",
|
||||
// Some(serde_json::json!([{
|
||||
// "patterns": [{
|
||||
// "regex": "my/relative-module",
|
||||
// "importNamePattern": "^Foo"
|
||||
// }]
|
||||
// }])),
|
||||
// ),
|
||||
(
|
||||
"import withPatternsCaseSensitive from 'FOO';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"regex": "FOO",
|
||||
"message": "foo is forbidden, use bar instead",
|
||||
"caseSensitive": true
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import { Foo } from '../../my/relative-module';",
|
||||
Some(serde_json::json!([{
|
||||
"patterns": [{
|
||||
"regex": "my/relative-module",
|
||||
"importNamePattern": "^Foo"
|
||||
}]
|
||||
}])),
|
||||
),
|
||||
(
|
||||
"import withPatternsCaseSensitive from 'foo';",
|
||||
Some(serde_json::json!([{
|
||||
|
|
|
|||
|
|
@ -597,6 +597,174 @@ 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]
|
||||
1 │ import { Foo } from 'foo';
|
||||
· ─────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:28]
|
||||
1 │ import { Foo as Bar } from 'foo';
|
||||
· ─────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:26]
|
||||
1 │ import Foo, { Bar } from 'foo';
|
||||
· ─────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:21]
|
||||
1 │ import { Foo } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:24]
|
||||
1 │ import { FooBar } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:26]
|
||||
1 │ import Foo, { Bar } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:26]
|
||||
1 │ import { Foo, Bar } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:26]
|
||||
1 │ import { Foo, Bar } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:22]
|
||||
1 │ import * as Foo from 'foo';
|
||||
· ─────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:22]
|
||||
1 │ import * as All from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): Import from @/utils instead.
|
||||
╭─[no_restricted_imports.tsx:1:39]
|
||||
1 │ import * as AllWithCustomMessage from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): Import from @/utils instead.
|
||||
╭─[no_restricted_imports.tsx:1:39]
|
||||
1 │ import * as AllWithCustomMessage from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:21]
|
||||
1 │ import { Foo } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:21]
|
||||
1 │ import { Foo } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:21]
|
||||
1 │ import { Foo } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:21]
|
||||
1 │ import { Foo } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:26]
|
||||
1 │ import { Foo, Bar } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:26]
|
||||
1 │ import { Foo, Bar } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:21]
|
||||
1 │ export { Foo } from 'foo';
|
||||
· ─────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:28]
|
||||
1 │ export { Foo as Bar } from 'foo';
|
||||
· ─────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:21]
|
||||
1 │ export { Foo } from 'foo';
|
||||
· ─────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:15]
|
||||
1 │ export * from 'foo';
|
||||
· ─────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:21]
|
||||
1 │ export { 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]
|
||||
1 │ export { 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]
|
||||
1 │ import { AllowedObject, DisallowedObject } from "foo";
|
||||
|
|
@ -653,6 +821,34 @@ 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]
|
||||
1 │ import * 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]
|
||||
1 │ import * 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:39]
|
||||
1 │ import withPatternsCaseSensitive from 'FOO';
|
||||
· ─────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used.
|
||||
╭─[no_restricted_imports.tsx:1:21]
|
||||
1 │ import { Foo } from '../../my/relative-module';
|
||||
· ──────────────────────────
|
||||
╰────
|
||||
help: Remove the import statement.
|
||||
|
||||
⚠ eslint(no-restricted-imports): foo is forbidden, use bar instead
|
||||
╭─[no_restricted_imports.tsx:1:39]
|
||||
1 │ import withPatternsCaseSensitive from 'foo';
|
||||
|
|
|
|||
Loading…
Reference in a new issue