refactor(linter): add MixedTupleRuleConfig (#23396)

Added a new struct for 3 rules:
- `eslint/func-name-matching`
- `import/extension`
- `react/jsx-no-script-url`

These rules accept an enum configuration like:
```rust
enum ConfigOptions {
 First(Option1),
 Second(Option2),
 Both(Option1, Option2)
}
```

Added the new struct for `eslint/func-name-matching` to test if the expected result matches the upstream configuration.
Changed the rule schema generation code, so enums (`subschema with any_of`), will be folded, Allowing us to support the 3 rules.
This commit is contained in:
Sysix committed 2026-06-15 16:53:26 +00:00
1 parent a8dce46fcd
commit fef29bdbce
6 files changed
+511 -237

No files matched your search

+28 -10
View File
@@ -80,12 +80,13 @@ export type CurlyType = "all" | "multi" | "multi-line" | "multi-or-nest";
export type CurlyConsistent = "consistent";
export type CompareType = "always" | "smart";
export type NullType = "always" | "never" | "ignore";
export type DummyRule = AllowWarnDeny | [AllowWarnDeny, ...unknown[]];
export type FuncNameMatchingMode = "always" | "never";
export type FuncNamesConfigType = "always" | "as-needed" | "never";
export type Style = "expression" | "declaration";
export type NamedExports = "ignore" | "expression" | "declaration";
export type PairOrder = "anyOrder" | "getBeforeSet" | "setBeforeGet";
export type Mode = "prefer-top-level" | "prefer-inline";
export type DummyRule = AllowWarnDeny | [AllowWarnDeny, ...unknown[]];
export type AbsoluteFirst = "absolute-first" | "disable-absolute-first";
export type MaxDependenciesConfigJson = number | MaxDependenciesConfig;
export type Target = "single" | "any";
@@ -829,7 +830,7 @@ export interface DummyRuleMap {
"block-scoped-var"?: RuleNoConfig;
"capitalized-comments"?: RuleNoConfig | [AllowWarnDeny, AlwaysNever] | [AllowWarnDeny, AlwaysNever, OptionsJsonEnum];
"class-methods-use-this"?: RuleNoConfig | [AllowWarnDeny, ClassMethodsUseThisConfig];
complexity?: RuleNoConfig | [AllowWarnDeny, number | ComplexityConfig];
complexity?: RuleNoConfig | ([AllowWarnDeny, number] | [AllowWarnDeny, ComplexityConfig]);
"constructor-super"?: RuleNoConfig;
curly?: RuleNoConfig | [AllowWarnDeny, CurlyType] | [AllowWarnDeny, CurlyType, CurlyConsistent];
"default-case"?: RuleNoConfig | [AllowWarnDeny, DefaultCaseConfig];
@@ -837,7 +838,14 @@ export interface DummyRuleMap {
"default-param-last"?: RuleNoConfig;
eqeqeq?: RuleNoConfig | [AllowWarnDeny, CompareType] | [AllowWarnDeny, CompareType, EqeqeqOptions];
"for-direction"?: RuleNoConfig;
"func-name-matching"?: DummyRule;
"func-name-matching"?:
| RuleNoConfig
| (
| [AllowWarnDeny, FuncNameMatchingMode]
| [AllowWarnDeny, FuncNameMatchingMode, FuncNameMatchingConfig]
| [AllowWarnDeny, FuncNameMatchingMode]
| [AllowWarnDeny, FuncNameMatchingConfig]
);
"func-names"?:
| RuleNoConfig
| [AllowWarnDeny, FuncNamesConfigType]
@@ -1014,13 +1022,13 @@ export interface DummyRuleMap {
| RuleNoConfig
| [AllowWarnDeny, AlwaysNever]
| [AllowWarnDeny, AlwaysNever, LogicalAssignmentOperatorsConfig];
"max-classes-per-file"?: RuleNoConfig | [AllowWarnDeny, number | MaxClassesPerFileConfig];
"max-depth"?: RuleNoConfig | [AllowWarnDeny, number | MaxDepth];
"max-lines"?: RuleNoConfig | [AllowWarnDeny, number | MaxLinesConfig];
"max-lines-per-function"?: RuleNoConfig | [AllowWarnDeny, number | MaxLinesPerFunctionConfig];
"max-nested-callbacks"?: RuleNoConfig | [AllowWarnDeny, number | MaxNestedCallbacks];
"max-params"?: RuleNoConfig | [AllowWarnDeny, number | MaxParamsConfig];
"max-statements"?: RuleNoConfig | [AllowWarnDeny, number | MaxStatementsConfig];
"max-classes-per-file"?: RuleNoConfig | ([AllowWarnDeny, number] | [AllowWarnDeny, MaxClassesPerFileConfig]);
"max-depth"?: RuleNoConfig | ([AllowWarnDeny, number] | [AllowWarnDeny, MaxDepth]);
"max-lines"?: RuleNoConfig | ([AllowWarnDeny, number] | [AllowWarnDeny, MaxLinesConfig]);
"max-lines-per-function"?: RuleNoConfig | ([AllowWarnDeny, number] | [AllowWarnDeny, MaxLinesPerFunctionConfig]);
"max-nested-callbacks"?: RuleNoConfig | ([AllowWarnDeny, number] | [AllowWarnDeny, MaxNestedCallbacks]);
"max-params"?: RuleNoConfig | ([AllowWarnDeny, number] | [AllowWarnDeny, MaxParamsConfig]);
"max-statements"?: RuleNoConfig | ([AllowWarnDeny, number] | [AllowWarnDeny, MaxStatementsConfig]);
"new-cap"?: RuleNoConfig | [AllowWarnDeny, NewCapConfig];
"nextjs/google-font-display"?: RuleNoConfig;
"nextjs/google-font-preconnect"?: RuleNoConfig;
@@ -1800,6 +1808,16 @@ export interface EqeqeqOptions {
*/
null?: NullType;
}
export interface FuncNameMatchingConfig {
/**
* If `considerPropertyDescriptor` is set to `true`, the check will take into account the use of `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty`.
*/
considerPropertyDescriptor?: boolean;
/**
* If `includeCommonJSModuleExports` is set to `true`, `module.exports` and `module["exports"]` will be checked by this rule.
*/
includeCommonJSModuleExports?: boolean;
}
export interface FuncNamesGeneratorsConfig {
/**
* Configuration for generator function expressions. If not specified, uses the
+112 -93
View File
@@ -397,104 +397,123 @@ impl JsonSchema for OxlintRules {
.into()
}
fn append_allow_warn_deny_to_schema(
config_schema: Schema,
r#gen: &mut SchemaGenerator,
) -> Schema {
let Schema::Object(mut obj) = config_schema else {
return SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(ArrayValidation {
items: Some(SingleOrVec::Vec(vec![
r#gen.subschema_for::<AllowWarnDeny>(),
config_schema,
])),
min_items: Some(2),
max_items: Some(2),
..Default::default()
})),
..Default::default()
}
.into();
};
debug_assert!(
(u8::from(obj.array.is_some())
+ u8::from(obj.object.is_some())
+ u8::from(obj.reference.is_some()))
<= 1,
"Expected rule schema to be either an object, an array, or a reference, but not multiple"
);
if let Some(reference) = obj.reference {
return SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(ArrayValidation {
items: Some(SingleOrVec::Vec(vec![
r#gen.subschema_for::<AllowWarnDeny>(),
Schema::Object(SchemaObject {
reference: Some(reference),
..Default::default()
}),
])),
min_items: Some(2),
max_items: Some(2),
..Default::default()
})),
..Default::default()
}
.into();
}
if let Some(array) = obj.array {
let items = match array.items {
None => vec![r#gen.subschema_for::<AllowWarnDeny>()],
Some(SingleOrVec::Single(config)) => {
vec![r#gen.subschema_for::<AllowWarnDeny>(), *config]
}
Some(SingleOrVec::Vec(configs)) => {
let mut items =
Vec::with_capacity(configs.len().saturating_add(1));
items.push(r#gen.subschema_for::<AllowWarnDeny>());
items.extend(configs);
items
}
};
let config_length = items.len() as u32;
return SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(ArrayValidation {
items: Some(SingleOrVec::Vec(items)),
min_items: Some(2),
max_items: Some(config_length),
..Default::default()
})),
..Default::default()
}
.into();
}
if let Some(subschemas) = &mut obj.subschemas
&& let Some(any_of) = &subschemas.any_of
{
subschemas.any_of = Some(
any_of
.iter()
.map(|schema| {
append_allow_warn_deny_to_schema(schema.clone(), r#gen)
})
.collect(),
);
return obj.into();
}
SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(ArrayValidation {
items: Some(SingleOrVec::Vec(vec![
r#gen.subschema_for::<AllowWarnDeny>(),
Schema::Object(obj),
])),
min_items: Some(2),
max_items: Some(2),
..Default::default()
})),
..Default::default()
}
.into()
}
let Some(schema) = r.schema(r#gen) else {
return r#gen.subschema_for::<RuleNoConfig>();
};
let schema = resolve_references_in_schema(&schema, r#gen).clone();
let Schema::Object(obj) = schema else {
let array_schema = SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(ArrayValidation {
items: Some(SingleOrVec::Vec(vec![
r#gen.subschema_for::<AllowWarnDeny>(),
Schema::Bool(true),
])),
min_items: Some(2),
max_items: Some(2),
..Default::default()
})),
..Default::default()
}
.into();
return with_default_rule_schema(array_schema, r#gen);
};
debug_assert!(
(u8::from(obj.array.is_some())
+ u8::from(obj.object.is_some())
+ u8::from(obj.reference.is_some()))
<= 1,
"Expected rule schema to be either an object, an array, or a reference, but not multiple"
);
if let Some(reference) = obj.reference {
let array_schema = SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(ArrayValidation {
items: Some(SingleOrVec::Vec(vec![
r#gen.subschema_for::<AllowWarnDeny>(),
Schema::Object(SchemaObject {
reference: Some(reference),
..Default::default()
}),
])),
min_items: Some(2),
max_items: Some(2),
..Default::default()
})),
..Default::default()
}
.into();
return with_default_rule_schema(array_schema, r#gen);
}
if let Some(array) = obj.array {
let items = match array.items {
None => vec![r#gen.subschema_for::<AllowWarnDeny>()],
Some(SingleOrVec::Single(config)) => {
vec![r#gen.subschema_for::<AllowWarnDeny>(), *config]
}
Some(SingleOrVec::Vec(configs)) => {
let mut items = Vec::with_capacity(configs.len().saturating_add(1));
items.push(r#gen.subschema_for::<AllowWarnDeny>());
items.extend(configs);
items
}
};
let config_length = items.len() as u32;
let array_schema = SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(ArrayValidation {
items: Some(SingleOrVec::Vec(items)),
min_items: Some(2),
max_items: Some(config_length),
..Default::default()
})),
..Default::default()
}
.into();
return with_default_rule_schema(array_schema, r#gen);
}
let array_schema = Schema::Object(SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(ArrayValidation {
items: Some(SingleOrVec::Vec(vec![
r#gen.subschema_for::<AllowWarnDeny>(),
Schema::Object(obj),
])),
min_items: Some(2),
max_items: Some(2),
..Default::default()
})),
..Default::default()
});
with_default_rule_schema(array_schema, r#gen)
let schema = append_allow_warn_deny_to_schema(schema, r#gen);
with_default_rule_schema(schema, r#gen)
}
let dummy_schema = r#gen.subschema_for::<DummyRule>();
+114 -1
View File
@@ -2,7 +2,10 @@
use std::borrow::Cow;
use std::{fmt, hash::Hash};
use schemars::{JsonSchema, SchemaGenerator, schema::Schema};
use schemars::{
JsonSchema, SchemaGenerator,
schema::{InstanceType, Schema, SchemaObject},
};
use serde::{Deserialize, Serialize};
use oxc_semantic::AstTypesBitset;
@@ -226,6 +229,116 @@ where
}
}
/// A wrapper type for deserializing ESLint-style mixed tuple rule configurations, where the first configuration object can be skipped.
///
/// Some ESLint rules take configurations in tuple form, e.g. `["foo", "qux", { "bar": "baz" }]`
/// where the first argument is optional and the second argument is the actual configuration object.
/// This type deserializes the array as a tuple `(Option<T1>, Option<T2>) | (Option<T2>)`.
#[derive(Debug, Clone)]
pub struct MixedTupleRuleConfig<T1, T2>(pub T1, pub T2);
impl<T1: Default, T2: Default> Default for MixedTupleRuleConfig<T1, T2> {
fn default() -> Self {
Self(T1::default(), T2::default())
}
}
impl<'de, T1, T2> serde::Deserialize<'de> for MixedTupleRuleConfig<T1, T2>
where
T1: serde::de::DeserializeOwned + Default,
T2: serde::de::DeserializeOwned + Default,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::Error;
let value = serde_json::Value::deserialize(deserializer)?;
if let serde_json::Value::Array(arr) = value {
let config = match arr.len() {
0 => Self(T1::default(), T2::default()),
1 => {
// If there's only one element, we need to determine whether it's T1 or T2.
// We can try deserializing it as T2 first, and if that fails, try T1.
let first_value = &arr[0];
if let Ok(t2) = T2::deserialize(first_value) {
Self(T1::default(), t2)
} else if let Ok(t1) = T1::deserialize(first_value) {
Self(t1, T2::default())
} else {
return Err(D::Error::custom(
"Expected configuration to match either the first or second tuple type",
));
}
}
2 => {
let t1 = T1::deserialize(&arr[0]).map_err(|e| {
D::Error::custom(format!("Error deserializing first tuple element: {e}"))
})?;
let t2 = T2::deserialize(&arr[1]).map_err(|e| {
D::Error::custom(format!("Error deserializing second tuple element: {e}"))
})?;
Self(t1, t2)
}
_ => {
return Err(D::Error::custom(
"Expected at most 2 elements in the configuration array",
));
}
};
Ok(config)
} else if value == serde_json::Value::Null {
// Missing configuration (null) is treated as default (no rule options provided)
Ok(Self(T1::default(), T2::default()))
} else {
Err(D::Error::custom("Expected array for rule configuration"))
}
}
}
impl<T1, T2> JsonSchema for MixedTupleRuleConfig<T1, T2>
where
T1: JsonSchema,
T2: JsonSchema,
{
fn schema_name() -> String {
"MixedTupleRuleConfig".to_string()
}
fn is_referenceable() -> bool {
false
}
fn json_schema(r#gen: &mut SchemaGenerator) -> Schema {
Schema::Object(SchemaObject {
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
any_of: Some(vec![
SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(schemars::schema::ArrayValidation {
items: Some(schemars::schema::SingleOrVec::Vec(vec![
r#gen.subschema_for::<T1>(),
r#gen.subschema_for::<T2>(),
])),
min_items: Some(2),
max_items: Some(2),
..Default::default()
})),
..Default::default()
}
.into(),
r#gen.subschema_for::<T1>(),
r#gen.subschema_for::<T2>(),
]),
..Default::default()
})),
..Default::default()
})
}
}
pub trait RuleRunner: Rule {
/// `AstType`s that this rule acts on, or `None` if the codegen
/// can't figure it out and the linter should call `run` on every node.
@@ -1,8 +1,7 @@
use std::borrow::Cow;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize, de};
use serde_json::Value;
use serde::{Deserialize, Serialize};
use oxc_ast::{
AstKind,
@@ -19,7 +18,7 @@ use oxc_syntax::{identifier::is_identifier_name, keyword::is_reserved_keyword};
use crate::{
AstNode,
context::LintContext,
rule::{Rule, TupleRuleConfig},
rule::{MixedTupleRuleConfig, Rule},
};
fn func_name_matching_diagnostic(
@@ -68,41 +67,9 @@ struct FuncNameMatchingConfig {
include_common_js_module_exports: bool,
}
#[derive(Debug, Default, Clone, Serialize, JsonSchema)]
#[derive(Debug, Default, Clone, Deserialize, JsonSchema)]
/// This rule takes an optional string of `"always"` or `"never"` (when omitted, it defaults to `"always"`), and an optional options object with two properties `considerPropertyDescriptor` and `includeCommonJSModuleExports`.
pub struct FuncNameMatching(FuncNameMatchingMode, FuncNameMatchingConfig);
impl<'de> Deserialize<'de> for FuncNameMatching {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let values = Vec::<Value>::deserialize(deserializer)?;
let mut mode = FuncNameMatchingMode::Always;
let mut options = FuncNameMatchingConfig::default();
match values.as_slice() {
[] => {}
[first] if first.is_string() => {
mode = serde_json::from_value(first.clone()).map_err(de::Error::custom)?;
}
[first] if first.is_object() => {
options = serde_json::from_value(first.clone()).map_err(de::Error::custom)?;
}
[first, second] if first.is_string() && second.is_object() => {
mode = serde_json::from_value(first.clone()).map_err(de::Error::custom)?;
options = serde_json::from_value(second.clone()).map_err(de::Error::custom)?;
}
_ => {
return Err(de::Error::custom(
r#"expected [], ["always"|"never"], [options], or ["always"|"never", options]"#,
));
}
}
Ok(Self(mode, options))
}
}
pub struct FuncNameMatching(MixedTupleRuleConfig<FuncNameMatchingMode, FuncNameMatchingConfig>);
declare_oxc_lint!(
/// ### What it does
@@ -221,14 +188,16 @@ declare_oxc_lint!(
eslint,
style,
none,
config = FuncNameMatching,
config = MixedTupleRuleConfig<FuncNameMatchingMode, FuncNameMatchingConfig>,
version = "1.62.0",
short_description = "Requires function expression names to match the variable or property names they are assigned to, or disallows such matches with `\"never\"`.",
);
impl Rule for FuncNameMatching {
fn from_configuration(value: serde_json::Value) -> Result<Self, serde_json::error::Error> {
serde_json::from_value::<TupleRuleConfig<Self>>(value).map(TupleRuleConfig::into_inner)
serde_json::from_value::<MixedTupleRuleConfig<FuncNameMatchingMode, FuncNameMatchingConfig>>(
value,
).map(Self)
}
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
@@ -250,7 +219,8 @@ impl Rule for FuncNameMatching {
return;
};
if !self.1.include_common_js_module_exports && is_module_exports(&assign_expr.left)
if !self.0.1.include_common_js_module_exports
&& is_module_exports(&assign_expr.left)
{
return;
}
@@ -274,7 +244,7 @@ impl Rule for FuncNameMatching {
impl FuncNameMatching {
fn should_warn(&self, name: &str, func_name: &str) -> bool {
match self.0 {
match self.0.0 {
FuncNameMatchingMode::Always => name != func_name,
FuncNameMatchingMode::Never => name == func_name,
}
@@ -292,7 +262,7 @@ impl FuncNameMatching {
name,
func_name.name,
is_property,
self.0,
self.0.0,
func_name.span,
));
}
@@ -310,7 +280,7 @@ impl FuncNameMatching {
if property_key_is_identifier(&property.key) && !property.computed {
let Some(property_name) = property.key.static_name() else { return };
if self.1.consider_property_descriptor && property_name == "value" {
if self.0.1.consider_property_descriptor && property_name == "value" {
match property_descriptor_name(node, ctx) {
DescriptorName::Name(descriptor_name) => {
self.report_if_should_warn(
+8 -9
View File
@@ -13,22 +13,21 @@ use crate::rules::RuleEnum;
/// These should return the DummyRule struct/schema instead of the actual rule struct/schema,
/// until we verify that the rule's schema is valid and can be generated by schemars.
#[cfg(feature = "ruledocs")]
const NO_VERIFIED_VALID_SCHEMA: [&str; 16] = [
"eslint/func-name-matching", // second config can be on first position like [AllowWarnDeny, Config1, Config2] | [AllowWarnDeny, Config1] | [AllowWarnDeny, Config2]
const NO_VERIFIED_VALID_SCHEMA: [&str; 15] = [
"eslint/no-restricted-globals", // uses spread syntax like [AllowWarnDeny, ...Config]
"eslint/no-restricted-imports", // uses spread syntax like [AllowWarnDeny, ...Config]
"eslint/no-restricted-properties", // uses spread syntax like [AllowWarnDeny, ...Config]
"node/callback-return", // uses array syntax [AllowWarnDeny, string[]]
"import/extensions", // second config can be on first position like[AllowWarnDeny, Config1, Config2] | [AllowWarnDeny, Config1] | [AllowWarnDeny, Config2]
"jest/prefer-lowercase-title", // has options from other rule #23186
"jest/valid-title", // has options from other rule #23186
"node/callback-return", // uses array syntax [AllowWarnDeny, string[]]
"jest/prefer-lowercase-title", // has options from other rule #23186
"jest/valid-title", // has options from other rule #23186
"vitest/prefer-lowercase-title", // has options from other rule #23186
"vitest/valid-title", // has options from other rule #23186
"jsdoc/require-param", // missing options #23356
"unicorn/filename-case", // missing options #23248
"vitest/valid-title", // has options from other rule #23186
"jsdoc/require-param", // missing options #23356
"unicorn/filename-case", // missing options #23248
"unicorn/numeric-separators-style", // missing options #23383
"jsx_a11y/no-noninteractive-element-interactions", // TS Generation generates ts 2411 error
"eslint/prefer-destructuring",
"import/extensions",
"react/jsx-no-script-url",
];
+236 -81
View File
@@ -2276,24 +2276,34 @@
"$ref": "#/definitions/RuleNoConfig"
},
{
"type": "array",
"items": [
"anyOf": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"anyOf": [
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"type": "number"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/ComplexityConfig"
}
]
],
"maxItems": 2,
"minItems": 2
}
],
"maxItems": 2,
"minItems": 2
]
}
]
},
@@ -2376,7 +2386,57 @@
"$ref": "#/definitions/RuleNoConfig"
},
"func-name-matching": {
"$ref": "#/definitions/DummyRule"
"anyOf": [
{
"$ref": "#/definitions/RuleNoConfig"
},
{
"anyOf": [
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/FuncNameMatchingMode"
},
{
"$ref": "#/definitions/FuncNameMatchingConfig"
}
],
"maxItems": 3,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/FuncNameMatchingMode"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/FuncNameMatchingConfig"
}
],
"maxItems": 2,
"minItems": 2
}
]
}
]
},
"func-names": {
"anyOf": [
@@ -3970,24 +4030,34 @@
"$ref": "#/definitions/RuleNoConfig"
},
{
"type": "array",
"items": [
"anyOf": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"anyOf": [
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"type": "number"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/MaxClassesPerFileConfig"
}
]
],
"maxItems": 2,
"minItems": 2
}
],
"maxItems": 2,
"minItems": 2
]
}
]
},
@@ -3997,24 +4067,34 @@
"$ref": "#/definitions/RuleNoConfig"
},
{
"type": "array",
"items": [
"anyOf": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"anyOf": [
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"type": "number"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/MaxDepth"
}
]
],
"maxItems": 2,
"minItems": 2
}
],
"maxItems": 2,
"minItems": 2
]
}
]
},
@@ -4024,24 +4104,34 @@
"$ref": "#/definitions/RuleNoConfig"
},
{
"type": "array",
"items": [
"anyOf": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"anyOf": [
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"type": "number"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/MaxLinesConfig"
}
]
],
"maxItems": 2,
"minItems": 2
}
],
"maxItems": 2,
"minItems": 2
]
}
]
},
@@ -4051,24 +4141,34 @@
"$ref": "#/definitions/RuleNoConfig"
},
{
"type": "array",
"items": [
"anyOf": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"anyOf": [
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"type": "number"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/MaxLinesPerFunctionConfig"
}
]
],
"maxItems": 2,
"minItems": 2
}
],
"maxItems": 2,
"minItems": 2
]
}
]
},
@@ -4078,24 +4178,34 @@
"$ref": "#/definitions/RuleNoConfig"
},
{
"type": "array",
"items": [
"anyOf": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"anyOf": [
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"type": "number"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/MaxNestedCallbacks"
}
]
],
"maxItems": 2,
"minItems": 2
}
],
"maxItems": 2,
"minItems": 2
]
}
]
},
@@ -4105,24 +4215,34 @@
"$ref": "#/definitions/RuleNoConfig"
},
{
"type": "array",
"items": [
"anyOf": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"anyOf": [
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"type": "number"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/MaxParamsConfig"
}
]
],
"maxItems": 2,
"minItems": 2
}
],
"maxItems": 2,
"minItems": 2
]
}
]
},
@@ -4132,24 +4252,34 @@
"$ref": "#/definitions/RuleNoConfig"
},
{
"type": "array",
"items": [
"anyOf": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"anyOf": [
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"type": "number"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "array",
"items": [
{
"$ref": "#/definitions/AllowWarnDeny"
},
{
"$ref": "#/definitions/MaxStatementsConfig"
}
]
],
"maxItems": 2,
"minItems": 2
}
],
"maxItems": 2,
"minItems": 2
]
}
]
},
@@ -10671,6 +10801,31 @@
}
]
},
"FuncNameMatchingConfig": {
"type": "object",
"properties": {
"considerPropertyDescriptor": {
"description": "If `considerPropertyDescriptor` is set to `true`, the check will take into account the use of `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty`.",
"default": false,
"type": "boolean",
"markdownDescription": "If `considerPropertyDescriptor` is set to `true`, the check will take into account the use of `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty`."
},
"includeCommonJSModuleExports": {
"description": "If `includeCommonJSModuleExports` is set to `true`, `module.exports` and `module[\"exports\"]` will be checked by this rule.",
"default": false,
"type": "boolean",
"markdownDescription": "If `includeCommonJSModuleExports` is set to `true`, `module.exports` and `module[\"exports\"]` will be checked by this rule."
}
},
"additionalProperties": false
},
"FuncNameMatchingMode": {
"type": "string",
"enum": [
"always",
"never"
]
},
"FuncNames": {
"type": "array",
"items": [