Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jsPlugins": [{ "name": "eslint-plugin-invalid", "specifier": "./plugin.ts" }],
"rules": {
"hahaha/no-debugger": "error"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
debugger;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Exit code
1

# stdout
```
Failed to parse configuration file.

x Failed to load JS plugin: ./plugin.ts
| Plugin alias 'eslint-plugin-invalid' is not valid. Must not start with 'eslint-plugin-', or be of form '@scope/eslint-plugin' or '@scope/eslint-plugin-name'.
```

# stderr
```
WARNING: JS plugins are experimental and not subject to semver.
Breaking changes are possible while JS plugins support is under development.
```
20 changes: 20 additions & 0 deletions apps/oxlint/test/fixtures/plugin_name_alias_invalid/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Plugin } from "#oxlint";

const plugin: Plugin = {
rules: {
"no-debugger": {
create(context) {
return {
DebuggerStatement(debuggerStatement) {
context.report({
message: "Unexpected Debugger Statement",
node: debuggerStatement,
});
},
};
},
},
},
};

export default plugin;
13 changes: 12 additions & 1 deletion crates/oxc_linter/src/config/config_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
ESLintRule, OxlintOverrides, OxlintRules,
external_plugins::ExternalPluginEntry,
overrides::OxlintOverride,
plugins::{LintPlugins, normalize_plugin_name},
plugins::{LintPlugins, is_normal_plugin_name, normalize_plugin_name},
},
external_linter::ExternalLinter,
external_plugin_store::{ExternalOptionsId, ExternalRuleId, ExternalRuleLookupError},
Expand Down Expand Up @@ -554,6 +554,17 @@ impl ConfigStoreBuilder {
// Use alias if provided.
// Otherwise use package name if the specifier is not relative, and normalize it.
let plugin_name = if let Some(alias_name) = alias {
// Check that the alias is valid - does not start with `eslint-plugin-` etc
if !is_normal_plugin_name(alias_name) {
return Err(ConfigBuilderError::PluginLoadFailed {
plugin_specifier: plugin_specifier.to_string(),
error: format!(
"Plugin alias '{alias_name}' is not valid. \
Must not start with 'eslint-plugin-', or be of form '@scope/eslint-plugin' \
or '@scope/eslint-plugin-name'."
),
});
}
Some(alias_name.to_string())
} else if let Some(pkg) = resolved.package_json()
&& let Some(package_name) = pkg.name()
Expand Down
14 changes: 14 additions & 0 deletions crates/oxc_linter/src/config/plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ pub fn normalize_plugin_name(plugin_name: &str) -> Cow<'_, str> {
Cow::Borrowed(plugin_name)
}

/// Checks if the given plugin name is valid.
///
/// Returns `true` if the given plugin name is already in its normalized form.
///
/// Returns `false` if it starts with `eslint-plugin-`, or is of the form `@scope/eslint-plugin`
/// or `@scope/eslint-plugin-something`.
pub fn is_normal_plugin_name(plugin_name: &str) -> bool {
let normalized = normalize_plugin_name(plugin_name);
match normalized {
Cow::Owned(_) => false,
Cow::Borrowed(normalized) => normalized.len() == plugin_name.len(),
}
}

bitflags! {
// NOTE: may be increased to a u32 if needed
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down
Loading