diff --git a/.gitattributes b/.gitattributes index 430cdbe291f..220269ea9c6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,6 +11,8 @@ crates/rome_js_analyze/src/registry.rs linguist-generated=true text=auto eol=lf crates/rome_service/src/configuration/linter/rules.rs linguist-generated=true text=auto eol=lf npm/backend-jsonrpc/src/workspace.ts linguist-generated=true text=auto eol=lf website/src/docs/lint/rules/**/*.md linguist-generated=true text=auto eol=lf +npm/rome/configuration_schema.json linguist-generated=true text=auto eol=lf +editors/vscode/configuration_schema.json linguist-generated=true text=auto eol=lf crates/rome_js_formatter/tests/**/*.ts.prettier-snap linguist-language=TypeScript @@ -20,3 +22,4 @@ crates/rome_js_formatter/tests/**/*.js.snap linguist-language=Markdown crates/rome_cli/tests/**/*.snap linguist-language=Markdown crates/rome_js_analyze/tests/specs/**/*.snap linguist-language=Markdown + diff --git a/Cargo.lock b/Cargo.lock index 4cc7dee7b12..8af330fd52a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2918,6 +2918,7 @@ dependencies = [ "git2", "pico-args", "proc-macro2", + "pulldown-cmark", "quote", "rome_analyze", "rome_js_analyze", diff --git a/crates/rome_cli/tests/commands/init.rs b/crates/rome_cli/tests/commands/init.rs new file mode 100644 index 00000000000..f95c175b8c0 --- /dev/null +++ b/crates/rome_cli/tests/commands/init.rs @@ -0,0 +1,83 @@ +use crate::configs::{CONFIG_INIT_DEFAULT, CONFIG_INIT_DEFAULT_WHEN_INSTALLED}; +use crate::run_cli; +use crate::snap_test::{assert_cli_snapshot, SnapshotPayload}; +use pico_args::Arguments; +use rome_console::BufferConsole; +use rome_fs::{FileSystemExt, MemoryFileSystem}; +use rome_service::DynRef; +use std::ffi::OsString; +use std::path::Path; + +#[test] +fn creates_config_file() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + DynRef::Borrowed(&mut console), + Arguments::from_vec(vec![OsString::from("init")]), + ); + assert!(result.is_ok(), "run_cli returned {result:?}"); + + let file_path = Path::new("rome.json"); + + let mut file = fs + .open(file_path) + .expect("configuration file was not written on disk"); + + let mut content = String::new(); + file.read_to_string(&mut content) + .expect("failed to read file from memory FS"); + assert_eq!(content, CONFIG_INIT_DEFAULT); + + drop(file); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "creates_config_file", + fs, + console, + result, + )); +} + +#[test] +fn creates_config_file_when_rome_installed_via_package_manager() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let file_path = Path::new("./") + .join("node_modules") + .join("rome") + .join("configuration_schema.json"); + fs.insert(file_path, *b"{}"); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + DynRef::Borrowed(&mut console), + Arguments::from_vec(vec![OsString::from("init")]), + ); + assert!(result.is_ok(), "run_cli returned {result:?}"); + + let file_path = Path::new("rome.json"); + + let mut file = fs + .open(file_path) + .expect("configuration file was not written on disk"); + + let mut content = String::new(); + file.read_to_string(&mut content) + .expect("failed to read file from memory FS"); + assert_eq!(content, CONFIG_INIT_DEFAULT_WHEN_INSTALLED); + + drop(file); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "creates_config_file_when_rome_installed_via_package_manager", + fs, + console, + result, + )); +} diff --git a/crates/rome_cli/tests/commands/mod.rs b/crates/rome_cli/tests/commands/mod.rs index 36cdac058d8..9a4f983b0f1 100644 --- a/crates/rome_cli/tests/commands/mod.rs +++ b/crates/rome_cli/tests/commands/mod.rs @@ -1,5 +1,6 @@ mod check; mod ci; mod format; +mod init; mod rage; mod version; diff --git a/crates/rome_cli/tests/configs.rs b/crates/rome_cli/tests/configs.rs index f16083a86ba..ca1d95019ae 100644 --- a/crates/rome_cli/tests/configs.rs +++ b/crates/rome_cli/tests/configs.rs @@ -17,6 +17,16 @@ pub const CONFIG_INIT_DEFAULT: &str = r#"{ } }"#; +pub const CONFIG_INIT_DEFAULT_WHEN_INSTALLED: &str = r#"{ + "$schema": "./node_modules/rome/configuration_schema.json", + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + } +}"#; + pub const CONFIG_DISABLED_FORMATTER: &str = r#"{ "formatter": { "enabled": false diff --git a/crates/rome_cli/tests/main.rs b/crates/rome_cli/tests/main.rs index 301ba44a474..48b102e73a2 100644 --- a/crates/rome_cli/tests/main.rs +++ b/crates/rome_cli/tests/main.rs @@ -217,52 +217,6 @@ mod main { } } -mod init { - use super::*; - use crate::configs::CONFIG_INIT_DEFAULT; - use crate::snap_test::SnapshotPayload; - use pico_args::Arguments; - use rome_console::BufferConsole; - use rome_fs::{FileSystemExt, MemoryFileSystem}; - use rome_service::DynRef; - use std::ffi::OsString; - use std::path::Path; - - #[test] - fn creates_config_file() { - let mut fs = MemoryFileSystem::default(); - let mut console = BufferConsole::default(); - - let result = run_cli( - DynRef::Borrowed(&mut fs), - DynRef::Borrowed(&mut console), - Arguments::from_vec(vec![OsString::from("init")]), - ); - assert!(result.is_ok(), "run_cli returned {result:?}"); - - let file_path = Path::new("rome.json"); - - let mut file = fs - .open(file_path) - .expect("configuration file was not written on disk"); - - let mut content = String::new(); - file.read_to_string(&mut content) - .expect("failed to read file from memory FS"); - assert_eq!(content, CONFIG_INIT_DEFAULT); - - drop(file); - - assert_cli_snapshot(SnapshotPayload::new( - module_path!(), - "creates_config_file", - fs, - console, - result, - )); - } -} - mod configuration { use super::*; use crate::configs::{ diff --git a/crates/rome_cli/tests/snapshots/main_init/creates_config_file.snap b/crates/rome_cli/tests/snapshots/main_commands_init/creates_config_file.snap similarity index 100% rename from crates/rome_cli/tests/snapshots/main_init/creates_config_file.snap rename to crates/rome_cli/tests/snapshots/main_commands_init/creates_config_file.snap diff --git a/crates/rome_cli/tests/snapshots/main_commands_init/creates_config_file_when_rome_installed_via_package_manager.snap b/crates/rome_cli/tests/snapshots/main_commands_init/creates_config_file_when_rome_installed_via_package_manager.snap new file mode 100644 index 00000000000..91357bb73fa --- /dev/null +++ b/crates/rome_cli/tests/snapshots/main_commands_init/creates_config_file_when_rome_installed_via_package_manager.snap @@ -0,0 +1,51 @@ +--- +source: crates/rome_cli/tests/snap_test.rs +expression: content +--- +## `rome.json` + +```json +{ + "$schema": "./node_modules/rome/configuration_schema.json", + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + } +} +``` + +## `./node_modules/rome/configuration_schema.json` + +```json +{} +``` + +# Emitted Messages + +```block + +Welcome to Rome! Let's get you started... + +Files created ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + - rome.json: Your project configuration. Documentation: https://rome.tools/configuration + +Next Steps ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + 1. Setup an editor extension + Get live errors as you type and format when you save. Learn more: https://rome.tools/editors + + 2. Try a command + rome ci checks for lint errors and verifies formatting. Run rome --help for a full list of commands and options. + + 3. Read the documentation + Our website serves as a comprehensive source of guides and documentation: https://docs.rome.tools + + 4. Get involved in the community + Ask questions, get support, or contribute by participating on GitHub (https://github.com/rome/tools), + or join our community Discord (https://discord.gg/rome) +``` + + diff --git a/crates/rome_fs/src/fs/memory.rs b/crates/rome_fs/src/fs/memory.rs index 0cb268cbf83..558bf60a309 100644 --- a/crates/rome_fs/src/fs/memory.rs +++ b/crates/rome_fs/src/fs/memory.rs @@ -75,6 +75,8 @@ impl FileSystem for MemoryFileSystem { self.open(path) } else if options.create_new || options.write { self.create(path) + } else if options.read { + self.read(path) } else { unimplemented!("the set of open options provided don't match any case") } diff --git a/crates/rome_service/src/configuration/linter/rules.rs b/crates/rome_service/src/configuration/linter/rules.rs index c0324218607..91acb9dac2c 100644 --- a/crates/rome_service/src/configuration/linter/rules.rs +++ b/crates/rome_service/src/configuration/linter/rules.rs @@ -297,14 +297,23 @@ pub struct A11y { #[allow(dead_code)] #[doc = r" A list of rules that belong to this group"] struct A11ySchema { + #[doc = "Avoid the autoFocus attribute"] no_autofocus: Option, + #[doc = "Prevent the usage of positive integers on tabIndex property"] no_positive_tabindex: Option, + #[doc = "It asserts that alternative text to images or areas, help to rely on to screen readers to understand the purpose and the context of the image."] use_alt_text: Option, + #[doc = "Enforce that anchor elements have content and that the content is accessible to screen readers."] use_anchor_content: Option, + #[doc = "Disallow target=\"_blank\" attribute without rel=\"noreferrer\""] use_blank_target: Option, + #[doc = "Enforces the usage of the attribute type for the element button"] use_button_type: Option, + #[doc = "Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event."] use_key_with_click_events: Option, + #[doc = "Enforce that onMouseOver/onMouseOut are accompanied by onFocus/onBlur for keyboard-only users. It is important to take into account users with physical disabilities who cannot use a mouse, who use assistive technology or screenreader."] use_key_with_mouse_events: Option, + #[doc = "Enforce that all anchors are valid, and they are navigable elements."] use_valid_anchor: Option, } impl A11y { @@ -411,7 +420,9 @@ pub struct Complexity { #[allow(dead_code)] #[doc = r" A list of rules that belong to this group"] struct ComplexitySchema { + #[doc = "Disallow unnecessary boolean casts"] no_extra_boolean_cast: Option, + #[doc = "Discard redundant terms from logical expressions."] use_simplified_logic_expression: Option, } impl Complexity { @@ -493,36 +504,67 @@ pub struct Correctness { #[allow(dead_code)] #[doc = r" A list of rules that belong to this group"] struct CorrectnessSchema { + #[doc = "Disallow the use of arguments"] no_arguments: Option, + #[doc = "Discourage the usage of Array index in keys."] no_array_index_key: Option, + #[doc = "Disallows using an async function as a Promise executor."] no_async_promise_executor: Option, + #[doc = "Disallow reassigning exceptions in catch clauses"] no_catch_assign: Option, + #[doc = "Prevent passing of children as props."] no_children_prop: Option, + #[doc = "Prevent comments from being inserted as text nodes"] no_comment_text: Option, + #[doc = "Disallow comparing against -0"] no_compare_neg_zero: Option, + #[doc = "Disallow the use of debugger"] no_debugger: Option, + #[doc = "Disallow the use of the delete operator"] no_delete: Option, + #[doc = "Require the use of === and !=="] no_double_equals: Option, + #[doc = "Disallow duplicate function arguments name."] no_dupe_args: Option, + #[doc = "Disallows empty destructuring patterns."] no_empty_pattern: Option, + #[doc = "Disallow reassigning function declarations."] no_function_assign: Option, + #[doc = "Disallow assigning to imported bindings"] no_import_assign: Option, + #[doc = "Disallow labels that share a name with a variable"] no_label_var: Option, + #[doc = "Disallow unclear usage of multiple space characters in regular expression literals"] no_multiple_spaces_in_regular_expression_literals: Option, + #[doc = "Disallow new operators with the Symbol object"] no_new_symbol: Option, + #[doc = "Prevent the usage of the return value of React.render."] no_render_return_value: Option, + #[doc = "This rule allows you to specify global variable names that you don’t want to use in your application."] no_restricted_globals: Option, + #[doc = "Disallow identifiers from shadowing restricted names."] no_shadow_restricted_names: Option, + #[doc = "Disallow sparse arrays"] no_sparse_array: Option, + #[doc = "Prevents the usage of variables that haven't been declared inside the document"] no_undeclared_variables: Option, + #[doc = "Avoid using unnecessary continue."] no_unnecessary_continue: Option, + #[doc = "Disallow unreachable code"] no_unreachable: Option, + #[doc = "Disallow using unsafe negation."] no_unsafe_negation: Option, + #[doc = "Disallow unused variables."] no_unused_variables: Option, + #[doc = "Disallow unnecessary fragments"] no_useless_fragments: Option, + #[doc = "This rules prevents void elements (AKA self-closing elements) from having children."] no_void_elements_with_children: Option, + #[doc = "Enforces case clauses have a single statement, emits a quick fix wrapping the statements in a block"] use_single_case_statement: Option, + #[doc = "This rule verifies the result of typeof $expr unary expressions is being compared to valid values, either string literals containing valid type names or other typeof expressions"] use_valid_typeof: Option, + #[doc = "Enforce the use of while loops instead of for loops when the initializer and update expressions are not needed"] use_while: Option, } impl Correctness { @@ -687,19 +729,33 @@ pub struct Nursery { #[allow(dead_code)] #[doc = r" A list of rules that belong to this group"] struct NurserySchema { + #[doc = "Disallow certain types."] no_banned_types: Option, + #[doc = "Disallow assignment operators in conditional expressions."] no_conditional_assignment: Option, + #[doc = "Prevents from having const variables being re-assigned."] no_const_assign: Option, + #[doc = "Prevents object literals having more than one property declaration for the same name. If an object property with the same name is defined multiple times (except when combining a getter with a setter), only the last definition makes it into the object and previous definitions are ignored, which is likely a mistake."] no_dupe_keys: Option, + #[doc = "Disallow the any type usage"] no_explicit_any: Option, + #[doc = "Prevents the incorrect use of super() inside classes. It also checks whether a call super() is missing from classes that extends other constructors."] no_invalid_constructor_super: Option, + #[doc = "Disallow literal numbers that lose precision"] no_precision_loss: Option, + #[doc = "Disallow control flow statements in finally blocks."] no_unsafe_finally: Option, + #[doc = "Enforce camel case naming convention."] use_camel_case: Option, + #[doc = "Require const declarations for variables that are never reassigned after declared."] use_const: Option, + #[doc = "Enforce all dependencies are correctly specified."] use_exhaustive_dependencies: Option, + #[doc = "Promotes the use of .flatMap() when map().flat() are used together."] use_flat_map: Option, + #[doc = "Disallow parseInt() and Number.parseInt() in favor of binary, octal, and hexadecimal literals"] use_numeric_literals: Option, + #[doc = "Enforce \"for\" loop update clause moving the counter in the right direction."] use_valid_for_direction: Option, } impl Nursery { @@ -791,7 +847,9 @@ pub struct Security { #[allow(dead_code)] #[doc = r" A list of rules that belong to this group"] struct SecuritySchema { + #[doc = "Prevent the usage of dangerous JSX props"] no_dangerously_set_inner_html: Option, + #[doc = "Report when a DOM element or a component uses both children and dangerouslySetInnerHTML prop."] no_dangerously_set_inner_html_with_children: Option, } impl Security { @@ -877,16 +935,27 @@ pub struct Style { #[allow(dead_code)] #[doc = r" A list of rules that belong to this group"] struct StyleSchema { + #[doc = "Disallow implicit true values on JSX boolean attributes"] no_implicit_boolean: Option, + #[doc = "Disallow negation in the condition of an if statement if it has an else clause"] no_negation_else: Option, + #[doc = "Disallow the use of constants which its value is the upper-case version of its name."] no_shouty_constants: Option, + #[doc = "Disallow template literals if interpolation and special-character handling are not needed"] no_unused_template_literal: Option, + #[doc = "Requires following curly brace conventions. JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to never omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity."] use_block_statements: Option, + #[doc = "This rule enforces the use of <>... over ...."] use_fragment_syntax: Option, + #[doc = "Enforce using concise optional chain instead of chained logical expressions."] use_optional_chain: Option, + #[doc = "Prevent extra closing tags for components without children"] use_self_closing_elements: Option, + #[doc = "When expressing array types, this rule promotes the usage of T[] shorthand instead of Array."] use_shorthand_array_type: Option, + #[doc = "Disallow multiple variable declarations in the same variable statement"] use_single_var_declarator: Option, + #[doc = "Template literals are preferred over string concatenation."] use_template: Option, } impl Style { diff --git a/crates/rome_service/src/configuration/mod.rs b/crates/rome_service/src/configuration/mod.rs index b78e02ad4b9..919e4160e91 100644 --- a/crates/rome_service/src/configuration/mod.rs +++ b/crates/rome_service/src/configuration/mod.rs @@ -13,7 +13,7 @@ use std::fmt::{Debug, Display, Formatter}; use std::io::ErrorKind; use std::marker::PhantomData; use std::num::NonZeroU64; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use tracing::{error, info}; mod formatter; @@ -31,6 +31,10 @@ use rome_js_analyze::metadata; #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[serde(deny_unknown_fields)] pub struct Configuration { + /// A field for the [JSON schema](https://json-schema.org/) specification + #[serde(rename(serialize = "$schema", deserialize = "$schema"))] + #[serde(skip_serializing_if = "Option::is_none")] + pub schema: Option, /// The configuration of the filesystem #[serde(skip_serializing_if = "Option::is_none")] pub files: Option, @@ -58,6 +62,7 @@ impl Default for Configuration { }), formatter: None, javascript: None, + schema: None, } } } @@ -212,7 +217,7 @@ pub fn load_config( /// - the program doesn't have the write rights pub fn create_config( fs: &mut DynRef, - configuration: Configuration, + mut configuration: Configuration, ) -> Result<(), RomeError> { let path = PathBuf::from(fs.config_name()); @@ -226,6 +231,13 @@ pub fn create_config( } })?; + // we now check if rome is installed inside `node_modules` and if so, we + let schema_path = Path::new("./node_modules/rome/configuration_schema.json"); + let options = OpenOptions::default().read(true); + if fs.open_with_options(schema_path, options).is_ok() { + configuration.schema = schema_path.to_str().map(String::from); + } + let contents = serde_json::to_string_pretty(&configuration) .map_err(|_| RomeError::Configuration(ConfigurationError::SerializationError))?; diff --git a/editors/vscode/configuration_schema.json b/editors/vscode/configuration_schema.json index b205644bd78..c073defa37a 100644 --- a/editors/vscode/configuration_schema.json +++ b/editors/vscode/configuration_schema.json @@ -4,6 +4,13 @@ "description": "The configuration that is contained inside the file `rome.json`", "type": "object", "properties": { + "$schema": { + "description": "A field for the [JSON schema](https://json-schema.org/) specification", + "type": [ + "string", + "null" + ] + }, "files": { "description": "The configuration of the filesystem", "anyOf": [ @@ -56,6 +63,7 @@ "type": "object", "properties": { "noAutofocus": { + "description": "Avoid the autoFocus attribute", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -66,6 +74,7 @@ ] }, "noPositiveTabindex": { + "description": "Prevent the usage of positive integers on tabIndex property", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -83,6 +92,7 @@ ] }, "useAltText": { + "description": "It asserts that alternative text to images or areas, help to rely on to screen readers to understand the purpose and the context of the image.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -93,6 +103,7 @@ ] }, "useAnchorContent": { + "description": "Enforce that anchor elements have content and that the content is accessible to screen readers.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -103,6 +114,7 @@ ] }, "useBlankTarget": { + "description": "Disallow target=\"_blank\" attribute without rel=\"noreferrer\"", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -113,6 +125,7 @@ ] }, "useButtonType": { + "description": "Enforces the usage of the attribute type for the element button", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -123,6 +136,7 @@ ] }, "useKeyWithClickEvents": { + "description": "Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -133,6 +147,7 @@ ] }, "useKeyWithMouseEvents": { + "description": "Enforce that onMouseOver/onMouseOut are accompanied by onFocus/onBlur for keyboard-only users. It is important to take into account users with physical disabilities who cannot use a mouse, who use assistive technology or screenreader.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -143,6 +158,7 @@ ] }, "useValidAnchor": { + "description": "Enforce that all anchors are valid, and they are navigable elements.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -159,6 +175,7 @@ "type": "object", "properties": { "noExtraBooleanCast": { + "description": "Disallow unnecessary boolean casts", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -176,6 +193,7 @@ ] }, "useSimplifiedLogicExpression": { + "description": "Discard redundant terms from logical expressions.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -192,6 +210,7 @@ "type": "object", "properties": { "noArguments": { + "description": "Disallow the use of arguments", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -202,6 +221,7 @@ ] }, "noArrayIndexKey": { + "description": "Discourage the usage of Array index in keys.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -212,6 +232,7 @@ ] }, "noAsyncPromiseExecutor": { + "description": "Disallows using an async function as a Promise executor.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -222,6 +243,7 @@ ] }, "noCatchAssign": { + "description": "Disallow reassigning exceptions in catch clauses", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -232,6 +254,7 @@ ] }, "noChildrenProp": { + "description": "Prevent passing of children as props.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -242,6 +265,7 @@ ] }, "noCommentText": { + "description": "Prevent comments from being inserted as text nodes", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -252,6 +276,7 @@ ] }, "noCompareNegZero": { + "description": "Disallow comparing against -0", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -262,6 +287,7 @@ ] }, "noDebugger": { + "description": "Disallow the use of debugger", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -272,6 +298,7 @@ ] }, "noDelete": { + "description": "Disallow the use of the delete operator", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -282,6 +309,7 @@ ] }, "noDoubleEquals": { + "description": "Require the use of === and !==", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -292,6 +320,7 @@ ] }, "noDupeArgs": { + "description": "Disallow duplicate function arguments name.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -302,6 +331,7 @@ ] }, "noEmptyPattern": { + "description": "Disallows empty destructuring patterns.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -312,6 +342,7 @@ ] }, "noFunctionAssign": { + "description": "Disallow reassigning function declarations.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -322,6 +353,7 @@ ] }, "noImportAssign": { + "description": "Disallow assigning to imported bindings", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -332,6 +364,7 @@ ] }, "noLabelVar": { + "description": "Disallow labels that share a name with a variable", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -342,6 +375,7 @@ ] }, "noMultipleSpacesInRegularExpressionLiterals": { + "description": "Disallow unclear usage of multiple space characters in regular expression literals", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -352,6 +386,7 @@ ] }, "noNewSymbol": { + "description": "Disallow new operators with the Symbol object", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -362,6 +397,7 @@ ] }, "noRenderReturnValue": { + "description": "Prevent the usage of the return value of React.render.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -372,6 +408,7 @@ ] }, "noRestrictedGlobals": { + "description": "This rule allows you to specify global variable names that you don’t want to use in your application.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -382,6 +419,7 @@ ] }, "noShadowRestrictedNames": { + "description": "Disallow identifiers from shadowing restricted names.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -392,6 +430,7 @@ ] }, "noSparseArray": { + "description": "Disallow sparse arrays", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -402,6 +441,7 @@ ] }, "noUndeclaredVariables": { + "description": "Prevents the usage of variables that haven't been declared inside the document", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -412,6 +452,7 @@ ] }, "noUnnecessaryContinue": { + "description": "Avoid using unnecessary continue.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -422,6 +463,7 @@ ] }, "noUnreachable": { + "description": "Disallow unreachable code", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -432,6 +474,7 @@ ] }, "noUnsafeNegation": { + "description": "Disallow using unsafe negation.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -442,6 +485,7 @@ ] }, "noUnusedVariables": { + "description": "Disallow unused variables.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -452,6 +496,7 @@ ] }, "noUselessFragments": { + "description": "Disallow unnecessary fragments", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -462,6 +507,7 @@ ] }, "noVoidElementsWithChildren": { + "description": "This rules prevents void elements (AKA self-closing elements) from having children.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -479,6 +525,7 @@ ] }, "useSingleCaseStatement": { + "description": "Enforces case clauses have a single statement, emits a quick fix wrapping the statements in a block", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -489,6 +536,7 @@ ] }, "useValidTypeof": { + "description": "This rule verifies the result of typeof $expr unary expressions is being compared to valid values, either string literals containing valid type names or other typeof expressions", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -499,6 +547,7 @@ ] }, "useWhile": { + "description": "Enforce the use of while loops instead of for loops when the initializer and update expressions are not needed", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -705,6 +754,7 @@ "type": "object", "properties": { "noBannedTypes": { + "description": "Disallow certain types.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -715,6 +765,7 @@ ] }, "noConditionalAssignment": { + "description": "Disallow assignment operators in conditional expressions.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -725,6 +776,7 @@ ] }, "noConstAssign": { + "description": "Prevents from having const variables being re-assigned.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -735,6 +787,7 @@ ] }, "noDupeKeys": { + "description": "Prevents object literals having more than one property declaration for the same name. If an object property with the same name is defined multiple times (except when combining a getter with a setter), only the last definition makes it into the object and previous definitions are ignored, which is likely a mistake.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -745,6 +798,7 @@ ] }, "noExplicitAny": { + "description": "Disallow the any type usage", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -755,6 +809,7 @@ ] }, "noInvalidConstructorSuper": { + "description": "Prevents the incorrect use of super() inside classes. It also checks whether a call super() is missing from classes that extends other constructors.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -765,6 +820,7 @@ ] }, "noPrecisionLoss": { + "description": "Disallow literal numbers that lose precision", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -775,6 +831,7 @@ ] }, "noUnsafeFinally": { + "description": "Disallow control flow statements in finally blocks.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -792,6 +849,7 @@ ] }, "useCamelCase": { + "description": "Enforce camel case naming convention.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -802,6 +860,7 @@ ] }, "useConst": { + "description": "Require const declarations for variables that are never reassigned after declared.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -812,6 +871,7 @@ ] }, "useExhaustiveDependencies": { + "description": "Enforce all dependencies are correctly specified.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -822,6 +882,7 @@ ] }, "useFlatMap": { + "description": "Promotes the use of .flatMap() when map().flat() are used together.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -832,6 +893,7 @@ ] }, "useNumericLiterals": { + "description": "Disallow parseInt() and Number.parseInt() in favor of binary, octal, and hexadecimal literals", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -842,6 +904,7 @@ ] }, "useValidForDirection": { + "description": "Enforce \"for\" loop update clause moving the counter in the right direction.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -984,6 +1047,7 @@ "type": "object", "properties": { "noDangerouslySetInnerHtml": { + "description": "Prevent the usage of dangerous JSX props", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -994,6 +1058,7 @@ ] }, "noDangerouslySetInnerHtmlWithChildren": { + "description": "Report when a DOM element or a component uses both children and dangerouslySetInnerHTML prop.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1024,6 +1089,7 @@ "type": "object", "properties": { "noImplicitBoolean": { + "description": "Disallow implicit true values on JSX boolean attributes", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1034,6 +1100,7 @@ ] }, "noNegationElse": { + "description": "Disallow negation in the condition of an if statement if it has an else clause", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1044,6 +1111,7 @@ ] }, "noShoutyConstants": { + "description": "Disallow the use of constants which its value is the upper-case version of its name.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1054,6 +1122,7 @@ ] }, "noUnusedTemplateLiteral": { + "description": "Disallow template literals if interpolation and special-character handling are not needed", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1071,6 +1140,7 @@ ] }, "useBlockStatements": { + "description": "Requires following curly brace conventions. JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to never omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1081,6 +1151,7 @@ ] }, "useFragmentSyntax": { + "description": "This rule enforces the use of <>... over ....", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1091,6 +1162,7 @@ ] }, "useOptionalChain": { + "description": "Enforce using concise optional chain instead of chained logical expressions.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1101,6 +1173,7 @@ ] }, "useSelfClosingElements": { + "description": "Prevent extra closing tags for components without children", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1111,6 +1184,7 @@ ] }, "useShorthandArrayType": { + "description": "When expressing array types, this rule promotes the usage of T[] shorthand instead of Array.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1121,6 +1195,7 @@ ] }, "useSingleVarDeclarator": { + "description": "Disallow multiple variable declarations in the same variable statement", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" @@ -1131,6 +1206,7 @@ ] }, "useTemplate": { + "description": "Template literals are preferred over string concatenation.", "anyOf": [ { "$ref": "#/definitions/RuleConfiguration" diff --git a/npm/backend-jsonrpc/src/workspace.ts b/npm/backend-jsonrpc/src/workspace.ts index 143dcb5cfbb..6bbe463df03 100644 --- a/npm/backend-jsonrpc/src/workspace.ts +++ b/npm/backend-jsonrpc/src/workspace.ts @@ -27,6 +27,10 @@ export interface UpdateSettingsParams { * The configuration that is contained inside the file `rome.json` */ export interface Configuration { + /** + * A field for the [JSON schema](https://json-schema.org/) specification + */ + $schema?: string; /** * The configuration of the filesystem */ @@ -148,99 +152,273 @@ export type TrailingComma = "all" | "es5" | "none"; * A list of rules that belong to this group */ export interface A11y { + /** + * Avoid the autoFocus attribute + */ noAutofocus?: RuleConfiguration; + /** + * Prevent the usage of positive integers on tabIndex property + */ noPositiveTabindex?: RuleConfiguration; /** * It enables the recommended rules for this group */ recommended?: boolean; + /** + * It asserts that alternative text to images or areas, help to rely on to screen readers to understand the purpose and the context of the image. + */ useAltText?: RuleConfiguration; + /** + * Enforce that anchor elements have content and that the content is accessible to screen readers. + */ useAnchorContent?: RuleConfiguration; + /** + * Disallow target="_blank" attribute without rel="noreferrer" + */ useBlankTarget?: RuleConfiguration; + /** + * Enforces the usage of the attribute type for the element button + */ useButtonType?: RuleConfiguration; + /** + * Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event. + */ useKeyWithClickEvents?: RuleConfiguration; + /** + * Enforce that onMouseOver/onMouseOut are accompanied by onFocus/onBlur for keyboard-only users. It is important to take into account users with physical disabilities who cannot use a mouse, who use assistive technology or screenreader. + */ useKeyWithMouseEvents?: RuleConfiguration; + /** + * Enforce that all anchors are valid, and they are navigable elements. + */ useValidAnchor?: RuleConfiguration; } /** * A list of rules that belong to this group */ export interface Complexity { + /** + * Disallow unnecessary boolean casts + */ noExtraBooleanCast?: RuleConfiguration; /** * It enables the recommended rules for this group */ recommended?: boolean; + /** + * Discard redundant terms from logical expressions. + */ useSimplifiedLogicExpression?: RuleConfiguration; } /** * A list of rules that belong to this group */ export interface Correctness { + /** + * Disallow the use of arguments + */ noArguments?: RuleConfiguration; + /** + * Discourage the usage of Array index in keys. + */ noArrayIndexKey?: RuleConfiguration; + /** + * Disallows using an async function as a Promise executor. + */ noAsyncPromiseExecutor?: RuleConfiguration; + /** + * Disallow reassigning exceptions in catch clauses + */ noCatchAssign?: RuleConfiguration; + /** + * Prevent passing of children as props. + */ noChildrenProp?: RuleConfiguration; + /** + * Prevent comments from being inserted as text nodes + */ noCommentText?: RuleConfiguration; + /** + * Disallow comparing against -0 + */ noCompareNegZero?: RuleConfiguration; + /** + * Disallow the use of debugger + */ noDebugger?: RuleConfiguration; + /** + * Disallow the use of the delete operator + */ noDelete?: RuleConfiguration; + /** + * Require the use of === and !== + */ noDoubleEquals?: RuleConfiguration; + /** + * Disallow duplicate function arguments name. + */ noDupeArgs?: RuleConfiguration; + /** + * Disallows empty destructuring patterns. + */ noEmptyPattern?: RuleConfiguration; + /** + * Disallow reassigning function declarations. + */ noFunctionAssign?: RuleConfiguration; + /** + * Disallow assigning to imported bindings + */ noImportAssign?: RuleConfiguration; + /** + * Disallow labels that share a name with a variable + */ noLabelVar?: RuleConfiguration; + /** + * Disallow unclear usage of multiple space characters in regular expression literals + */ noMultipleSpacesInRegularExpressionLiterals?: RuleConfiguration; + /** + * Disallow new operators with the Symbol object + */ noNewSymbol?: RuleConfiguration; + /** + * Prevent the usage of the return value of React.render. + */ noRenderReturnValue?: RuleConfiguration; + /** + * This rule allows you to specify global variable names that you don’t want to use in your application. + */ noRestrictedGlobals?: RuleConfiguration; + /** + * Disallow identifiers from shadowing restricted names. + */ noShadowRestrictedNames?: RuleConfiguration; + /** + * Disallow sparse arrays + */ noSparseArray?: RuleConfiguration; + /** + * Prevents the usage of variables that haven't been declared inside the document + */ noUndeclaredVariables?: RuleConfiguration; + /** + * Avoid using unnecessary continue. + */ noUnnecessaryContinue?: RuleConfiguration; + /** + * Disallow unreachable code + */ noUnreachable?: RuleConfiguration; + /** + * Disallow using unsafe negation. + */ noUnsafeNegation?: RuleConfiguration; + /** + * Disallow unused variables. + */ noUnusedVariables?: RuleConfiguration; + /** + * Disallow unnecessary fragments + */ noUselessFragments?: RuleConfiguration; + /** + * This rules prevents void elements (AKA self-closing elements) from having children. + */ noVoidElementsWithChildren?: RuleConfiguration; /** * It enables the recommended rules for this group */ recommended?: boolean; + /** + * Enforces case clauses have a single statement, emits a quick fix wrapping the statements in a block + */ useSingleCaseStatement?: RuleConfiguration; + /** + * This rule verifies the result of typeof $expr unary expressions is being compared to valid values, either string literals containing valid type names or other typeof expressions + */ useValidTypeof?: RuleConfiguration; + /** + * Enforce the use of while loops instead of for loops when the initializer and update expressions are not needed + */ useWhile?: RuleConfiguration; } /** * A list of rules that belong to this group */ export interface Nursery { + /** + * Disallow certain types. + */ noBannedTypes?: RuleConfiguration; + /** + * Disallow assignment operators in conditional expressions. + */ noConditionalAssignment?: RuleConfiguration; + /** + * Prevents from having const variables being re-assigned. + */ noConstAssign?: RuleConfiguration; + /** + * Prevents object literals having more than one property declaration for the same name. If an object property with the same name is defined multiple times (except when combining a getter with a setter), only the last definition makes it into the object and previous definitions are ignored, which is likely a mistake. + */ noDupeKeys?: RuleConfiguration; + /** + * Disallow the any type usage + */ noExplicitAny?: RuleConfiguration; + /** + * Prevents the incorrect use of super() inside classes. It also checks whether a call super() is missing from classes that extends other constructors. + */ noInvalidConstructorSuper?: RuleConfiguration; + /** + * Disallow literal numbers that lose precision + */ noPrecisionLoss?: RuleConfiguration; + /** + * Disallow control flow statements in finally blocks. + */ noUnsafeFinally?: RuleConfiguration; /** * It enables the recommended rules for this group */ recommended?: boolean; + /** + * Enforce camel case naming convention. + */ useCamelCase?: RuleConfiguration; + /** + * Require const declarations for variables that are never reassigned after declared. + */ useConst?: RuleConfiguration; + /** + * Enforce all dependencies are correctly specified. + */ useExhaustiveDependencies?: RuleConfiguration; + /** + * Promotes the use of .flatMap() when map().flat() are used together. + */ useFlatMap?: RuleConfiguration; + /** + * Disallow parseInt() and Number.parseInt() in favor of binary, octal, and hexadecimal literals + */ useNumericLiterals?: RuleConfiguration; + /** + * Enforce "for" loop update clause moving the counter in the right direction. + */ useValidForDirection?: RuleConfiguration; } /** * A list of rules that belong to this group */ export interface Security { + /** + * Prevent the usage of dangerous JSX props + */ noDangerouslySetInnerHtml?: RuleConfiguration; + /** + * Report when a DOM element or a component uses both children and dangerouslySetInnerHTML prop. + */ noDangerouslySetInnerHtmlWithChildren?: RuleConfiguration; /** * It enables the recommended rules for this group @@ -251,20 +429,53 @@ export interface Security { * A list of rules that belong to this group */ export interface Style { + /** + * Disallow implicit true values on JSX boolean attributes + */ noImplicitBoolean?: RuleConfiguration; + /** + * Disallow negation in the condition of an if statement if it has an else clause + */ noNegationElse?: RuleConfiguration; + /** + * Disallow the use of constants which its value is the upper-case version of its name. + */ noShoutyConstants?: RuleConfiguration; + /** + * Disallow template literals if interpolation and special-character handling are not needed + */ noUnusedTemplateLiteral?: RuleConfiguration; /** * It enables the recommended rules for this group */ recommended?: boolean; + /** + * Requires following curly brace conventions. JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to never omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity. + */ useBlockStatements?: RuleConfiguration; + /** + * This rule enforces the use of <>... over .... + */ useFragmentSyntax?: RuleConfiguration; + /** + * Enforce using concise optional chain instead of chained logical expressions. + */ useOptionalChain?: RuleConfiguration; + /** + * Prevent extra closing tags for components without children + */ useSelfClosingElements?: RuleConfiguration; + /** + * When expressing array types, this rule promotes the usage of T[] shorthand instead of Array. + */ useShorthandArrayType?: RuleConfiguration; + /** + * Disallow multiple variable declarations in the same variable statement + */ useSingleVarDeclarator?: RuleConfiguration; + /** + * Template literals are preferred over string concatenation. + */ useTemplate?: RuleConfiguration; } export type RuleConfiguration = RulePlainConfiguration | RuleWithOptions; diff --git a/npm/rome/configuration_schema.json b/npm/rome/configuration_schema.json new file mode 100644 index 00000000000..c073defa37a --- /dev/null +++ b/npm/rome/configuration_schema.json @@ -0,0 +1,1230 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Configuration", + "description": "The configuration that is contained inside the file `rome.json`", + "type": "object", + "properties": { + "$schema": { + "description": "A field for the [JSON schema](https://json-schema.org/) specification", + "type": [ + "string", + "null" + ] + }, + "files": { + "description": "The configuration of the filesystem", + "anyOf": [ + { + "$ref": "#/definitions/FilesConfiguration" + }, + { + "type": "null" + } + ] + }, + "formatter": { + "description": "The configuration of the formatter", + "anyOf": [ + { + "$ref": "#/definitions/FormatterConfiguration" + }, + { + "type": "null" + } + ] + }, + "javascript": { + "description": "Specific configuration for the JavaScript language", + "anyOf": [ + { + "$ref": "#/definitions/JavascriptConfiguration" + }, + { + "type": "null" + } + ] + }, + "linter": { + "description": "The configuration for the linter", + "anyOf": [ + { + "$ref": "#/definitions/LinterConfiguration" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "A11y": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noAutofocus": { + "description": "Avoid the autoFocus attribute", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noPositiveTabindex": { + "description": "Prevent the usage of positive integers on tabIndex property", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useAltText": { + "description": "It asserts that alternative text to images or areas, help to rely on to screen readers to understand the purpose and the context of the image.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useAnchorContent": { + "description": "Enforce that anchor elements have content and that the content is accessible to screen readers.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useBlankTarget": { + "description": "Disallow target=\"_blank\" attribute without rel=\"noreferrer\"", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useButtonType": { + "description": "Enforces the usage of the attribute type for the element button", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useKeyWithClickEvents": { + "description": "Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useKeyWithMouseEvents": { + "description": "Enforce that onMouseOver/onMouseOut are accompanied by onFocus/onBlur for keyboard-only users. It is important to take into account users with physical disabilities who cannot use a mouse, who use assistive technology or screenreader.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useValidAnchor": { + "description": "Enforce that all anchors are valid, and they are navigable elements.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "Complexity": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noExtraBooleanCast": { + "description": "Disallow unnecessary boolean casts", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useSimplifiedLogicExpression": { + "description": "Discard redundant terms from logical expressions.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "Correctness": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noArguments": { + "description": "Disallow the use of arguments", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noArrayIndexKey": { + "description": "Discourage the usage of Array index in keys.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noAsyncPromiseExecutor": { + "description": "Disallows using an async function as a Promise executor.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noCatchAssign": { + "description": "Disallow reassigning exceptions in catch clauses", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noChildrenProp": { + "description": "Prevent passing of children as props.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noCommentText": { + "description": "Prevent comments from being inserted as text nodes", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noCompareNegZero": { + "description": "Disallow comparing against -0", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDebugger": { + "description": "Disallow the use of debugger", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDelete": { + "description": "Disallow the use of the delete operator", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDoubleEquals": { + "description": "Require the use of === and !==", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDupeArgs": { + "description": "Disallow duplicate function arguments name.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noEmptyPattern": { + "description": "Disallows empty destructuring patterns.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noFunctionAssign": { + "description": "Disallow reassigning function declarations.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noImportAssign": { + "description": "Disallow assigning to imported bindings", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noLabelVar": { + "description": "Disallow labels that share a name with a variable", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noMultipleSpacesInRegularExpressionLiterals": { + "description": "Disallow unclear usage of multiple space characters in regular expression literals", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noNewSymbol": { + "description": "Disallow new operators with the Symbol object", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noRenderReturnValue": { + "description": "Prevent the usage of the return value of React.render.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noRestrictedGlobals": { + "description": "This rule allows you to specify global variable names that you don’t want to use in your application.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noShadowRestrictedNames": { + "description": "Disallow identifiers from shadowing restricted names.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noSparseArray": { + "description": "Disallow sparse arrays", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUndeclaredVariables": { + "description": "Prevents the usage of variables that haven't been declared inside the document", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnnecessaryContinue": { + "description": "Avoid using unnecessary continue.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnreachable": { + "description": "Disallow unreachable code", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnsafeNegation": { + "description": "Disallow using unsafe negation.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnusedVariables": { + "description": "Disallow unused variables.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUselessFragments": { + "description": "Disallow unnecessary fragments", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noVoidElementsWithChildren": { + "description": "This rules prevents void elements (AKA self-closing elements) from having children.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useSingleCaseStatement": { + "description": "Enforces case clauses have a single statement, emits a quick fix wrapping the statements in a block", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useValidTypeof": { + "description": "This rule verifies the result of typeof $expr unary expressions is being compared to valid values, either string literals containing valid type names or other typeof expressions", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useWhile": { + "description": "Enforce the use of while loops instead of for loops when the initializer and update expressions are not needed", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "FilesConfiguration": { + "description": "The configuration of the filesystem", + "type": "object", + "properties": { + "ignore": { + "description": "A list of Unix shell style patterns. Rome tools will ignore files/folders that will match these patterns.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "maxSize": { + "description": "The maximum allowed size for source code files in bytes. Files above this limit will be ignored for performance reason. Defaults to 1 MiB", + "default": null, + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 1.0 + } + }, + "additionalProperties": false + }, + "FormatterConfiguration": { + "type": "object", + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "formatWithErrors": { + "description": "Stores whether formatting should be allowed to proceed if a given file has syntax errors", + "default": false, + "type": "boolean" + }, + "ignore": { + "description": "A list of Unix shell style patterns. The formatter will ignore files/folders that will match these patterns.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "indentSize": { + "description": "The size of the indentation, 2 by default", + "default": 2, + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "indentStyle": { + "description": "The indent style.", + "default": "tab", + "allOf": [ + { + "$ref": "#/definitions/PlainIndentStyle" + } + ] + }, + "lineWidth": { + "description": "What's the max width of a line. Defaults to 80.", + "default": 80, + "allOf": [ + { + "$ref": "#/definitions/LineWidth" + } + ] + } + }, + "additionalProperties": false + }, + "JavascriptConfiguration": { + "type": "object", + "properties": { + "formatter": { + "anyOf": [ + { + "$ref": "#/definitions/JavascriptFormatter" + }, + { + "type": "null" + } + ] + }, + "globals": { + "description": "A list of global bindings that should be ignored by the analyzers\n\nIf defined here, they should not emit diagnostics.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + "additionalProperties": false + }, + "JavascriptFormatter": { + "type": "object", + "properties": { + "quoteProperties": { + "description": "When properties in objects are quoted. Defaults to asNeeded.", + "default": "asNeeded", + "allOf": [ + { + "$ref": "#/definitions/QuoteProperties" + } + ] + }, + "quoteStyle": { + "description": "The style for quotes. Defaults to double.", + "default": "double", + "allOf": [ + { + "$ref": "#/definitions/QuoteStyle" + } + ] + }, + "semicolons": { + "description": "Whether the formatter prints semicolons for all statements or only in for statements where it is necessary because of ASI.", + "default": "always", + "allOf": [ + { + "$ref": "#/definitions/Semicolons" + } + ] + }, + "trailingComma": { + "description": "Print trailing commas wherever possible in multi-line comma-separated syntactic structures. Defaults to \"all\".", + "default": "all", + "allOf": [ + { + "$ref": "#/definitions/TrailingComma" + } + ] + } + }, + "additionalProperties": false + }, + "LineWidth": { + "description": "Validated value for the `line_width` formatter options\n\nThe allowed range of values is 1..=320", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "LinterConfiguration": { + "type": "object", + "properties": { + "enabled": { + "description": "if `false`, it disables the feature and the linter won't be executed. `true` by default", + "default": true, + "type": "boolean" + }, + "ignore": { + "description": "A list of Unix shell style patterns. The formatter will ignore files/folders that will match these patterns.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "rules": { + "description": "List of rules", + "default": { + "recommended": true + }, + "anyOf": [ + { + "$ref": "#/definitions/Rules" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Nursery": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noBannedTypes": { + "description": "Disallow certain types.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noConditionalAssignment": { + "description": "Disallow assignment operators in conditional expressions.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noConstAssign": { + "description": "Prevents from having const variables being re-assigned.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDupeKeys": { + "description": "Prevents object literals having more than one property declaration for the same name. If an object property with the same name is defined multiple times (except when combining a getter with a setter), only the last definition makes it into the object and previous definitions are ignored, which is likely a mistake.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noExplicitAny": { + "description": "Disallow the any type usage", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noInvalidConstructorSuper": { + "description": "Prevents the incorrect use of super() inside classes. It also checks whether a call super() is missing from classes that extends other constructors.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noPrecisionLoss": { + "description": "Disallow literal numbers that lose precision", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnsafeFinally": { + "description": "Disallow control flow statements in finally blocks.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useCamelCase": { + "description": "Enforce camel case naming convention.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useConst": { + "description": "Require const declarations for variables that are never reassigned after declared.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useExhaustiveDependencies": { + "description": "Enforce all dependencies are correctly specified.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useFlatMap": { + "description": "Promotes the use of .flatMap() when map().flat() are used together.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useNumericLiterals": { + "description": "Disallow parseInt() and Number.parseInt() in favor of binary, octal, and hexadecimal literals", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useValidForDirection": { + "description": "Enforce \"for\" loop update clause moving the counter in the right direction.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "PlainIndentStyle": { + "type": "string", + "enum": [ + "tab", + "space" + ] + }, + "QuoteProperties": { + "type": "string", + "enum": [ + "asNeeded", + "preserve" + ] + }, + "QuoteStyle": { + "type": "string", + "enum": [ + "double", + "single" + ] + }, + "RuleConfiguration": { + "anyOf": [ + { + "$ref": "#/definitions/RulePlainConfiguration" + }, + { + "$ref": "#/definitions/RuleWithOptions" + } + ] + }, + "RulePlainConfiguration": { + "type": "string", + "enum": [ + "warn", + "error", + "off" + ] + }, + "RuleWithOptions": { + "type": "object", + "required": [ + "level", + "options" + ], + "properties": { + "level": { + "$ref": "#/definitions/RulePlainConfiguration" + }, + "options": true + }, + "additionalProperties": false + }, + "Rules": { + "type": "object", + "properties": { + "a11y": { + "anyOf": [ + { + "$ref": "#/definitions/A11y" + }, + { + "type": "null" + } + ] + }, + "complexity": { + "anyOf": [ + { + "$ref": "#/definitions/Complexity" + }, + { + "type": "null" + } + ] + }, + "correctness": { + "anyOf": [ + { + "$ref": "#/definitions/Correctness" + }, + { + "type": "null" + } + ] + }, + "nursery": { + "anyOf": [ + { + "$ref": "#/definitions/Nursery" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the lint rules recommended by Rome. `true` by default.", + "type": [ + "boolean", + "null" + ] + }, + "security": { + "anyOf": [ + { + "$ref": "#/definitions/Security" + }, + { + "type": "null" + } + ] + }, + "style": { + "anyOf": [ + { + "$ref": "#/definitions/Style" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Security": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noDangerouslySetInnerHtml": { + "description": "Prevent the usage of dangerous JSX props", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDangerouslySetInnerHtmlWithChildren": { + "description": "Report when a DOM element or a component uses both children and dangerouslySetInnerHTML prop.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + } + } + }, + "Semicolons": { + "type": "string", + "enum": [ + "always", + "asNeeded" + ] + }, + "Style": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noImplicitBoolean": { + "description": "Disallow implicit true values on JSX boolean attributes", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noNegationElse": { + "description": "Disallow negation in the condition of an if statement if it has an else clause", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noShoutyConstants": { + "description": "Disallow the use of constants which its value is the upper-case version of its name.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnusedTemplateLiteral": { + "description": "Disallow template literals if interpolation and special-character handling are not needed", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useBlockStatements": { + "description": "Requires following curly brace conventions. JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to never omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useFragmentSyntax": { + "description": "This rule enforces the use of <>... over ....", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useOptionalChain": { + "description": "Enforce using concise optional chain instead of chained logical expressions.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useSelfClosingElements": { + "description": "Prevent extra closing tags for components without children", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useShorthandArrayType": { + "description": "When expressing array types, this rule promotes the usage of T[] shorthand instead of Array.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useSingleVarDeclarator": { + "description": "Disallow multiple variable declarations in the same variable statement", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useTemplate": { + "description": "Template literals are preferred over string concatenation.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "TrailingComma": { + "type": "string", + "enum": [ + "all", + "es5", + "none" + ] + } + } +} \ No newline at end of file diff --git a/npm/rome/package.json b/npm/rome/package.json index dc025bcf4b5..4bc977c03ee 100644 --- a/npm/rome/package.json +++ b/npm/rome/package.json @@ -18,6 +18,7 @@ "files": [ "bin/rome", "scripts/postinstall.js", + "configuration_schema.json", "README.md" ], "keywords": [ diff --git a/npm/rome/schema.json b/npm/rome/schema.json new file mode 100644 index 00000000000..66de26af630 --- /dev/null +++ b/npm/rome/schema.json @@ -0,0 +1,1159 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Configuration", + "description": "The configuration that is contained inside the file `rome.json`", + "type": "object", + "properties": { + "files": { + "description": "The configuration of the filesystem", + "anyOf": [ + { + "$ref": "#/definitions/FilesConfiguration" + }, + { + "type": "null" + } + ] + }, + "formatter": { + "description": "The configuration of the formatter", + "anyOf": [ + { + "$ref": "#/definitions/FormatterConfiguration" + }, + { + "type": "null" + } + ] + }, + "javascript": { + "description": "Specific configuration for the JavaScript language", + "anyOf": [ + { + "$ref": "#/definitions/JavascriptConfiguration" + }, + { + "type": "null" + } + ] + }, + "linter": { + "description": "The configuration for the linter", + "anyOf": [ + { + "$ref": "#/definitions/LinterConfiguration" + }, + { + "type": "null" + } + ] + }, + "schema": { + "description": "A field for the [JSON schema](https://json-schema.org/) specification", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "A11y": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noAutofocus": { + "description": "Avoid the autoFocus attribute", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noPositiveTabindex": { + "description": "Prevent the usage of positive integers on tabIndex property", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useAltText": { + "description": "It asserts that alternative text to images or areas, help to rely on to screen readers to understand the purpose and the context of the image.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useAnchorContent": { + "description": "Enforce that anchor elements have content and that the content is accessible to screen readers.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useBlankTarget": { + "description": "Disallow target=\"_blank\" attribute without rel=\"noreferrer\"", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useButtonType": { + "description": "Enforces the usage of the attribute type for the element button", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useKeyWithClickEvents": { + "description": "Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useKeyWithMouseEvents": { + "description": "Enforce that onMouseOver/onMouseOut are accompanied by onFocus/onBlur for keyboard-only users. It is important to take into account users with physical disabilities who cannot use a mouse, who use assistive technology or screenreader.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useValidAnchor": { + "description": "Enforce that all anchors are valid, and they are navigable elements.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "Complexity": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noExtraBooleanCast": { + "description": "Disallow unnecessary boolean casts", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useSimplifiedLogicExpression": { + "description": "Discard redundant terms from logical expressions.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "Correctness": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noArguments": { + "description": "Disallow the use of arguments", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noArrayIndexKey": { + "description": "Discourage the usage of Array index in keys.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noAsyncPromiseExecutor": { + "description": "Disallows using an async function as a Promise executor.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noCatchAssign": { + "description": "Disallow reassigning exceptions in catch clauses", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noChildrenProp": { + "description": "Prevent passing of children as props.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noCommentText": { + "description": "Prevent comments from being inserted as text nodes", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noCompareNegZero": { + "description": "Disallow comparing against -0", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDebugger": { + "description": "Disallow the use of debugger", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDelete": { + "description": "Disallow the use of the delete operator", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDoubleEquals": { + "description": "Require the use of === and !==", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDupeArgs": { + "description": "Disallow duplicate function arguments name.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noEmptyPattern": { + "description": "Disallows empty destructuring patterns.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noFunctionAssign": { + "description": "Disallow reassigning function declarations.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noImportAssign": { + "description": "Disallow assigning to imported bindings", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noLabelVar": { + "description": "Disallow labels that share a name with a variable", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noMultipleSpacesInRegularExpressionLiterals": { + "description": "Disallow unclear usage of multiple space characters in regular expression literals", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noNewSymbol": { + "description": "Disallow new operators with the Symbol object", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noRenderReturnValue": { + "description": "Prevent the usage of the return value of React.render.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noRestrictedGlobals": { + "description": "This rule allows you to specify global variable names that you don’t want to use in your application.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noShadowRestrictedNames": { + "description": "Disallow identifiers from shadowing restricted names.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noSparseArray": { + "description": "Disallow sparse arrays", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUndeclaredVariables": { + "description": "Prevents the usage of variables that haven't been declared inside the document", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnnecessaryContinue": { + "description": "Avoid using unnecessary continue.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnreachable": { + "description": "Disallow unreachable code", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnsafeNegation": { + "description": "Disallow using unsafe negation.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnusedVariables": { + "description": "Disallow unused variables.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUselessFragments": { + "description": "Disallow unnecessary fragments", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noVoidElementsWithChildren": { + "description": "This rules prevents void elements (AKA self-closing elements) from having children.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useSingleCaseStatement": { + "description": "Enforces case clauses have a single statement, emits a quick fix wrapping the statements in a block", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useValidTypeof": { + "description": "This rule verifies the result of typeof $expr unary expressions is being compared to valid values, either string literals containing valid type names or other typeof expressions", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useWhile": { + "description": "Enforce the use of while loops instead of for loops when the initializer and update expressions are not needed", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "FilesConfiguration": { + "description": "The configuration of the filesystem", + "type": "object", + "properties": { + "maxSize": { + "description": "The maximum allowed size for source code files in bytes. Files above this limit will be ignored for performance reason. Defaults to 1 MiB", + "default": null, + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 1.0 + } + }, + "additionalProperties": false + }, + "FormatterConfiguration": { + "type": "object", + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "formatWithErrors": { + "description": "Stores whether formatting should be allowed to proceed if a given file has syntax errors", + "default": false, + "type": "boolean" + }, + "ignore": { + "description": "A list of Unix shell style patterns. The formatter will ignore files/folders that will match these patterns.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "indentSize": { + "description": "The size of the indentation, 2 by default", + "default": 2, + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "indentStyle": { + "description": "The indent style.", + "default": "tab", + "allOf": [ + { + "$ref": "#/definitions/PlainIndentStyle" + } + ] + }, + "lineWidth": { + "description": "What's the max width of a line. Defaults to 80.", + "default": 80, + "allOf": [ + { + "$ref": "#/definitions/LineWidth" + } + ] + } + }, + "additionalProperties": false + }, + "JavascriptConfiguration": { + "type": "object", + "properties": { + "formatter": { + "anyOf": [ + { + "$ref": "#/definitions/JavascriptFormatter" + }, + { + "type": "null" + } + ] + }, + "globals": { + "description": "A list of global bindings that should be ignored by the analyzers\n\nIf defined here, they should not emit diagnostics.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + "additionalProperties": false + }, + "JavascriptFormatter": { + "type": "object", + "properties": { + "quoteProperties": { + "description": "When properties in objects are quoted. Defaults to asNeeded.", + "default": "asNeeded", + "allOf": [ + { + "$ref": "#/definitions/QuoteProperties" + } + ] + }, + "quoteStyle": { + "description": "The style for quotes. Defaults to double.", + "default": "double", + "allOf": [ + { + "$ref": "#/definitions/QuoteStyle" + } + ] + }, + "trailingComma": { + "description": "Print trailing commas wherever possible in multi-line comma-separated syntactic structures. Defaults to \"all\".", + "default": "all", + "allOf": [ + { + "$ref": "#/definitions/TrailingComma" + } + ] + } + }, + "additionalProperties": false + }, + "LineWidth": { + "description": "Validated value for the `line_width` formatter options\n\nThe allowed range of values is 1..=320", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "LinterConfiguration": { + "type": "object", + "properties": { + "enabled": { + "description": "if `false`, it disables the feature and the linter won't be executed. `true` by default", + "default": true, + "type": "boolean" + }, + "ignore": { + "description": "A list of Unix shell style patterns. The formatter will ignore files/folders that will match these patterns.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "rules": { + "description": "List of rules", + "default": { + "recommended": true + }, + "anyOf": [ + { + "$ref": "#/definitions/Rules" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Nursery": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noBannedTypes": { + "description": "Disallow certain types.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noConstAssign": { + "description": "Prevents from having const variables being re-assigned.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDupeKeys": { + "description": "Prevents object literals having more than one property declaration for the same name. If an object property with the same name is defined multiple times (except when combining a getter with a setter), only the last definition makes it into the object and previous definitions are ignored, which is likely a mistake.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noExplicitAny": { + "description": "Disallow the any type usage", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noInvalidConstructorSuper": { + "description": "Prevents the incorrect use of super() inside classes. It also checks whether a call super() is missing from classes that extends other constructors.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useCamelCase": { + "description": "Enforce camel case naming convention.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useExhaustiveDependencies": { + "description": "Enforce all dependencies are correctly specified.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useFlatMap": { + "description": "Promotes the use of .flatMap() when map().flat() are used together.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useNumericLiterals": { + "description": "Disallow parseInt() and Number.parseInt() in favor of binary, octal, and hexadecimal literals", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useValidForDirection": { + "description": "Enforce \"for\" loop update clause moving the counter in the right direction.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "PlainIndentStyle": { + "type": "string", + "enum": [ + "tab", + "space" + ] + }, + "QuoteProperties": { + "type": "string", + "enum": [ + "asNeeded", + "preserve" + ] + }, + "QuoteStyle": { + "type": "string", + "enum": [ + "double", + "single" + ] + }, + "RuleConfiguration": { + "anyOf": [ + { + "$ref": "#/definitions/RulePlainConfiguration" + }, + { + "$ref": "#/definitions/RuleWithOptions" + } + ] + }, + "RulePlainConfiguration": { + "type": "string", + "enum": [ + "warn", + "error", + "off" + ] + }, + "RuleWithOptions": { + "type": "object", + "required": [ + "level", + "options" + ], + "properties": { + "level": { + "$ref": "#/definitions/RulePlainConfiguration" + }, + "options": true + }, + "additionalProperties": false + }, + "Rules": { + "type": "object", + "properties": { + "a11y": { + "anyOf": [ + { + "$ref": "#/definitions/A11y" + }, + { + "type": "null" + } + ] + }, + "complexity": { + "anyOf": [ + { + "$ref": "#/definitions/Complexity" + }, + { + "type": "null" + } + ] + }, + "correctness": { + "anyOf": [ + { + "$ref": "#/definitions/Correctness" + }, + { + "type": "null" + } + ] + }, + "nursery": { + "anyOf": [ + { + "$ref": "#/definitions/Nursery" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the lint rules recommended by Rome. `true` by default.", + "type": [ + "boolean", + "null" + ] + }, + "security": { + "anyOf": [ + { + "$ref": "#/definitions/Security" + }, + { + "type": "null" + } + ] + }, + "style": { + "anyOf": [ + { + "$ref": "#/definitions/Style" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Security": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noDangerouslySetInnerHtml": { + "description": "Prevent the usage of dangerous JSX props", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noDangerouslySetInnerHtmlWithChildren": { + "description": "Report when a DOM element or a component uses both children and dangerouslySetInnerHTML prop.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + } + } + }, + "Style": { + "description": "A list of rules that belong to this group", + "type": "object", + "properties": { + "noImplicitBoolean": { + "description": "Disallow implicit true values on JSX boolean attributes", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noNegationElse": { + "description": "Disallow negation in the condition of an if statement if it has an else clause", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noShoutyConstants": { + "description": "Disallow the use of constants which its value is the upper-case version of its name.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "noUnusedTemplateLiteral": { + "description": "Disallow template literals if interpolation and special-character handling are not needed", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "recommended": { + "description": "It enables the recommended rules for this group", + "type": [ + "boolean", + "null" + ] + }, + "useBlockStatements": { + "description": "Requires following curly brace conventions. JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to never omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useFragmentSyntax": { + "description": "This rule enforces the use of <>... over ....", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useOptionalChain": { + "description": "Enforce using concise optional chain instead of chained logical expressions.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useSelfClosingElements": { + "description": "Prevent extra closing tags for components without children", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useShorthandArrayType": { + "description": "When expressing array types, this rule promotes the usage of T[] shorthand instead of Array.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useSingleVarDeclarator": { + "description": "Disallow multiple variable declarations in the same variable statement", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, + "useTemplate": { + "description": "Template literals are preferred over string concatenation.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + } + } + }, + "TrailingComma": { + "type": "string", + "enum": [ + "all", + "es5", + "none" + ] + } + } +} \ No newline at end of file diff --git a/xtask/codegen/Cargo.toml b/xtask/codegen/Cargo.toml index 0f2a0b51646..f144a99de60 100644 --- a/xtask/codegen/Cargo.toml +++ b/xtask/codegen/Cargo.toml @@ -16,6 +16,7 @@ ureq = "2.4.0" git2 = { version = "0.15.0", default-features = false } filetime = "0.2.15" case = "1.0.0" +pulldown-cmark = { version = "0.9", default-features = false } rome_rowan = { path = "../../crates/rome_rowan", optional = true } rome_analyze = { path = "../../crates/rome_analyze", optional = true } diff --git a/xtask/codegen/src/generate_configuration.rs b/xtask/codegen/src/generate_configuration.rs index d4232841d76..f03c3a2f13a 100644 --- a/xtask/codegen/src/generate_configuration.rs +++ b/xtask/codegen/src/generate_configuration.rs @@ -1,7 +1,10 @@ use case::CaseExt; use proc_macro2::{Ident, Literal, Span}; +use pulldown_cmark::{Event, Parser, Tag}; use quote::quote; -use rome_analyze::{GroupCategory, Queryable, RegistryVisitor, Rule, RuleCategory, RuleGroup}; +use rome_analyze::{ + GroupCategory, Queryable, RegistryVisitor, Rule, RuleCategory, RuleGroup, RuleMetadata, +}; use rome_js_analyze::visit_registry; use rome_js_syntax::JsLanguage; use std::collections::BTreeMap; @@ -13,7 +16,7 @@ pub(crate) fn generate_rules_configuration(mode: Mode) -> Result<()> { #[derive(Default)] struct LintRulesVisitor { - groups: BTreeMap<&'static str, BTreeMap<&'static str, bool>>, + groups: BTreeMap<&'static str, BTreeMap<&'static str, RuleMetadata>>, } impl RegistryVisitor for LintRulesVisitor { @@ -32,7 +35,7 @@ pub(crate) fn generate_rules_configuration(mode: Mode) -> Result<()> { self.groups .entry(::NAME) .or_insert_with(BTreeMap::new) - .insert(R::METADATA.name, R::METADATA.recommended); + .insert(R::METADATA.name, R::METADATA); } } @@ -57,7 +60,50 @@ pub(crate) fn generate_rules_configuration(mode: Mode) -> Result<()> { let mut number_of_recommended_rules: u8 = 0; let number_of_rules = Literal::u8_unsuffixed(rules.len() as u8); - for (index, (rule, recommended)) in rules.iter().enumerate() { + for (index, (rule, metadata)) in rules.iter().enumerate() { + let summary = { + let mut docs = String::new(); + let parser = Parser::new(metadata.docs); + for event in parser { + match event { + Event::Text(text) => { + docs.push_str(text.as_ref()); + } + Event::Code(text) => { + docs.push_str(text.as_ref()); + } + Event::SoftBreak => { + docs.push(' '); + } + + Event::Start(Tag::Paragraph) => {} + Event::End(Tag::Paragraph) => { + break; + } + + Event::Start(tag) => match tag { + Tag::Strong | Tag::Paragraph => { + continue; + } + + _ => panic!("Unimplemented tag {:?}", { tag }), + }, + + Event::End(tag) => match tag { + Tag::Strong | Tag::Paragraph => { + continue; + } + _ => panic!("Unimplemented tag {:?}", { tag }), + }, + + _ => { + panic!("Unimplemented event {:?}", { event }) + } + } + } + docs + }; + let rule_position = Literal::u8_unsuffixed(index as u8); let rule_identifier = Ident::new(&to_lower_snake_case(rule), Span::call_site()); let declaration = quote! { @@ -65,7 +111,7 @@ pub(crate) fn generate_rules_configuration(mode: Mode) -> Result<()> { pub #rule_identifier: RuleConfiguration }; declarations.push(declaration); - if *recommended { + if metadata.recommended { lines_recommended_rule_as_filter.push(quote! { RuleFilter::Rule(#group, Self::CATEGORY_RULES[#rule_position]) }); @@ -79,6 +125,7 @@ pub(crate) fn generate_rules_configuration(mode: Mode) -> Result<()> { #rule }); schema_lines_rules.push(quote! { + #[doc = #summary] #rule_identifier: Option }); } diff --git a/xtask/codegen/src/generate_schema.rs b/xtask/codegen/src/generate_schema.rs index a55de167298..185868a5269 100644 --- a/xtask/codegen/src/generate_schema.rs +++ b/xtask/codegen/src/generate_schema.rs @@ -5,11 +5,13 @@ use xtask::{project_root, Mode, Result}; use xtask_codegen::update; pub(crate) fn generate_configuration_schema(mode: Mode) -> Result<()> { - let schema_path = project_root().join("editors/vscode/configuration_schema.json"); + let schema_path_vscode = project_root().join("editors/vscode/configuration_schema.json"); + let schema_path_npm = project_root().join("npm/rome/configuration_schema.json"); let schema = schema_for!(Configuration); let json_schema = to_string_pretty(&schema)?; - update(&schema_path, &json_schema, &mode)?; + update(&schema_path_vscode, &json_schema, &mode)?; + update(&schema_path_npm, &json_schema, &mode)?; Ok(()) }