diff --git a/crates/oxc_linter/src/rules/eslint/no_restricted_imports.rs b/crates/oxc_linter/src/rules/eslint/no_restricted_imports.rs index 6b6976c9409d2..4a0b8673f4a9a 100644 --- a/crates/oxc_linter/src/rules/eslint/no_restricted_imports.rs +++ b/crates/oxc_linter/src/rules/eslint/no_restricted_imports.rs @@ -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, @@ -13,18 +15,130 @@ use crate::{ ModuleRecord, }; -fn no_restricted_imports_diagnostic( - ctx: &LintContext, +fn diagnostic_with_maybe_help(span: Span, msg: String, help: Option) -> OxcDiagnostic { + if let Some(help) = help { + return OxcDiagnostic::warn(msg).with_help(help).with_label(span); + } + + OxcDiagnostic::warn(msg).with_label(span) +} + +fn diagnostic_path(span: Span, help: Option, source: &str) -> OxcDiagnostic { + let msg = format!("'{source}' import is restricted from being used."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_pattern(span: Span, help: Option, source: &str) -> OxcDiagnostic { + let msg = format!("'{source}' import is restricted from being used by a pattern."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_pattern_and_import_name( span: Span, - message: Option, + help: Option, + name: &str, source: &str, -) { - let msg = message.unwrap_or_else(|| { - CompactStr::new(&format!("'{source}' import is restricted from being used.")) - }); - ctx.diagnostic( - OxcDiagnostic::warn(msg).with_help("Remove the import statement.").with_label(span), - ); +) -> OxcDiagnostic { + let msg = + format!("'{name}' import from '{source}' is restricted from being used by a pattern."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_pattern_and_everything( + span: Span, + help: Option, + name: &str, + source: &str, +) -> OxcDiagnostic { + let msg = + format!("* import is invalid because '{name}' from '{source}' is restricted from being used by a pattern."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_pattern_and_everything_with_regex_import_name( + span: Span, + help: Option, + name: &SerdeRegexWrapper, + source: &str, +) -> OxcDiagnostic { + let regex = name.as_str(); + let msg = + format!("* import is invalid because import name matching '{regex}' pattern from '{source}' is restricted from being used."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_everything( + span: Span, + help: Option, + name: &str, + source: &str, +) -> OxcDiagnostic { + let msg = format!("* import is invalid because '{name}' from '{source}' is restricted."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_import_name( + span: Span, + help: Option, + name: &str, + source: &str, +) -> OxcDiagnostic { + let msg = format!("'{name}' import from '{source}' is restricted."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_allowed_import_name( + span: Span, + help: Option, + name: &str, + source: &str, + allowed: &str, +) -> OxcDiagnostic { + let msg = format!("'{name}' import from '{source}' is restricted because only {allowed} import(s) is/are allowed."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_everything_with_allowed_import_name( + span: Span, + help: Option, + source: &str, + allowed: &str, +) -> OxcDiagnostic { + let msg = + format!("* import is invalid because only '{allowed}' from '{source}' is/are allowed."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_allowed_import_name_pattern( + span: Span, + help: Option, + name: &str, + source: &str, + allowed_pattern: &str, +) -> OxcDiagnostic { + let msg = format!("'{name}' import from '{source}' is restricted because only imports that match the pattern '{allowed_pattern}' are allowed from '{source}'."); + + diagnostic_with_maybe_help(span, msg, help) +} + +fn diagnostic_everything_with_allowed_import_name_pattern( + span: Span, + help: Option, + source: &str, + allowed_pattern: &str, +) -> OxcDiagnostic { + let msg = format!("* import is invalid because only imports that match the pattern '{allowed_pattern}' from '{source}' are allowed."); + + diagnostic_with_maybe_help(span, msg, help) } #[derive(Debug, Default, Clone)] @@ -48,21 +162,51 @@ pub struct NoRestrictedImportsConfig { #[serde(rename_all = "camelCase")] struct RestrictedPath { name: CompactStr, - import_names: Option>, - allow_import_names: Option>, + import_names: Option>, + allow_import_names: Option>, message: Option, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct RestrictedPattern { - group: Vec, - import_names: Option>, - allow_import_names: Option>, + group: Option>, + regex: Option>, + import_names: Option>, + import_name_pattern: Option>, + allow_import_names: Option>, + allow_import_name_pattern: Option>, case_sensitive: Option, message: Option, } +/// A wrapper type which implements `Serialize` and `Deserialize` for +/// types involving `Regex` +#[derive(Debug, Clone, Eq, Hash, PartialEq)] +pub struct SerdeRegexWrapper(pub T); + +impl std::ops::Deref for SerdeRegexWrapper { + type Target = Regex; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'de> Deserialize<'de> for SerdeRegexWrapper { + fn deserialize(d: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let s = >::deserialize(d)?; + + match s.parse() { + Ok(regex) => Ok(SerdeRegexWrapper(regex)), + Err(err) => Err(D::Error::custom(err)), + } + } +} + #[derive(Debug)] enum GlobResult { Found, @@ -147,8 +291,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::(path_value.clone()) { - patterns.push(path); + if let Ok(pattern) = serde_json::from_value::(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); } } _ => (), @@ -158,99 +325,205 @@ fn add_configuration_patterns_from_object( fn add_configuration_patterns_from_string(paths: &mut Vec, 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, }); } -fn is_name_span_allowed_in_path(name: &CompactStr, path: &RestrictedPath) -> bool { +#[derive(PartialEq)] +enum NameSpanAllowedResult { + Allowed, + GeneralDisallowed, + NameDisallowed, +} + +fn is_name_span_allowed_in_path(name: &CompactStr, path: &RestrictedPath) -> NameSpanAllowedResult { // fast check if this name is allowed if path.allow_import_names.as_ref().is_some_and(|allowed| allowed.contains(name)) { - return true; + return NameSpanAllowedResult::Allowed; } - // when no importNames option is provided, no import in general is allowed if path.import_names.as_ref().is_none() { - return false; + // when no importNames and no allowImportNames option is provided, no import in general is allowed + if path.allow_import_names.is_some() { + return NameSpanAllowedResult::NameDisallowed; + } + + return NameSpanAllowedResult::GeneralDisallowed; } // the name is found is the importNames list if path.import_names.as_ref().is_some_and(|disallowed| disallowed.contains(name)) { - return false; + return NameSpanAllowedResult::NameDisallowed; } // we allow it - true + NameSpanAllowedResult::Allowed } -fn is_name_span_allowed_in_pattern(name: &CompactStr, pattern: &RestrictedPattern) -> bool { +fn is_name_span_allowed_in_pattern( + name: &CompactStr, + pattern: &RestrictedPattern, +) -> NameSpanAllowedResult { // fast check if this name is allowed if pattern.allow_import_names.as_ref().is_some_and(|allowed| allowed.contains(name)) { - return true; + return NameSpanAllowedResult::Allowed; + } + + // fast check if this name is allowed + if pattern.get_allow_import_name_pattern_result(name) { + return NameSpanAllowedResult::Allowed; } - // when no importNames option is provided, no import in general is allowed - if pattern.import_names.as_ref().is_none() { - return false; + // 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() { + if pattern.allow_import_names.is_some() || pattern.allow_import_name_pattern.is_some() { + return NameSpanAllowedResult::NameDisallowed; + } + + return NameSpanAllowedResult::GeneralDisallowed; } // the name is found is the importNames list if pattern.import_names.as_ref().is_some_and(|disallowed| disallowed.contains(name)) { - return false; + return NameSpanAllowedResult::NameDisallowed; + } + + // the name is found is the importNamePattern + if pattern.get_import_name_pattern_result(name) { + return NameSpanAllowedResult::NameDisallowed; } // we allow it - true + NameSpanAllowedResult::Allowed +} + +#[derive(PartialEq, Debug)] +enum IsSkipAbleResult { + Allowed, + GeneralDisallowed(NameSpan), + DefaultDisallowed, + NameDisallowed(NameSpan), } impl RestrictedPath { - fn is_skip_able_import(&self, name: &ImportImportName) -> bool { + fn is_skip_able_import(&self, name: &ImportImportName) -> IsSkipAbleResult { match &name { - ImportImportName::Name(import) => is_name_span_allowed_in_path(&import.name, self), - ImportImportName::Default(_) => { - is_name_span_allowed_in_path(&CompactStr::new("default"), self) + ImportImportName::Name(import) => { + match is_name_span_allowed_in_path(&import.name, self) { + NameSpanAllowedResult::NameDisallowed => { + IsSkipAbleResult::NameDisallowed(import.clone()) + } + NameSpanAllowedResult::GeneralDisallowed => { + IsSkipAbleResult::GeneralDisallowed(import.clone()) + } + NameSpanAllowedResult::Allowed => IsSkipAbleResult::Allowed, + } + } + ImportImportName::Default(span) => { + let name = CompactStr::new("default"); + + match is_name_span_allowed_in_path(&name, self) { + NameSpanAllowedResult::NameDisallowed => { + IsSkipAbleResult::NameDisallowed(NameSpan::new(name, *span)) + } + NameSpanAllowedResult::GeneralDisallowed => { + IsSkipAbleResult::GeneralDisallowed(NameSpan::new(name, *span)) + } + NameSpanAllowedResult::Allowed => IsSkipAbleResult::Allowed, + } } - ImportImportName::NamespaceObject => false, + ImportImportName::NamespaceObject => IsSkipAbleResult::DefaultDisallowed, } } - fn is_skip_able_export(&self, name: &ExportImportName) -> bool { + fn is_skip_able_export(&self, name: &ExportImportName) -> IsSkipAbleResult { match &name { - ExportImportName::Name(import) => is_name_span_allowed_in_path(&import.name, self), - ExportImportName::All | ExportImportName::AllButDefault => false, - ExportImportName::Null => true, + ExportImportName::Name(import) => { + match is_name_span_allowed_in_path(&import.name, self) { + NameSpanAllowedResult::NameDisallowed => { + IsSkipAbleResult::NameDisallowed(import.clone()) + } + NameSpanAllowedResult::GeneralDisallowed => { + IsSkipAbleResult::GeneralDisallowed(import.clone()) + } + NameSpanAllowedResult::Allowed => IsSkipAbleResult::Allowed, + } + } + ExportImportName::All | ExportImportName::AllButDefault => { + IsSkipAbleResult::DefaultDisallowed + } + ExportImportName::Null => IsSkipAbleResult::Allowed, } } } impl RestrictedPattern { - fn is_skip_able_import(&self, name: &ImportImportName) -> bool { + fn is_skip_able_import(&self, name: &ImportImportName) -> IsSkipAbleResult { match &name { - ImportImportName::Name(import) => is_name_span_allowed_in_pattern(&import.name, self), - ImportImportName::Default(_) => { - is_name_span_allowed_in_pattern(&CompactStr::new("default"), self) + ImportImportName::Name(import) => { + match is_name_span_allowed_in_pattern(&import.name, self) { + NameSpanAllowedResult::NameDisallowed => { + IsSkipAbleResult::NameDisallowed(import.clone()) + } + NameSpanAllowedResult::GeneralDisallowed => { + IsSkipAbleResult::GeneralDisallowed(import.clone()) + } + NameSpanAllowedResult::Allowed => IsSkipAbleResult::Allowed, + } } - ImportImportName::NamespaceObject => false, + ImportImportName::Default(span) => { + let name: CompactStr = CompactStr::new("default"); + match is_name_span_allowed_in_pattern(&name, self) { + NameSpanAllowedResult::NameDisallowed => { + IsSkipAbleResult::NameDisallowed(NameSpan::new(name, *span)) + } + NameSpanAllowedResult::GeneralDisallowed => { + IsSkipAbleResult::GeneralDisallowed(NameSpan::new(name, *span)) + } + NameSpanAllowedResult::Allowed => IsSkipAbleResult::Allowed, + } + } + ImportImportName::NamespaceObject => IsSkipAbleResult::DefaultDisallowed, } } - fn is_skip_able_export(&self, name: &ExportImportName) -> bool { + fn is_skip_able_export(&self, name: &ExportImportName) -> IsSkipAbleResult { match &name { - ExportImportName::Name(import) => is_name_span_allowed_in_pattern(&import.name, self), - ExportImportName::All | ExportImportName::AllButDefault => false, - ExportImportName::Null => true, + ExportImportName::Name(import) => { + match is_name_span_allowed_in_pattern(&import.name, self) { + NameSpanAllowedResult::NameDisallowed => { + IsSkipAbleResult::NameDisallowed(import.clone()) + } + NameSpanAllowedResult::GeneralDisallowed => { + IsSkipAbleResult::GeneralDisallowed(import.clone()) + } + NameSpanAllowedResult::Allowed => IsSkipAbleResult::Allowed, + } + } + ExportImportName::All | ExportImportName::AllButDefault => { + IsSkipAbleResult::DefaultDisallowed + } + ExportImportName::Null => IsSkipAbleResult::Allowed, } } - 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()); } @@ -273,6 +546,30 @@ impl RestrictedPattern { GlobResult::Found } + + fn get_regex_result(&self, name: &NameSpan) -> bool { + let Some(regex) = &self.regex else { + return false; + }; + + regex.find(name.name()).is_some() + } + + fn get_import_name_pattern_result(&self, name: &CompactStr) -> bool { + let Some(import_name_pattern) = &self.import_name_pattern else { + return false; + }; + + import_name_pattern.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; + }; + + allow_import_names.find(name).is_some() + } } impl Rule for NoRestrictedImports { @@ -355,7 +652,7 @@ impl NoRestrictedImports { for (source, requests) in &module_record.requested_modules { for request in requests { if request.is_import && module_record.import_entries.is_empty() { - side_effect_import_map.entry(source).or_default().push(request.span); + side_effect_import_map.entry(source).or_default().push(request.statement_span); } } } @@ -364,7 +661,7 @@ impl NoRestrictedImports { for (source, spans) in &side_effect_import_map { if source.as_str() == path.name.as_str() && path.import_names.is_none() { if let Some(span) = spans.iter().next() { - no_restricted_imports_diagnostic(ctx, *span, path.message.clone(), source); + ctx.diagnostic(diagnostic_path(*span, path.message.clone(), source)); } } } @@ -379,40 +676,63 @@ impl NoRestrictedImports { continue; } - if path.is_skip_able_import(&entry.import_name) { + let result = &path.is_skip_able_import(&entry.import_name); + + if *result == IsSkipAbleResult::Allowed { continue; } - let span = entry.module_request.span(); + let diagnostic = get_diagnostic_from_is_skip_able_result_path( + entry.statement_span, + source, + result, + path, + ); - no_restricted_imports_diagnostic(ctx, span, path.message.clone(), source); + ctx.diagnostic(diagnostic); } let mut whitelist_found = false; let mut found_errors = vec![]; for pattern in &self.patterns { - if pattern.is_skip_able_import(&entry.import_name) { + let result = &pattern.is_skip_able_import(&entry.import_name); + + if *result == IsSkipAbleResult::Allowed { 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; } GlobResult::Found => { - let span = entry.module_request.span(); - - found_errors.push((span, pattern)); + let diagnostic = get_diagnostic_from_is_skip_able_result_pattern( + entry.statement_span, + source, + result, + pattern, + ); + + found_errors.push(diagnostic); } GlobResult::None => (), }; + + if pattern.get_regex_result(&entry.module_request) { + ctx.diagnostic(get_diagnostic_from_is_skip_able_result_pattern( + entry.statement_span, + source, + result, + pattern, + )); + } } if !whitelist_found && !found_errors.is_empty() { - for (span, pattern) in found_errors { - no_restricted_imports_diagnostic(ctx, span, pattern.message.clone(), source); + for diagnostic in found_errors { + ctx.diagnostic(diagnostic); } } } @@ -428,20 +748,25 @@ impl NoRestrictedImports { continue; } - if path.is_skip_able_export(&entry.import_name) { + let result = &path.is_skip_able_export(&entry.import_name); + + if *result == IsSkipAbleResult::Allowed { continue; } - let span = entry.span; + let diagnostic = + get_diagnostic_from_is_skip_able_result_path(entry.span, source, result, path); - no_restricted_imports_diagnostic(ctx, span, path.message.clone(), source); + ctx.diagnostic(diagnostic); } let mut whitelist_found = false; let mut found_errors = vec![]; for pattern in &self.patterns { - if pattern.is_skip_able_export(&entry.import_name) { + let result = &pattern.is_skip_able_export(&entry.import_name); + + if *result == IsSkipAbleResult::Allowed { continue; } @@ -449,25 +774,159 @@ 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; } GlobResult::Found => { - let span = module_request.span(); + let diagnostic = get_diagnostic_from_is_skip_able_result_pattern( + entry.span, source, result, pattern, + ); - found_errors.push((span, pattern)); + found_errors.push(diagnostic); } GlobResult::None => (), }; + + if pattern.get_regex_result(module_request) { + ctx.diagnostic(get_diagnostic_from_is_skip_able_result_pattern( + entry.span, source, result, pattern, + )); + } } if !whitelist_found && !found_errors.is_empty() { - for (span, pattern) in found_errors { - no_restricted_imports_diagnostic(ctx, span, pattern.message.clone(), source); + for diagnostic in found_errors { + ctx.diagnostic(diagnostic); + } + } + } +} + +fn get_diagnostic_from_is_skip_able_result_path( + span: Span, + source: &str, + result: &IsSkipAbleResult, + path: &RestrictedPath, +) -> OxcDiagnostic { + match result { + IsSkipAbleResult::GeneralDisallowed(_) => { + diagnostic_path(span, path.message.clone(), source) + } + IsSkipAbleResult::DefaultDisallowed => { + if let Some(import_names) = &path.import_names { + diagnostic_everything( + span, + path.message.clone(), + import_names.join(", ").as_str(), + source, + ) + } else if let Some(allowed_import_names) = &path.allow_import_names { + diagnostic_everything_with_allowed_import_name( + span, + path.message.clone(), + source, + allowed_import_names.join(", ").as_str(), + ) + } else { + diagnostic_path(span, path.message.clone(), source) + } + } + IsSkipAbleResult::NameDisallowed(name_span) => { + if let Some(allow_import_names) = &path.allow_import_names { + diagnostic_allowed_import_name( + name_span.clone().span(), + path.message.clone(), + name_span.name(), + source, + allow_import_names.join(", ").as_str(), + ) + } else { + diagnostic_import_name( + name_span.clone().span(), + path.message.clone(), + name_span.name(), + source, + ) + } + } + IsSkipAbleResult::Allowed => unreachable!("should be filtered out by the parent function"), + } +} + +fn get_diagnostic_from_is_skip_able_result_pattern( + span: Span, + source: &str, + result: &IsSkipAbleResult, + pattern: &RestrictedPattern, +) -> OxcDiagnostic { + match result { + IsSkipAbleResult::GeneralDisallowed(_) => { + diagnostic_pattern(span, pattern.message.clone(), source) + } + IsSkipAbleResult::DefaultDisallowed => { + let diagnostic = if let Some(import_names) = &pattern.import_names { + diagnostic_pattern_and_everything( + span, + pattern.message.clone(), + import_names.join(", ").as_str(), + source, + ) + } else if let Some(import_name_patterns) = &pattern.import_name_pattern { + diagnostic_pattern_and_everything_with_regex_import_name( + span, + pattern.message.clone(), + import_name_patterns, + source, + ) + } else if let Some(allow_import_name_pattern) = &pattern.allow_import_name_pattern { + diagnostic_everything_with_allowed_import_name_pattern( + span, + pattern.message.clone(), + source, + allow_import_name_pattern.as_str(), + ) + } else if let Some(allowed_import_names) = &pattern.allow_import_names { + diagnostic_everything_with_allowed_import_name( + span, + pattern.message.clone(), + source, + allowed_import_names.join(", ").as_str(), + ) + } else { + diagnostic_pattern(span, pattern.message.clone(), source) + }; + + diagnostic + } + IsSkipAbleResult::NameDisallowed(name_span) => { + if let Some(allow_import_names) = &pattern.allow_import_names { + diagnostic_allowed_import_name( + name_span.clone().span(), + pattern.message.clone(), + name_span.name(), + source, + allow_import_names.join(", ").as_str(), + ) + } else if let Some(allow_import_name_pattern) = &pattern.allow_import_name_pattern { + diagnostic_allowed_import_name_pattern( + name_span.clone().span(), + pattern.message.clone(), + name_span.name(), + source, + allow_import_name_pattern.as_str(), + ) + } else { + diagnostic_pattern_and_import_name( + name_span.clone().span(), + pattern.message.clone(), + name_span.name(), + source, + ) } } + IsSkipAbleResult::Allowed => unreachable!("should be filtered out by parent function"), } } @@ -709,160 +1168,160 @@ 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" - // }] - // }])), - // ), ( - r#"import { AllowedObject } from "foo";"#, + "import Foo from 'foo';", Some(serde_json::json!([{ - "paths": [{ - "name": "foo", - "allowImportNames": ["AllowedObject"], - "message": r#"Please import anything except "AllowedObject" from /bar/ instead."# + "patterns": [{ + "group": ["foo"], + "importNamePattern": "^Foo" }] }])), ), ( - "import { foo } from 'foo';", + "import Foo from 'foo';", Some(serde_json::json!([{ - "paths": [{ - "name": "foo", - "allowImportNames": ["foo"] + "patterns": [{ + "importNames": ["Foo"], + "group": ["foo"], + "importNamePattern": "^Foo" }] }])), ), ( - "import { foo } from 'foo';", + "import Foo from '../../my/relative-module';", Some(serde_json::json!([{ "patterns": [{ - "group": ["foo"], - "allowImportNames": ["foo"] + "group": ["**/my/relative-module"], + "importNamePattern": "^Foo" }] }])), ), ( - "export { bar } from 'foo';", + "import { Bar } from '../../my/relative-module';", Some(serde_json::json!([{ - "paths": [{ - "name": "foo", - "allowImportNames": ["bar"] + "patterns": [{ + "group": ["**/my/relative-module"], + "importNamePattern": "^Foo" }] }])), ), ( - "export { bar } from 'foo';", + "import { Bar as Foo } from '../../my/relative-module';", Some(serde_json::json!([{ "patterns": [{ - "group": ["foo"], - "allowImportNames": ["bar"] + "group": ["**/my/relative-module"], + "importNamePattern": "^Foo" }] }])), ), - // ( - // "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 { 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!([{ + "paths": [{ + "name": "foo", + "allowImportNames": ["AllowedObject"], + "message": r#"Please import anything except "AllowedObject" from /bar/ instead."# + }] + }])), + ), + ( + "import { foo } from 'foo';", + Some(serde_json::json!([{ + "paths": [{ + "name": "foo", + "allowImportNames": ["foo"] + }] + }])), + ), + ( + "import { foo } from 'foo';", + Some(serde_json::json!([{ + "patterns": [{ + "group": ["foo"], + "allowImportNames": ["foo"] + }] + }])), + ), + ( + "export { bar } from 'foo';", + Some(serde_json::json!([{ + "paths": [{ + "name": "foo", + "allowImportNames": ["bar"] + }] + }])), + ), + ( + "export { bar } from 'foo';", + Some(serde_json::json!([{ + "patterns": [{ + "group": ["foo"], + "allowImportNames": ["bar"] + }] + }])), ), + ( + "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!([{ @@ -935,6 +1394,7 @@ fn test() { ), (r#"export * from "fs";"#, Some(serde_json::json!(["fs"]))), (r#"export * as ns from "fs";"#, Some(serde_json::json!(["fs"]))), + // ToDo: wrong span (r#"export {a} from "fs";"#, Some(serde_json::json!(["fs"]))), ( r#"export {foo as b} from "fs";"#, @@ -986,6 +1446,7 @@ fn test() { }] }])), ), + // ToDo: wrong span ( r#"export * as ns from "fs";"#, Some(serde_json::json!([{ @@ -1474,214 +1935,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!([{ @@ -1758,50 +2219,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!([{ diff --git a/crates/oxc_linter/src/snapshots/eslint_no_restricted_imports.snap b/crates/oxc_linter/src/snapshots/eslint_no_restricted_imports.snap index fc8dde990dd5e..e95efbc77845b 100644 --- a/crates/oxc_linter/src/snapshots/eslint_no_restricted_imports.snap +++ b/crates/oxc_linter/src/snapshots/eslint_no_restricted_imports.snap @@ -3,659 +3,787 @@ source: crates/oxc_linter/src/tester.rs snapshot_kind: text --- ⚠ eslint(no-restricted-imports): 'fs' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:8] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import "fs" - · ──── + · ─────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): 'os' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:16] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import os from "os"; - · ──── + · ──────────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): 'foo/bar' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:8] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import "foo/bar"; - · ───────── + · ───────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): 'foo/bar' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:23] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withPaths from "foo/bar"; - · ───────── + · ──────────────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'foo/bar' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): 'foo/bar' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withPatterns from "foo/bar"; - · ───────── + · ─────────────────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): foo is forbidden, use foo/bar instead - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): 'foo/baz' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withPatterns from "foo/baz"; - · ───────── + · ─────────────────────────────────── ╰──── - help: Remove the import statement. + help: foo is forbidden, use foo/bar instead - ⚠ eslint(no-restricted-imports): some foo subimports are restricted - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): 'foo/baz' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withPatterns from "foo/baz"; - · ───────── + · ─────────────────────────────────── ╰──── - help: Remove the import statement. + help: some foo subimports are restricted - ⚠ eslint(no-restricted-imports): 'foo/bar' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): 'foo/bar' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withPatterns from "foo/bar"; - · ───────── + · ─────────────────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:41] + ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withPatternsCaseInsensitive from 'foo'; - · ───── + · ────────────────────────────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'foo/bar' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:28] + ⚠ eslint(no-restricted-imports): 'foo/bar' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withGitignores from "foo/bar"; - · ───────── + · ───────────────────────────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): 'fs' import is restricted from being used. ╭─[no_restricted_imports.tsx:1:1] 1 │ export * from "fs"; · ─────────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): 'fs' import is restricted from being used. ╭─[no_restricted_imports.tsx:1:1] 1 │ export * as ns from "fs"; · ───────────────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): 'fs' import is restricted from being used. ╭─[no_restricted_imports.tsx:1:9] 1 │ export {a} from "fs"; · ─ ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): Don"t import "foo". + ⚠ eslint(no-restricted-imports): 'foo' import from 'fs' is restricted. ╭─[no_restricted_imports.tsx:1:9] 1 │ export {foo as b} from "fs"; - · ──────── + · ─── ╰──── - help: Remove the import statement. + help: Don"t import "foo". - ⚠ eslint(no-restricted-imports): Don"t import "foo". + ⚠ eslint(no-restricted-imports): 'foo' import from 'fs' is restricted. ╭─[no_restricted_imports.tsx:1:9] 1 │ export {"foo" as b} from "fs"; - · ────────── + · ───── ╰──── - help: Remove the import statement. + help: Don"t import "foo". - ⚠ eslint(no-restricted-imports): Don"t import "foo". + ⚠ eslint(no-restricted-imports): 'foo' import from 'fs' is restricted. ╭─[no_restricted_imports.tsx:1:9] 1 │ export {"foo"} from "fs"; · ───── ╰──── - help: Remove the import statement. + help: Don"t import "foo". - ⚠ eslint(no-restricted-imports): Don"t import "👍". + ⚠ eslint(no-restricted-imports): '👍' import from 'fs' is restricted. ╭─[no_restricted_imports.tsx:1:9] 1 │ export {'👍'} from "fs"; · ──── ╰──── - help: Remove the import statement. + help: Don"t import "👍". - ⚠ eslint(no-restricted-imports): Don"t import "". + ⚠ eslint(no-restricted-imports): '' import from 'fs' is restricted. ╭─[no_restricted_imports.tsx:1:9] 1 │ export {''} from "fs"; · ── ╰──── - help: Remove the import statement. + help: Don"t import "". - ⚠ eslint(no-restricted-imports): Don"t import "foo". + ⚠ eslint(no-restricted-imports): * import is invalid because 'foo' from 'fs' is restricted. ╭─[no_restricted_imports.tsx:1:1] 1 │ export * as ns from "fs"; · ───────────────────────── ╰──── - help: Remove the import statement. + help: Don"t import "foo". - ⚠ eslint(no-restricted-imports): Please import from "bar" instead. - ╭─[no_restricted_imports.tsx:1:28] + ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withGitignores from "foo"; - · ───── + · ───────────────────────────────── ╰──── - help: Remove the import statement. + help: Please import from "bar" instead. - ⚠ eslint(no-restricted-imports): Please import from "baz" instead. - ╭─[no_restricted_imports.tsx:1:28] + ⚠ eslint(no-restricted-imports): 'bar' import is restricted from being used. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withGitignores from "bar"; - · ───── + · ───────────────────────────────── ╰──── - help: Remove the import statement. + help: Please import from "baz" instead. - ⚠ eslint(no-restricted-imports): Please import from "bar" instead. - ╭─[no_restricted_imports.tsx:1:28] + ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withGitignores from "foo"; - · ───── + · ───────────────────────────────── ╰──── - help: Remove the import statement. + help: Please import from "bar" instead. - ⚠ eslint(no-restricted-imports): Please import the default import of "foo" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:30] + ⚠ eslint(no-restricted-imports): 'default' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:8] 1 │ import DisallowedObject from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Please import the default import of "foo" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:22] + ⚠ eslint(no-restricted-imports): * import is invalid because 'DisallowedObject' from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import * as All from "foo"; - · ───── + · ─────────────────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" from /bar/ instead. + ⚠ eslint(no-restricted-imports): * import is invalid because 'DisallowedObject' from 'foo' is restricted. ╭─[no_restricted_imports.tsx:1:1] 1 │ export * from "foo"; · ──────────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" from /bar/ instead. - ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. + ⚠ eslint(no-restricted-imports): * import is invalid because 'DisallowedObject1, DisallowedObject2' from 'foo' is restricted. ╭─[no_restricted_imports.tsx:1:1] 1 │ export * from "foo"; · ──────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:34] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { DisallowedObject } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:51] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { DisallowedObject as AllowedObject } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:53] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { 'DisallowedObject' as AllowedObject } from "foo"; - · ───── + · ────────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" from /bar/ instead. - ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:31] + ⚠ eslint(no-restricted-imports): '👍' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { '👍' 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:27] + ⚠ eslint(no-restricted-imports): '' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { '' as bar } from "foo"; - · ───── + · ── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:49] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { AllowedObject, DisallowedObject } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:69] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { AllowedObject, DisallowedObject as AllowedObjectTwo } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" and "DisallowedObjectTwo" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:69] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { AllowedObject, DisallowedObject as AllowedObjectTwo } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" and "DisallowedObjectTwo" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" and "DisallowedObjectTwo" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:69] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { AllowedObject, DisallowedObject as AllowedObjectTwo } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" and "DisallowedObjectTwo" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import the default import of "foo" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:69] + ⚠ eslint(no-restricted-imports): 'default' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:8] 1 │ import DisallowedObject, { AllowedObject as AllowedObjectTwo } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Please import the default import of "foo" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:69] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import AllowedObject, { DisallowedObject as AllowedObjectTwo } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:50] + ⚠ eslint(no-restricted-imports): * import is invalid because 'DisallowedObject' from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import AllowedObject, * as AllowedObjectTwo from "foo"; - · ───── + · ─────────────────────────────────────────────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import "DisallowedObject" and "DisallowedObjectTwo" from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:50] + ⚠ eslint(no-restricted-imports): * import is invalid because 'DisallowedObject, DisallowedObjectTwo' from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import AllowedObject, * as AllowedObjectTwo from "foo"; - · ───── + · ─────────────────────────────────────────────────────── ╰──── - help: Remove the import statement. + help: Please import "DisallowedObject" and "DisallowedObjectTwo" from /bar/ instead. - ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:73] + ⚠ eslint(no-restricted-imports): 'DisallowedObjectOne' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { DisallowedObjectOne, DisallowedObjectTwo, AllowedObject } from "foo"; - · ───── + · ─────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:73] + ⚠ eslint(no-restricted-imports): 'DisallowedObjectTwo' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:31] 1 │ import { DisallowedObjectOne, DisallowedObjectTwo, AllowedObject } from "foo"; - · ───── + · ─────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): Please import this module from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:73] + ⚠ eslint(no-restricted-imports): 'DisallowedObjectOne' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { DisallowedObjectOne, DisallowedObjectTwo, AllowedObject } from "foo"; - · ───── + · ─────────────────── ╰──── - help: Remove the import statement. + help: Please import this module from /bar/ instead. - ⚠ eslint(no-restricted-imports): Please import this module from /bar/ instead. - ╭─[no_restricted_imports.tsx:1:73] + ⚠ eslint(no-restricted-imports): 'DisallowedObjectTwo' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:31] 1 │ import { DisallowedObjectOne, DisallowedObjectTwo, AllowedObject } from "foo"; - · ───── + · ─────────────────── ╰──── - help: Remove the import statement. + help: Please import this module from /bar/ instead. - ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:56] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { AllowedObject, DisallowedObject as Bar } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): 'bar' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:15] 1 │ import foo, { bar } from 'mod'; - · ───── + · ─── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): import Image from ui/_components instead - ╭─[no_restricted_imports.tsx:1:41] + ⚠ eslint(no-restricted-imports): 'Image' import from 'react-native' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { Image, Text, ScrollView } from 'react-native' - · ────────────── + · ───── ╰──── - help: Remove the import statement. + help: import Image from ui/_components instead - ⚠ eslint(no-restricted-imports): import Text from ui/_components instead - ╭─[no_restricted_imports.tsx:1:41] + ⚠ eslint(no-restricted-imports): 'Text' import from 'react-native' is restricted. + ╭─[no_restricted_imports.tsx:1:17] 1 │ import { Image, Text, ScrollView } from 'react-native' - · ────────────── + · ──── ╰──── - help: Remove the import statement. + help: import Text from ui/_components instead - ⚠ eslint(no-restricted-imports): import ScrollView from ui/_components instead - ╭─[no_restricted_imports.tsx:1:41] + ⚠ eslint(no-restricted-imports): 'ScrollView' import from 'react-native' is restricted. + ╭─[no_restricted_imports.tsx:1:23] 1 │ import { Image, Text, ScrollView } from 'react-native' - · ────────────── + · ────────── ╰──── - help: Remove the import statement. + help: import ScrollView from ui/_components instead - ⚠ eslint(no-restricted-imports): Import foo from qux instead. - ╭─[no_restricted_imports.tsx:1:31] + ⚠ eslint(no-restricted-imports): 'foo' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { foo, bar, baz } from 'mod' - · ───── + · ─── ╰──── - help: Remove the import statement. + help: Import foo from qux instead. - ⚠ eslint(no-restricted-imports): Import baz from qux instead. - ╭─[no_restricted_imports.tsx:1:31] + ⚠ eslint(no-restricted-imports): 'baz' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:20] 1 │ import { foo, bar, baz } from 'mod' - · ───── + · ─── ╰──── - help: Remove the import statement. + help: Import baz from qux instead. - ⚠ eslint(no-restricted-imports): Don"t use "foo" and `qux` from "mod". - ╭─[no_restricted_imports.tsx:1:36] + ⚠ eslint(no-restricted-imports): 'foo' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { foo, bar, baz, qux } from 'mod' - · ───── + · ─── ╰──── - help: Remove the import statement. + help: Don"t use "foo" and `qux` from "mod". - ⚠ eslint(no-restricted-imports): Use `barbaz` instead of `bar`. - ╭─[no_restricted_imports.tsx:1:36] + ⚠ eslint(no-restricted-imports): 'bar' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:15] 1 │ import { foo, bar, baz, qux } from 'mod' - · ───── + · ─── ╰──── - help: Remove the import statement. + help: Use `barbaz` instead of `bar`. - ⚠ eslint(no-restricted-imports): Don"t use "foo" and `qux` from "mod". - ╭─[no_restricted_imports.tsx:1:36] + ⚠ eslint(no-restricted-imports): 'qux' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { foo, bar, baz, qux } from 'mod' - · ───── + · ─── ╰──── - help: Remove the import statement. + help: Don"t use "foo" and `qux` from "mod". - ⚠ eslint(no-restricted-imports): Don"t use "foo" or "baz" from "mod". - ╭─[no_restricted_imports.tsx:1:36] + ⚠ eslint(no-restricted-imports): 'foo' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { foo, bar, baz, qux } from 'mod' - · ───── + · ─── ╰──── - help: Remove the import statement. + help: Don"t use "foo" or "baz" from "mod". - ⚠ eslint(no-restricted-imports): Use "b" or `bar` from "quux/mod" instead. - ╭─[no_restricted_imports.tsx:1:36] + ⚠ eslint(no-restricted-imports): 'bar' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:15] 1 │ import { foo, bar, baz, qux } from 'mod' - · ───── + · ─── ╰──── - help: Remove the import statement. + help: Use "b" or `bar` from "quux/mod" instead. - ⚠ eslint(no-restricted-imports): Don"t use "foo" or "baz" from "mod". - ╭─[no_restricted_imports.tsx:1:36] + ⚠ eslint(no-restricted-imports): 'baz' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:20] 1 │ import { foo, bar, baz, qux } from 'mod' - · ───── + · ─── ╰──── - help: Remove the import statement. + help: Don"t use "foo" or "baz" from "mod". - ⚠ eslint(no-restricted-imports): Import foo from qux instead. - ╭─[no_restricted_imports.tsx:1:22] + ⚠ eslint(no-restricted-imports): * import is invalid because 'foo' from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import * as mod from 'mod' - · ───── + · ────────────────────────── ╰──── - help: Remove the import statement. + help: Import foo from qux instead. - ⚠ eslint(no-restricted-imports): Import bar from qux instead. - ╭─[no_restricted_imports.tsx:1:22] + ⚠ eslint(no-restricted-imports): * import is invalid because 'bar' from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import * as mod from 'mod' - · ───── + · ────────────────────────── ╰──── - help: Remove the import statement. + help: Import bar from qux instead. ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:21] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import { foo } from 'mod' - · ───── + · ───────────────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:21] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import { bar } from 'mod' - · ───── + · ───────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): Import bar from qux instead. - ╭─[no_restricted_imports.tsx:1:21] + ⚠ eslint(no-restricted-imports): 'bar' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { bar } from 'mod' - · ───── + · ─── ╰──── - help: Remove the import statement. + help: Import bar from qux instead. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): 'default' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:8] 1 │ import foo, { bar } from 'mod'; - · ───── + · ─── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:27] + ⚠ eslint(no-restricted-imports): 'default' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:8] 1 │ import foo, * as bar from 'mod'; - · ───── + · ─── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:27] + ⚠ eslint(no-restricted-imports): * import is invalid because 'default' from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import foo, * as bar from 'mod'; - · ───── + · ──────────────────────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:22] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import * as bar from 'foo'; - · ───── + · ─────────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:27] + ⚠ eslint(no-restricted-imports): 'a' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { a, a as b } from 'mod'; - · ───── + · ─ ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:27] + ⚠ eslint(no-restricted-imports): 'a' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:13] 1 │ import { a, a as b } from 'mod'; - · ───── + · ─ ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. + ⚠ eslint(no-restricted-imports): 'x' import from 'mod' is restricted. ╭─[no_restricted_imports.tsx:1:10] 1 │ export { x as y, x as z } from 'mod'; - · ────── + · ─ ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. + ⚠ eslint(no-restricted-imports): 'x' import from 'mod' is restricted. ╭─[no_restricted_imports.tsx:1:18] 1 │ export { x as y, x as z } from 'mod'; - · ────── + · ─ ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:37] + ⚠ eslint(no-restricted-imports): 'default' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:8] 1 │ import foo, { default as bar } from 'mod'; - · ───── + · ─── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:37] + ⚠ eslint(no-restricted-imports): 'default' import from 'mod' is restricted. + ╭─[no_restricted_imports.tsx:1:15] 1 │ import foo, { default as bar } from 'mod'; - · ───── + · ─────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): '../foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:22] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import relative from '../foo'; - · ──────── + · ────────────────────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): '../foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:31] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import relativeWithPaths from '../foo'; - · ──────── + · ─────────────────────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): '../foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:34] + ⚠ eslint(no-restricted-imports): '../foo' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import relativeWithPatterns from '../foo'; - · ──────── + · ────────────────────────────────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): '/foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:22] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import absolute from '/foo'; - · ────── + · ──────────────────────────── ╰──── - help: Remove the import statement. ⚠ eslint(no-restricted-imports): '/foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:31] + ╭─[no_restricted_imports.tsx:1:1] 1 │ import absoluteWithPaths from '/foo'; - · ────── + · ───────────────────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): '/foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:34] + ⚠ eslint(no-restricted-imports): '/foo' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import absoluteWithPatterns 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] + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { Foo } from '../../my/relative-module'; - · ────────────────────────── + · ─── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): Import from @/utils instead. - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] 1 │ import { Foo, Bar } from '../../my/relative-module'; - · ────────────────────────── + · ─── ╰──── - help: Remove the import statement. + help: Import from @/utils instead. - ⚠ eslint(no-restricted-imports): Import from @/utils instead. - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): 'Bar' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:15] 1 │ import { Foo, Bar } from '../../my/relative-module'; - · ────────────────────────── + · ─── ╰──── - help: Remove the import statement. + help: Import from @/utils instead. - ⚠ eslint(no-restricted-imports): '../../my/relative-module' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:22] + ⚠ eslint(no-restricted-imports): * import is invalid because 'Foo' from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 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] + ⚠ eslint(no-restricted-imports): * import is invalid because 'Foo' from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import * as AllWithCustomMessage from '../../my/relative-module'; - · ────────────────────────── + · ───────────────────────────────────────────────────────────────── ╰──── - help: Remove the import statement. + help: Import from @/utils instead. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): 'default' import from 'mod' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:8] 1 │ import def, * as ns from 'mod'; - · ───── + · ─── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:26] + ⚠ eslint(no-restricted-imports): * import is invalid because 'default' from 'mod' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import def, * as ns from 'mod'; - · ───── + · ─────────────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'mod' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:17] + ⚠ eslint(no-restricted-imports): 'default' import from 'mod' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:8] 1 │ import Foo from 'mod'; - · ───── + · ─── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:49] + ⚠ eslint(no-restricted-imports): 'Foo' import from 'foo' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo } from 'foo'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from 'foo' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo as Bar } from 'foo'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Bar' import from 'foo' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:15] + 1 │ import Foo, { Bar } from 'foo'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'FooBar' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { FooBar } from '../../my/relative-module'; + · ────── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Bar' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:15] + 1 │ import Foo, { Bar } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo, Bar } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Bar' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:15] + 1 │ import { Foo, Bar } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): * import is invalid because import name matching '^Foo' pattern from 'foo' is restricted from being used. + ╭─[no_restricted_imports.tsx:1:1] + 1 │ import * as Foo from 'foo'; + · ─────────────────────────── + ╰──── + + ⚠ eslint(no-restricted-imports): * import is invalid because import name matching '^Foo' pattern from '../../my/relative-module' is restricted from being used. + ╭─[no_restricted_imports.tsx:1:1] + 1 │ import * as All from '../../my/relative-module'; + · ──────────────────────────────────────────────── + ╰──── + + ⚠ eslint(no-restricted-imports): * import is invalid because import name matching '^Foo' pattern from '../../my/relative-module' is restricted from being used. + ╭─[no_restricted_imports.tsx:1:1] + 1 │ import * as AllWithCustomMessage from '../../my/relative-module'; + · ───────────────────────────────────────────────────────────────── + ╰──── + help: Import from @/utils instead. + + ⚠ eslint(no-restricted-imports): * import is invalid because 'Foo' from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] + 1 │ import * as AllWithCustomMessage from '../../my/relative-module'; + · ───────────────────────────────────────────────────────────────── + ╰──── + help: Import from @/utils instead. + + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo, Bar } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Bar' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:15] + 1 │ import { Foo, Bar } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from 'foo' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ export { Foo } from 'foo'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from 'foo' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ export { Foo as Bar } from 'foo'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Foo' import from 'foo' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ export { Foo } from 'foo'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): * import is invalid because import name matching '^Foo' pattern from 'foo' is restricted from being used. + ╭─[no_restricted_imports.tsx:1:1] + 1 │ export * from 'foo'; + · ──────────────────── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Bar' import from 'foo' is restricted because only imports that match the pattern '^Foo' are allowed from 'foo'. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ export { Bar } from 'foo'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'Bar' import from 'foo' is restricted because only imports that match the pattern '^Foo' are allowed from 'foo'. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ export { Bar } from 'foo'; + · ─── + ╰──── + help: Only imports that match the pattern "/^Foo/u" are allowed to be imported from "foo". + + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted because only AllowedObject import(s) is/are allowed. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { AllowedObject, DisallowedObject } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): Only "AllowedObject" is allowed to be imported from "foo". - ╭─[no_restricted_imports.tsx:1:49] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted because only AllowedObject import(s) is/are allowed. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { AllowedObject, DisallowedObject } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Only "AllowedObject" is allowed to be imported from "foo". - ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:49] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted because only AllowedObject import(s) is/are allowed. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { AllowedObject, DisallowedObject } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): Only "AllowedObject" is allowed to be imported from "foo". - ╭─[no_restricted_imports.tsx:1:49] + ⚠ eslint(no-restricted-imports): 'DisallowedObject' import from 'foo' is restricted because only AllowedObject import(s) is/are allowed. + ╭─[no_restricted_imports.tsx:1:25] 1 │ import { AllowedObject, DisallowedObject } from "foo"; - · ───── + · ──────────────── ╰──── - help: Remove the import statement. + help: Only "AllowedObject" is allowed to be imported from "foo". - ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:32] + ⚠ eslint(no-restricted-imports): * import is invalid because only 'AllowedObject' from 'foo' is/are allowed. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import * as AllowedObject from "foo"; - · ───── + · ───────────────────────────────────── ╰──── - help: Remove the import statement. - ⚠ eslint(no-restricted-imports): Only "AllowedObject" is allowed to be imported from "foo". - ╭─[no_restricted_imports.tsx:1:32] + ⚠ eslint(no-restricted-imports): * import is invalid because only 'AllowedObject' from 'foo' is/are allowed. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import * as AllowedObject from "foo"; - · ───── + · ───────────────────────────────────── ╰──── - help: Remove the import statement. + help: Only "AllowedObject" is allowed to be imported from "foo". - ⚠ eslint(no-restricted-imports): 'foo/bar' import is restricted from being used. - ╭─[no_restricted_imports.tsx:1:32] + ⚠ eslint(no-restricted-imports): * import is invalid because only 'AllowedObject' from 'foo/bar' is/are allowed. + ╭─[no_restricted_imports.tsx:1:1] + 1 │ import * as AllowedObject from "foo/bar"; + · ───────────────────────────────────────── + ╰──── + + ⚠ eslint(no-restricted-imports): * import is invalid because only 'AllowedObject' from 'foo/bar' is/are allowed. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import * as AllowedObject from "foo/bar"; - · ───────── + · ───────────────────────────────────────── ╰──── - help: Remove the import statement. + help: Only "AllowedObject" is allowed to be imported from "foo". - ⚠ eslint(no-restricted-imports): Only "AllowedObject" is allowed to be imported from "foo". - ╭─[no_restricted_imports.tsx:1:32] + ⚠ eslint(no-restricted-imports): * import is invalid because only imports that match the pattern '^Allow' from 'foo/bar' are allowed. + ╭─[no_restricted_imports.tsx:1:1] 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] + ⚠ eslint(no-restricted-imports): * import is invalid because only imports that match the pattern '^Allow' from 'foo/bar' are allowed. + ╭─[no_restricted_imports.tsx:1:1] + 1 │ import * as AllowedObject from "foo/bar"; + · ───────────────────────────────────────── + ╰──── + help: Only import names starting with "Allow" are allowed to be imported from "foo". + + ⚠ eslint(no-restricted-imports): 'FOO' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] + 1 │ import withPatternsCaseSensitive from 'FOO'; + · ──────────────────────────────────────────── + ╰──── + help: foo is forbidden, use bar instead + + ⚠ eslint(no-restricted-imports): 'Foo' import from '../../my/relative-module' is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:10] + 1 │ import { Foo } from '../../my/relative-module'; + · ─── + ╰──── + + ⚠ eslint(no-restricted-imports): 'foo' import is restricted from being used by a pattern. + ╭─[no_restricted_imports.tsx:1:1] 1 │ import withPatternsCaseSensitive from 'foo'; - · ───── + · ──────────────────────────────────────────── ╰──── - help: Remove the import statement. + help: foo is forbidden, use bar instead