mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
feat(linter): add schema for node/callback-return (#23615)
- Avoided looping over `array` of `array`, we only want to know the first level of structure for detecting a tuple config - refactored some code and introduced a `.clone()` at the beginning. Hope this is fine for the rule doc code path. Feeling sometimes stupid without AI quick fixes :') - enabled `node-callback-return` schema, which is the only rule that accepts a array as a config - https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/callback-return.md
This commit is contained in:
1 parent
6d355ab8b3
commit
b638d0ee1d
4 files changed
+71
-43
No files matched your search
@@ -162,6 +162,10 @@ export type NoUnusedVarsFixMode = "off" | "suggestion" | "fix" | "safe-fix";
|
||||
export type NoUseBeforeDefineConfigJson = Nofunc | NoUseBeforeDefineConfig;
|
||||
export type Nofunc = "nofunc";
|
||||
export type Location = "start" | "anywhere";
|
||||
/**
|
||||
* The rule takes a single option - an array of possible callback names - which may include object methods. The default callback names are `callback`, `cb`, `next`.
|
||||
*/
|
||||
export type CallbackReturn = string[];
|
||||
/**
|
||||
* The rule takes a single string option: the name of the error parameter.
|
||||
*
|
||||
@@ -1220,7 +1224,7 @@ export interface DummyRuleMap {
|
||||
"no-void"?: RuleNoConfig | [AllowWarnDeny, NoVoid];
|
||||
"no-warning-comments"?: RuleNoConfig | [AllowWarnDeny, NoWarningCommentsConfigJson];
|
||||
"no-with"?: RuleNoConfig;
|
||||
"node/callback-return"?: DummyRule;
|
||||
"node/callback-return"?: RuleNoConfig | [AllowWarnDeny, CallbackReturn];
|
||||
"node/global-require"?: RuleNoConfig;
|
||||
"node/handle-callback-err"?: RuleNoConfig | [AllowWarnDeny, HandleCallbackErrConfig];
|
||||
"node/no-exports-assign"?: RuleNoConfig;
|
||||
|
||||
@@ -357,18 +357,24 @@ impl JsonSchema for OxlintRules {
|
||||
schema: &'a Schema,
|
||||
r#gen: &'a SchemaGenerator,
|
||||
) -> &'a Schema {
|
||||
let mut current = schema;
|
||||
while let Some(next) = r#gen.dereference(current) {
|
||||
current = next;
|
||||
}
|
||||
let Some(current) = r#gen.dereference(schema) else {
|
||||
return schema;
|
||||
};
|
||||
|
||||
let Schema::Object(obj) = current else {
|
||||
return current;
|
||||
return schema;
|
||||
};
|
||||
|
||||
// We only need to dereference array schemas for rule config.
|
||||
// Reuse the schema for other cases.
|
||||
if obj.array.is_none() {
|
||||
// We only need to dereference array schemas with at least 2 entries. A single entry array schema is used for configs which accepts an array.
|
||||
// 2 entries means that it is a tuple config, and `AllowWarnDeny` needs to be appended for each entry in the tuple.
|
||||
if obj.array.as_ref().is_none_or(|array| {
|
||||
array
|
||||
.items
|
||||
.as_ref()
|
||||
.is_none_or(|items| !matches!(items, SingleOrVec::Vec(_)))
|
||||
}) {
|
||||
return schema;
|
||||
}
|
||||
|
||||
@@ -401,7 +407,7 @@ impl JsonSchema for OxlintRules {
|
||||
config_schema: Schema,
|
||||
r#gen: &mut SchemaGenerator,
|
||||
) -> Schema {
|
||||
let Schema::Object(mut obj) = config_schema else {
|
||||
let Schema::Object(mut obj) = config_schema.clone() else {
|
||||
return SchemaObject {
|
||||
instance_type: Some(InstanceType::Array.into()),
|
||||
array: Some(Box::new(ArrayValidation {
|
||||
@@ -426,41 +432,35 @@ impl JsonSchema for OxlintRules {
|
||||
"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
|
||||
debug_assert!(
|
||||
array.additional_items.is_none(),
|
||||
"Expected array schema to have no additionalItems for rule config"
|
||||
);
|
||||
// We only need to handle the cases where multiple items exists,
|
||||
// because single item array schema is used for rules which accepts an array as config,
|
||||
// and we just need to append `AllowWarnDeny` for that case.
|
||||
let Some(SingleOrVec::Vec(configs)) = array.items 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();
|
||||
};
|
||||
|
||||
let mut items = Vec::with_capacity(configs.len().saturating_add(1));
|
||||
items.push(r#gen.subschema_for::<AllowWarnDeny>());
|
||||
items.extend(configs);
|
||||
|
||||
let config_length = items.len() as u32;
|
||||
|
||||
return SchemaObject {
|
||||
@@ -496,7 +496,7 @@ impl JsonSchema for OxlintRules {
|
||||
array: Some(Box::new(ArrayValidation {
|
||||
items: Some(SingleOrVec::Vec(vec![
|
||||
r#gen.subschema_for::<AllowWarnDeny>(),
|
||||
Schema::Object(obj),
|
||||
config_schema,
|
||||
])),
|
||||
min_items: Some(2),
|
||||
max_items: Some(2),
|
||||
|
||||
@@ -10,11 +10,10 @@ 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; 10] = [
|
||||
const NO_VERIFIED_VALID_SCHEMA: [&str; 9] = [
|
||||
"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[]]
|
||||
"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
|
||||
|
||||
@@ -1138,6 +1138,14 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"CallbackReturn": {
|
||||
"description": "The rule takes a single option - an array of possible callback names - which may include object methods. The default callback names are `callback`, `cb`, `next`.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"markdownDescription": "The rule takes a single option - an array of possible callback names - which may include object methods. The default callback names are `callback`, `cb`, `next`."
|
||||
},
|
||||
"CapitalizedCommentsOptions": {
|
||||
"description": "Configuration for the capitalized-comments rule.\n\nThe first element specifies whether comments should `\"always\"` or `\"never\"`\nbegin with a capital letter. The second element is an optional object\ncontaining additional options.",
|
||||
"type": "array",
|
||||
@@ -5517,7 +5525,24 @@
|
||||
"$ref": "#/definitions/RuleNoConfig"
|
||||
},
|
||||
"node/callback-return": {
|
||||
"$ref": "#/definitions/DummyRule"
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/RuleNoConfig"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowWarnDeny"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/CallbackReturn"
|
||||
}
|
||||
],
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"node/global-require": {
|
||||
"$ref": "#/definitions/RuleNoConfig"
|
||||
|
||||
Reference in new issue
Block a user