diff --git a/crates/oxc_linter/src/config/config_builder.rs b/crates/oxc_linter/src/config/config_builder.rs index 0d3b4bcf6a0a8..c691becd91e33 100644 --- a/crates/oxc_linter/src/config/config_builder.rs +++ b/crates/oxc_linter/src/config/config_builder.rs @@ -93,6 +93,7 @@ impl ConfigStoreBuilder { overrides, path, ignore_patterns: _, + extends: _, } = oxlintrc; let config = LintConfig { plugins, settings, env, globals, path: Some(path) }; diff --git a/crates/oxc_linter/src/config/oxlintrc.rs b/crates/oxc_linter/src/config/oxlintrc.rs index a33271a5a9389..9607d4431281d 100644 --- a/crates/oxc_linter/src/config/oxlintrc.rs +++ b/crates/oxc_linter/src/config/oxlintrc.rs @@ -96,6 +96,12 @@ pub struct Oxlintrc { /// Globs to ignore during linting. These are resolved from the configuration file path. #[serde(rename = "ignorePatterns")] pub ignore_patterns: Vec, + /// Paths of configuration files that this configuration file extends (inherits from). The files + /// are resolved relative to the location of the configuration file that contains the `extends` + /// property. The configuration files are merged from the first to the last, with the last file + /// overriding the previous ones. + #[serde(skip_serializing_if = "Vec::is_empty")] + pub extends: Vec, } impl Oxlintrc { @@ -156,6 +162,7 @@ mod test { assert_eq!(config.settings, OxlintSettings::default()); assert_eq!(config.env, OxlintEnv::default()); assert_eq!(config.path, PathBuf::default()); + assert_eq!(config.extends, Vec::::default()); } #[test] @@ -185,4 +192,23 @@ mod test { serde_json::from_str(r#"{ "plugins": ["typescript", "@typescript-eslint"] }"#).unwrap(); assert_eq!(config.plugins, LintPlugins::TYPESCRIPT); } + + #[test] + fn test_oxlintrc_extends() { + let config: Oxlintrc = serde_json::from_str( + r#"{"extends": [".oxlintrc.json", "./oxlint-ts.json", "../.config/.oxlintrc.json"]}"#, + ) + .unwrap(); + assert_eq!( + config.extends, + vec![ + PathBuf::from(".oxlintrc.json"), + PathBuf::from("./oxlint-ts.json"), + PathBuf::from("../.config/.oxlintrc.json") + ] + ); + + let config: Oxlintrc = serde_json::from_str(r#"{"extends": []}"#).unwrap(); + assert_eq!(0, config.extends.len()); + } } diff --git a/crates/oxc_linter/src/snapshots/schema_json.snap b/crates/oxc_linter/src/snapshots/schema_json.snap index 02082bc9833b9..241a51d159e04 100644 --- a/crates/oxc_linter/src/snapshots/schema_json.snap +++ b/crates/oxc_linter/src/snapshots/schema_json.snap @@ -27,6 +27,13 @@ expression: json } ] }, + "extends": { + "description": "Paths of configuration files that this configuration file extends (inherits from). The files are resolved relative to the location of the configuration file that contains the `extends` property. The configuration files are merged from the first to the last, with the last file overriding the previous ones.", + "type": "array", + "items": { + "type": "string" + } + }, "globals": { "description": "Enabled or disabled specific global variables.", "default": {}, diff --git a/npm/oxlint/configuration_schema.json b/npm/oxlint/configuration_schema.json index 8e08f077c29b3..5aded2af93e0f 100644 --- a/npm/oxlint/configuration_schema.json +++ b/npm/oxlint/configuration_schema.json @@ -23,6 +23,13 @@ } ] }, + "extends": { + "description": "Paths of configuration files that this configuration file extends (inherits from). The files are resolved relative to the location of the configuration file that contains the `extends` property. The configuration files are merged from the first to the last, with the last file overriding the previous ones.", + "type": "array", + "items": { + "type": "string" + } + }, "globals": { "description": "Enabled or disabled specific global variables.", "default": {}, diff --git a/tasks/website/src/linter/snapshots/schema_markdown.snap b/tasks/website/src/linter/snapshots/schema_markdown.snap index 641e40ccd3b3f..0c9fffe2f7861 100644 --- a/tasks/website/src/linter/snapshots/schema_markdown.snap +++ b/tasks/website/src/linter/snapshots/schema_markdown.snap @@ -140,6 +140,14 @@ Predefine global variables. Environments specify what global variables are predefined. See [ESLint's list of environments](https://eslint.org/docs/v8.x/use/configure/language-options#specifying-environments) for what environments are available and what each one provides. +## extends + +type: `string[]` + + +Paths of configuration files that this configuration file extends (inherits from). The files are resolved relative to the location of the configuration file that contains the `extends` property. The configuration files are merged from the first to the last, with the last file overriding the previous ones. + + ## globals type: `Record`