mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
feat(linter): add schema for react/jsx-filename-extension (#23315)
issue #22955 --------- Co-authored-by: Cameron <cameron.clark@hey.com>
This commit is contained in:
1 parent
e6bdfd4c89
commit
0708b5a233
5 files changed
+170
-14
No files matched your search
@@ -176,6 +176,7 @@ export type ForbidItem2 =
|
||||
message?: string;
|
||||
};
|
||||
export type EnforceBooleanAttribute = "always" | "never";
|
||||
export type JsxFilenameExtensionAllowMode = "always" | "as-needed";
|
||||
export type FragmentMode = "syntax" | "element";
|
||||
export type IgnoreEnforceOption = "ignore" | "enforce";
|
||||
export type NoDidMountSetStateConfig = "allowed" | "disallow-in-func";
|
||||
@@ -1202,7 +1203,7 @@ export interface DummyRuleMap {
|
||||
| [AllowWarnDeny, EnforceBooleanAttribute]
|
||||
| [AllowWarnDeny, EnforceBooleanAttribute, JsxBooleanValueOptions];
|
||||
"react/jsx-curly-brace-presence"?: DummyRule;
|
||||
"react/jsx-filename-extension"?: DummyRule;
|
||||
"react/jsx-filename-extension"?: AllowWarnDeny | [AllowWarnDeny] | [AllowWarnDeny, JsxFilenameExtensionConfig];
|
||||
"react/jsx-fragments"?: AllowWarnDeny | [AllowWarnDeny] | [AllowWarnDeny, FragmentMode];
|
||||
"react/jsx-handler-names"?: DummyRule;
|
||||
"react/jsx-key"?: AllowWarnDeny | [AllowWarnDeny] | [AllowWarnDeny, JsxKeyConfig];
|
||||
@@ -4152,6 +4153,22 @@ export interface JsxBooleanValueOptions {
|
||||
*/
|
||||
never?: string[];
|
||||
}
|
||||
export interface JsxFilenameExtensionConfig {
|
||||
/**
|
||||
* When to allow a JSX filename extension. By default all files may have a JSX extension.
|
||||
* Set this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax.
|
||||
*/
|
||||
allow?: JsxFilenameExtensionAllowMode;
|
||||
/**
|
||||
* The set of allowed file extensions.
|
||||
* Can include or exclude the leading dot (e.g., "jsx" and ".jsx" are both valid).
|
||||
*/
|
||||
extensions?: string[];
|
||||
/**
|
||||
* If enabled, files that do not contain code (i.e. are empty, contain only whitespaces or comments) will not be rejected.
|
||||
*/
|
||||
ignoreFilesWithoutCode?: boolean;
|
||||
}
|
||||
export interface JsxKeyConfig {
|
||||
/**
|
||||
* When true, check fragment shorthand `<>` for keys
|
||||
|
||||
@@ -34,15 +34,15 @@ fn extension_only_for_jsx_diagnostic(ext: &str, span: Span) -> OxcDiagnostic {
|
||||
|
||||
#[derive(Debug, Default, Clone, JsonSchema, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
enum AllowType {
|
||||
/// Always allow a `.jsx` file extension.
|
||||
enum JsxFilenameExtensionAllowMode {
|
||||
/// Always allow a JSX filename extension.
|
||||
#[default]
|
||||
Always,
|
||||
/// Only allow `.jsx` file extension for files that contain JSX syntax.
|
||||
/// Only allow JSX filename extension for files that contain JSX syntax.
|
||||
AsNeeded,
|
||||
}
|
||||
|
||||
impl AllowType {
|
||||
impl JsxFilenameExtensionAllowMode {
|
||||
pub fn from(raw: &str) -> Self {
|
||||
match raw {
|
||||
"as-needed" => Self::AsNeeded,
|
||||
@@ -55,11 +55,11 @@ impl AllowType {
|
||||
pub struct JsxFilenameExtension(Box<JsxFilenameExtensionConfig>);
|
||||
|
||||
#[derive(Debug, Clone, JsonSchema, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase", default)]
|
||||
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
|
||||
pub struct JsxFilenameExtensionConfig {
|
||||
/// When to allow a JSX filename extension. By default all files may have a JSX extension.
|
||||
/// Set this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax.
|
||||
allow: AllowType,
|
||||
allow: JsxFilenameExtensionAllowMode,
|
||||
/// The set of allowed file extensions.
|
||||
/// Can include or exclude the leading dot (e.g., "jsx" and ".jsx" are both valid).
|
||||
extensions: Vec<CompactStr>,
|
||||
@@ -70,7 +70,7 @@ pub struct JsxFilenameExtensionConfig {
|
||||
impl Default for JsxFilenameExtensionConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
allow: AllowType::Always,
|
||||
allow: JsxFilenameExtensionAllowMode::Always,
|
||||
extensions: vec![CompactStr::from("jsx")],
|
||||
ignore_files_without_code: false,
|
||||
}
|
||||
@@ -132,7 +132,7 @@ impl Rule for JsxFilenameExtension {
|
||||
let allow = config
|
||||
.and_then(|config| config.get("allow"))
|
||||
.and_then(Value::as_str)
|
||||
.map(AllowType::from)
|
||||
.map(JsxFilenameExtensionAllowMode::from)
|
||||
.unwrap_or_default();
|
||||
|
||||
let extensions = config
|
||||
@@ -173,7 +173,7 @@ impl Rule for JsxFilenameExtension {
|
||||
return;
|
||||
}
|
||||
|
||||
if matches!(self.allow, AllowType::AsNeeded) {
|
||||
if matches!(self.allow, JsxFilenameExtensionAllowMode::AsNeeded) {
|
||||
if self.ignore_files_without_code && ctx.nodes().len() == 1 {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ 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; 40] = [
|
||||
const NO_VERIFIED_VALID_SCHEMA: [&str; 39] = [
|
||||
"eslint/func-name-matching",
|
||||
"eslint/no-restricted-globals",
|
||||
"eslint/no-restricted-imports",
|
||||
@@ -36,7 +36,6 @@ const NO_VERIFIED_VALID_SCHEMA: [&str; 40] = [
|
||||
"node/callback-return",
|
||||
"react/exhaustive-deps",
|
||||
"react/jsx-curly-brace-presence",
|
||||
"react/jsx-filename-extension",
|
||||
"react/jsx-handler-names",
|
||||
"react/jsx-no-script-url",
|
||||
"react/jsx-no-target-blank",
|
||||
|
||||
@@ -5572,7 +5572,24 @@
|
||||
"$ref": "#/definitions/DummyRule"
|
||||
},
|
||||
"react/jsx-filename-extension": {
|
||||
"$ref": "#/definitions/DummyRule"
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowWarnDeny"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowWarnDeny"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/JsxFilenameExtensionConfig"
|
||||
}
|
||||
],
|
||||
"maxItems": 2,
|
||||
"minItems": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"react/jsx-fragments": {
|
||||
"anyOf": [
|
||||
@@ -10301,6 +10318,59 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"JsxFilenameExtensionAllowMode": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Always allow a JSX filename extension.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"always"
|
||||
],
|
||||
"markdownDescription": "Always allow a JSX filename extension."
|
||||
},
|
||||
{
|
||||
"description": "Only allow JSX filename extension for files that contain JSX syntax.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"as-needed"
|
||||
],
|
||||
"markdownDescription": "Only allow JSX filename extension for files that contain JSX syntax."
|
||||
}
|
||||
]
|
||||
},
|
||||
"JsxFilenameExtensionConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "When to allow a JSX filename extension. By default all files may have a JSX extension.\nSet this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax.",
|
||||
"default": "always",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/JsxFilenameExtensionAllowMode"
|
||||
}
|
||||
],
|
||||
"markdownDescription": "When to allow a JSX filename extension. By default all files may have a JSX extension.\nSet this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax."
|
||||
},
|
||||
"extensions": {
|
||||
"description": "The set of allowed file extensions.\nCan include or exclude the leading dot (e.g., \"jsx\" and \".jsx\" are both valid).",
|
||||
"default": [
|
||||
"jsx"
|
||||
],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"markdownDescription": "The set of allowed file extensions.\nCan include or exclude the leading dot (e.g., \"jsx\" and \".jsx\" are both valid)."
|
||||
},
|
||||
"ignoreFilesWithoutCode": {
|
||||
"description": "If enabled, files that do not contain code (i.e. are empty, contain only whitespaces or comments) will not be rejected.",
|
||||
"default": false,
|
||||
"type": "boolean",
|
||||
"markdownDescription": "If enabled, files that do not contain code (i.e. are empty, contain only whitespaces or comments) will not be rejected."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"JsxKeyConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -5576,7 +5576,24 @@ expression: json
|
||||
"$ref": "#/definitions/DummyRule"
|
||||
},
|
||||
"react/jsx-filename-extension": {
|
||||
"$ref": "#/definitions/DummyRule"
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowWarnDeny"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowWarnDeny"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/JsxFilenameExtensionConfig"
|
||||
}
|
||||
],
|
||||
"maxItems": 2,
|
||||
"minItems": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"react/jsx-fragments": {
|
||||
"anyOf": [
|
||||
@@ -10305,6 +10322,59 @@ expression: json
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"JsxFilenameExtensionAllowMode": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Always allow a JSX filename extension.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"always"
|
||||
],
|
||||
"markdownDescription": "Always allow a JSX filename extension."
|
||||
},
|
||||
{
|
||||
"description": "Only allow JSX filename extension for files that contain JSX syntax.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"as-needed"
|
||||
],
|
||||
"markdownDescription": "Only allow JSX filename extension for files that contain JSX syntax."
|
||||
}
|
||||
]
|
||||
},
|
||||
"JsxFilenameExtensionConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "When to allow a JSX filename extension. By default all files may have a JSX extension.\nSet this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax.",
|
||||
"default": "always",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/JsxFilenameExtensionAllowMode"
|
||||
}
|
||||
],
|
||||
"markdownDescription": "When to allow a JSX filename extension. By default all files may have a JSX extension.\nSet this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax."
|
||||
},
|
||||
"extensions": {
|
||||
"description": "The set of allowed file extensions.\nCan include or exclude the leading dot (e.g., \"jsx\" and \".jsx\" are both valid).",
|
||||
"default": [
|
||||
"jsx"
|
||||
],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"markdownDescription": "The set of allowed file extensions.\nCan include or exclude the leading dot (e.g., \"jsx\" and \".jsx\" are both valid)."
|
||||
},
|
||||
"ignoreFilesWithoutCode": {
|
||||
"description": "If enabled, files that do not contain code (i.e. are empty, contain only whitespaces or comments) will not be rejected.",
|
||||
"default": false,
|
||||
"type": "boolean",
|
||||
"markdownDescription": "If enabled, files that do not contain code (i.e. are empty, contain only whitespaces or comments) will not be rejected."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"JsxKeyConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
Reference in new issue
Block a user