diff --git a/.changeset/based-bears-brawl.md b/.changeset/based-bears-brawl.md
new file mode 100644
index 000000000000..1b77fc3ef71f
--- /dev/null
+++ b/.changeset/based-bears-brawl.md
@@ -0,0 +1,28 @@
+---
+"@biomejs/biome": minor
+---
+
+Biome's resolver now supports `baseUrl` if specified in `tsconfig.json`.
+
+#### Example
+
+Given the following file structure:
+
+**`tsconfig.json`**
+```json
+{
+ "compilerOptions": {
+ "baseUrl": "./src",
+ }
+}
+```
+
+**`src/foo.ts`**
+```ts
+export function foo() {}
+```
+
+In this scenario, `import { foo } from "foo";` should work regardless of the
+location of the file containing the `import` statement.
+
+Fixes [#6432](https://github.com/biomejs/biome/issues/6432).
diff --git a/.changeset/breezy-suns-leave.md b/.changeset/breezy-suns-leave.md
new file mode 100644
index 000000000000..84f3fc9d48d9
--- /dev/null
+++ b/.changeset/breezy-suns-leave.md
@@ -0,0 +1,5 @@
+---
+"@biomejs/biome": minor
+---
+
+Added `ignore` option to `noUnknownAtRules`. If an unknown at-rule matches any of the items provided in `ignore`, a diagnostic won't be emitted.
diff --git a/.changeset/busy-pens-send.md b/.changeset/busy-pens-send.md
new file mode 100644
index 000000000000..e0b837916a97
--- /dev/null
+++ b/.changeset/busy-pens-send.md
@@ -0,0 +1,26 @@
+---
+"@biomejs/biome": minor
+---
+
+Enhanced the `init` command. The `init` command now checks if the existing project contains known ignore files and known generated folders.
+
+If Biome finds `.gitignore` or `.ignore` files, it will add the following configuration to `biome.json`:
+```diff
+{
++ "vcs": {
++ "enabled": true,
++ "clientKind": "git",
++ "useIgnoreFile": true
++ }
+}
+```
+
+If Biome finds a `dist/` folder, it will exclude it automatically using the double-exclude syntax:
+
+```diff
+{
++ "files": {
++ "includes": ["**", "!!**/dist"]
++ }
+}
+```
diff --git a/.changeset/crazy-steaks-mix.md b/.changeset/crazy-steaks-mix.md
new file mode 100644
index 000000000000..cb34a19d8f09
--- /dev/null
+++ b/.changeset/crazy-steaks-mix.md
@@ -0,0 +1,5 @@
+---
+"@biomejs/biome": minor
+---
+
+The rules in a domain are no longer enabled automatically by the installed dependencies unless the rule is recommended.
diff --git a/.changeset/css-parse-modules-flag.md b/.changeset/css-parse-modules-flag.md
new file mode 100644
index 000000000000..4b4996043911
--- /dev/null
+++ b/.changeset/css-parse-modules-flag.md
@@ -0,0 +1,14 @@
+---
+"@biomejs/biome": minor
+---
+
+Added `--css-parse-css-modules` CLI flag to control whether CSS Modules syntax is enabled.
+
+You can now enable or disable CSS Modules parsing directly from the command line:
+
+```shell
+biome check --css-parse-css-modules=true file.module.css
+biome format --css-parse-css-modules=true file.module.css
+biome lint --css-parse-css-modules=true file.module.css
+biome ci --css-parse-css-modules=true file.module.css
+```
diff --git a/.changeset/css-parse-tailwind-flag.md b/.changeset/css-parse-tailwind-flag.md
new file mode 100644
index 000000000000..b2464c9049c9
--- /dev/null
+++ b/.changeset/css-parse-tailwind-flag.md
@@ -0,0 +1,14 @@
+---
+"@biomejs/biome": minor
+---
+
+Added `--css-parse-tailwind-directives` CLI flag to control whether Tailwind CSS 4.0 directives and functions are enabled.
+
+You can now enable or disable Tailwind CSS 4.0 directive parsing directly from the command line:
+
+```shell
+biome check --css-parse-tailwind-directives=true file.css
+biome format --css-parse-tailwind-directives=true file.css
+biome lint --css-parse-tailwind-directives=true file.css
+biome ci --css-parse-tailwind-directives=true file.css
+```
diff --git a/.changeset/dull-drinks-switch.md b/.changeset/dull-drinks-switch.md
new file mode 100644
index 000000000000..4b81c869e8db
--- /dev/null
+++ b/.changeset/dull-drinks-switch.md
@@ -0,0 +1,12 @@
+---
+"@biomejs/biome": minor
+---
+
+Updated the formatting of `.svelte` and `.vue` files. Now the indentation of the JavaScript blocks matches Prettier's:
+
+```diff
+
+```
diff --git a/.changeset/eager-suns-smoke.md b/.changeset/eager-suns-smoke.md
new file mode 100644
index 000000000000..76dabb768b5d
--- /dev/null
+++ b/.changeset/eager-suns-smoke.md
@@ -0,0 +1,5 @@
+---
+"@biomejs/biome": patch
+---
+
+Fixed an issue where the JUnit reporter returned a zero-based location. Now the location returned is one-based.
diff --git a/.changeset/few-bees-reply.md b/.changeset/few-bees-reply.md
new file mode 100644
index 000000000000..b56a6b94778e
--- /dev/null
+++ b/.changeset/few-bees-reply.md
@@ -0,0 +1,24 @@
+---
+"@biomejs/biome": minor
+---
+
+Implemented the `indentScriptAndStyle` option for vue and svelte files, with the default set to `false` to match [Prettier's `vueIndentScriptAndStyle` option](https://prettier.io/docs/options#vue-files-script-and-style-tags-indentation). When enabled, this option indents the content within `
+```
diff --git a/.changeset/forced-files-forget.md b/.changeset/forced-files-forget.md
new file mode 100644
index 000000000000..186e5add6ba4
--- /dev/null
+++ b/.changeset/forced-files-forget.md
@@ -0,0 +1,44 @@
+---
+"@biomejs/biome": minor
+---
+
+Deprecated the option `files.experimentalScannerIgnores` in favour of **force-ignore** syntax in `files.includes`.
+
+`files.includes` supports ignoring files by prefixing globs with an exclamation mark (`!`). With this change, it also supports _force_-ignoring globs by prefixing them with a double exclamation mark (`!!`).
+
+The effect of force-ignoring is that the scanner will not index files matching the glob, even in project mode, even if those files are imported by other files, and even if they are files that receive special treatment by Biome, such as nested `biome.json` files.
+
+#### Example
+
+Let's take the following configuration:
+
+```json
+{
+ "files": {
+ "includes": [
+ "**",
+ "!**/generated",
+ "!!**/dist",
+ "fixtures/example/dist/*.js"
+ ]
+ },
+ "linter": {
+ "domains": {
+ "project": "all"
+ }
+ }
+}
+```
+
+This configuration achieves the following:
+
+- Because the [project domain](https://biomejs.dev/linter/domains/#project) is enabled, all supported files in the project are indexed _and_ processed by the linter, _except_:
+- Files inside a `generated` folder are not processed by the linter, but they will get indexed _if_ a file outside a `generated` folder imports them.
+- Files inside a `dist` folder are never indexed nor processed, not even if they are imported for any purpose, _except_:
+- When the `dist` folder is inside `fixtures/example/`, its `.js` files _do_ get both indexed and processed.
+
+In general, we now recommend using the force-ignore syntax for any folders that contain _output_ files, such as `build/` and `dist/`. For such folders, it is highly unlikely that indexing has any useful benefits. For folders containing generated files, you may wish to use the regular ignore syntax so that type information can still be extracted from the files.
+
+`experimentalScannerIgnores` will continue to work for now, but you'll see a deprecation warning if you still use it.
+
+Run the `biome migrate --write` command to automatically update the configuration file.
diff --git a/.changeset/gentle-pots-hunt.md b/.changeset/gentle-pots-hunt.md
new file mode 100644
index 000000000000..d8582ffb6f74
--- /dev/null
+++ b/.changeset/gentle-pots-hunt.md
@@ -0,0 +1,64 @@
+---
+"@biomejs/biome": minor
+---
+
+Added a new reporter named `rdjson`. This reporter prints diagnostics following the [RDJSON format](https://deepwiki.com/reviewdog/reviewdog/3.2-reviewdog-diagnostic-format):
+
+The following command:
+
+```shell
+biome check --reporter=rdjson
+```
+
+Will emit diagnostics in the following format:
+
+```json
+{
+ "source": {
+ "name": "Biome",
+ "url": "https://biomejs.dev"
+ },
+ "diagnostics": [
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 0
+ },
+ "start": {
+ "column": 7,
+ "line": 0
+ }
+ }
+ },
+ "message": "This import is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 10,
+ "line": 1
+ },
+ "start": {
+ "column": 9,
+ "line": 1
+ }
+ }
+ },
+ "message": "Several of these imports are unused."
+ }
+ ]
+}
+```
diff --git a/.changeset/icy-views-lick.md b/.changeset/icy-views-lick.md
new file mode 100644
index 000000000000..17839a23bddf
--- /dev/null
+++ b/.changeset/icy-views-lick.md
@@ -0,0 +1,14 @@
+---
+"@biomejs/biome": minor
+---
+
+The `formatWithErrors` option can now be set via CLI using the `--format-with-errors` flag.
+
+This flag was previously only available in the configuration file. It allows formatting to proceed on files with syntax errors, which is useful during development when you want to auto-format code while fixing syntax issues.
+
+#### Example
+
+```shell
+biome format --format-with-errors=true --write file.js
+```
+
diff --git a/.changeset/json-parse-comments-flag.md b/.changeset/json-parse-comments-flag.md
new file mode 100644
index 000000000000..d2f3bf48608a
--- /dev/null
+++ b/.changeset/json-parse-comments-flag.md
@@ -0,0 +1,14 @@
+---
+"@biomejs/biome": minor
+---
+
+Added `--json-parse-allow-comments` CLI flag to control whether comments are allowed in JSON files.
+
+You can now enable or disable comment parsing in JSON files directly from the command line:
+
+```shell
+biome check --json-parse-allow-comments=true file.json
+biome format --json-parse-allow-comments=true file.json
+biome lint --json-parse-allow-comments=true file.json
+biome ci --json-parse-allow-comments=true file.json
+```
diff --git a/.changeset/json-parse-trailing-commas-flag.md b/.changeset/json-parse-trailing-commas-flag.md
new file mode 100644
index 000000000000..1135b8771ecf
--- /dev/null
+++ b/.changeset/json-parse-trailing-commas-flag.md
@@ -0,0 +1,14 @@
+---
+"@biomejs/biome": minor
+---
+
+Added `--json-parse-allow-trailing-commas` CLI flag to control whether trailing commas are allowed in JSON files.
+
+You can now enable or disable trailing comma parsing in JSON files directly from the command line:
+
+```shell
+biome check --json-parse-allow-trailing-commas=true file.json
+biome format --json-parse-allow-trailing-commas=true file.json
+biome lint --json-parse-allow-trailing-commas=true file.json
+biome ci --json-parse-allow-trailing-commas=true file.json
+```
diff --git a/.changeset/large-lands-brush.md b/.changeset/large-lands-brush.md
new file mode 100644
index 000000000000..f8202e29e017
--- /dev/null
+++ b/.changeset/large-lands-brush.md
@@ -0,0 +1,13 @@
+---
+"@biomejs/biome": minor
+---
+
+Promoted new lint rules:
+- Promoted `noNonNullAssertedOptionalChain` to the suspicious group
+- Promoted `useReactFunctionComponents` to the `style` group
+- Promoted `useImageSize` to the `correctness` group
+- Promoted `useConsistentTypeDefinitions` to the `style` group
+- Promoted `useQwikClasslist` to the `correctness` group
+- Promoted `noSecrets` to the `security` group
+
+Removed the lint rule `useAnchorHref`, because its use case is covered by `useValidAnchor`.
diff --git a/.changeset/light-women-live.md b/.changeset/light-women-live.md
new file mode 100644
index 000000000000..70201706760e
--- /dev/null
+++ b/.changeset/light-women-live.md
@@ -0,0 +1,39 @@
+---
+"@biomejs/biome": minor
+---
+
+Added the new `checkstyle` reporter. When `--reporter=checkstyle` is passed to the CLI, Biome will emit diagnostics for [Checkstyle format](https://checkstyle.org/):
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
diff --git a/.changeset/max-managers-mandate.md b/.changeset/max-managers-mandate.md
new file mode 100644
index 000000000000..0e97ba306344
--- /dev/null
+++ b/.changeset/max-managers-mandate.md
@@ -0,0 +1,5 @@
+---
+"@biomejs/biome": patch
+---
+
+Fixed an issue with the `files.maxSize` setting. Previously the setting would always be looked up in the root settings, even in monorepos where a closer `biome.json` is available. It now correctly uses the nearest configuration.
diff --git a/.changeset/new-signs-tie.md b/.changeset/new-signs-tie.md
new file mode 100644
index 000000000000..7f6bdc21533d
--- /dev/null
+++ b/.changeset/new-signs-tie.md
@@ -0,0 +1,5 @@
+---
+"@biomejs/biome": minor
+---
+
+Added "@rbxts/react" as an alias for "react" for handling the reactClassic jsxRuntime.
diff --git a/.changeset/polite-pets-serve.md b/.changeset/polite-pets-serve.md
new file mode 100644
index 000000000000..e7a6ffab67e8
--- /dev/null
+++ b/.changeset/polite-pets-serve.md
@@ -0,0 +1,5 @@
+---
+"@biomejs/biome": minor
+---
+
+Added `.oxlintrc.json` to well-known files.
diff --git a/.changeset/seven-beans-cough.md b/.changeset/seven-beans-cough.md
new file mode 100644
index 000000000000..6fda8245ed2b
--- /dev/null
+++ b/.changeset/seven-beans-cough.md
@@ -0,0 +1,12 @@
+---
+"@biomejs/biome": minor
+---
+
+The following rules are now a part of the `react` domain, and they won't be enabled automatically unless you enabled the domain, or Biome detects `react` as a dependency of your closest `package.json`:
+
+- [`lint/correctness/noChildrenProp`](https://biomejs.dev/linter/rules/no-children-prop/) (recommended)
+- [`lint/correctness/noReactPropAssignments`](https://biomejs.dev/linter/rules/no-react-prop-assignments/)
+- [`lint/security/noDangerouslySetInnerHtml`](https://biomejs.dev/linter/rules/no-dangerously-set-inner-html/) (recommended)
+- [`lint/security/noDangerouslySetInnerHtmlWithChildren`](https://biomejs.dev/linter/rules/no-dangerously-set-inner-html-with-children/) (recommended)
+- [`lint/style/useComponentExportOnlyModules`](https://biomejs.dev/linter/rules/use-component-export-only-modules/)
+- [`lint/suspicious/noArrayIndexKey`](https://biomejs.dev/linter/rules/no-array-index-key/) (recommended)
diff --git a/.changeset/social-hornets-wait.md b/.changeset/social-hornets-wait.md
new file mode 100644
index 000000000000..c485403a2d81
--- /dev/null
+++ b/.changeset/social-hornets-wait.md
@@ -0,0 +1,12 @@
+---
+"@biomejs/biome": minor
+---
+
+Added the ability to show severity `Information` diagnostics in reporter outputs.
+
+If one or more rules are triggered, and they are configured to emit an `Information` diagnostic, now they're counted in the final output:
+
+```bash
+Checked 1 file in . No fixes applied.
+Found 1 info.
+```
diff --git a/.changeset/stupid-groups-grow.md b/.changeset/stupid-groups-grow.md
new file mode 100644
index 000000000000..1a33f2921767
--- /dev/null
+++ b/.changeset/stupid-groups-grow.md
@@ -0,0 +1,9 @@
+---
+"@biomejs/biome": minor
+---
+
+Added linting and assist support for `.html` files, with addition of two new configurations:
+- `html.linter.enabled`
+- `html.assist.enabled`
+
+The HTML linter, in this release, only contains the rule `noHeaderScope`. More rules will be released in the upcoming releases.
diff --git a/.changeset/tasty-hairs-shop.md b/.changeset/tasty-hairs-shop.md
new file mode 100644
index 000000000000..87aade5d6853
--- /dev/null
+++ b/.changeset/tasty-hairs-shop.md
@@ -0,0 +1,17 @@
+---
+"@biomejs/biome": minor
+---
+
+Added a new CSS parser option `tailwindDirectives`. Enabling this option will allow all of Tailwind v4's syntax additions to be parsed and formatted by Biome.
+
+You can enable this by setting `css.parser.tailwindDirectives` to `true` in your Biome configuration.
+
+```json
+{
+ "css": {
+ "parser": {
+ "tailwindDirectives": true
+ }
+ }
+}
+```
diff --git a/.changeset/upset-apes-reply.md b/.changeset/upset-apes-reply.md
new file mode 100644
index 000000000000..984e8d32c946
--- /dev/null
+++ b/.changeset/upset-apes-reply.md
@@ -0,0 +1,7 @@
+---
+"@biomejs/biome": minor
+---
+
+React 19.2 support is now supported in Biome:
+- Treats `useEffectEvent` like `useRef` in [`useExhaustiveDependencies`](https://biomejs.dev/linter/rules/use-exhaustive-dependencies/)
+- Added ` ` to known React APIs.
diff --git a/.changeset/upset-impalas-grab.md b/.changeset/upset-impalas-grab.md
new file mode 100644
index 000000000000..7a27e22c929e
--- /dev/null
+++ b/.changeset/upset-impalas-grab.md
@@ -0,0 +1,12 @@
+---
+"@biomejs/biome": minor
+---
+
+Added **experimental** full support for HTML, Vue, Svelte and Astro files. In this release, the HTML parser
+has been enhanced, and it's now able to parse `.vue`, `.svelte` and `.astro` files.
+
+This means that now Biome is able to lint and format the JavaScript (TypeScript), HTML and CSS code that is contained in these files.
+
+Now that the main architecture is stable and working, in the upcoming patches and minors we will also fix possible inaccuracies and edge cases coming from existing lint rules, such as `noUnusedVariables` inside `
"#;
-const SVELTE_TS_CONTEXT_MODULE_FILE_FORMATTED: &str = r#"
-
"#;
-
const SVELTE_CARRIAGE_RETURN_LINE_FEED_FILE_UNFORMATTED: &str =
"\r\n
";
@@ -176,12 +170,6 @@ fn format_svelte_ts_context_module_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(
- &fs,
- svelte_file_path,
- SVELTE_TS_CONTEXT_MODULE_FILE_FORMATTED,
- );
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_svelte_ts_context_module_files_write",
@@ -225,6 +213,107 @@ fn format_svelte_carriage_return_line_feed_files() {
));
}
+#[test]
+fn full_support() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ fs.insert(
+ "biome.json".into(),
+ r#"{ "html": { "formatter": {"enabled": true}, "linter": {"enabled": true}, "experimentalFullSupportEnabled": true } }"#.as_bytes(),
+ );
+
+ let astro_file_path = Utf8Path::new("file.svelte");
+ fs.insert(
+ astro_file_path.into(),
+ r#"
+
+Svelte
+
+
+"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["check", "--write", "--unsafe", astro_file_path.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "full_support",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn full_support_ts() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ fs.insert(
+ "biome.json".into(),
+ r#"{ "html": { "formatter": {"enabled": true}, "linter": {"enabled": true}, "experimentalFullSupportEnabled": true } }"#.as_bytes(),
+ );
+
+ let astro_file_path = Utf8Path::new("file.svelte");
+ fs.insert(
+ astro_file_path.into(),
+ r#"
+
+Svelte
+
+
+"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["check", "--write", "--unsafe", astro_file_path.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "full_support_ts",
+ fs,
+ console,
+ result,
+ ));
+}
+
#[test]
fn format_stdin_successfully() {
let fs = MemoryFileSystem::default();
diff --git a/crates/biome_cli/tests/cases/handle_vue_files.rs b/crates/biome_cli/tests/cases/handle_vue_files.rs
index 5ecd78c8115b..1c98fb509f9a 100644
--- a/crates/biome_cli/tests/cases/handle_vue_files.rs
+++ b/crates/biome_cli/tests/cases/handle_vue_files.rs
@@ -1,5 +1,5 @@
use crate::run_cli;
-use crate::snap_test::{SnapshotPayload, assert_cli_snapshot, assert_file_contents};
+use crate::snap_test::{SnapshotPayload, assert_cli_snapshot};
use biome_console::BufferConsole;
use biome_fs::MemoryFileSystem;
use bpaf::Args;
@@ -11,36 +11,18 @@ statement ( ) ;
"#;
-const VUE_IMPLICIT_JS_FILE_FORMATTED: &str = r#"
- "#;
-
const VUE_EXPLICIT_JS_FILE_UNFORMATTED: &str = r#"
"#;
-const VUE_EXPLICIT_JS_FILE_FORMATTED: &str = r#"
- "#;
-
const VUE_TS_FILE_UNFORMATTED: &str = r#"
"#;
-const VUE_TS_FILE_FORMATTED: &str = r#"
- "#;
-
const VUE_JS_FILE_NOT_LINTED: &str = r#"
"#;
-const VUE_FILE_IMPORTS_AFTER: &str = r#"
- "#;
-
const VUE_CARRIAGE_RETURN_LINE_FEED_FILE_UNFORMATTED: &str =
"\r\n ";
@@ -125,8 +101,6 @@ fn format_vue_implicit_js_files() {
assert!(result.is_err(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, VUE_IMPLICIT_JS_FILE_UNFORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_vue_implicit_js_files",
@@ -155,8 +129,6 @@ fn format_vue_implicit_js_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, VUE_IMPLICIT_JS_FILE_FORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_vue_implicit_js_files_write",
@@ -185,8 +157,6 @@ fn format_vue_explicit_js_files() {
assert!(result.is_err(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, VUE_EXPLICIT_JS_FILE_UNFORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_vue_explicit_js_files",
@@ -215,8 +185,6 @@ fn format_vue_explicit_js_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, VUE_EXPLICIT_JS_FILE_FORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_vue_explicit_js_files_write",
@@ -242,8 +210,6 @@ fn format_empty_vue_js_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, " ");
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_empty_vue_js_files_write",
@@ -269,8 +235,6 @@ fn format_vue_ts_files() {
assert!(result.is_err(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, VUE_TS_FILE_UNFORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_vue_ts_files",
@@ -296,8 +260,6 @@ fn format_vue_ts_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, VUE_TS_FILE_FORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_vue_ts_files_write",
@@ -323,8 +285,6 @@ fn format_empty_vue_ts_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, " ");
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_empty_vue_ts_files_write",
@@ -353,12 +313,6 @@ fn format_vue_carriage_return_line_feed_files() {
assert!(result.is_err(), "run_cli returned {result:?}");
- assert_file_contents(
- &fs,
- vue_file_path,
- VUE_CARRIAGE_RETURN_LINE_FEED_FILE_UNFORMATTED,
- );
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_vue_carriage_return_line_feed_files",
@@ -387,8 +341,6 @@ fn format_vue_generic_component_files() {
assert!(result.is_err(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, VUE_GENERIC_COMPONENT_FILE_UNFORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_vue_generic_component_files",
@@ -472,8 +424,6 @@ fn sorts_imports_check() {
assert!(result.is_err(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, VUE_FILE_IMPORTS_BEFORE);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"sorts_imports_check",
@@ -508,8 +458,6 @@ fn sorts_imports_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, vue_file_path, VUE_FILE_IMPORTS_AFTER);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"sorts_imports_write",
@@ -519,6 +467,107 @@ fn sorts_imports_write() {
));
}
+#[test]
+fn full_support() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ fs.insert(
+ "biome.json".into(),
+ r#"{ "html": { "formatter": {"enabled": true}, "linter": {"enabled": true}, "experimentalFullSupportEnabled": true } }"#.as_bytes(),
+ );
+
+ let astro_file_path = Utf8Path::new("file.vue");
+ fs.insert(
+ astro_file_path.into(),
+ r#"
+
+Svelte
+
+
+"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["check", "--write", "--unsafe", astro_file_path.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "full_support",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn full_support_ts() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ fs.insert(
+ "biome.json".into(),
+ r#"{ "html": { "formatter": {"enabled": true}, "linter": {"enabled": true}, "experimentalFullSupportEnabled": true } }"#.as_bytes(),
+ );
+
+ let astro_file_path = Utf8Path::new("file.vue");
+ fs.insert(
+ astro_file_path.into(),
+ r#"
+
+Svelte
+
+
+"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["check", "--write", "--unsafe", astro_file_path.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "full_support_ts",
+ fs,
+ console,
+ result,
+ ));
+}
+
#[test]
fn format_stdin_successfully() {
let fs = MemoryFileSystem::default();
@@ -743,8 +792,6 @@ fn vue_compiler_macros_as_globals() {
Args::from(["lint", vue_file_path.as_str()].as_slice()),
);
- assert_file_contents(&fs, vue_file_path, VUE_TS_FILE_SETUP_GLOBALS);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"vue_compiler_macros_as_globals",
diff --git a/crates/biome_cli/tests/cases/html.rs b/crates/biome_cli/tests/cases/html.rs
index d7a27a71318e..2dd7cddb5ddc 100644
--- a/crates/biome_cli/tests/cases/html.rs
+++ b/crates/biome_cli/tests/cases/html.rs
@@ -90,3 +90,286 @@ fn should_not_error_when_interpolation_is_enabled() {
result,
));
}
+
+#[test]
+fn should_format_indent_embedded_languages() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let html_file = Utf8Path::new("file.html");
+ fs.insert(
+ html_file.into(),
+ r#"
+
+"#
+ .as_bytes(),
+ );
+
+ fs.insert(
+ Utf8Path::new("biome.json").into(),
+ r#"{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--write", html_file.as_str()].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_format_indent_embedded_languages",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn should_format_indent_embedded_languages_with_language_options() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let html_file = Utf8Path::new("file.html");
+ fs.insert(
+ html_file.into(),
+ r#"
+
+"#
+ .as_bytes(),
+ );
+
+ fs.insert(
+ Utf8Path::new("biome.json").into(),
+ r#"{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ }
+ },
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "single"
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--write", html_file.as_str()].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_format_indent_embedded_languages_with_language_options",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn should_pull_diagnostics_from_embedded_languages_when_formatting() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let html_file = Utf8Path::new("file.html");
+ fs.insert(
+ html_file.into(),
+ r#"
+
+"#
+ .as_bytes(),
+ );
+
+ fs.insert(
+ Utf8Path::new("biome.json").into(),
+ r#"{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--write", html_file.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_pull_diagnostics_from_embedded_languages_when_formatting",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn should_pull_diagnostics_from_embedded_languages_when_linting() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let html_file = Utf8Path::new("file.html");
+ fs.insert(
+ html_file.into(),
+ r#"
+
+
+"#
+ .as_bytes(),
+ );
+
+ fs.insert(
+ Utf8Path::new("biome.json").into(),
+ r#"{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ },
+ "linter": {
+ "enabled": true
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["lint", html_file.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_pull_diagnostics_from_embedded_languages_when_linting",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn should_apply_fixes_to_embedded_languages() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let html_file = Utf8Path::new("file.html");
+ fs.insert(
+ html_file.into(),
+ r#"
+
+"#
+ .as_bytes(),
+ );
+
+ fs.insert(
+ Utf8Path::new("biome.json").into(),
+ r#"{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ },
+ "linter": {
+ "enabled": true
+ },
+ "assist": {
+ "enabled": true
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["check", "--write", "--unsafe", html_file.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_apply_fixes_to_embedded_languages",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn should_lint_a_html_file() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let html_file = Utf8Path::new("file.html");
+ fs.insert(
+ html_file.into(),
+ r#"
+"#
+ .as_bytes(),
+ );
+
+ fs.insert(
+ Utf8Path::new("biome.json").into(),
+ r#"{
+ "html": {
+ "linter": {
+ "enabled": true
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["lint", html_file.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_lint_a_html_file",
+ fs,
+ console,
+ result,
+ ));
+}
diff --git a/crates/biome_cli/tests/cases/included_files.rs b/crates/biome_cli/tests/cases/included_files.rs
index 6ed630487d35..351cb3efb465 100644
--- a/crates/biome_cli/tests/cases/included_files.rs
+++ b/crates/biome_cli/tests/cases/included_files.rs
@@ -1,7 +1,7 @@
-use crate::run_cli;
use crate::snap_test::{SnapshotPayload, assert_cli_snapshot, assert_file_contents};
+use crate::{run_cli, run_cli_with_dyn_fs};
use biome_console::BufferConsole;
-use biome_fs::MemoryFileSystem;
+use biome_fs::{MemoryFileSystem, TemporaryFs};
use bpaf::Args;
use camino::Utf8Path;
@@ -92,6 +92,152 @@ fn does_not_handle_included_files_if_overridden_by_ignore() {
));
}
+#[test]
+fn does_not_handle_included_files_if_overridden_by_forced_ignore() {
+ let mut console = BufferConsole::default();
+ let fs = MemoryFileSystem::default();
+ let file_path = Utf8Path::new("biome.json");
+ fs.insert(
+ file_path.into(),
+ r#"{ "files": { "includes": ["*.js", "!!test.js"] } }"#.as_bytes(),
+ );
+
+ let test = Utf8Path::new("test.js");
+ fs.insert(test.into(), UNFORMATTED.as_bytes());
+
+ let test2 = Utf8Path::new("test2.js");
+ fs.insert(test2.into(), UNFORMATTED.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--write", test.as_str(), test2.as_str()].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_file_contents(&fs, test2, FORMATTED);
+
+ assert_file_contents(&fs, test, UNFORMATTED);
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "does_not_handle_included_files_if_overridden_by_forced_ignore",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn does_not_handle_files_inside_force_ignored_folders() {
+ let mut console = BufferConsole::default();
+ let fs = MemoryFileSystem::default();
+ let file_path = Utf8Path::new("biome.json");
+ fs.insert(
+ file_path.into(),
+ r#"{ "files": { "includes": ["*.js", "!!test"] } }"#.as_bytes(),
+ );
+
+ let root_a = Utf8Path::new("a.js");
+ fs.insert(root_a.into(), UNFORMATTED.as_bytes());
+
+ let nested_a = Utf8Path::new("test/a.js");
+ fs.insert(nested_a.into(), UNFORMATTED.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--write", root_a.as_str(), nested_a.as_str()].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_file_contents(&fs, nested_a, UNFORMATTED);
+
+ assert_file_contents(&fs, root_a, FORMATTED);
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "does_not_handle_files_inside_force_ignored_folders",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn errors_on_ignored_nested_biome_json() {
+ let mut console = BufferConsole::default();
+ let mut fs = TemporaryFs::new("errors_on_ignored_nested_biome_json");
+ fs.create_file(
+ "biome.json",
+ r#"{ "files": { "includes": ["**/*.js", "!nested/biome.json"] } }"#,
+ );
+ fs.create_file(
+ "nested/biome.json",
+ r#"{ "formatter": { "enabled": false } }"#,
+ );
+
+ let root_a = "a.js";
+ fs.create_file(root_a, UNFORMATTED);
+
+ let nested_a = "nested/a.js";
+ fs.create_file(nested_a, UNFORMATTED);
+
+ let result = run_cli_with_dyn_fs(
+ Box::new(fs.create_os()),
+ &mut console,
+ Args::from(["format", fs.cli_path()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "errors_on_ignored_nested_biome_json",
+ fs.create_mem(),
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn can_force_ignore_biome_json() {
+ let mut console = BufferConsole::default();
+ let mut fs = TemporaryFs::new("can_force_ignore_biome_json");
+ fs.create_file(
+ "biome.json",
+ r#"{ "files": { "includes": ["**/*.js", "!!nested/biome.json"] } }"#,
+ );
+ fs.create_file(
+ "nested/biome.json",
+ r#"{ "formatter": { "enabled": false } }"#,
+ );
+
+ let root_a = "a.js";
+ fs.create_file(root_a, UNFORMATTED);
+
+ let nested_a = "nested/a.js";
+ fs.create_file(nested_a, UNFORMATTED);
+
+ let result = run_cli_with_dyn_fs(
+ Box::new(fs.create_os()),
+ &mut console,
+ Args::from(["format", fs.cli_path()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "can_force_ignore_biome_json",
+ fs.create_mem(),
+ console,
+ result,
+ ));
+}
+
#[test]
fn does_not_handle_files_in_ignored_folder() {
let mut console = BufferConsole::default();
diff --git a/crates/biome_cli/tests/cases/indent_script_and_style.rs b/crates/biome_cli/tests/cases/indent_script_and_style.rs
new file mode 100644
index 000000000000..0220cb9e60af
--- /dev/null
+++ b/crates/biome_cli/tests/cases/indent_script_and_style.rs
@@ -0,0 +1,196 @@
+use crate::run_cli;
+use crate::snap_test::{SnapshotPayload, assert_cli_snapshot};
+use biome_console::BufferConsole;
+use biome_fs::MemoryFileSystem;
+use bpaf::Args;
+use camino::Utf8Path;
+
+const BIOME_CONFIG_INDENT: &str = r#"
+{
+ "html": {
+ "formatter": {
+ "indentScriptAndStyle": true
+ }
+ }
+}
+"#;
+
+const VUE_FILE_UNFORMATTED: &str = r#"
+ "#;
+
+#[test]
+fn unindent_vue_by_default() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let vue_file_path = Utf8Path::new("file.vue");
+ fs.insert(vue_file_path.into(), VUE_FILE_UNFORMATTED.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--write"].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "unindent_vue_by_default",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn indent_vue_by_cli() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let vue_file_path = Utf8Path::new("file.vue");
+ fs.insert(vue_file_path.into(), VUE_FILE_UNFORMATTED.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "format",
+ "--write",
+ "--html-formatter-indent-script-and-style=true",
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "indent_vue_by_cli",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn indent_vue_by_config() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let vue_file_path = Utf8Path::new("file.vue");
+ fs.insert(vue_file_path.into(), VUE_FILE_UNFORMATTED.as_bytes());
+ let biome_config = Utf8Path::new("biome.json");
+ fs.insert(biome_config.into(), BIOME_CONFIG_INDENT.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--write"].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "indent_vue_by_config",
+ fs,
+ console,
+ result,
+ ));
+}
+
+const SVELTE_FILE_UNFORMATTED: &str = r#"
+
"#;
+
+#[test]
+fn unindent_svelte_by_default() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let svelte_file_path = Utf8Path::new("file.svelte");
+ fs.insert(svelte_file_path.into(), SVELTE_FILE_UNFORMATTED.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--write"].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "indent_svelte_by_default",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn indent_svelte_by_cli() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let svelte_file_path = Utf8Path::new("file.svelte");
+ fs.insert(svelte_file_path.into(), SVELTE_FILE_UNFORMATTED.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "format",
+ "--write",
+ "--html-formatter-indent-script-and-style=true",
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "indent_svelte_by_cli",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn indent_svelte_by_config() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let svelte_file_path = Utf8Path::new("file.svelte");
+ fs.insert(svelte_file_path.into(), SVELTE_FILE_UNFORMATTED.as_bytes());
+ let biome_config = Utf8Path::new("biome.json");
+ fs.insert(biome_config.into(), BIOME_CONFIG_INDENT.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--write"].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "indent_svelte_by_config",
+ fs,
+ console,
+ result,
+ ));
+}
diff --git a/crates/biome_cli/tests/cases/json_parsing.rs b/crates/biome_cli/tests/cases/json_parsing.rs
new file mode 100644
index 000000000000..8fd69427b5df
--- /dev/null
+++ b/crates/biome_cli/tests/cases/json_parsing.rs
@@ -0,0 +1,433 @@
+use crate::snap_test::SnapshotPayload;
+use crate::{assert_cli_snapshot, run_cli};
+use biome_console::BufferConsole;
+use biome_fs::MemoryFileSystem;
+use bpaf::Args;
+use camino::Utf8Path;
+
+// Tests for --json-parse-allow-comments flag
+
+#[test]
+fn check_json_parse_allow_comments_true() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Utf8Path::new("file.json");
+ // JSON with comments
+ fs.insert(
+ file_path.into(),
+ "{\n // This is a comment\n \"key\": \"value\"\n}".as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "check",
+ "--json-parse-allow-comments=true",
+ file_path.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "check_json_parse_allow_comments_true",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn check_json_parse_allow_comments_false() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Utf8Path::new("file.json");
+ // JSON with comments
+ fs.insert(
+ file_path.into(),
+ "{\n // This is a comment\n \"key\": \"value\"\n}".as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "check",
+ "--json-parse-allow-comments=false",
+ file_path.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "check_json_parse_allow_comments_false",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn format_json_parse_allow_comments_true() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Utf8Path::new("file.json");
+ // JSON with comments
+ fs.insert(
+ file_path.into(),
+ "{\n // This is a comment\n \"key\": \"value\"\n}".as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "format",
+ "--json-parse-allow-comments=true",
+ file_path.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "format_json_parse_allow_comments_true",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn lint_json_parse_allow_comments_true() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Utf8Path::new("file.json");
+ // JSON with comments
+ fs.insert(
+ file_path.into(),
+ "{\n // This is a comment\n \"key\": \"value\"\n}".as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "lint",
+ "--json-parse-allow-comments=true",
+ file_path.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "lint_json_parse_allow_comments_true",
+ fs,
+ console,
+ result,
+ ));
+}
+
+// Tests for --json-parse-allow-trailing-commas flag
+
+#[test]
+fn check_json_parse_allow_trailing_commas_true() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Utf8Path::new("file.json");
+ // JSON with trailing comma
+ fs.insert(file_path.into(), "{\n \"key\": \"value\",\n}".as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "check",
+ "--json-parse-allow-trailing-commas=true",
+ file_path.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "check_json_parse_allow_trailing_commas_true",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn check_json_parse_allow_trailing_commas_false() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Utf8Path::new("file.json");
+ // JSON with trailing comma
+ fs.insert(file_path.into(), "{\n \"key\": \"value\",\n}".as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "check",
+ "--json-parse-allow-trailing-commas=false",
+ file_path.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "check_json_parse_allow_trailing_commas_false",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn format_json_parse_allow_trailing_commas_true() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Utf8Path::new("file.json");
+ // JSON with trailing comma
+ fs.insert(file_path.into(), "{\n \"key\": \"value\",\n}".as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "format",
+ "--json-parse-allow-trailing-commas=true",
+ file_path.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "format_json_parse_allow_trailing_commas_true",
+ fs,
+ console,
+ result,
+ ));
+}
+
+// Combined tests
+
+#[test]
+fn check_combined_json_parser_flags() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Utf8Path::new("file.json");
+ // JSON with both comments and trailing comma
+ fs.insert(
+ file_path.into(),
+ "{\n // Comment\n \"key\": \"value\",\n}".as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "check",
+ "--json-parse-allow-comments=true",
+ "--json-parse-allow-trailing-commas=true",
+ file_path.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "check_combined_json_parser_flags",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn ci_json_parse_allow_comments_true() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Utf8Path::new("file.json");
+ // JSON with comments
+ fs.insert(
+ file_path.into(),
+ "{\n // This is a comment\n \"key\": \"value\"\n}".as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["ci", "--json-parse-allow-comments=true", file_path.as_str()].as_slice()),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "ci_json_parse_allow_comments_true",
+ fs,
+ console,
+ result,
+ ));
+}
+
+// Config override tests
+
+#[test]
+fn check_json_parser_flags_override_config() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ // Config that disallows comments
+ let config_path = Utf8Path::new("biome.json");
+ fs.insert(
+ config_path.into(),
+ r#"{
+ "json": {
+ "parser": {
+ "allowComments": false
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let file_path = Utf8Path::new("file.json");
+ fs.insert(
+ file_path.into(),
+ "{\n // Comment\n \"key\": \"value\"\n}".as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "check",
+ "--json-parse-allow-comments=true",
+ file_path.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "check_json_parser_flags_override_config",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn check_json_parse_respects_config_allow_comments() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ // Config that allows comments
+ let config_path = Utf8Path::new("biome.json");
+ fs.insert(
+ config_path.into(),
+ r#"{
+ "json": {
+ "parser": {
+ "allowComments": true
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let file_path = Utf8Path::new("file.json");
+ fs.insert(
+ file_path.into(),
+ "{\n // Comment\n \"key\": \"value\"\n}".as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["check", file_path.as_str()].as_slice()),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "check_json_parse_respects_config_allow_comments",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn check_json_parse_respects_config_allow_trailing_commas() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ // Config that allows trailing commas
+ let config_path = Utf8Path::new("biome.json");
+ fs.insert(
+ config_path.into(),
+ r#"{
+ "json": {
+ "parser": {
+ "allowTrailingCommas": true
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let file_path = Utf8Path::new("file.json");
+ fs.insert(file_path.into(), "{\n \"key\": \"value\",\n}".as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["check", file_path.as_str()].as_slice()),
+ );
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "check_json_parse_respects_config_allow_trailing_commas",
+ fs,
+ console,
+ result,
+ ));
+}
diff --git a/crates/biome_cli/tests/cases/linter_domains.rs b/crates/biome_cli/tests/cases/linter_domains.rs
index 237bff6b1907..9d50fe546b47 100644
--- a/crates/biome_cli/tests/cases/linter_domains.rs
+++ b/crates/biome_cli/tests/cases/linter_domains.rs
@@ -355,3 +355,101 @@ describe("foo", () => {
result,
));
}
+
+#[test]
+fn should_enable_domain_via_cli() {
+ let mut console = BufferConsole::default();
+ let fs = MemoryFileSystem::default();
+ let config = Utf8Path::new("biome.json");
+ fs.insert(
+ config.into(),
+ r#"{
+ "linter": {
+ "rules": {
+ "recommended": false
+ },
+ "domains": {
+ "test": "all"
+ }
+ }
+}
+"#
+ .as_bytes(),
+ );
+ let test1 = Utf8Path::new("test1.js");
+ fs.insert(
+ test1.into(),
+ r#"describe.only("bar", () => {});
+"#
+ .as_bytes(),
+ );
+
+ let content = r#"
+describe("foo", () => {
+ beforeEach(() => {});
+ beforeEach(() => {});
+ test("bar", () => {
+ someFn();
+ });
+});
+ "#;
+ let test2 = Utf8Path::new("test2.js");
+ fs.insert(test2.into(), content.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["lint", "--only=test", test1.as_str(), test2.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_enable_domain_via_cli",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn should_disable_domain_via_cli() {
+ let mut console = BufferConsole::default();
+ let fs = MemoryFileSystem::default();
+ let test1 = Utf8Path::new("test1.js");
+ fs.insert(
+ test1.into(),
+ r#"describe.only("bar", () => {});
+"#
+ .as_bytes(),
+ );
+
+ let content = r#"
+describe("foo", () => {
+ beforeEach(() => {});
+ beforeEach(() => {});
+ test("bar", () => {
+ someFn();
+ });
+});
+ "#;
+ let test2 = Utf8Path::new("test2.js");
+ fs.insert(test2.into(), content.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["lint", "--skip=test", test1.as_str(), test2.as_str()].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_disable_domain_via_cli",
+ fs,
+ console,
+ result,
+ ));
+}
diff --git a/crates/biome_cli/tests/cases/mod.rs b/crates/biome_cli/tests/cases/mod.rs
index 3616fba4755c..6e3155065ff7 100644
--- a/crates/biome_cli/tests/cases/mod.rs
+++ b/crates/biome_cli/tests/cases/mod.rs
@@ -5,9 +5,11 @@ mod assist;
mod biome_json_support;
mod config_extends;
mod config_path;
+mod css_parsing;
mod cts_files;
mod diagnostics;
mod editorconfig;
+mod format_with_errors;
mod graphql;
mod handle_astro_files;
mod handle_css_files;
@@ -15,6 +17,8 @@ mod handle_svelte_files;
mod handle_vue_files;
mod html;
mod included_files;
+mod indent_script_and_style;
+mod json_parsing;
mod linter_domains;
mod linter_groups_plain;
mod migrate_v2;
@@ -24,12 +28,15 @@ mod overrides_linter;
mod overrides_max_file_size;
mod overrides_organize_imports;
mod protected_files;
+mod reporter_checkstyle;
mod reporter_github;
mod reporter_gitlab;
mod reporter_junit;
+mod reporter_rdjson;
mod reporter_summary;
mod reporter_terminal;
mod rules_via_dependencies;
mod suppressions;
+mod tailwind_directives;
mod unknown_files;
mod vcs_ignored_files;
diff --git a/crates/biome_cli/tests/cases/reporter_checkstyle.rs b/crates/biome_cli/tests/cases/reporter_checkstyle.rs
new file mode 100644
index 000000000000..5d9d59114e8f
--- /dev/null
+++ b/crates/biome_cli/tests/cases/reporter_checkstyle.rs
@@ -0,0 +1,170 @@
+use crate::run_cli;
+use crate::snap_test::{SnapshotPayload, assert_cli_snapshot};
+use biome_console::BufferConsole;
+use biome_fs::MemoryFileSystem;
+use bpaf::Args;
+use camino::Utf8Path;
+
+const MAIN_1: &str = r#"import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;"#;
+
+const MAIN_2: &str = r#"import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;"#;
+
+#[test]
+fn reports_diagnostics_checkstyle_check_command() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path1 = Utf8Path::new("main.ts");
+ fs.insert(file_path1.into(), MAIN_1.as_bytes());
+
+ let file_path2 = Utf8Path::new("index.ts");
+ fs.insert(file_path2.into(), MAIN_2.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "check",
+ "--reporter=checkstyle",
+ file_path1.as_str(),
+ file_path2.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "reports_diagnostics_checkstyle_check_command",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn reports_diagnostics_checkstyle_ci_command() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path1 = Utf8Path::new("main.ts");
+ fs.insert(file_path1.into(), MAIN_1.as_bytes());
+
+ let file_path2 = Utf8Path::new("index.ts");
+ fs.insert(file_path2.into(), MAIN_2.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "ci",
+ "--reporter=checkstyle",
+ file_path1.as_str(),
+ file_path2.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "reports_diagnostics_checkstyle_ci_command",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn reports_diagnostics_checkstyle_lint_command() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path1 = Utf8Path::new("main.ts");
+ fs.insert(file_path1.into(), MAIN_1.as_bytes());
+
+ let file_path2 = Utf8Path::new("index.ts");
+ fs.insert(file_path2.into(), MAIN_2.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "lint",
+ "--reporter=checkstyle",
+ file_path1.as_str(),
+ file_path2.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "reports_diagnostics_checkstyle_lint_command",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn reports_diagnostics_checkstyle_format_command() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path1 = Utf8Path::new("main.ts");
+ fs.insert(file_path1.into(), MAIN_1.as_bytes());
+
+ let file_path2 = Utf8Path::new("index.ts");
+ fs.insert(file_path2.into(), MAIN_2.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "format",
+ "--reporter=checkstyle",
+ file_path1.as_str(),
+ file_path2.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "reports_diagnostics_checkstyle_format_command",
+ fs,
+ console,
+ result,
+ ));
+}
diff --git a/crates/biome_cli/tests/cases/reporter_rdjson.rs b/crates/biome_cli/tests/cases/reporter_rdjson.rs
new file mode 100644
index 000000000000..455f9db20fac
--- /dev/null
+++ b/crates/biome_cli/tests/cases/reporter_rdjson.rs
@@ -0,0 +1,170 @@
+use crate::run_cli;
+use crate::snap_test::{SnapshotPayload, assert_cli_snapshot};
+use biome_console::BufferConsole;
+use biome_fs::MemoryFileSystem;
+use bpaf::Args;
+use camino::Utf8Path;
+
+const MAIN_1: &str = r#"import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;"#;
+
+const MAIN_2: &str = r#"import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;"#;
+
+#[test]
+fn reports_diagnostics_rdjson_check_command() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path1 = Utf8Path::new("main.ts");
+ fs.insert(file_path1.into(), MAIN_1.as_bytes());
+
+ let file_path2 = Utf8Path::new("index.ts");
+ fs.insert(file_path2.into(), MAIN_2.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "check",
+ "--reporter=rdjson",
+ file_path1.as_str(),
+ file_path2.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "reports_diagnostics_rdjson_check_command",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn reports_diagnostics_rdjson_ci_command() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path1 = Utf8Path::new("main.ts");
+ fs.insert(file_path1.into(), MAIN_1.as_bytes());
+
+ let file_path2 = Utf8Path::new("index.ts");
+ fs.insert(file_path2.into(), MAIN_2.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "ci",
+ "--reporter=rdjson",
+ file_path1.as_str(),
+ file_path2.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "reports_diagnostics_rdjson_ci_command",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn reports_diagnostics_rdjson_lint_command() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path1 = Utf8Path::new("main.ts");
+ fs.insert(file_path1.into(), MAIN_1.as_bytes());
+
+ let file_path2 = Utf8Path::new("index.ts");
+ fs.insert(file_path2.into(), MAIN_2.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "lint",
+ "--reporter=rdjson",
+ file_path1.as_str(),
+ file_path2.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "reports_diagnostics_rdjson_lint_command",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn reports_diagnostics_rdjson_format_command() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path1 = Utf8Path::new("main.ts");
+ fs.insert(file_path1.into(), MAIN_1.as_bytes());
+
+ let file_path2 = Utf8Path::new("index.ts");
+ fs.insert(file_path2.into(), MAIN_2.as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "format",
+ "--reporter=rdjson",
+ file_path1.as_str(),
+ file_path2.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "reports_diagnostics_rdjson_format_command",
+ fs,
+ console,
+ result,
+ ));
+}
diff --git a/crates/biome_cli/tests/cases/tailwind_directives.rs b/crates/biome_cli/tests/cases/tailwind_directives.rs
new file mode 100644
index 000000000000..d07496c62421
--- /dev/null
+++ b/crates/biome_cli/tests/cases/tailwind_directives.rs
@@ -0,0 +1,139 @@
+use crate::run_cli;
+use crate::snap_test::{SnapshotPayload, assert_cli_snapshot};
+use biome_console::BufferConsole;
+use biome_fs::MemoryFileSystem;
+use bpaf::Args;
+use camino::Utf8Path;
+
+#[test]
+fn should_parse_tailwind_directive() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let css_file_content = r#"@theme {}"#;
+ let css_file = Utf8Path::new("input.css");
+ fs.insert(css_file.into(), css_file_content.as_bytes());
+
+ let config_path = Utf8Path::new("biome.json");
+ fs.insert(
+ config_path.into(),
+ r#"{
+ "formatter": {
+ "enabled": true
+ },
+ "css": {
+ "parser": {
+ "tailwindDirectives": true
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", "--css-formatter-enabled=true", css_file.as_str()].as_slice()),
+ );
+
+ // should format the file
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_parse_tailwind_directive",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn should_not_parse_tailwind_directive_when_disabled() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let css_file_content = r#"@theme {}"#;
+ let css_file = Utf8Path::new("input.css");
+ fs.insert(css_file.into(), css_file_content.as_bytes());
+
+ let config_path = Utf8Path::new("biome.json");
+ fs.insert(
+ config_path.into(),
+ r#"{
+ "formatter": {
+ "enabled": true
+ },
+ "css": {
+ "parser": {
+ "tailwindDirectives": false
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["format", css_file.as_str()].as_slice()),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_not_parse_tailwind_directive_when_disabled",
+ fs,
+ console,
+ result,
+ ));
+}
+
+#[test]
+fn tw_should_not_show_unknown_at_rule_diagnostic() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let css_file_content = r#"@theme {}"#;
+ let css_file = Utf8Path::new("input.css");
+ fs.insert(css_file.into(), css_file_content.as_bytes());
+
+ let config_path = Utf8Path::new("biome.json");
+ fs.insert(
+ config_path.into(),
+ r#"{
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": false,
+ "suspicious": {
+ "noUnknownAtRules": "warn"
+ }
+ }
+ },
+ "css": {
+ "parser": {
+ "tailwindDirectives": true
+ }
+ }
+}"#
+ .as_bytes(),
+ );
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(["lint", css_file.as_str()].as_slice()),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "tw_should_not_show_unknown_at_rule_diagnostic",
+ fs,
+ console,
+ result,
+ ));
+}
diff --git a/crates/biome_cli/tests/commands/check.rs b/crates/biome_cli/tests/commands/check.rs
index 6c8e39fc84b2..7fedfad28813 100644
--- a/crates/biome_cli/tests/commands/check.rs
+++ b/crates/biome_cli/tests/commands/check.rs
@@ -3251,3 +3251,38 @@ fn check_does_not_enable_assist() {
result,
));
}
+
+#[test]
+fn check_format_with_syntax_errors_when_flag_enabled() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let invalid = Utf8Path::new("invalid.js");
+ fs.insert(invalid.into(), "while ) {}".as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "check",
+ "--format-with-errors=true",
+ "--write",
+ invalid.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_file_contents(&fs, invalid, "while ) {}\n");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "check_format_with_syntax_errors_when_flag_enabled",
+ fs,
+ console,
+ result,
+ ));
+}
diff --git a/crates/biome_cli/tests/commands/format.rs b/crates/biome_cli/tests/commands/format.rs
index 269b6c11d7f1..2ea9e8ba8291 100644
--- a/crates/biome_cli/tests/commands/format.rs
+++ b/crates/biome_cli/tests/commands/format.rs
@@ -47,36 +47,18 @@ statement ( ) ;
"#;
-const SVELTE_IMPLICIT_JS_FILE_FORMATTED: &str = r#"
-
"#;
-
const SVELTE_EXPLICIT_JS_FILE_UNFORMATTED: &str = r#"
"#;
-const SVELTE_EXPLICIT_JS_FILE_FORMATTED: &str = r#"
-
"#;
-
const SVELTE_TS_FILE_UNFORMATTED: &str = r#"
"#;
-const SVELTE_TS_FILE_FORMATTED: &str = r#"
-
"#;
-
const APPLY_TRAILING_COMMAS_BEFORE: &str = r#"
const a = [
longlonglonglongItem1longlonglonglongItem1,
@@ -2996,8 +2978,6 @@ fn format_svelte_implicit_js_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, svelte_file_path, SVELTE_IMPLICIT_JS_FILE_FORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_svelte_implicit_js_files_write",
@@ -3056,8 +3036,6 @@ fn format_svelte_explicit_js_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, svelte_file_path, SVELTE_EXPLICIT_JS_FILE_FORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_svelte_explicit_js_files_write",
@@ -3083,8 +3061,6 @@ fn format_empty_svelte_js_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, svelte_file_path, "
");
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_empty_svelte_js_files_write",
@@ -3143,8 +3119,6 @@ fn format_svelte_ts_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, svelte_file_path, SVELTE_TS_FILE_FORMATTED);
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_svelte_ts_files_write",
@@ -3170,8 +3144,6 @@ fn format_empty_svelte_ts_files_write() {
assert!(result.is_ok(), "run_cli returned {result:?}");
- assert_file_contents(&fs, svelte_file_path, "");
-
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"format_empty_svelte_ts_files_write",
@@ -3443,7 +3415,6 @@ fn applies_custom_bracket_spacing_for_graphql() {
));
}
-/// Change this when HTML formatting is enabled by default
#[test]
fn html_disabled_by_default() {
let fs = MemoryFileSystem::default();
@@ -3459,12 +3430,6 @@ fn html_disabled_by_default() {
);
assert!(result.is_err(), "run_cli returned {result:?}");
- assert!(matches!(
- result,
- Err(biome_cli::CliDiagnostic::NoFilesWereProcessed(_))
- ));
-
- assert_file_contents(&fs, file_path, "");
assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
@@ -3573,3 +3538,38 @@ fn should_not_format_file_with_syntax_errors() {
result,
));
}
+
+#[test]
+fn should_format_file_with_syntax_errors_when_flag_enabled() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let invalid = Utf8Path::new("invalid.js");
+ fs.insert(invalid.into(), "while ) {}".as_bytes());
+
+ let (fs, result) = run_cli(
+ fs,
+ &mut console,
+ Args::from(
+ [
+ "format",
+ "--format-with-errors=true",
+ "--write",
+ invalid.as_str(),
+ ]
+ .as_slice(),
+ ),
+ );
+
+ assert!(result.is_err(), "run_cli returned {result:?}");
+
+ assert_file_contents(&fs, invalid, "while ) {}\n");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "should_format_file_with_syntax_errors_when_flag_enabled",
+ fs,
+ console,
+ result,
+ ));
+}
diff --git a/crates/biome_cli/tests/commands/init.rs b/crates/biome_cli/tests/commands/init.rs
index 2fd012165705..3e3ad81ec205 100644
--- a/crates/biome_cli/tests/commands/init.rs
+++ b/crates/biome_cli/tests/commands/init.rs
@@ -40,6 +40,26 @@ fn creates_config_file() {
));
}
+#[test]
+fn enables_vcs_and_ignore_dist() {
+ let fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ fs.insert(".gitignore".into(), "".as_bytes());
+ fs.insert("dist".into(), "".as_bytes());
+
+ let (fs, result) = run_cli(fs, &mut console, Args::from(["init"].as_slice()));
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "enables_vcs_and_ignore_dist",
+ fs,
+ console,
+ result,
+ ));
+}
+
#[test]
fn creates_config_jsonc_file() {
let fs = MemoryFileSystem::default();
diff --git a/crates/biome_cli/tests/snapshots/main_cases_assist/assist_emit_diagnostic_but_doesnt_block.snap b/crates/biome_cli/tests/snapshots/main_cases_assist/assist_emit_diagnostic_but_doesnt_block.snap
index af58f74012f8..07fd51d67084 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_assist/assist_emit_diagnostic_but_doesnt_block.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_assist/assist_emit_diagnostic_but_doesnt_block.snap
@@ -44,4 +44,5 @@ file.json:1:1 assist/source/useSortedKeys FIXABLE ━━━━━━━━━
```block
Checked 1 file in . No fixes applied.
+Found 1 info.
```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_combined_css_parser_flags.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_combined_css_parser_flags.snap
new file mode 100644
index 000000000000..41e1fab027c3
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_combined_css_parser_flags.snap
@@ -0,0 +1,44 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.module.css`
+
+```css
+@import 'tailwindcss';
+.className { composes: other from './other.module.css'; }
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.module.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - @import·'tailwindcss';
+ 2 │ - .className·{·composes:·other·from·'./other.module.css';·}
+ 1 │ + @import·"tailwindcss";
+ 2 │ + .className·{
+ 3 │ + → composes:·other·from·"./other.module.css";
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_combined_format_with_errors_and_css_modules.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_combined_format_with_errors_and_css_modules.snap
new file mode 100644
index 000000000000..c702b34e99a8
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_combined_format_with_errors_and_css_modules.snap
@@ -0,0 +1,71 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.module.css`
+
+```css
+.className { composes: other from './other.module.css';
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.module.css:1:56 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ .className { composes: other from './other.module.css';
+ │
+
+ i the file ends here
+
+ > 1 │ .className { composes: other from './other.module.css';
+ │
+
+
+```
+
+```block
+file.module.css:1:56 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ .className { composes: other from './other.module.css';
+ │
+
+ i the file ends here
+
+ > 1 │ .className { composes: other from './other.module.css';
+ │
+
+
+```
+
+```block
+file.module.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - .className·{·composes:·other·from·'./other.module.css';
+ 1 │ + .className·{·composes:·other·from·'./other.module.css';
+ 2 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_css_modules_false.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_css_modules_false.snap
new file mode 100644
index 000000000000..1596635267df
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_css_modules_false.snap
@@ -0,0 +1,61 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.module.css`
+
+```css
+.className { composes: other from './other.module.css'; }
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.module.css:1:14 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × `composes` declaration is not a standard CSS feature.
+
+ > 1 │ .className { composes: other from './other.module.css'; }
+ │ ^^^^^^^^
+
+ i You can enable `composes` declaration parsing by setting the `css.parser.cssModules` option to `true` in your configuration file.
+
+
+```
+
+```block
+file.module.css:1:14 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × `composes` declaration is not a standard CSS feature.
+
+ > 1 │ .className { composes: other from './other.module.css'; }
+ │ ^^^^^^^^
+
+ i You can enable `composes` declaration parsing by setting the `css.parser.cssModules` option to `true` in your configuration file.
+
+
+```
+
+```block
+file.module.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Code formatting aborted due to parsing errors. To format code with errors, enable the 'formatter.formatWithErrors' option.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_css_modules_true.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_css_modules_true.snap
new file mode 100644
index 000000000000..7a8aa653242b
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_css_modules_true.snap
@@ -0,0 +1,41 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.module.css`
+
+```css
+.className { composes: other from './other.module.css'; }
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.module.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - .className·{·composes:·other·from·'./other.module.css';·}
+ 1 │ + .className·{
+ 2 │ + → composes:·other·from·"./other.module.css";
+ 3 │ + }
+ 4 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_respects_config_css_modules.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_respects_config_css_modules.snap
new file mode 100644
index 000000000000..17887617bb80
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_respects_config_css_modules.snap
@@ -0,0 +1,53 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "css": {
+ "parser": {
+ "cssModules": true
+ }
+ }
+}
+```
+
+## `file.module.css`
+
+```css
+.className { composes: other from './other.module.css'; }
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.module.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - .className·{·composes:·other·from·'./other.module.css';·}
+ 1 │ + .className·{
+ 2 │ + → composes:·other·from·"./other.module.css";
+ 3 │ + }
+ 4 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_respects_config_tailwind_directives.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_respects_config_tailwind_directives.snap
new file mode 100644
index 000000000000..02d436fe1a1e
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_respects_config_tailwind_directives.snap
@@ -0,0 +1,56 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "css": {
+ "parser": {
+ "tailwindDirectives": true
+ }
+ }
+}
+```
+
+## `file.css`
+
+```css
+@import 'tailwindcss';
+.foo { color: red; }
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - @import·'tailwindcss';
+ 2 │ - .foo·{·color:·red;·}
+ 1 │ + @import·"tailwindcss";
+ 2 │ + .foo·{
+ 3 │ + → color:·red;
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_tailwind_directives_false.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_tailwind_directives_false.snap
new file mode 100644
index 000000000000..918d4fffbb05
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_tailwind_directives_false.snap
@@ -0,0 +1,44 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.css`
+
+```css
+@import 'tailwindcss';
+.foo { color: red; }
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - @import·'tailwindcss';
+ 2 │ - .foo·{·color:·red;·}
+ 1 │ + @import·"tailwindcss";
+ 2 │ + .foo·{
+ 3 │ + → color:·red;
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_tailwind_directives_true.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_tailwind_directives_true.snap
new file mode 100644
index 000000000000..918d4fffbb05
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parse_tailwind_directives_true.snap
@@ -0,0 +1,44 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.css`
+
+```css
+@import 'tailwindcss';
+.foo { color: red; }
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - @import·'tailwindcss';
+ 2 │ - .foo·{·color:·red;·}
+ 1 │ + @import·"tailwindcss";
+ 2 │ + .foo·{
+ 3 │ + → color:·red;
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parser_flags_override_config.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parser_flags_override_config.snap
new file mode 100644
index 000000000000..f489be1fa3e6
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/check_css_parser_flags_override_config.snap
@@ -0,0 +1,53 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "css": {
+ "parser": {
+ "cssModules": false
+ }
+ }
+}
+```
+
+## `file.module.css`
+
+```css
+.className { composes: other from './other.module.css'; }
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.module.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - .className·{·composes:·other·from·'./other.module.css';·}
+ 1 │ + .className·{
+ 2 │ + → composes:·other·from·"./other.module.css";
+ 3 │ + }
+ 4 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/ci_css_parse_tailwind_directives_true.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/ci_css_parse_tailwind_directives_true.snap
new file mode 100644
index 000000000000..1d5aa4a0f4f0
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/ci_css_parse_tailwind_directives_true.snap
@@ -0,0 +1,44 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.css`
+
+```css
+@import 'tailwindcss';
+.foo { color: red; }
+```
+
+# Termination Message
+
+```block
+ci ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × File content differs from formatting output
+
+ 1 │ - @import·'tailwindcss';
+ 2 │ - .foo·{·color:·red;·}
+ 1 │ + @import·"tailwindcss";
+ 2 │ + .foo·{
+ 3 │ + → color:·red;
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/format_css_parse_css_modules_true.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/format_css_parse_css_modules_true.snap
new file mode 100644
index 000000000000..907a04b95f34
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/format_css_parse_css_modules_true.snap
@@ -0,0 +1,41 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.module.css`
+
+```css
+.className { composes: other from './other.module.css'; }
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.module.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - .className·{·composes:·other·from·'./other.module.css';·}
+ 1 │ + .className·{
+ 2 │ + → composes:·other·from·"./other.module.css";
+ 3 │ + }
+ 4 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/format_css_parse_tailwind_directives_true.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/format_css_parse_tailwind_directives_true.snap
new file mode 100644
index 000000000000..fabc3c3342a6
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/format_css_parse_tailwind_directives_true.snap
@@ -0,0 +1,44 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.css`
+
+```css
+@import 'tailwindcss';
+.foo { color: red; }
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - @import·'tailwindcss';
+ 2 │ - .foo·{·color:·red;·}
+ 1 │ + @import·"tailwindcss";
+ 2 │ + .foo·{
+ 3 │ + → color:·red;
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_css_parsing/lint_css_parse_css_modules_true.snap b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/lint_css_parse_css_modules_true.snap
new file mode 100644
index 000000000000..2141223891fd
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_css_parsing/lint_css_parse_css_modules_true.snap
@@ -0,0 +1,15 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.module.css`
+
+```css
+.className { composes: other from './other.module.css'; }
+```
+
+# Emitted Messages
+
+```block
+Checked 1 file in . No fixes applied.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_false.snap b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_false.snap
new file mode 100644
index 000000000000..51d0b8e7720c
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_false.snap
@@ -0,0 +1,107 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.js`
+
+```js
+let a = {
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.js:1:1 lint/style/useConst FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This let declares a variable that is only assigned once.
+
+ > 1 │ let a = {
+ │ ^^^
+
+ i 'a' is never reassigned.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Safe fix: Use const instead.
+
+ - let·a·=·{
+ + const·a·=·{
+
+
+```
+
+```block
+file.js:1:5 lint/correctness/noUnusedVariables FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This variable a is unused.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Unused variables are often the result of an incomplete refactoring, typos, or other sources of bugs.
+
+ i Unsafe fix: If this is intentional, prepend a with an underscore.
+
+ - let·a·=·{
+ + let·_a·=·{
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Code formatting aborted due to parsing errors. To format code with errors, enable the 'formatter.formatWithErrors' option.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+Found 2 warnings.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_overrides_config.snap b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_overrides_config.snap
new file mode 100644
index 000000000000..8a6c95ae1719
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_overrides_config.snap
@@ -0,0 +1,121 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "formatter": {
+ "formatWithErrors": false
+ }
+}
+```
+
+## `file.js`
+
+```js
+let a = {
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.js:1:1 lint/style/useConst FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This let declares a variable that is only assigned once.
+
+ > 1 │ let a = {
+ │ ^^^
+
+ i 'a' is never reassigned.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Safe fix: Use const instead.
+
+ - let·a·=·{
+ + const·a·=·{
+
+
+```
+
+```block
+file.js:1:5 lint/correctness/noUnusedVariables FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This variable a is unused.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Unused variables are often the result of an incomplete refactoring, typos, or other sources of bugs.
+
+ i Unsafe fix: If this is intentional, prepend a with an underscore.
+
+ - let·a·=·{
+ + let·_a·=·{
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - let·a·=·{
+ 1 │ + let·a·=·{
+ 2 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+Found 2 warnings.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_respects_config_false.snap b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_respects_config_false.snap
new file mode 100644
index 000000000000..04c2bd51e9b3
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_respects_config_false.snap
@@ -0,0 +1,117 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "formatter": {
+ "formatWithErrors": false
+ }
+}
+```
+
+## `file.js`
+
+```js
+let a = {
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.js:1:1 lint/style/useConst FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This let declares a variable that is only assigned once.
+
+ > 1 │ let a = {
+ │ ^^^
+
+ i 'a' is never reassigned.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Safe fix: Use const instead.
+
+ - let·a·=·{
+ + const·a·=·{
+
+
+```
+
+```block
+file.js:1:5 lint/correctness/noUnusedVariables FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This variable a is unused.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Unused variables are often the result of an incomplete refactoring, typos, or other sources of bugs.
+
+ i Unsafe fix: If this is intentional, prepend a with an underscore.
+
+ - let·a·=·{
+ + let·_a·=·{
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Code formatting aborted due to parsing errors. To format code with errors, enable the 'formatter.formatWithErrors' option.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+Found 2 warnings.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_respects_config_true.snap b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_respects_config_true.snap
new file mode 100644
index 000000000000..924475cc4711
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_respects_config_true.snap
@@ -0,0 +1,121 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "formatter": {
+ "formatWithErrors": true
+ }
+}
+```
+
+## `file.js`
+
+```js
+let a = {
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.js:1:1 lint/style/useConst FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This let declares a variable that is only assigned once.
+
+ > 1 │ let a = {
+ │ ^^^
+
+ i 'a' is never reassigned.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Safe fix: Use const instead.
+
+ - let·a·=·{
+ + const·a·=·{
+
+
+```
+
+```block
+file.js:1:5 lint/correctness/noUnusedVariables FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This variable a is unused.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Unused variables are often the result of an incomplete refactoring, typos, or other sources of bugs.
+
+ i Unsafe fix: If this is intentional, prepend a with an underscore.
+
+ - let·a·=·{
+ + let·_a·=·{
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - let·a·=·{
+ 1 │ + let·a·=·{
+ 2 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+Found 2 warnings.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_true.snap b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_true.snap
new file mode 100644
index 000000000000..b0059d6d5127
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/check_format_with_errors_true.snap
@@ -0,0 +1,111 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.js`
+
+```js
+let a = {
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.js:1:1 lint/style/useConst FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This let declares a variable that is only assigned once.
+
+ > 1 │ let a = {
+ │ ^^^
+
+ i 'a' is never reassigned.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Safe fix: Use const instead.
+
+ - let·a·=·{
+ + const·a·=·{
+
+
+```
+
+```block
+file.js:1:5 lint/correctness/noUnusedVariables FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This variable a is unused.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Unused variables are often the result of an incomplete refactoring, typos, or other sources of bugs.
+
+ i Unsafe fix: If this is intentional, prepend a with an underscore.
+
+ - let·a·=·{
+ + let·_a·=·{
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - let·a·=·{
+ 1 │ + let·a·=·{
+ 2 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+Found 2 warnings.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/ci_format_with_errors_false.snap b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/ci_format_with_errors_false.snap
new file mode 100644
index 000000000000..ae6ab262af18
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/ci_format_with_errors_false.snap
@@ -0,0 +1,107 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.js`
+
+```js
+let a = {
+```
+
+# Termination Message
+
+```block
+ci ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.js:1:1 lint/style/useConst FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This let declares a variable that is only assigned once.
+
+ > 1 │ let a = {
+ │ ^^^
+
+ i 'a' is never reassigned.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Safe fix: Use const instead.
+
+ - let·a·=·{
+ + const·a·=·{
+
+
+```
+
+```block
+file.js:1:5 lint/correctness/noUnusedVariables FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This variable a is unused.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Unused variables are often the result of an incomplete refactoring, typos, or other sources of bugs.
+
+ i Unsafe fix: If this is intentional, prepend a with an underscore.
+
+ - let·a·=·{
+ + let·_a·=·{
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Code formatting aborted due to parsing errors. To format code with errors, enable the 'formatter.formatWithErrors' option.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+Found 2 warnings.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/ci_format_with_errors_true.snap b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/ci_format_with_errors_true.snap
new file mode 100644
index 000000000000..ae6ab262af18
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/ci_format_with_errors_true.snap
@@ -0,0 +1,107 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.js`
+
+```js
+let a = {
+```
+
+# Termination Message
+
+```block
+ci ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.js:1:1 lint/style/useConst FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This let declares a variable that is only assigned once.
+
+ > 1 │ let a = {
+ │ ^^^
+
+ i 'a' is never reassigned.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Safe fix: Use const instead.
+
+ - let·a·=·{
+ + const·a·=·{
+
+
+```
+
+```block
+file.js:1:5 lint/correctness/noUnusedVariables FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This variable a is unused.
+
+ > 1 │ let a = {
+ │ ^
+
+ i Unused variables are often the result of an incomplete refactoring, typos, or other sources of bugs.
+
+ i Unsafe fix: If this is intentional, prepend a with an underscore.
+
+ - let·a·=·{
+ + let·_a·=·{
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Code formatting aborted due to parsing errors. To format code with errors, enable the 'formatter.formatWithErrors' option.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+Found 2 warnings.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/format_format_with_errors_false.snap b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/format_format_with_errors_false.snap
new file mode 100644
index 000000000000..c265864207eb
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/format_format_with_errors_false.snap
@@ -0,0 +1,57 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.js`
+
+```js
+let a = {
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × No files were processed in the specified paths.
+
+ i Check your biome.json or biome.jsonc to ensure the paths are not ignored by the configuration.
+
+ i These paths were provided but ignored:
+
+ - file.js
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Code formatting aborted due to parsing errors. To format code with errors, enable the 'formatter.formatWithErrors' option.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/format_format_with_errors_true.snap b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/format_format_with_errors_true.snap
new file mode 100644
index 000000000000..4e0bab83da58
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_format_with_errors/format_format_with_errors_true.snap
@@ -0,0 +1,55 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.js`
+
+```js
+let a = {
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.js:1:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `}` but instead the file ends
+
+ > 1 │ let a = {
+ │
+
+ i the file ends here
+
+ > 1 │ let a = {
+ │
+
+
+```
+
+```block
+file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - let·a·=·{
+ 1 │ + let·a·=·{
+ 2 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 2 errors.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_successfully.snap
index 11f58f50807c..ae06582d9726 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_successfully.snap
@@ -9,7 +9,7 @@ expression: redactor(content)
import {a as a} from 'mod';
import { something } from "file.astro";
debugger;
-statement ( ) ;
+something ( ) ;
var foo: string = "";
---
@@ -33,7 +33,7 @@ stdin ━━━━━━━━━━━━━━━━━━━━━━━━
import {a as a} from 'mod';
import { something } from "file.astro";
debugger;
-statement ( ) ;
+something ( ) ;
var foo: string = "";
---
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_successfully.snap
index eadc402d611f..1a7599f26dc6 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_successfully.snap
@@ -9,7 +9,7 @@ expression: redactor(content)
import {a as a} from 'mod';
import { something } from "file.astro";
debugger;
-statement ( ) ;
+something ( ) ;
var foo: string = "";
---
@@ -23,7 +23,7 @@ import { something } from "file.astro";
import { a } from "mod";
debugger;
-statement();
+something();
var foo: string = "";
---
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_unsafe_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_unsafe_successfully.snap
index 13196f41657b..b1412d62ed4c 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_unsafe_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_unsafe_successfully.snap
@@ -9,7 +9,7 @@ expression: redactor(content)
import {a as a} from 'mod';
import { something } from "file.astro";
debugger;
-statement ( ) ;
+something ( ) ;
var foo: string = "";
---
@@ -19,7 +19,9 @@ var foo: string = "";
```block
---
-statement();
+import { something } from "file.astro";
+
+something();
var _foo: string = "";
---
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_carriage_return_line_feed_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_carriage_return_line_feed_files.snap
index f55a27c6412d..0033e4387ed6 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_carriage_return_line_feed_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_carriage_return_line_feed_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.astro`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_files.snap
index 44c7d972b017..31ff6405b81c 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.astro`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_files_write.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_files_write.snap
index a8c0d75b19f3..b814a07472c7 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_files_write.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_astro_files_write.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.astro`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_empty_astro_files_write.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_empty_astro_files_write.snap
index e89ea4089214..824c6b4362c7 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_empty_astro_files_write.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_empty_astro_files_write.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.astro`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_stdin_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_stdin_successfully.snap
index f35db9c9f4ea..e4f13aa7ff44 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_stdin_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_stdin_successfully.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
# Input messages
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_stdin_write_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_stdin_write_successfully.snap
index f35db9c9f4ea..e4f13aa7ff44 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_stdin_write_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/format_stdin_write_successfully.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
# Input messages
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/full_support.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/full_support.snap
new file mode 100644
index 000000000000..630710ed971d
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/full_support.snap
@@ -0,0 +1,84 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": { "enabled": true },
+ "linter": { "enabled": true },
+ "experimentalFullSupportEnabled": true
+ }
+}
+```
+
+## `file.astro`
+
+```astro
+---
+import { sure } from "sure.js";
+import z from "zod";
+
+const schema = z.object().optional();
+schema + sure();
+---
+
+
+ Astro
+
+
+
+
+
+
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.astro:13:20 lint/a11y/useGenericFontNames ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Generic font family missing.
+
+ 12 │
+ 15 │
+
+ i Consider adding a generic font family as a fallback.
+
+ i For examples and more information, see the MDN Web Docs
+
+ - serif
+ - sans-serif
+ - monospace
+ - etc.
+
+
+```
+
+```block
+Checked 1 file in . Fixed 1 file.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_and_fix_astro_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_and_fix_astro_files.snap
index 4aa0b34043c7..f90d5b6ed9f4 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_and_fix_astro_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_and_fix_astro_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.astro`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_astro_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_astro_files.snap
index 3e1749644670..572c72c5401e 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_astro_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_astro_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.astro`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_stdin_write_unsafe_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_stdin_write_unsafe_successfully.snap
index b7f146f1f149..1d7e582f8211 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_stdin_write_unsafe_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_stdin_write_unsafe_successfully.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
# Input messages
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/sorts_imports_check.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/sorts_imports_check.snap
index e731a08d5193..9140b7f9144c 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/sorts_imports_check.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/sorts_imports_check.snap
@@ -1,7 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
expression: redactor(content)
-snapshot_kind: text
---
## `file.astro`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/sorts_imports_write.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/sorts_imports_write.snap
index 37f6a314f2a6..04482f71c100 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/sorts_imports_write.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/sorts_imports_write.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.astro`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_stdin_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_stdin_successfully.snap
index 92327807f837..1ba5c8d048d8 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_stdin_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_stdin_successfully.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
# Input messages
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_stdin_write_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_stdin_write_successfully.snap
index 92327807f837..1ba5c8d048d8 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_stdin_write_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_stdin_write_successfully.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
# Input messages
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_carriage_return_line_feed_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_carriage_return_line_feed_files.snap
index 6ef15cc52403..9fcc1b5c5d98 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_carriage_return_line_feed_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_carriage_return_line_feed_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.svelte`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_ts_context_module_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_ts_context_module_files.snap
index 03343624327d..faedefeb9756 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_ts_context_module_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_ts_context_module_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.svelte`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_ts_context_module_files_write.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_ts_context_module_files_write.snap
index e91727fdcbbb..0c91d98ebb08 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_ts_context_module_files_write.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/format_svelte_ts_context_module_files_write.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.svelte`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/full_support.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/full_support.snap
new file mode 100644
index 000000000000..99a9ef12eb34
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/full_support.snap
@@ -0,0 +1,85 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": { "enabled": true },
+ "linter": { "enabled": true },
+ "experimentalFullSupportEnabled": true
+ }
+}
+```
+
+## `file.svelte`
+
+```svelte
+
+
+
+
+ Svelte
+
+
+
+
+
+
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.svelte:12:20 lint/a11y/useGenericFontNames ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Generic font family missing.
+
+ 11 │
+ 14 │
+
+ i Consider adding a generic font family as a fallback.
+
+ i For examples and more information, see the MDN Web Docs
+
+ - serif
+ - sans-serif
+ - monospace
+ - etc.
+
+
+```
+
+```block
+Checked 1 file in . Fixed 1 file.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/full_support_ts.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/full_support_ts.snap
new file mode 100644
index 000000000000..7881c62ba9bc
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/full_support_ts.snap
@@ -0,0 +1,90 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": { "enabled": true },
+ "linter": { "enabled": true },
+ "experimentalFullSupportEnabled": true
+ }
+}
+```
+
+## `file.svelte`
+
+```svelte
+
+
+
+
+ Svelte
+
+
+
+
+
+
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.svelte:17:20 lint/a11y/useGenericFontNames ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Generic font family missing.
+
+ 16 │
+ 19 │
+
+ i Consider adding a generic font family as a fallback.
+
+ i For examples and more information, see the MDN Web Docs
+
+ - serif
+ - sans-serif
+ - monospace
+ - etc.
+
+
+```
+
+```block
+Checked 1 file in . Fixed 1 file.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/lint_stdin_write_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/lint_stdin_write_successfully.snap
index 84c51eb6a9c1..40619a10536b 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/lint_stdin_write_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/lint_stdin_write_successfully.snap
@@ -1,7 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
-snapshot_kind: text
+expression: redactor(content)
---
# Input messages
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/sorts_imports_check.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/sorts_imports_check.snap
index 9b2255630191..41c27b373f44 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/sorts_imports_check.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_svelte_files/sorts_imports_check.snap
@@ -1,7 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
expression: redactor(content)
-snapshot_kind: text
---
## `file.svelte`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_empty_vue_js_files_write.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_empty_vue_js_files_write.snap
index a863cdf10518..52fd60cca984 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_empty_vue_js_files_write.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_empty_vue_js_files_write.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_empty_vue_ts_files_write.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_empty_vue_ts_files_write.snap
index a863cdf10518..52fd60cca984 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_empty_vue_ts_files_write.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_empty_vue_ts_files_write.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_stdin_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_stdin_successfully.snap
index d058d5a113cf..c4e1d2583381 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_stdin_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_stdin_successfully.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
# Input messages
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_stdin_write_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_stdin_write_successfully.snap
index d058d5a113cf..c4e1d2583381 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_stdin_write_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_stdin_write_successfully.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
# Input messages
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_carriage_return_line_feed_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_carriage_return_line_feed_files.snap
index df58e49eb16a..8a5687984cdb 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_carriage_return_line_feed_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_carriage_return_line_feed_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_explicit_js_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_explicit_js_files.snap
index ac7a211fbd3e..55fbbe9ecf96 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_explicit_js_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_explicit_js_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_explicit_js_files_write.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_explicit_js_files_write.snap
index 4337d0c15551..dc136b257506 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_explicit_js_files_write.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_explicit_js_files_write.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_generic_component_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_generic_component_files.snap
index 94bf179b067f..04422014d428 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_generic_component_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_generic_component_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_implicit_js_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_implicit_js_files.snap
index 9df73170f5fb..8b5a0e806bb1 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_implicit_js_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_implicit_js_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_implicit_js_files_write.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_implicit_js_files_write.snap
index 7e446f95cb5c..22ec5b9065c4 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_implicit_js_files_write.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_implicit_js_files_write.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_ts_files.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_ts_files.snap
index 5b2b803d4ffe..d76c0dcd1544 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_ts_files.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_ts_files.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_ts_files_write.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_ts_files_write.snap
index dc601086e18a..561de366266e 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_ts_files_write.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/format_vue_ts_files_write.snap
@@ -1,6 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
+expression: redactor(content)
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/full_support.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/full_support.snap
new file mode 100644
index 000000000000..e9836d5bd52a
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/full_support.snap
@@ -0,0 +1,85 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": { "enabled": true },
+ "linter": { "enabled": true },
+ "experimentalFullSupportEnabled": true
+ }
+}
+```
+
+## `file.vue`
+
+```vue
+
+
+
+
+ Svelte
+
+
+
+
+
+
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.vue:12:20 lint/a11y/useGenericFontNames ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Generic font family missing.
+
+ 11 │
+ 14 │
+
+ i Consider adding a generic font family as a fallback.
+
+ i For examples and more information, see the MDN Web Docs
+
+ - serif
+ - sans-serif
+ - monospace
+ - etc.
+
+
+```
+
+```block
+Checked 1 file in . Fixed 1 file.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/full_support_ts.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/full_support_ts.snap
new file mode 100644
index 000000000000..f35c33f606ac
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/full_support_ts.snap
@@ -0,0 +1,90 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": { "enabled": true },
+ "linter": { "enabled": true },
+ "experimentalFullSupportEnabled": true
+ }
+}
+```
+
+## `file.vue`
+
+```vue
+
+
+
+
+ Svelte
+
+
+
+
+
+
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.vue:17:20 lint/a11y/useGenericFontNames ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Generic font family missing.
+
+ 16 │
+ 19 │
+
+ i Consider adding a generic font family as a fallback.
+
+ i For examples and more information, see the MDN Web Docs
+
+ - serif
+ - sans-serif
+ - monospace
+ - etc.
+
+
+```
+
+```block
+Checked 1 file in . Fixed 1 file.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/lint_stdin_write_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/lint_stdin_write_successfully.snap
index 1d3412d13497..4bb448cc1576 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/lint_stdin_write_successfully.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/lint_stdin_write_successfully.snap
@@ -1,7 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
-expression: content
-snapshot_kind: text
+expression: redactor(content)
---
# Input messages
diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/sorts_imports_check.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/sorts_imports_check.snap
index ecd150cc8323..6f4ad5095a7b 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/sorts_imports_check.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/sorts_imports_check.snap
@@ -1,7 +1,6 @@
---
source: crates/biome_cli/tests/snap_test.rs
expression: redactor(content)
-snapshot_kind: text
---
## `file.vue`
diff --git a/crates/biome_cli/tests/snapshots/main_cases_html/should_apply_fixes_to_embedded_languages.snap b/crates/biome_cli/tests/snapshots/main_cases_html/should_apply_fixes_to_embedded_languages.snap
new file mode 100644
index 000000000000..3acbfa2f6b04
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_html/should_apply_fixes_to_embedded_languages.snap
@@ -0,0 +1,79 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ },
+ "linter": {
+ "enabled": true
+ },
+ "assist": {
+ "enabled": true
+ }
+ }
+}
+```
+
+## `file.html`
+
+```html
+
+
+
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.html:7:48 lint/suspicious/noDuplicateProperties ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
+
+ 6 │
+ > 7 │
+ │ ^^^^^^^^^^^^^^^^
+ 8 │
+
+ i background-color is already defined here.
+
+ 6 │
+ > 7 │
+ │ ^^^^^^^^^^^^^^^^
+ 8 │
+
+ i Remove or rename the duplicate property to ensure consistent styling.
+
+
+```
+
+```block
+Checked 1 file in . Fixed 1 file.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_html/should_format_indent_embedded_languages.snap b/crates/biome_cli/tests/snapshots/main_cases_html/should_format_indent_embedded_languages.snap
new file mode 100644
index 000000000000..5908c428fe34
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_html/should_format_indent_embedded_languages.snap
@@ -0,0 +1,40 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ }
+ }
+}
+```
+
+## `file.html`
+
+```html
+
+
+
+```
+
+# Emitted Messages
+
+```block
+Formatted 1 file in . Fixed 1 file.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_html/should_format_indent_embedded_languages_with_language_options.snap b/crates/biome_cli/tests/snapshots/main_cases_html/should_format_indent_embedded_languages_with_language_options.snap
new file mode 100644
index 000000000000..3baa3a0b5242
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_html/should_format_indent_embedded_languages_with_language_options.snap
@@ -0,0 +1,45 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ }
+ },
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "single"
+ }
+ }
+}
+```
+
+## `file.html`
+
+```html
+
+
+
+```
+
+# Emitted Messages
+
+```block
+Formatted 1 file in . Fixed 1 file.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_html/should_lint_a_html_file.snap b/crates/biome_cli/tests/snapshots/main_cases_html/should_lint_a_html_file.snap
new file mode 100644
index 000000000000..5506bda346f4
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_html/should_lint_a_html_file.snap
@@ -0,0 +1,63 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "linter": {
+ "enabled": true
+ }
+ }
+}
+```
+
+## `file.html`
+
+```html
+
+
+```
+
+# Termination Message
+
+```block
+lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.html:1:6 lint/a11y/noHeaderScope FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Avoid using the scope attribute on elements other than th elements.
+
+ > 1 │
+ │ ^^^^^^^^^^^
+ 2 │
+
+ i The scope attribute is used to associate a data cell with its corresponding header cell in a data table,
+ so it should be placed on th elements to provide accessibility to screen readers.
+
+ i Follow the links for more information,
+ WCAG 1.3.1
+ WCAG 4.1.1
+
+ i Unsafe fix: Remove the scope attribute.
+
+ 1 │
+ │ -----------
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_html/should_pull_diagnostics_from_embedded_languages_when_formatting.snap b/crates/biome_cli/tests/snapshots/main_cases_html/should_pull_diagnostics_from_embedded_languages_when_formatting.snap
new file mode 100644
index 000000000000..5ea13670267f
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_html/should_pull_diagnostics_from_embedded_languages_when_formatting.snap
@@ -0,0 +1,79 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ }
+ }
+}
+```
+
+## `file.html`
+
+```html
+
+
+
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.html:1:18 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected a name for the function in a function declaration, but found none
+
+ > 1 │
+ │ ^
+ 2 │
+ 3 │
+
+
+```
+
+```block
+file.html:2:25 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Expected a compound selector but instead found '{'.
+
+ 1 │
+ > 2 │
+ │ ^
+ 3 │
+
+ i Expected a compound selector here.
+
+ 1 │
+ > 2 │
+ │ ^
+ 3 │
+
+
+```
+
+```block
+Formatted 1 file in . Fixed 1 file.
+Found 2 errors.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_html/should_pull_diagnostics_from_embedded_languages_when_linting.snap b/crates/biome_cli/tests/snapshots/main_cases_html/should_pull_diagnostics_from_embedded_languages_when_linting.snap
new file mode 100644
index 000000000000..703234dbf89c
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_html/should_pull_diagnostics_from_embedded_languages_when_linting.snap
@@ -0,0 +1,124 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": {
+ "enabled": true,
+ "indentScriptAndStyle": true
+ },
+ "linter": {
+ "enabled": true
+ }
+ }
+}
+```
+
+## `file.html`
+
+```html
+
+
+
+
+```
+
+# Termination Message
+
+```block
+lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.html:2:16 lint/correctness/noUnusedImports FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! This import is unused.
+
+ 1 │
+ > 2 │
+ │ ^
+ 3 │
+ 4 │
+
+ i Unused imports might be the result of an incomplete refactoring.
+
+ i Unsafe fix: Remove the unused imports.
+
+ 1 │ import·z·from·"zod"
+ │ -------------------
+
+```
+
+```block
+file.html:1:9 lint/suspicious/noDebugger FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × This is an unexpected use of the debugger statement.
+
+ > 1 │
+ │ ^^^^^^^^
+ 2 │
+ 3 │
+
+ i Unsafe fix: Remove debugger statement
+
+ 1 │ debugger
+ │ --------
+
+```
+
+```block
+file.html:2:9 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Illegal use of an import declaration outside of a module
+
+ 1 │
+ > 2 │
+ │ ^^^^^^^^^^^^^^^^^^^
+ 3 │
+ 4 │
+
+ i not allowed inside scripts
+
+
+```
+
+```block
+file.html:3:48 lint/suspicious/noDuplicateProperties ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
+
+ 1 │
+ 2 │
+ > 3 │
+ │ ^^^^^^^^^^^^^^^^
+ 4 │
+
+ i background-color is already defined here.
+
+ 1 │
+ 2 │
+ > 3 │
+ │ ^^^^^^^^^^^^^^^^
+ 4 │
+
+ i Remove or rename the duplicate property to ensure consistent styling.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+Found 1 warning.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_included_files/can_force_ignore_biome_json.snap b/crates/biome_cli/tests/snapshots/main_cases_included_files/can_force_ignore_biome_json.snap
new file mode 100644
index 000000000000..70b2ae077c89
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_included_files/can_force_ignore_biome_json.snap
@@ -0,0 +1,81 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{ "files": { "includes": ["**/*.js", "!!nested/biome.json"] } }
+```
+
+## `nested/biome.json`
+
+```json
+{ "formatter": { "enabled": false } }
+```
+
+## `a.js`
+
+```js
+ statement( )
+```
+
+## `nested/a.js`
+
+```js
+ statement( )
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+a.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - ··statement(··)··
+ 1 │ + statement();
+ 2 │ +
+
+
+```
+
+```block
+biome.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - {·"files":·{·"includes":·["**/*.js",·"!!nested/biome.json"]·}·}
+ 1 │ + {·"files":·{·"includes":·["**/*.js",·"!!nested/biome.json"]·}·}
+ 2 │ +
+
+
+```
+
+```block
+nested/a.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - ··statement(··)··
+ 1 │ + statement();
+ 2 │ +
+
+
+```
+
+```block
+Checked 3 files in . No fixes applied.
+Found 3 errors.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_included_files/does_not_handle_files_inside_force_ignored_folders.snap b/crates/biome_cli/tests/snapshots/main_cases_included_files/does_not_handle_files_inside_force_ignored_folders.snap
new file mode 100644
index 000000000000..9e522f3f8b39
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_included_files/does_not_handle_files_inside_force_ignored_folders.snap
@@ -0,0 +1,28 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{ "files": { "includes": ["*.js", "!!test"] } }
+```
+
+## `a.js`
+
+```js
+statement();
+
+```
+
+## `test/a.js`
+
+```js
+ statement( )
+```
+
+# Emitted Messages
+
+```block
+Formatted 1 file in . Fixed 1 file.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_included_files/does_not_handle_included_files_if_overridden_by_forced_ignore.snap b/crates/biome_cli/tests/snapshots/main_cases_included_files/does_not_handle_included_files_if_overridden_by_forced_ignore.snap
new file mode 100644
index 000000000000..597652a1547e
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_included_files/does_not_handle_included_files_if_overridden_by_forced_ignore.snap
@@ -0,0 +1,28 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{ "files": { "includes": ["*.js", "!!test.js"] } }
+```
+
+## `test.js`
+
+```js
+ statement( )
+```
+
+## `test2.js`
+
+```js
+statement();
+
+```
+
+# Emitted Messages
+
+```block
+Formatted 1 file in . Fixed 1 file.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_included_files/errors_on_ignored_nested_biome_json.snap b/crates/biome_cli/tests/snapshots/main_cases_included_files/errors_on_ignored_nested_biome_json.snap
new file mode 100644
index 000000000000..b39a4bf2321d
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_included_files/errors_on_ignored_nested_biome_json.snap
@@ -0,0 +1,54 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{ "files": { "includes": ["**/*.js", "!nested/biome.json"] } }
+```
+
+## `nested/biome.json`
+
+```json
+{ "formatter": { "enabled": false } }
+```
+
+## `a.js`
+
+```js
+ statement( )
+```
+
+## `nested/a.js`
+
+```js
+ statement( )
+```
+
+# Termination Message
+
+```block
+configuration ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Biome exited because the configuration resulted in errors. Please fix them.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+/errors_on_ignored_nested_biome_json/nested/biome.json configuration ━━━━━━━━━━━━━━━━━━━━
+
+ × Found a nested root configuration, but there's already a root configuration.
+
+ i The other configuration was found in /errors_on_ignored_nested_biome_json.
+
+ i Use the migration command from the root of the project to update the configuration.
+
+ $ biome migrate --write
+
+
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_svelte_by_cli.snap b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_svelte_by_cli.snap
new file mode 100644
index 000000000000..f92b4d450fe3
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_svelte_by_cli.snap
@@ -0,0 +1,19 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.svelte`
+
+```svelte
+
+
+```
+
+# Emitted Messages
+
+```block
+Formatted 1 file in . Fixed 1 file.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_svelte_by_config.snap b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_svelte_by_config.snap
new file mode 100644
index 000000000000..bbbae2a6a19a
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_svelte_by_config.snap
@@ -0,0 +1,31 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": {
+ "indentScriptAndStyle": true
+ }
+ }
+}
+```
+
+## `file.svelte`
+
+```svelte
+
+
+```
+
+# Emitted Messages
+
+```block
+Formatted 2 files in . Fixed 2 files.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_svelte_by_default.snap b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_svelte_by_default.snap
new file mode 100644
index 000000000000..3ebc360bb6cc
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_svelte_by_default.snap
@@ -0,0 +1,19 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.svelte`
+
+```svelte
+
+
+```
+
+# Emitted Messages
+
+```block
+Formatted 1 file in . Fixed 1 file.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_vue_by_cli.snap b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_vue_by_cli.snap
new file mode 100644
index 000000000000..0c1d222592a1
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_vue_by_cli.snap
@@ -0,0 +1,19 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.vue`
+
+```vue
+
+
+```
+
+# Emitted Messages
+
+```block
+Formatted 1 file in . Fixed 1 file.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_vue_by_config.snap b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_vue_by_config.snap
new file mode 100644
index 000000000000..a20fc21d8748
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/indent_vue_by_config.snap
@@ -0,0 +1,31 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "html": {
+ "formatter": {
+ "indentScriptAndStyle": true
+ }
+ }
+}
+```
+
+## `file.vue`
+
+```vue
+
+
+```
+
+# Emitted Messages
+
+```block
+Formatted 2 files in . Fixed 2 files.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/unindent_vue_by_default.snap b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/unindent_vue_by_default.snap
new file mode 100644
index 000000000000..22ec5b9065c4
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_indent_script_and_style/unindent_vue_by_default.snap
@@ -0,0 +1,19 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.vue`
+
+```vue
+
+
+```
+
+# Emitted Messages
+
+```block
+Formatted 1 file in . Fixed 1 file.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_combined_json_parser_flags.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_combined_json_parser_flags.snap
new file mode 100644
index 000000000000..0c7ba8d597c7
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_combined_json_parser_flags.snap
@@ -0,0 +1,47 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.json`
+
+```json
+{
+ // Comment
+ "key": "value",
+}
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 1 │ {
+ 2 │ - ··//·Comment
+ 3 │ - ··"key":·"value",
+ 4 │ - }
+ 2 │ + → //·Comment
+ 3 │ + → "key":·"value"
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_comments_false.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_comments_false.snap
new file mode 100644
index 000000000000..2e4e386049ba
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_comments_false.snap
@@ -0,0 +1,208 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.json`
+
+```json
+{
+ // This is a comment
+ "key": "value"
+}
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json:2:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Expected a property but instead found '// This is a comment'.
+
+ 1 │ {
+ > 2 │ // This is a comment
+ │ ^^^^^^^^^^^^^^^^^^^^
+ 3 │ "key": "value"
+ 4 │ }
+
+ i Expected a property here.
+
+ 1 │ {
+ > 2 │ // This is a comment
+ │ ^^^^^^^^^^^^^^^^^^^^
+ 3 │ "key": "value"
+ 4 │ }
+
+
+```
+
+```block
+file.json:3:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × End of file expected
+
+ 1 │ {
+ 2 │ // This is a comment
+ > 3 │ "key": "value"
+ │ ^^^^^
+ 4 │ }
+
+ i Use an array for a sequence of values: `[1, 2]`
+
+
+```
+
+```block
+file.json:3:8 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × End of file expected
+
+ 1 │ {
+ 2 │ // This is a comment
+ > 3 │ "key": "value"
+ │ ^
+ 4 │ }
+
+ i Use an array for a sequence of values: `[1, 2]`
+
+
+```
+
+```block
+file.json:3:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × End of file expected
+
+ 1 │ {
+ 2 │ // This is a comment
+ > 3 │ "key": "value"
+ │ ^^^^^^^
+ 4 │ }
+
+ i Use an array for a sequence of values: `[1, 2]`
+
+
+```
+
+```block
+file.json:4:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × End of file expected
+
+ 2 │ // This is a comment
+ 3 │ "key": "value"
+ > 4 │ }
+ │ ^
+
+ i Use an array for a sequence of values: `[1, 2]`
+
+
+```
+
+```block
+file.json:2:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Expected a property but instead found '// This is a comment'.
+
+ 1 │ {
+ > 2 │ // This is a comment
+ │ ^^^^^^^^^^^^^^^^^^^^
+ 3 │ "key": "value"
+ 4 │ }
+
+ i Expected a property here.
+
+ 1 │ {
+ > 2 │ // This is a comment
+ │ ^^^^^^^^^^^^^^^^^^^^
+ 3 │ "key": "value"
+ 4 │ }
+
+
+```
+
+```block
+file.json:3:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × End of file expected
+
+ 1 │ {
+ 2 │ // This is a comment
+ > 3 │ "key": "value"
+ │ ^^^^^
+ 4 │ }
+
+ i Use an array for a sequence of values: `[1, 2]`
+
+
+```
+
+```block
+file.json:3:8 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × End of file expected
+
+ 1 │ {
+ 2 │ // This is a comment
+ > 3 │ "key": "value"
+ │ ^
+ 4 │ }
+
+ i Use an array for a sequence of values: `[1, 2]`
+
+
+```
+
+```block
+file.json:3:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × End of file expected
+
+ 1 │ {
+ 2 │ // This is a comment
+ > 3 │ "key": "value"
+ │ ^^^^^^^
+ 4 │ }
+
+ i Use an array for a sequence of values: `[1, 2]`
+
+
+```
+
+```block
+file.json:4:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × End of file expected
+
+ 2 │ // This is a comment
+ 3 │ "key": "value"
+ > 4 │ }
+ │ ^
+
+ i Use an array for a sequence of values: `[1, 2]`
+
+
+```
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Code formatting aborted due to parsing errors. To format code with errors, enable the 'formatter.formatWithErrors' option.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 11 errors.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_comments_true.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_comments_true.snap
new file mode 100644
index 000000000000..99007c97feb2
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_comments_true.snap
@@ -0,0 +1,47 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.json`
+
+```json
+{
+ // This is a comment
+ "key": "value"
+}
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 1 │ {
+ 2 │ - ··//·This·is·a·comment
+ 3 │ - ··"key":·"value"
+ 4 │ - }
+ 2 │ + → //·This·is·a·comment
+ 3 │ + → "key":·"value"
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_trailing_commas_false.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_trailing_commas_false.snap
new file mode 100644
index 000000000000..d0a094d499d2
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_trailing_commas_false.snap
@@ -0,0 +1,77 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.json`
+
+```json
+{
+ "key": "value",
+}
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json:3:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Expected a property but instead found '}'.
+
+ 1 │ {
+ 2 │ "key": "value",
+ > 3 │ }
+ │ ^
+
+ i Expected a property here.
+
+ 1 │ {
+ 2 │ "key": "value",
+ > 3 │ }
+ │ ^
+
+
+```
+
+```block
+file.json:3:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Expected a property but instead found '}'.
+
+ 1 │ {
+ 2 │ "key": "value",
+ > 3 │ }
+ │ ^
+
+ i Expected a property here.
+
+ 1 │ {
+ 2 │ "key": "value",
+ > 3 │ }
+ │ ^
+
+
+```
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Code formatting aborted due to parsing errors. To format code with errors, enable the 'formatter.formatWithErrors' option.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 3 errors.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_trailing_commas_true.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_trailing_commas_true.snap
new file mode 100644
index 000000000000..05bfbdfefa9d
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_allow_trailing_commas_true.snap
@@ -0,0 +1,44 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.json`
+
+```json
+{
+ "key": "value",
+}
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 1 │ {
+ 2 │ - ··"key":·"value",
+ 3 │ - }
+ 2 │ + → "key":·"value"
+ 3 │ + }
+ 4 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_respects_config_allow_comments.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_respects_config_allow_comments.snap
new file mode 100644
index 000000000000..1217c508b358
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_respects_config_allow_comments.snap
@@ -0,0 +1,59 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "json": {
+ "parser": {
+ "allowComments": true
+ }
+ }
+}
+```
+
+## `file.json`
+
+```json
+{
+ // Comment
+ "key": "value"
+}
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 1 │ {
+ 2 │ - ··//·Comment
+ 3 │ - ··"key":·"value"
+ 4 │ - }
+ 2 │ + → //·Comment
+ 3 │ + → "key":·"value"
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_respects_config_allow_trailing_commas.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_respects_config_allow_trailing_commas.snap
new file mode 100644
index 000000000000..f0937ef47c9e
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parse_respects_config_allow_trailing_commas.snap
@@ -0,0 +1,56 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "json": {
+ "parser": {
+ "allowTrailingCommas": true
+ }
+ }
+}
+```
+
+## `file.json`
+
+```json
+{
+ "key": "value",
+}
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 1 │ {
+ 2 │ - ··"key":·"value",
+ 3 │ - }
+ 2 │ + → "key":·"value"
+ 3 │ + }
+ 4 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parser_flags_override_config.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parser_flags_override_config.snap
new file mode 100644
index 000000000000..e75f360426be
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/check_json_parser_flags_override_config.snap
@@ -0,0 +1,59 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "json": {
+ "parser": {
+ "allowComments": false
+ }
+ }
+}
+```
+
+## `file.json`
+
+```json
+{
+ // Comment
+ "key": "value"
+}
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 1 │ {
+ 2 │ - ··//·Comment
+ 3 │ - ··"key":·"value"
+ 4 │ - }
+ 2 │ + → //·Comment
+ 3 │ + → "key":·"value"
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/ci_json_parse_allow_comments_true.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/ci_json_parse_allow_comments_true.snap
new file mode 100644
index 000000000000..e67728786b5c
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/ci_json_parse_allow_comments_true.snap
@@ -0,0 +1,47 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.json`
+
+```json
+{
+ // This is a comment
+ "key": "value"
+}
+```
+
+# Termination Message
+
+```block
+ci ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × File content differs from formatting output
+
+ 1 1 │ {
+ 2 │ - ··//·This·is·a·comment
+ 3 │ - ··"key":·"value"
+ 4 │ - }
+ 2 │ + → //·This·is·a·comment
+ 3 │ + → "key":·"value"
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/format_json_parse_allow_comments_true.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/format_json_parse_allow_comments_true.snap
new file mode 100644
index 000000000000..3610e9a2efc5
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/format_json_parse_allow_comments_true.snap
@@ -0,0 +1,47 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.json`
+
+```json
+{
+ // This is a comment
+ "key": "value"
+}
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 1 │ {
+ 2 │ - ··//·This·is·a·comment
+ 3 │ - ··"key":·"value"
+ 4 │ - }
+ 2 │ + → //·This·is·a·comment
+ 3 │ + → "key":·"value"
+ 4 │ + }
+ 5 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/format_json_parse_allow_trailing_commas_true.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/format_json_parse_allow_trailing_commas_true.snap
new file mode 100644
index 000000000000..cb470f0a6cde
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/format_json_parse_allow_trailing_commas_true.snap
@@ -0,0 +1,44 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.json`
+
+```json
+{
+ "key": "value",
+}
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+file.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 1 │ {
+ 2 │ - ··"key":·"value",
+ 3 │ - }
+ 2 │ + → "key":·"value"
+ 3 │ + }
+ 4 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_json_parsing/lint_json_parse_allow_comments_true.snap b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/lint_json_parse_allow_comments_true.snap
new file mode 100644
index 000000000000..76d29946b13c
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_json_parsing/lint_json_parse_allow_comments_true.snap
@@ -0,0 +1,18 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `file.json`
+
+```json
+{
+ // This is a comment
+ "key": "value"
+}
+```
+
+# Emitted Messages
+
+```block
+Checked 1 file in . No fixes applied.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_linter_domains/should_disable_domain_via_cli.snap b/crates/biome_cli/tests/snapshots/main_cases_linter_domains/should_disable_domain_via_cli.snap
new file mode 100644
index 000000000000..4f07f34d06b7
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_linter_domains/should_disable_domain_via_cli.snap
@@ -0,0 +1,30 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `test1.js`
+
+```js
+describe.only("bar", () => {});
+
+```
+
+## `test2.js`
+
+```js
+
+describe("foo", () => {
+ beforeEach(() => {});
+ beforeEach(() => {});
+ test("bar", () => {
+ someFn();
+ });
+});
+
+```
+
+# Emitted Messages
+
+```block
+Checked 2 files in . No fixes applied.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_linter_domains/should_enable_domain_via_cli.snap b/crates/biome_cli/tests/snapshots/main_cases_linter_domains/should_enable_domain_via_cli.snap
new file mode 100644
index 000000000000..35ecee406dce
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_linter_domains/should_enable_domain_via_cli.snap
@@ -0,0 +1,95 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "linter": {
+ "rules": {
+ "recommended": false
+ },
+ "domains": {
+ "test": "all"
+ }
+ }
+}
+```
+
+## `test1.js`
+
+```js
+describe.only("bar", () => {});
+
+```
+
+## `test2.js`
+
+```js
+
+describe("foo", () => {
+ beforeEach(() => {});
+ beforeEach(() => {});
+ test("bar", () => {
+ someFn();
+ });
+});
+
+```
+
+# Termination Message
+
+```block
+lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+test1.js:1:10 lint/suspicious/noFocusedTests FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ ! Don't focus the test.
+
+ > 1 │ describe.only("bar", () => {});
+ │ ^^^^
+ 2 │
+
+ i The 'only' method is often used for debugging or during implementation.
+
+ i Consider removing 'only' to ensure all tests are executed.
+
+ i Unsafe fix: Remove focus from test.
+
+ 1 │ describe.only("bar",·()·=>·{});
+ │ -----
+
+```
+
+```block
+test2.js:4:5 lint/suspicious/noDuplicateTestHooks ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × The test hook beforeEach is used multiple times in the same test block.
+
+ 2 │ describe("foo", () => {
+ 3 │ beforeEach(() => {});
+ > 4 │ beforeEach(() => {});
+ │ ^^^^^^^^^^^^^^^^^^^^
+ 5 │ test("bar", () => {
+ 6 │ someFn();
+
+ i The presence of the same hook more than once in the same test block can create unexpected errors inside tests. Remove one of them.
+
+
+```
+
+```block
+Checked 2 files in . No fixes applied.
+Found 1 error.
+Found 1 warning.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_check_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_check_command.snap
new file mode 100644
index 000000000000..c54003c2b98b
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_check_command.snap
@@ -0,0 +1,79 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `index.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+## `main.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_ci_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_ci_command.snap
new file mode 100644
index 000000000000..8bb30bc09340
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_ci_command.snap
@@ -0,0 +1,79 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `index.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+## `main.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+# Termination Message
+
+```block
+ci ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_format_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_format_command.snap
new file mode 100644
index 000000000000..da430cd97cca
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_format_command.snap
@@ -0,0 +1,57 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `index.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+## `main.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+
+
+
+
+
+
+
+
+
+
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_lint_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_lint_command.snap
new file mode 100644
index 000000000000..0afea3f2b7ca
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_checkstyle/reports_diagnostics_checkstyle_lint_command.snap
@@ -0,0 +1,75 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `index.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+## `main.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+# Termination Message
+
+```block
+lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_check_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_check_command.snap
index 71bf4ba399d8..032483e606ca 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_check_command.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_check_command.snap
@@ -48,112 +48,112 @@ check ━━━━━━━━━━━━━━━━━━━━━━━━
- line 0, col 7, This import is unused.
+ line 1, col 8, This import is unused.
- line 1, col 9, Several of these imports are unused.
+ line 2, col 10, Several of these imports are unused.
- line 7, col 4, This variable f is unused.
+ line 8, col 5, This variable f is unused.
- line 8, col 6, This variable f is unused.
+ line 9, col 7, This variable f is unused.
- line 0, col 7, This import is unused.
+ line 1, col 8, This import is unused.
- line 1, col 9, Several of these imports are unused.
+ line 2, col 10, Several of these imports are unused.
- line 7, col 4, This variable f is unused.
+ line 8, col 5, This variable f is unused.
- line 8, col 6, This variable f is unused.
+ line 9, col 7, This variable f is unused.
- line 0, col 0, The imports and exports are not sorted.
+ line 1, col 1, The imports and exports are not sorted.
- line 3, col 2, Using == may be unsafe if you are relying on type coercion.
+ line 4, col 3, Using == may be unsafe if you are relying on type coercion.
- line 5, col 0, This is an unexpected use of the debugger statement.
+ line 6, col 1, This is an unexpected use of the debugger statement.
- line 7, col 4, This variable implicitly has the any type.
+ line 8, col 5, This variable implicitly has the any type.
- line 8, col 6, This variable implicitly has the any type.
+ line 9, col 7, This variable implicitly has the any type.
- line 1, col 9, Shouldn't redeclare 'z'. Consider to delete it or rename it.
+ line 2, col 10, Shouldn't redeclare 'z'. Consider to delete it or rename it.
- line 8, col 6, Shouldn't redeclare 'f'. Consider to delete it or rename it.
+ line 9, col 7, Shouldn't redeclare 'f'. Consider to delete it or rename it.
- line 0, col 0, The imports and exports are not sorted.
+ line 1, col 1, The imports and exports are not sorted.
- line 3, col 2, Using == may be unsafe if you are relying on type coercion.
+ line 4, col 3, Using == may be unsafe if you are relying on type coercion.
- line 5, col 0, This is an unexpected use of the debugger statement.
+ line 6, col 1, This is an unexpected use of the debugger statement.
- line 7, col 4, This variable implicitly has the any type.
+ line 8, col 5, This variable implicitly has the any type.
- line 8, col 6, This variable implicitly has the any type.
+ line 9, col 7, This variable implicitly has the any type.
- line 1, col 9, Shouldn't redeclare 'z'. Consider to delete it or rename it.
+ line 2, col 10, Shouldn't redeclare 'z'. Consider to delete it or rename it.
- line 8, col 6, Shouldn't redeclare 'f'. Consider to delete it or rename it.
+ line 9, col 7, Shouldn't redeclare 'f'. Consider to delete it or rename it.
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_ci_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_ci_command.snap
index 4d045861c664..4d0ce7d234a5 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_ci_command.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_ci_command.snap
@@ -48,112 +48,112 @@ ci ━━━━━━━━━━━━━━━━━━━━━━━━━
- line 0, col 7, This import is unused.
+ line 1, col 8, This import is unused.
- line 1, col 9, Several of these imports are unused.
+ line 2, col 10, Several of these imports are unused.
- line 7, col 4, This variable f is unused.
+ line 8, col 5, This variable f is unused.
- line 8, col 6, This variable f is unused.
+ line 9, col 7, This variable f is unused.
- line 0, col 7, This import is unused.
+ line 1, col 8, This import is unused.
- line 1, col 9, Several of these imports are unused.
+ line 2, col 10, Several of these imports are unused.
- line 7, col 4, This variable f is unused.
+ line 8, col 5, This variable f is unused.
- line 8, col 6, This variable f is unused.
+ line 9, col 7, This variable f is unused.
- line 0, col 0, The imports and exports are not sorted.
+ line 1, col 1, The imports and exports are not sorted.
- line 3, col 2, Using == may be unsafe if you are relying on type coercion.
+ line 4, col 3, Using == may be unsafe if you are relying on type coercion.
- line 5, col 0, This is an unexpected use of the debugger statement.
+ line 6, col 1, This is an unexpected use of the debugger statement.
- line 7, col 4, This variable implicitly has the any type.
+ line 8, col 5, This variable implicitly has the any type.
- line 8, col 6, This variable implicitly has the any type.
+ line 9, col 7, This variable implicitly has the any type.
- line 1, col 9, Shouldn't redeclare 'z'. Consider to delete it or rename it.
+ line 2, col 10, Shouldn't redeclare 'z'. Consider to delete it or rename it.
- line 8, col 6, Shouldn't redeclare 'f'. Consider to delete it or rename it.
+ line 9, col 7, Shouldn't redeclare 'f'. Consider to delete it or rename it.
- line 0, col 0, The imports and exports are not sorted.
+ line 1, col 1, The imports and exports are not sorted.
- line 3, col 2, Using == may be unsafe if you are relying on type coercion.
+ line 4, col 3, Using == may be unsafe if you are relying on type coercion.
- line 5, col 0, This is an unexpected use of the debugger statement.
+ line 6, col 1, This is an unexpected use of the debugger statement.
- line 7, col 4, This variable implicitly has the any type.
+ line 8, col 5, This variable implicitly has the any type.
- line 8, col 6, This variable implicitly has the any type.
+ line 9, col 7, This variable implicitly has the any type.
- line 1, col 9, Shouldn't redeclare 'z'. Consider to delete it or rename it.
+ line 2, col 10, Shouldn't redeclare 'z'. Consider to delete it or rename it.
- line 8, col 6, Shouldn't redeclare 'f'. Consider to delete it or rename it.
+ line 9, col 7, Shouldn't redeclare 'f'. Consider to delete it or rename it.
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_lint_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_lint_command.snap
index 1f68608af584..64cee2656ef9 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_lint_command.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_junit/reports_diagnostics_junit_lint_command.snap
@@ -48,102 +48,102 @@ lint ━━━━━━━━━━━━━━━━━━━━━━━━━
- line 0, col 7, This import is unused.
+ line 1, col 8, This import is unused.
- line 1, col 9, Several of these imports are unused.
+ line 2, col 10, Several of these imports are unused.
- line 7, col 4, This variable f is unused.
+ line 8, col 5, This variable f is unused.
- line 8, col 6, This variable f is unused.
+ line 9, col 7, This variable f is unused.
- line 0, col 7, This import is unused.
+ line 1, col 8, This import is unused.
- line 1, col 9, Several of these imports are unused.
+ line 2, col 10, Several of these imports are unused.
- line 7, col 4, This variable f is unused.
+ line 8, col 5, This variable f is unused.
- line 8, col 6, This variable f is unused.
+ line 9, col 7, This variable f is unused.
- line 3, col 2, Using == may be unsafe if you are relying on type coercion.
+ line 4, col 3, Using == may be unsafe if you are relying on type coercion.
- line 5, col 0, This is an unexpected use of the debugger statement.
+ line 6, col 1, This is an unexpected use of the debugger statement.
- line 7, col 4, This variable implicitly has the any type.
+ line 8, col 5, This variable implicitly has the any type.
- line 8, col 6, This variable implicitly has the any type.
+ line 9, col 7, This variable implicitly has the any type.
- line 1, col 9, Shouldn't redeclare 'z'. Consider to delete it or rename it.
+ line 2, col 10, Shouldn't redeclare 'z'. Consider to delete it or rename it.
- line 8, col 6, Shouldn't redeclare 'f'. Consider to delete it or rename it.
+ line 9, col 7, Shouldn't redeclare 'f'. Consider to delete it or rename it.
- line 3, col 2, Using == may be unsafe if you are relying on type coercion.
+ line 4, col 3, Using == may be unsafe if you are relying on type coercion.
- line 5, col 0, This is an unexpected use of the debugger statement.
+ line 6, col 1, This is an unexpected use of the debugger statement.
- line 7, col 4, This variable implicitly has the any type.
+ line 8, col 5, This variable implicitly has the any type.
- line 8, col 6, This variable implicitly has the any type.
+ line 9, col 7, This variable implicitly has the any type.
- line 1, col 9, Shouldn't redeclare 'z'. Consider to delete it or rename it.
+ line 2, col 10, Shouldn't redeclare 'z'. Consider to delete it or rename it.
- line 8, col 6, Shouldn't redeclare 'f'. Consider to delete it or rename it.
+ line 9, col 7, Shouldn't redeclare 'f'. Consider to delete it or rename it.
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_check_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_check_command.snap
new file mode 100644
index 000000000000..1d5dea980434
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_check_command.snap
@@ -0,0 +1,567 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `index.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+## `main.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+{
+ "source": {
+ "name": "Biome",
+ "url": "https://biomejs.dev"
+ },
+ "diagnostics": [
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 12,
+ "line": 1
+ },
+ "start": {
+ "column": 8,
+ "line": 1
+ }
+ }
+ },
+ "message": "This import is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Several of these imports are unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 12,
+ "line": 1
+ },
+ "start": {
+ "column": 8,
+ "line": 1
+ }
+ }
+ },
+ "message": "This import is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Several of these imports are unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/assist/actions/organize-imports",
+ "value": "assist/source/organizeImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 21,
+ "line": 1
+ },
+ "start": {
+ "column": 1,
+ "line": 1
+ }
+ }
+ },
+ "message": "The imports and exports are not sorted."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-double-equals",
+ "value": "lint/suspicious/noDoubleEquals"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 5,
+ "line": 4
+ },
+ "start": {
+ "column": 3,
+ "line": 4
+ }
+ }
+ },
+ "message": "Using == may be unsafe if you are relying on type coercion."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-debugger",
+ "value": "lint/suspicious/noDebugger"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 9,
+ "line": 6
+ },
+ "start": {
+ "column": 1,
+ "line": 6
+ }
+ }
+ },
+ "message": "This is an unexpected use of the debugger statement."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'z'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 1
+ },
+ "start": {
+ "column": 10,
+ "line": 1
+ }
+ },
+ "text": "'z' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'f'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ },
+ "text": "'f' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "value": "format"
+ },
+ "message": "Formatter would have printed the following content:"
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/assist/actions/organize-imports",
+ "value": "assist/source/organizeImports"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 21,
+ "line": 1
+ },
+ "start": {
+ "column": 1,
+ "line": 1
+ }
+ }
+ },
+ "message": "The imports and exports are not sorted."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-double-equals",
+ "value": "lint/suspicious/noDoubleEquals"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 5,
+ "line": 4
+ },
+ "start": {
+ "column": 3,
+ "line": 4
+ }
+ }
+ },
+ "message": "Using == may be unsafe if you are relying on type coercion."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-debugger",
+ "value": "lint/suspicious/noDebugger"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 9,
+ "line": 6
+ },
+ "start": {
+ "column": 1,
+ "line": 6
+ }
+ }
+ },
+ "message": "This is an unexpected use of the debugger statement."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'z'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 1
+ },
+ "start": {
+ "column": 10,
+ "line": 1
+ }
+ },
+ "text": "'z' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'f'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ },
+ "text": "'f' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "value": "format"
+ },
+ "message": "Formatter would have printed the following content:"
+ }
+ ]
+}
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_ci_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_ci_command.snap
new file mode 100644
index 000000000000..76260abd86cd
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_ci_command.snap
@@ -0,0 +1,567 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `index.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+## `main.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+# Termination Message
+
+```block
+ci ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+{
+ "source": {
+ "name": "Biome",
+ "url": "https://biomejs.dev"
+ },
+ "diagnostics": [
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 12,
+ "line": 1
+ },
+ "start": {
+ "column": 8,
+ "line": 1
+ }
+ }
+ },
+ "message": "This import is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Several of these imports are unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 12,
+ "line": 1
+ },
+ "start": {
+ "column": 8,
+ "line": 1
+ }
+ }
+ },
+ "message": "This import is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Several of these imports are unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/assist/actions/organize-imports",
+ "value": "assist/source/organizeImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 21,
+ "line": 1
+ },
+ "start": {
+ "column": 1,
+ "line": 1
+ }
+ }
+ },
+ "message": "The imports and exports are not sorted."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-double-equals",
+ "value": "lint/suspicious/noDoubleEquals"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 5,
+ "line": 4
+ },
+ "start": {
+ "column": 3,
+ "line": 4
+ }
+ }
+ },
+ "message": "Using == may be unsafe if you are relying on type coercion."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-debugger",
+ "value": "lint/suspicious/noDebugger"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 9,
+ "line": 6
+ },
+ "start": {
+ "column": 1,
+ "line": 6
+ }
+ }
+ },
+ "message": "This is an unexpected use of the debugger statement."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'z'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 1
+ },
+ "start": {
+ "column": 10,
+ "line": 1
+ }
+ },
+ "text": "'z' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'f'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ },
+ "text": "'f' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "value": "format"
+ },
+ "message": "File content differs from formatting output"
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/assist/actions/organize-imports",
+ "value": "assist/source/organizeImports"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 21,
+ "line": 1
+ },
+ "start": {
+ "column": 1,
+ "line": 1
+ }
+ }
+ },
+ "message": "The imports and exports are not sorted."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-double-equals",
+ "value": "lint/suspicious/noDoubleEquals"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 5,
+ "line": 4
+ },
+ "start": {
+ "column": 3,
+ "line": 4
+ }
+ }
+ },
+ "message": "Using == may be unsafe if you are relying on type coercion."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-debugger",
+ "value": "lint/suspicious/noDebugger"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 9,
+ "line": 6
+ },
+ "start": {
+ "column": 1,
+ "line": 6
+ }
+ }
+ },
+ "message": "This is an unexpected use of the debugger statement."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'z'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 1
+ },
+ "start": {
+ "column": 10,
+ "line": 1
+ }
+ },
+ "text": "'z' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'f'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ },
+ "text": "'f' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "value": "format"
+ },
+ "message": "File content differs from formatting output"
+ }
+ ]
+}
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_format_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_format_command.snap
new file mode 100644
index 000000000000..a9cd97d40c4c
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_format_command.snap
@@ -0,0 +1,67 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `index.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+## `main.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+{
+ "source": {
+ "name": "Biome",
+ "url": "https://biomejs.dev"
+ },
+ "diagnostics": [
+ {
+ "code": {
+ "value": "format"
+ },
+ "message": "Formatter would have printed the following content:"
+ },
+ {
+ "code": {
+ "value": "format"
+ },
+ "message": "Formatter would have printed the following content:"
+ }
+ ]
+}
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_lint_command.snap b/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_lint_command.snap
new file mode 100644
index 000000000000..5ee56beb8a0f
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_reporter_rdjson/reports_diagnostics_rdjson_lint_command.snap
@@ -0,0 +1,515 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `index.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+## `main.ts`
+
+```ts
+import { z} from "z"
+import { z, b , a} from "lodash"
+
+a ==b
+
+debugger
+
+let f;
+ let f;
+```
+
+# Termination Message
+
+```block
+lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+{
+ "source": {
+ "name": "Biome",
+ "url": "https://biomejs.dev"
+ },
+ "diagnostics": [
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 12,
+ "line": 1
+ },
+ "start": {
+ "column": 8,
+ "line": 1
+ }
+ }
+ },
+ "message": "This import is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Several of these imports are unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 12,
+ "line": 1
+ },
+ "start": {
+ "column": 8,
+ "line": 1
+ }
+ }
+ },
+ "message": "This import is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-imports",
+ "value": "lint/correctness/noUnusedImports"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Several of these imports are unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-unused-variables",
+ "value": "lint/correctness/noUnusedVariables"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable f is unused."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-double-equals",
+ "value": "lint/suspicious/noDoubleEquals"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 5,
+ "line": 4
+ },
+ "start": {
+ "column": 3,
+ "line": 4
+ }
+ }
+ },
+ "message": "Using == may be unsafe if you are relying on type coercion."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-debugger",
+ "value": "lint/suspicious/noDebugger"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 9,
+ "line": 6
+ },
+ "start": {
+ "column": 1,
+ "line": 6
+ }
+ }
+ },
+ "message": "This is an unexpected use of the debugger statement."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'z'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 1
+ },
+ "start": {
+ "column": 10,
+ "line": 1
+ }
+ },
+ "text": "'z' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "index.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'f'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ },
+ "text": "'f' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-double-equals",
+ "value": "lint/suspicious/noDoubleEquals"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 5,
+ "line": 4
+ },
+ "start": {
+ "column": 3,
+ "line": 4
+ }
+ }
+ },
+ "message": "Using == may be unsafe if you are relying on type coercion."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-debugger",
+ "value": "lint/suspicious/noDebugger"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 9,
+ "line": 6
+ },
+ "start": {
+ "column": 1,
+ "line": 6
+ }
+ }
+ },
+ "message": "This is an unexpected use of the debugger statement."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-implicit-any-let",
+ "value": "lint/suspicious/noImplicitAnyLet"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "This variable implicitly has the any type."
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 2
+ },
+ "start": {
+ "column": 10,
+ "line": 2
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'z'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 11,
+ "line": 1
+ },
+ "start": {
+ "column": 10,
+ "line": 1
+ }
+ },
+ "text": "'z' is defined here:"
+ }
+ ]
+ },
+ {
+ "code": {
+ "url": "https://biomejs.dev/linter/rules/no-redeclare",
+ "value": "lint/suspicious/noRedeclare"
+ },
+ "location": {
+ "path": "main.ts",
+ "range": {
+ "end": {
+ "column": 8,
+ "line": 9
+ },
+ "start": {
+ "column": 7,
+ "line": 9
+ }
+ }
+ },
+ "message": "Shouldn't redeclare 'f'. Consider to delete it or rename it.",
+ "suggestions": [
+ {
+ "range": {
+ "end": {
+ "column": 6,
+ "line": 8
+ },
+ "start": {
+ "column": 5,
+ "line": 8
+ }
+ },
+ "text": "'f' is defined here:"
+ }
+ ]
+ }
+ ]
+}
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_tailwind_directives/should_not_parse_tailwind_directive_when_disabled.snap b/crates/biome_cli/tests/snapshots/main_cases_tailwind_directives/should_not_parse_tailwind_directive_when_disabled.snap
new file mode 100644
index 000000000000..338076f2ffe3
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_tailwind_directives/should_not_parse_tailwind_directive_when_disabled.snap
@@ -0,0 +1,69 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "formatter": {
+ "enabled": true
+ },
+ "css": {
+ "parser": {
+ "tailwindDirectives": false
+ }
+ }
+}
+```
+
+## `input.css`
+
+```css
+@theme {}
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × No files were processed in the specified paths.
+
+ i Check your biome.json or biome.jsonc to ensure the paths are not ignored by the configuration.
+
+ i These paths were provided but ignored:
+
+ - input.css
+
+
+
+```
+
+# Emitted Messages
+
+```block
+input.css:1:2 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Tailwind-specific syntax is disabled.
+
+ > 1 │ @theme {}
+ │ ^^^^^^^^
+
+ i Enable `tailwindDirectives` in the css parser options, or remove this if you are not using Tailwind CSS.
+
+
+```
+
+```block
+input.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Code formatting aborted due to parsing errors. To format code with errors, enable the 'formatter.formatWithErrors' option.
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_tailwind_directives/should_parse_tailwind_directive.snap b/crates/biome_cli/tests/snapshots/main_cases_tailwind_directives/should_parse_tailwind_directive.snap
new file mode 100644
index 000000000000..70425257e883
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_tailwind_directives/should_parse_tailwind_directive.snap
@@ -0,0 +1,55 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "formatter": {
+ "enabled": true
+ },
+ "css": {
+ "parser": {
+ "tailwindDirectives": true
+ }
+ }
+}
+```
+
+## `input.css`
+
+```css
+@theme {}
+```
+
+# Termination Message
+
+```block
+format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while running checks.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+input.css format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Formatter would have printed the following content:
+
+ 1 │ - @theme·{}
+ 1 │ + @theme·{
+ 2 │ + }
+ 3 │ +
+
+
+```
+
+```block
+Checked 1 file in . No fixes applied.
+Found 1 error.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_tailwind_directives/tw_should_not_show_unknown_at_rule_diagnostic.snap b/crates/biome_cli/tests/snapshots/main_cases_tailwind_directives/tw_should_not_show_unknown_at_rule_diagnostic.snap
new file mode 100644
index 000000000000..e44c8615c7be
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_cases_tailwind_directives/tw_should_not_show_unknown_at_rule_diagnostic.snap
@@ -0,0 +1,36 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `biome.json`
+
+```json
+{
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": false,
+ "suspicious": {
+ "noUnknownAtRules": "warn"
+ }
+ }
+ },
+ "css": {
+ "parser": {
+ "tailwindDirectives": true
+ }
+ }
+}
+```
+
+## `input.css`
+
+```css
+@theme {}
+```
+
+# Emitted Messages
+
+```block
+Checked 1 file in . No fixes applied.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_cases_vcs_ignored_files/ignore_vcs_ignored_file_via_cli.snap b/crates/biome_cli/tests/snapshots/main_cases_vcs_ignored_files/ignore_vcs_ignored_file_via_cli.snap
index bcd80017e9ba..ad3c9de73031 100644
--- a/crates/biome_cli/tests/snapshots/main_cases_vcs_ignored_files/ignore_vcs_ignored_file_via_cli.snap
+++ b/crates/biome_cli/tests/snapshots/main_cases_vcs_ignored_files/ignore_vcs_ignored_file_via_cli.snap
@@ -42,4 +42,5 @@ file1.js:1:1 lint/complexity/useFlatMap FIXABLE ━━━━━━━━━━
```block
Checked 1 file in . No fixes applied.
+Found 1 info.
```
diff --git a/crates/biome_cli/tests/snapshots/main_commands_check/check_format_with_syntax_errors_when_flag_enabled.snap b/crates/biome_cli/tests/snapshots/main_commands_check/check_format_with_syntax_errors_when_flag_enabled.snap
new file mode 100644
index 000000000000..eec4334f47a1
--- /dev/null
+++ b/crates/biome_cli/tests/snapshots/main_commands_check/check_format_with_syntax_errors_when_flag_enabled.snap
@@ -0,0 +1,54 @@
+---
+source: crates/biome_cli/tests/snap_test.rs
+expression: redactor(content)
+---
+## `invalid.js`
+
+```js
+while ) {}
+
+```
+
+# Termination Message
+
+```block
+check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × Some errors were emitted while applying fixes.
+
+
+
+```
+
+# Emitted Messages
+
+```block
+invalid.js:1:7 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `(` but instead found `)`
+
+ > 1 │ while ) {}
+ │ ^
+
+ i Remove )
+
+
+```
+
+```block
+invalid.js:1:7 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ × expected `(` but instead found `)`
+
+ > 1 │ while ) {}
+ │ ^
+
+ i Remove )
+
+
+```
+
+```block
+Checked 1 file in . Fixed 1 file.
+Found 2 errors.
+```
diff --git a/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap b/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap
index 3b0f5b5fba21..bb0130f2958e 100644
--- a/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap
+++ b/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap
@@ -8,7 +8,12 @@ expression: redactor(content)
Runs formatter, linter and import sorting to the requested files.
Usage: check [--write] [--unsafe] [--assist-enabled=] [--enforce-assist=] [
---staged] [--changed] [--since=REF] [PATH]...
+--format-with-errors=] [--staged] [--changed] [--since=REF] [PATH]...
+
+Options that changes how the JSON parser behaves
+ --json-parse-allow-comments= Allow parsing comments in `.json` files
+ --json-parse-allow-trailing-commas= Allow parsing trailing commas in `.json`
+ files
The configuration that is contained inside the file `biome.json`
--vcs-enabled= Whether Biome should integrate itself with the VCS client
@@ -27,9 +32,11 @@ The configuration that is contained inside the file `biome.json`
1 MiB
--files-ignore-unknown= Tells Biome to not emit diagnostics when handling files
that it doesn't know
+ --format-with-errors= Whether formatting should be allowed to proceed if a
+ given file has syntax errors
--indent-style= The indent style.
--indent-width=NUMBER The size of the indentation, 2 by default
- --line-ending= The type of line ending.
+ --line-ending= The type of line ending.
--line-width=NUMBER What's the max width of a line. Defaults to 80.
--attribute-position= The attribute position style in HTML-ish languages.
Defaults to auto.
@@ -71,8 +78,9 @@ The configuration that is contained inside the file `biome.json`
its super languages) files.
--javascript-formatter-indent-width=NUMBER The size of the indentation applied to
JavaScript (and its super languages) files. Default to 2.
- --javascript-formatter-line-ending= The type of line ending applied to
- JavaScript (and its super languages) files.
+ --javascript-formatter-line-ending= The type of line ending applied to
+ JavaScript (and its super languages) files. `auto` uses CRLF on
+ Windows and LF on other platforms.
--javascript-formatter-line-width=NUMBER What's the max width of a line applied to
JavaScript (and its super languages) files. Defaults to 80.
--javascript-formatter-quote-style= The type of quotes used in JavaScript
@@ -97,14 +105,18 @@ The configuration that is contained inside the file `biome.json`
languages) files.
--javascript-assist-enabled= Control the assist for JavaScript (and its super
languages) files.
+ --json-parse-allow-comments= Allow parsing comments in `.json` files
+ --json-parse-allow-trailing-commas= Allow parsing trailing commas in `.json`
+ files
--json-formatter-enabled= Control the formatter for JSON (and its super
languages) files.
--json-formatter-indent-style= The indent style applied to JSON (and its super
languages) files.
--json-formatter-indent-width=NUMBER The size of the indentation applied to JSON (and its
super languages) files. Default to 2.
- --json-formatter-line-ending= The type of line ending applied to JSON (and its
- super languages) files.
+ --json-formatter-line-ending= The type of line ending applied to JSON (and
+ its super languages) files. `auto` uses CRLF on Windows and LF on
+ other platforms.
--json-formatter-line-width=NUMBER What's the max width of a line applied to JSON (and its
super languages) files. Defaults to 80.
--json-formatter-trailing-commas= Print trailing commas wherever possible in
@@ -124,14 +136,18 @@ The configuration that is contained inside the file `biome.json`
files.
--json-assist-enabled= Control the assist for JSON (and its super languages)
files.
+ --css-parse-css-modules= Enables parsing of CSS Modules specific features.
+ --css-parse-tailwind-directives= Enables parsing of Tailwind CSS 4.0 directives
+ and functions.
--css-formatter-enabled= Control the formatter for CSS (and its super
languages) files.
--css-formatter-indent-style= The indent style applied to CSS (and its super
languages) files.
--css-formatter-indent-width=NUMBER The size of the indentation applied to CSS (and its
super languages) files. Default to 2.
- --css-formatter-line-ending= The type of line ending applied to CSS (and its
- super languages) files.
+ --css-formatter-line-ending= The type of line ending applied to CSS (and
+ its super languages) files. `auto` uses CRLF on Windows and LF on
+ other platforms.
--css-formatter-line-width=NUMBER What's the max width of a line applied to CSS (and its
super languages) files. Defaults to 80.
--css-formatter-quote-style= The type of quotes used in CSS code. Defaults
@@ -142,8 +158,8 @@ The configuration that is contained inside the file `biome.json`
--graphql-formatter-indent-style= The indent style applied to GraphQL files.
--graphql-formatter-indent-width=NUMBER The size of the indentation applied to GraphQL
files. Default to 2.
- --graphql-formatter-line-ending= The type of line ending applied to GraphQL
- files.
+ --graphql-formatter-line-ending= The type of line ending applied to
+ GraphQL files. `auto` uses CRLF on Windows and LF on other platforms.
--graphql-formatter-line-width=NUMBER What's the max width of a line applied to GraphQL
files. Defaults to 80.
--graphql-formatter-quote-style= The type of quotes used in GraphQL code.
@@ -165,8 +181,9 @@ The configuration that is contained inside the file `biome.json`
languages) files.
--html-formatter-indent-width=NUMBER The size of the indentation applied to HTML (and its
super languages) files. Default to 2.
- --html-formatter-line-ending= The type of line ending applied to HTML (and its
- super languages) files.
+ --html-formatter-line-ending= The type of line ending applied to HTML (and
+ its super languages) files. `auto` uses CRLF on Windows and LF on
+ other platforms.
--html-formatter-line-width=NUMBER What's the max width of a line applied to HTML (and its
super languages) files. Defaults to 80.
--html-formatter-attribute-position= The attribute position style in HTML
@@ -181,6 +198,10 @@ The configuration that is contained inside the file `biome.json`
`
```
+
+
+## Unimplemented nodes/tokens
+
+"\nbody {\n background-color: seagreen;\n}\n" => 7..47
## Output 1
-----
@@ -60,3 +65,9 @@ body {
}
```
+
+
+
+## Unimplemented nodes/tokens
+
+"\nbody {\n background-color: seagreen;\n}\n" => 7..47
diff --git a/crates/biome_html_parser/src/lib.rs b/crates/biome_html_parser/src/lib.rs
index e1fc03939328..e7bc87796c4b 100644
--- a/crates/biome_html_parser/src/lib.rs
+++ b/crates/biome_html_parser/src/lib.rs
@@ -10,8 +10,8 @@ pub use parser::HtmlParseOptions;
use crate::parser::{HtmlLosslessTreeSink, HtmlParser};
use crate::syntax::parse_root;
use biome_html_syntax::{HtmlRoot, HtmlSyntaxNode};
-use biome_parser::AnyParse;
use biome_parser::diagnostic::ParseDiagnostic;
+use biome_parser::{AnyParse, NodeParse};
use biome_rowan::{AstNode, NodeCache};
/// Parses the provided string as HTML program using the provided node cache.
@@ -105,10 +105,11 @@ impl From for AnyParse {
fn from(parse: HtmlParse) -> Self {
let root = parse.syntax();
let diagnostics = parse.into_diagnostics();
- Self::new(
+ NodeParse::new(
// SAFETY: the parser should always return a root node
root.as_send().unwrap(),
diagnostics,
)
+ .into()
}
}
diff --git a/crates/biome_html_parser/src/parser.rs b/crates/biome_html_parser/src/parser.rs
index e6b9ad3548be..66261d3154b6 100644
--- a/crates/biome_html_parser/src/parser.rs
+++ b/crates/biome_html_parser/src/parser.rs
@@ -117,6 +117,18 @@ impl HtmlParseOptions {
self.frontmatter = true;
self
}
+
+ /// Toggle parsing of double-quoted text expressions.
+ ///
+ /// When `value` is `true`, enables [`TextExpressionKind::Double`].
+ /// When `false`, disables text expressions entirely (`None`).
+ /// Use [`HtmlParseOptions::with_single_text_expression`] to enable single-quoted mode.
+ pub fn set_double_text_expression(&mut self, value: bool) {
+ match value {
+ true => self.text_expression = Some(TextExpressionKind::Double),
+ false => self.text_expression = None,
+ }
+ }
}
impl From<&HtmlFileSource> for HtmlParseOptions {
diff --git a/crates/biome_html_parser/src/syntax/astro.rs b/crates/biome_html_parser/src/syntax/astro.rs
index b6a5809a49e9..26673a0818ab 100644
--- a/crates/biome_html_parser/src/syntax/astro.rs
+++ b/crates/biome_html_parser/src/syntax/astro.rs
@@ -1,7 +1,9 @@
use crate::parser::HtmlParser;
use crate::syntax::parse_error::expected_closed_fence;
use crate::token_source::HtmlLexContext;
-use biome_html_syntax::HtmlSyntaxKind::{ASTRO_FRONTMATTER_ELEMENT, FENCE, HTML_LITERAL};
+use biome_html_syntax::HtmlSyntaxKind::{
+ ASTRO_EMBEDDED_CONTENT, ASTRO_FRONTMATTER_ELEMENT, FENCE, HTML_LITERAL,
+};
use biome_html_syntax::T;
use biome_parser::Parser;
use biome_parser::prelude::ParsedSyntax;
@@ -18,11 +20,19 @@ pub(crate) fn parse_astro_fence(p: &mut HtmlParser) -> ParsedSyntax {
let c = m.complete(p, ASTRO_FRONTMATTER_ELEMENT);
return ParsedSyntax::Present(c);
}
- if p.at(HTML_LITERAL) {
- p.bump_with_context(HTML_LITERAL, HtmlLexContext::AstroFencedCodeBlock);
- }
+ parse_astro_embedded(p).ok();
p.expect(T![---]);
let c = m.complete(p, ASTRO_FRONTMATTER_ELEMENT);
ParsedSyntax::Present(c)
}
+
+pub(crate) fn parse_astro_embedded(p: &mut HtmlParser) -> ParsedSyntax {
+ if !p.at(HTML_LITERAL) {
+ return Absent;
+ }
+ let m = p.start();
+ p.bump_with_context(HTML_LITERAL, HtmlLexContext::AstroFencedCodeBlock);
+
+ ParsedSyntax::Present(m.complete(p, ASTRO_EMBEDDED_CONTENT))
+}
diff --git a/crates/biome_html_parser/src/syntax/mod.rs b/crates/biome_html_parser/src/syntax/mod.rs
index 3ed586ff622f..2b3e77be002c 100644
--- a/crates/biome_html_parser/src/syntax/mod.rs
+++ b/crates/biome_html_parser/src/syntax/mod.rs
@@ -153,17 +153,30 @@ fn parse_element(p: &mut HtmlParser) -> ParsedSyntax {
},
);
let opening = m.complete(p, HTML_OPENING_ELEMENT);
- loop {
- ElementList.parse_list(p);
- if let Some(mut closing) =
- parse_closing_tag(p).or_add_diagnostic(p, expected_closing_tag)
- && !closing.text(p).contains(opening_tag_name.as_str())
- {
- p.error(expected_matching_closing_tag(p, closing.range(p)).into_diagnostic(p));
- closing.change_to_bogus(p);
- continue;
+ if is_embedded_language_tag {
+ // embedded language tags always have 1 element as content
+ let list = p.start();
+ if p.at(HTML_LITERAL) {
+ let m = p.start();
+ p.bump(HTML_LITERAL);
+ m.complete(p, HTML_EMBEDDED_CONTENT);
+ }
+ list.complete(p, HTML_ELEMENT_LIST);
+
+ parse_closing_tag(p).or_add_diagnostic(p, expected_closing_tag);
+ } else {
+ loop {
+ ElementList.parse_list(p);
+ if let Some(mut closing) =
+ parse_closing_tag(p).or_add_diagnostic(p, expected_closing_tag)
+ && !closing.text(p).contains(opening_tag_name.as_str())
+ {
+ p.error(expected_matching_closing_tag(p, closing.range(p)).into_diagnostic(p));
+ closing.change_to_bogus(p);
+ continue;
+ }
+ break;
}
- break;
}
let previous = opening.precede(p);
diff --git a/crates/biome_html_parser/tests/html_specs/error/astro/attribute_expression.astro.snap b/crates/biome_html_parser/tests/html_specs/error/astro/attribute_expression.astro.snap
index a371d16ed40f..e4f647274404 100644
--- a/crates/biome_html_parser/tests/html_specs/error/astro/attribute_expression.astro.snap
+++ b/crates/biome_html_parser/tests/html_specs/error/astro/attribute_expression.astro.snap
@@ -22,7 +22,9 @@ HtmlRoot {
bom_token: missing (optional),
frontmatter: AstroFrontmatterElement {
l_fence_token: FENCE@0..3 "---" [] [],
- content_token: HTML_LITERAL@3..31 "const foo = \"lorem ipsum\";\n" [Newline("\n")] [],
+ content: AstroEmbeddedContent {
+ content_token: HTML_LITERAL@3..31 "const foo = \"lorem ipsum\";\n" [Newline("\n")] [],
+ },
r_fence_token: FENCE@31..34 "---" [] [],
},
directive: missing (optional),
@@ -97,7 +99,8 @@ HtmlRoot {
0: (empty)
1: ASTRO_FRONTMATTER_ELEMENT@0..34
0: FENCE@0..3 "---" [] []
- 1: HTML_LITERAL@3..31 "const foo = \"lorem ipsum\";\n" [Newline("\n")] []
+ 1: ASTRO_EMBEDDED_CONTENT@3..31
+ 0: HTML_LITERAL@3..31 "const foo = \"lorem ipsum\";\n" [Newline("\n")] []
2: FENCE@31..34 "---" [] []
2: (empty)
3: HTML_ELEMENT_LIST@34..71
diff --git a/crates/biome_html_parser/tests/html_specs/error/frontmatter.html.snap b/crates/biome_html_parser/tests/html_specs/error/frontmatter.html.snap
index 59bae0bfa586..1e2dcdaa09f7 100644
--- a/crates/biome_html_parser/tests/html_specs/error/frontmatter.html.snap
+++ b/crates/biome_html_parser/tests/html_specs/error/frontmatter.html.snap
@@ -22,7 +22,9 @@ HtmlRoot {
frontmatter: AstroBogusFrontmatter {
items: [
FENCE@0..3 "---" [] [],
- HTML_LITERAL@3..16 "layout: foo\n" [Newline("\n")] [],
+ AstroEmbeddedContent {
+ content_token: HTML_LITERAL@3..16 "layout: foo\n" [Newline("\n")] [],
+ },
FENCE@16..19 "---" [] [],
],
},
@@ -81,7 +83,8 @@ HtmlRoot {
0: (empty)
1: ASTRO_BOGUS_FRONTMATTER@0..19
0: FENCE@0..3 "---" [] []
- 1: HTML_LITERAL@3..16 "layout: foo\n" [Newline("\n")] []
+ 1: ASTRO_EMBEDDED_CONTENT@3..16
+ 0: HTML_LITERAL@3..16 "layout: foo\n" [Newline("\n")] []
2: FENCE@16..19 "---" [] []
2: (empty)
3: HTML_ELEMENT_LIST@19..64
diff --git a/crates/biome_html_parser/tests/html_specs/error/frontmatter_bogus.html.snap b/crates/biome_html_parser/tests/html_specs/error/frontmatter_bogus.html.snap
index a0a87055fb03..15f2d3a8b118 100644
--- a/crates/biome_html_parser/tests/html_specs/error/frontmatter_bogus.html.snap
+++ b/crates/biome_html_parser/tests/html_specs/error/frontmatter_bogus.html.snap
@@ -24,7 +24,9 @@ HtmlRoot {
frontmatter: AstroBogusFrontmatter {
items: [
FENCE@0..3 "---" [] [],
- HTML_LITERAL@3..20 "const b = \"bar\"\n" [Newline("\n")] [],
+ AstroEmbeddedContent {
+ content_token: HTML_LITERAL@3..20 "const b = \"bar\"\n" [Newline("\n")] [],
+ },
FENCE@20..23 "---" [] [],
],
},
@@ -100,7 +102,8 @@ HtmlRoot {
0: (empty)
1: ASTRO_BOGUS_FRONTMATTER@0..23
0: FENCE@0..3 "---" [] []
- 1: HTML_LITERAL@3..20 "const b = \"bar\"\n" [Newline("\n")] []
+ 1: ASTRO_EMBEDDED_CONTENT@3..20
+ 0: HTML_LITERAL@3..20 "const b = \"bar\"\n" [Newline("\n")] []
2: FENCE@20..23 "---" [] []
2: (empty)
3: HTML_ELEMENT_LIST@23..68
diff --git a/crates/biome_html_parser/tests/html_specs/error/missing_fence.astro.snap b/crates/biome_html_parser/tests/html_specs/error/missing_fence.astro.snap
index 5d489696383b..8954e097ddf3 100644
--- a/crates/biome_html_parser/tests/html_specs/error/missing_fence.astro.snap
+++ b/crates/biome_html_parser/tests/html_specs/error/missing_fence.astro.snap
@@ -19,7 +19,7 @@ HtmlRoot {
bom_token: missing (optional),
frontmatter: AstroFrontmatterElement {
l_fence_token: FENCE@0..3 "---" [] [],
- content_token: missing (optional),
+ content: missing (required),
r_fence_token: missing (required),
},
directive: missing (optional),
diff --git a/crates/biome_html_parser/tests/html_specs/ok/astro/attribute_expression.astro.snap b/crates/biome_html_parser/tests/html_specs/ok/astro/attribute_expression.astro.snap
index 1f43377eed95..256d56051ee0 100644
--- a/crates/biome_html_parser/tests/html_specs/ok/astro/attribute_expression.astro.snap
+++ b/crates/biome_html_parser/tests/html_specs/ok/astro/attribute_expression.astro.snap
@@ -22,7 +22,9 @@ HtmlRoot {
bom_token: missing (optional),
frontmatter: AstroFrontmatterElement {
l_fence_token: FENCE@0..3 "---" [] [],
- content_token: HTML_LITERAL@3..31 "const foo = \"lorem ipsum\";\n" [Newline("\n")] [],
+ content: AstroEmbeddedContent {
+ content_token: HTML_LITERAL@3..31 "const foo = \"lorem ipsum\";\n" [Newline("\n")] [],
+ },
r_fence_token: FENCE@31..34 "---" [] [],
},
directive: missing (optional),
@@ -94,7 +96,8 @@ HtmlRoot {
0: (empty)
1: ASTRO_FRONTMATTER_ELEMENT@0..34
0: FENCE@0..3 "---" [] []
- 1: HTML_LITERAL@3..31 "const foo = \"lorem ipsum\";\n" [Newline("\n")] []
+ 1: ASTRO_EMBEDDED_CONTENT@3..31
+ 0: HTML_LITERAL@3..31 "const foo = \"lorem ipsum\";\n" [Newline("\n")] []
2: FENCE@31..34 "---" [] []
2: (empty)
3: HTML_ELEMENT_LIST@34..73
diff --git a/crates/biome_html_parser/tests/html_specs/ok/embedded-languages/script-basic.html.snap b/crates/biome_html_parser/tests/html_specs/ok/embedded-languages/script-basic.html.snap
index 4f99514c76f3..8036a51f9eb4 100644
--- a/crates/biome_html_parser/tests/html_specs/ok/embedded-languages/script-basic.html.snap
+++ b/crates/biome_html_parser/tests/html_specs/ok/embedded-languages/script-basic.html.snap
@@ -30,7 +30,7 @@ HtmlRoot {
r_angle_token: R_ANGLE@7..8 ">" [] [],
},
children: HtmlElementList [
- HtmlContent {
+ HtmlEmbeddedContent {
value_token: HTML_LITERAL@8..40 "\n\tconsole.log('Hello, world!');\n" [] [],
},
],
@@ -64,7 +64,7 @@ HtmlRoot {
2: HTML_ATTRIBUTE_LIST@7..7
3: R_ANGLE@7..8 ">" [] []
1: HTML_ELEMENT_LIST@8..40
- 0: HTML_CONTENT@8..40
+ 0: HTML_EMBEDDED_CONTENT@8..40
0: HTML_LITERAL@8..40 "\n\tconsole.log('Hello, world!');\n" [] []
2: HTML_CLOSING_ELEMENT@40..49
0: L_ANGLE@40..41 "<" [] []
diff --git a/crates/biome_html_parser/tests/html_specs/ok/embedded-languages/script-in-string.html.snap b/crates/biome_html_parser/tests/html_specs/ok/embedded-languages/script-in-string.html.snap
index bcdac3f0bd27..53cb21d634b7 100644
--- a/crates/biome_html_parser/tests/html_specs/ok/embedded-languages/script-in-string.html.snap
+++ b/crates/biome_html_parser/tests/html_specs/ok/embedded-languages/script-in-string.html.snap
@@ -28,7 +28,7 @@ HtmlRoot {
r_angle_token: R_ANGLE@7..8 ">" [] [],
},
children: HtmlElementList [
- HtmlContent {
+ HtmlEmbeddedContent {
value_token: HTML_LITERAL@8..97 "window.jQuery || document.write('
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(element.is_javascript_tag());
+
+ let html = r#"
+
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(element.is_javascript_tag());
+ assert_eq!(element.get_script_type(), Some(ScriptType::Classic));
+
+ let html = r#"
+
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(element.is_javascript_tag());
+ assert_eq!(element.get_script_type(), Some(ScriptType::Classic));
+
+ let html = r#"
+
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(element.is_javascript_tag());
+ assert_eq!(element.get_script_type(), Some(ScriptType::Module));
+
+ // FIXME: Uncomment when the parser supports unquoted attribute values.
+ //let html = r#"
+ //
+ // "#;
+ //let syntax = parse_html(html, HtmlParseOptions::default());
+ //let element = syntax
+ // .tree()
+ // .syntax()
+ // .descendants()
+ // .find_map(HtmlElement::cast)
+ // .unwrap();
+ //
+ //assert!(element.is_javascript_tag());
+ //assert_eq!(element.get_script_type(), Some(ScriptType::Module));
+
+ let html = r#"
+
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(element.is_javascript_tag());
+ assert_eq!(element.get_script_type(), Some(ScriptType::Classic));
+
+ let html = r#"
+
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(!element.is_javascript_tag());
+ assert_eq!(element.get_script_type(), Some(ScriptType::ImportMap));
+}
diff --git a/crates/biome_html_syntax/Cargo.toml b/crates/biome_html_syntax/Cargo.toml
index e1f0de13fee1..0de0afc55978 100644
--- a/crates/biome_html_syntax/Cargo.toml
+++ b/crates/biome_html_syntax/Cargo.toml
@@ -19,6 +19,11 @@ biome_string_case = { workspace = true }
camino = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"] }
+
+[dev-dependencies]
+biome_html_factory = { path = "../biome_html_factory" }
+biome_html_parser = { path = "../biome_html_parser" }
+
[features]
schema = ["schemars", "biome_rowan/serde"]
diff --git a/crates/biome_html_syntax/src/attr_ext.rs b/crates/biome_html_syntax/src/attr_ext.rs
new file mode 100644
index 000000000000..c3e00dea6cd3
--- /dev/null
+++ b/crates/biome_html_syntax/src/attr_ext.rs
@@ -0,0 +1,17 @@
+use crate::{AnyHtmlAttributeInitializer, inner_string_text};
+use biome_rowan::Text;
+
+impl AnyHtmlAttributeInitializer {
+ /// Returns the string value of the attribute, if available, without quotes.
+ pub fn string_value(&self) -> Option {
+ match self {
+ Self::HtmlSingleTextExpression(_) => None,
+ Self::HtmlString(string) => Some(
+ string
+ .value_token()
+ .map(|token| inner_string_text(&token).into())
+ .unwrap_or_default(),
+ ),
+ }
+ }
+}
diff --git a/crates/biome_html_syntax/src/element_ext.rs b/crates/biome_html_syntax/src/element_ext.rs
index ea786c900fd3..c3e08d5ef87e 100644
--- a/crates/biome_html_syntax/src/element_ext.rs
+++ b/crates/biome_html_syntax/src/element_ext.rs
@@ -1,5 +1,8 @@
-use crate::HtmlSelfClosingElement;
-use biome_rowan::SyntaxResult;
+use crate::{
+ AnyHtmlElement, AstroEmbeddedContent, HtmlAttribute, HtmlElement, HtmlEmbeddedContent,
+ HtmlSelfClosingElement, HtmlSyntaxToken, ScriptType, inner_string_text,
+};
+use biome_rowan::{AstNodeList, SyntaxResult, TokenText, declare_node_union};
/// https://html.spec.whatwg.org/#void-elements
const VOID_ELEMENTS: &[&str] = &[
@@ -18,3 +21,281 @@ impl HtmlSelfClosingElement {
.is_ok())
}
}
+
+impl AnyHtmlElement {
+ pub fn is_javascript_tag(&self) -> bool {
+ match self {
+ Self::AnyHtmlContent(_)
+ | Self::HtmlBogusElement(_)
+ | Self::HtmlSelfClosingElement(_)
+ | Self::HtmlCdataSection(_) => false,
+ Self::HtmlElement(element) => element.is_javascript_tag(),
+ }
+ }
+
+ pub fn is_style_tag(&self) -> bool {
+ match self {
+ Self::AnyHtmlContent(_)
+ | Self::HtmlBogusElement(_)
+ | Self::HtmlSelfClosingElement(_)
+ | Self::HtmlCdataSection(_) => false,
+ Self::HtmlElement(element) => element.is_style_tag(),
+ }
+ }
+
+ pub fn find_attribute_by_name(&self, name_to_lookup: &str) -> Option {
+ match self {
+ Self::HtmlElement(element) => element.find_attribute_by_name(name_to_lookup),
+ Self::HtmlSelfClosingElement(element) => element.find_attribute_by_name(name_to_lookup),
+ // Other variants don't have attributes
+ Self::AnyHtmlContent(_) | Self::HtmlBogusElement(_) | Self::HtmlCdataSection(_) => None,
+ }
+ }
+
+ pub fn name(&self) -> Option {
+ match self {
+ Self::HtmlElement(el) => {
+ let opening_element = el.opening_element().ok()?;
+ let name = opening_element.name().ok()?;
+ let name_token = name.value_token().ok()?;
+ Some(name_token.token_text_trimmed())
+ }
+ Self::HtmlSelfClosingElement(el) => {
+ let name = el.name().ok()?;
+ let name_token = name.value_token().ok()?;
+ Some(name_token.token_text_trimmed())
+ }
+ _ => None,
+ }
+ }
+}
+
+impl HtmlSelfClosingElement {
+ pub fn find_attribute_by_name(&self, name_to_lookup: &str) -> Option {
+ self.attributes().iter().find_map(|attr| {
+ let attribute = attr.as_html_attribute()?;
+ let name = attribute.name().ok()?;
+ let name_token = name.value_token().ok()?;
+ if name_token
+ .text_trimmed()
+ .eq_ignore_ascii_case(name_to_lookup)
+ {
+ Some(attribute.clone())
+ } else {
+ None
+ }
+ })
+ }
+}
+
+impl HtmlElement {
+ pub fn find_attribute_by_name(&self, name_to_lookup: &str) -> Option {
+ self.opening_element()
+ .ok()?
+ .attributes()
+ .iter()
+ .find_map(|attr| {
+ let attribute = attr.as_html_attribute()?;
+ let name = attribute.name().ok()?;
+ let name_token = name.value_token().ok()?;
+ if name_token
+ .text_trimmed()
+ .eq_ignore_ascii_case(name_to_lookup)
+ {
+ Some(attribute.clone())
+ } else {
+ None
+ }
+ })
+ }
+
+ pub fn is_javascript_tag(&self) -> bool {
+ self.get_script_type()
+ .is_some_and(ScriptType::is_javascript)
+ }
+
+ pub fn is_supported_script_tag(&self) -> bool {
+ self.get_script_type().is_some_and(ScriptType::is_supported)
+ }
+
+ /// Returns the type of script for a `
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(element.is_javascript_tag());
+
+ let html = r#"
+
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(element.is_javascript_tag());
+
+ let html = r#"
+
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(element.is_javascript_tag());
+
+ let html = r#"
+
+ "#;
+ let syntax = parse_html(html, HtmlParseOptions::default());
+ let element = syntax
+ .tree()
+ .syntax()
+ .descendants()
+ .find_map(HtmlElement::cast)
+ .unwrap();
+
+ assert!(element.is_javascript_tag());
+ }
+}
+
+declare_node_union! {
+ pub AnyEmbeddedContent = HtmlEmbeddedContent | AstroEmbeddedContent
+}
+
+impl AnyEmbeddedContent {
+ pub fn value_token(&self) -> Option {
+ match self {
+ Self::HtmlEmbeddedContent(node) => node.value_token().ok(),
+ Self::AstroEmbeddedContent(node) => node.content_token(),
+ }
+ }
+}
diff --git a/crates/biome_html_syntax/src/file_source.rs b/crates/biome_html_syntax/src/file_source.rs
index 4c0d85f14a53..2328c417f8d4 100644
--- a/crates/biome_html_syntax/src/file_source.rs
+++ b/crates/biome_html_syntax/src/file_source.rs
@@ -10,24 +10,6 @@ pub struct HtmlFileSource {
variant: HtmlVariant,
}
-impl HtmlFileSource {
- pub const fn is_astro(&self) -> bool {
- matches!(self.variant, HtmlVariant::Astro)
- }
-
- pub fn variant(&self) -> &HtmlVariant {
- &self.variant
- }
-
- pub fn text_expressions(&self) -> Option<&HtmlTextExpressions> {
- if let HtmlVariant::Standard(text_expressions) = &self.variant {
- Some(text_expressions)
- } else {
- None
- }
- }
-}
-
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(
Debug, Clone, Default, Copy, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize,
@@ -66,8 +48,32 @@ impl HtmlFileSource {
/// Returns `true` if the current file is `.html` and doesn't support
/// any text expression capability
- pub fn is_html(&self) -> bool {
- self.variant == HtmlVariant::default()
+ pub const fn is_html(&self) -> bool {
+ matches!(self.variant, HtmlVariant::Standard(_))
+ }
+
+ pub const fn is_vue(&self) -> bool {
+ matches!(self.variant, HtmlVariant::Vue)
+ }
+
+ pub const fn is_svelte(&self) -> bool {
+ matches!(self.variant, HtmlVariant::Svelte)
+ }
+
+ pub const fn is_astro(&self) -> bool {
+ matches!(self.variant, HtmlVariant::Astro)
+ }
+
+ pub fn variant(&self) -> &HtmlVariant {
+ &self.variant
+ }
+
+ pub fn text_expressions(&self) -> Option<&HtmlTextExpressions> {
+ if let HtmlVariant::Standard(text_expressions) = &self.variant {
+ Some(text_expressions)
+ } else {
+ None
+ }
}
pub fn html_with_text_expressions() -> Self {
@@ -94,9 +100,12 @@ impl HtmlFileSource {
}
/// Try to return the HTML file source corresponding to this file name from well-known files
- pub fn try_from_well_known(_: &Utf8Path) -> Result {
- // TODO: to be implemented
- Err(FileSourceError::UnknownFileName)
+ pub fn try_from_well_known(path: &Utf8Path) -> Result {
+ let Some(extension) = path.extension() else {
+ return Err(FileSourceError::MissingFileExtension);
+ };
+
+ Self::try_from_extension(extension)
}
/// Try to return the HTML file source corresponding to this file extension
@@ -124,7 +133,7 @@ impl HtmlFileSource {
match language_id {
"html" => Ok(Self::html()),
"astro" => Ok(Self::astro()),
- "vue" => Ok(Self::vue()),
+ "vuejs" | "vue" => Ok(Self::vue()),
"svelte" => Ok(Self::svelte()),
_ => Err(FileSourceError::UnknownLanguageId),
}
diff --git a/crates/biome_html_syntax/src/generated/kind.rs b/crates/biome_html_syntax/src/generated/kind.rs
index 5edc36f15042..da52952ad0b2 100644
--- a/crates/biome_html_syntax/src/generated/kind.rs
+++ b/crates/biome_html_syntax/src/generated/kind.rs
@@ -42,6 +42,7 @@ pub enum HtmlSyntaxKind {
HTML_SELF_CLOSING_TAG,
HTML_ELEMENT,
ASTRO_FRONTMATTER_ELEMENT,
+ ASTRO_EMBEDDED_CONTENT,
HTML_OPENING_ELEMENT,
HTML_CLOSING_ELEMENT,
HTML_SELF_CLOSING_ELEMENT,
@@ -53,6 +54,7 @@ pub enum HtmlSyntaxKind {
HTML_ELEMENT_LIST,
HTML_ATTRIBUTE_LIST,
HTML_CONTENT,
+ HTML_EMBEDDED_CONTENT,
HTML_CDATA_SECTION,
COMMENT,
HTML_DOUBLE_TEXT_EXPRESSION,
diff --git a/crates/biome_html_syntax/src/generated/macros.rs b/crates/biome_html_syntax/src/generated/macros.rs
index 55bd8b9c27fa..5aec3e8bff8f 100644
--- a/crates/biome_html_syntax/src/generated/macros.rs
+++ b/crates/biome_html_syntax/src/generated/macros.rs
@@ -16,6 +16,10 @@ macro_rules! map_syntax_node {
($ node : expr , $ pattern : pat => $ body : expr) => {
match $node {
node => match $crate::HtmlSyntaxNode::kind(&node) {
+ $crate::HtmlSyntaxKind::ASTRO_EMBEDDED_CONTENT => {
+ let $pattern = unsafe { $crate::AstroEmbeddedContent::new_unchecked(node) };
+ $body
+ }
$crate::HtmlSyntaxKind::ASTRO_FRONTMATTER_ELEMENT => {
let $pattern = unsafe { $crate::AstroFrontmatterElement::new_unchecked(node) };
$body
@@ -57,6 +61,10 @@ macro_rules! map_syntax_node {
let $pattern = unsafe { $crate::HtmlElement::new_unchecked(node) };
$body
}
+ $crate::HtmlSyntaxKind::HTML_EMBEDDED_CONTENT => {
+ let $pattern = unsafe { $crate::HtmlEmbeddedContent::new_unchecked(node) };
+ $body
+ }
$crate::HtmlSyntaxKind::HTML_OPENING_ELEMENT => {
let $pattern = unsafe { $crate::HtmlOpeningElement::new_unchecked(node) };
$body
diff --git a/crates/biome_html_syntax/src/generated/nodes.rs b/crates/biome_html_syntax/src/generated/nodes.rs
index 126711d7dcfd..b6cbdab84914 100644
--- a/crates/biome_html_syntax/src/generated/nodes.rs
+++ b/crates/biome_html_syntax/src/generated/nodes.rs
@@ -20,6 +20,41 @@ use std::fmt::{Debug, Formatter};
#[doc = r" the slots are not statically known."]
pub(crate) const SLOT_MAP_EMPTY_VALUE: u8 = u8::MAX;
#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct AstroEmbeddedContent {
+ pub(crate) syntax: SyntaxNode,
+}
+impl AstroEmbeddedContent {
+ #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"]
+ #[doc = r""]
+ #[doc = r" # Safety"]
+ #[doc = r" This function must be guarded with a call to [AstNode::can_cast]"]
+ #[doc = r" or a match on [SyntaxNode::kind]"]
+ #[inline]
+ pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self {
+ Self { syntax }
+ }
+ pub fn as_fields(&self) -> AstroEmbeddedContentFields {
+ AstroEmbeddedContentFields {
+ content_token: self.content_token(),
+ }
+ }
+ pub fn content_token(&self) -> Option {
+ support::token(&self.syntax, 0usize)
+ }
+}
+impl Serialize for AstroEmbeddedContent {
+ fn serialize(&self, serializer: S) -> Result
+ where
+ S: Serializer,
+ {
+ self.as_fields().serialize(serializer)
+ }
+}
+#[derive(Serialize)]
+pub struct AstroEmbeddedContentFields {
+ pub content_token: Option,
+}
+#[derive(Clone, PartialEq, Eq, Hash)]
pub struct AstroFrontmatterElement {
pub(crate) syntax: SyntaxNode,
}
@@ -36,15 +71,15 @@ impl AstroFrontmatterElement {
pub fn as_fields(&self) -> AstroFrontmatterElementFields {
AstroFrontmatterElementFields {
l_fence_token: self.l_fence_token(),
- content_token: self.content_token(),
+ content: self.content(),
r_fence_token: self.r_fence_token(),
}
}
pub fn l_fence_token(&self) -> SyntaxResult {
support::required_token(&self.syntax, 0usize)
}
- pub fn content_token(&self) -> Option {
- support::token(&self.syntax, 1usize)
+ pub fn content(&self) -> SyntaxResult {
+ support::required_node(&self.syntax, 1usize)
}
pub fn r_fence_token(&self) -> SyntaxResult {
support::required_token(&self.syntax, 2usize)
@@ -61,7 +96,7 @@ impl Serialize for AstroFrontmatterElement {
#[derive(Serialize)]
pub struct AstroFrontmatterElementFields {
pub l_fence_token: SyntaxResult,
- pub content_token: Option,
+ pub content: SyntaxResult,
pub r_fence_token: SyntaxResult,
}
#[derive(Clone, PartialEq, Eq, Hash)]
@@ -470,6 +505,41 @@ pub struct HtmlElementFields {
pub closing_element: SyntaxResult,
}
#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct HtmlEmbeddedContent {
+ pub(crate) syntax: SyntaxNode,
+}
+impl HtmlEmbeddedContent {
+ #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"]
+ #[doc = r""]
+ #[doc = r" # Safety"]
+ #[doc = r" This function must be guarded with a call to [AstNode::can_cast]"]
+ #[doc = r" or a match on [SyntaxNode::kind]"]
+ #[inline]
+ pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self {
+ Self { syntax }
+ }
+ pub fn as_fields(&self) -> HtmlEmbeddedContentFields {
+ HtmlEmbeddedContentFields {
+ value_token: self.value_token(),
+ }
+ }
+ pub fn value_token(&self) -> SyntaxResult {
+ support::required_token(&self.syntax, 0usize)
+ }
+}
+impl Serialize for HtmlEmbeddedContent {
+ fn serialize(&self, serializer: S) -> Result
+ where
+ S: Serializer,
+ {
+ self.as_fields().serialize(serializer)
+ }
+}
+#[derive(Serialize)]
+pub struct HtmlEmbeddedContentFields {
+ pub value_token: SyntaxResult,
+}
+#[derive(Clone, PartialEq, Eq, Hash)]
pub struct HtmlOpeningElement {
pub(crate) syntax: SyntaxNode,
}
@@ -847,6 +917,7 @@ impl AnyHtmlAttributeInitializer {
pub enum AnyHtmlContent {
AnyHtmlTextExpression(AnyHtmlTextExpression),
HtmlContent(HtmlContent),
+ HtmlEmbeddedContent(HtmlEmbeddedContent),
}
impl AnyHtmlContent {
pub fn as_any_html_text_expression(&self) -> Option<&AnyHtmlTextExpression> {
@@ -861,6 +932,12 @@ impl AnyHtmlContent {
_ => None,
}
}
+ pub fn as_html_embedded_content(&self) -> Option<&HtmlEmbeddedContent> {
+ match &self {
+ Self::HtmlEmbeddedContent(item) => Some(item),
+ _ => None,
+ }
+ }
}
#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
pub enum AnyHtmlElement {
@@ -928,6 +1005,56 @@ impl AnyHtmlTextExpression {
}
}
}
+impl AstNode for AstroEmbeddedContent {
+ type Language = Language;
+ const KIND_SET: SyntaxKindSet =
+ SyntaxKindSet::from_raw(RawSyntaxKind(ASTRO_EMBEDDED_CONTENT as u16));
+ fn can_cast(kind: SyntaxKind) -> bool {
+ kind == ASTRO_EMBEDDED_CONTENT
+ }
+ fn cast(syntax: SyntaxNode) -> Option {
+ if Self::can_cast(syntax.kind()) {
+ Some(Self { syntax })
+ } else {
+ None
+ }
+ }
+ fn syntax(&self) -> &SyntaxNode {
+ &self.syntax
+ }
+ fn into_syntax(self) -> SyntaxNode {
+ self.syntax
+ }
+}
+impl std::fmt::Debug for AstroEmbeddedContent {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ thread_local! { static DEPTH : std :: cell :: Cell < u8 > = const { std :: cell :: Cell :: new (0) } };
+ let current_depth = DEPTH.get();
+ let result = if current_depth < 16 {
+ DEPTH.set(current_depth + 1);
+ f.debug_struct("AstroEmbeddedContent")
+ .field(
+ "content_token",
+ &support::DebugOptionalElement(self.content_token()),
+ )
+ .finish()
+ } else {
+ f.debug_struct("AstroEmbeddedContent").finish()
+ };
+ DEPTH.set(current_depth);
+ result
+ }
+}
+impl From for SyntaxNode {
+ fn from(n: AstroEmbeddedContent) -> Self {
+ n.syntax
+ }
+}
+impl From for SyntaxElement {
+ fn from(n: AstroEmbeddedContent) -> Self {
+ n.syntax.into()
+ }
+}
impl AstNode for AstroFrontmatterElement {
type Language = Language;
const KIND_SET: SyntaxKindSet =
@@ -960,10 +1087,7 @@ impl std::fmt::Debug for AstroFrontmatterElement {
"l_fence_token",
&support::DebugSyntaxResult(self.l_fence_token()),
)
- .field(
- "content_token",
- &support::DebugOptionalElement(self.content_token()),
- )
+ .field("content", &support::DebugSyntaxResult(self.content()))
.field(
"r_fence_token",
&support::DebugSyntaxResult(self.r_fence_token()),
@@ -1487,6 +1611,56 @@ impl From for SyntaxElement {
n.syntax.into()
}
}
+impl AstNode for HtmlEmbeddedContent {
+ type Language = Language;
+ const KIND_SET: SyntaxKindSet =
+ SyntaxKindSet::from_raw(RawSyntaxKind(HTML_EMBEDDED_CONTENT as u16));
+ fn can_cast(kind: SyntaxKind) -> bool {
+ kind == HTML_EMBEDDED_CONTENT
+ }
+ fn cast(syntax: SyntaxNode) -> Option {
+ if Self::can_cast(syntax.kind()) {
+ Some(Self { syntax })
+ } else {
+ None
+ }
+ }
+ fn syntax(&self) -> &SyntaxNode {
+ &self.syntax
+ }
+ fn into_syntax(self) -> SyntaxNode {
+ self.syntax
+ }
+}
+impl std::fmt::Debug for HtmlEmbeddedContent {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ thread_local! { static DEPTH : std :: cell :: Cell < u8 > = const { std :: cell :: Cell :: new (0) } };
+ let current_depth = DEPTH.get();
+ let result = if current_depth < 16 {
+ DEPTH.set(current_depth + 1);
+ f.debug_struct("HtmlEmbeddedContent")
+ .field(
+ "value_token",
+ &support::DebugSyntaxResult(self.value_token()),
+ )
+ .finish()
+ } else {
+ f.debug_struct("HtmlEmbeddedContent").finish()
+ };
+ DEPTH.set(current_depth);
+ result
+ }
+}
+impl From for SyntaxNode {
+ fn from(n: HtmlEmbeddedContent) -> Self {
+ n.syntax
+ }
+}
+impl From for SyntaxElement {
+ fn from(n: HtmlEmbeddedContent) -> Self {
+ n.syntax.into()
+ }
+}
impl AstNode for HtmlOpeningElement {
type Language = Language;
const KIND_SET: SyntaxKindSet =
@@ -2075,13 +2249,19 @@ impl From for AnyHtmlContent {
Self::HtmlContent(node)
}
}
+impl From for AnyHtmlContent {
+ fn from(node: HtmlEmbeddedContent) -> Self {
+ Self::HtmlEmbeddedContent(node)
+ }
+}
impl AstNode for AnyHtmlContent {
type Language = Language;
- const KIND_SET: SyntaxKindSet =
- AnyHtmlTextExpression::KIND_SET.union(HtmlContent::KIND_SET);
+ const KIND_SET: SyntaxKindSet = AnyHtmlTextExpression::KIND_SET
+ .union(HtmlContent::KIND_SET)
+ .union(HtmlEmbeddedContent::KIND_SET);
fn can_cast(kind: SyntaxKind) -> bool {
match kind {
- HTML_CONTENT => true,
+ HTML_CONTENT | HTML_EMBEDDED_CONTENT => true,
k if AnyHtmlTextExpression::can_cast(k) => true,
_ => false,
}
@@ -2089,6 +2269,7 @@ impl AstNode for AnyHtmlContent {
fn cast(syntax: SyntaxNode) -> Option {
let res = match syntax.kind() {
HTML_CONTENT => Self::HtmlContent(HtmlContent { syntax }),
+ HTML_EMBEDDED_CONTENT => Self::HtmlEmbeddedContent(HtmlEmbeddedContent { syntax }),
_ => {
if let Some(any_html_text_expression) = AnyHtmlTextExpression::cast(syntax) {
return Some(Self::AnyHtmlTextExpression(any_html_text_expression));
@@ -2101,12 +2282,14 @@ impl AstNode for AnyHtmlContent {
fn syntax(&self) -> &SyntaxNode {
match self {
Self::HtmlContent(it) => &it.syntax,
+ Self::HtmlEmbeddedContent(it) => &it.syntax,
Self::AnyHtmlTextExpression(it) => it.syntax(),
}
}
fn into_syntax(self) -> SyntaxNode {
match self {
Self::HtmlContent(it) => it.syntax,
+ Self::HtmlEmbeddedContent(it) => it.syntax,
Self::AnyHtmlTextExpression(it) => it.into_syntax(),
}
}
@@ -2116,6 +2299,7 @@ impl std::fmt::Debug for AnyHtmlContent {
match self {
Self::AnyHtmlTextExpression(it) => std::fmt::Debug::fmt(it, f),
Self::HtmlContent(it) => std::fmt::Debug::fmt(it, f),
+ Self::HtmlEmbeddedContent(it) => std::fmt::Debug::fmt(it, f),
}
}
}
@@ -2124,6 +2308,7 @@ impl From for SyntaxNode {
match n {
AnyHtmlContent::AnyHtmlTextExpression(it) => it.into(),
AnyHtmlContent::HtmlContent(it) => it.into(),
+ AnyHtmlContent::HtmlEmbeddedContent(it) => it.into(),
}
}
}
@@ -2343,6 +2528,11 @@ impl std::fmt::Display for AnyHtmlTextExpression {
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for AstroEmbeddedContent {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for AstroFrontmatterElement {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
@@ -2393,6 +2583,11 @@ impl std::fmt::Display for HtmlElement {
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for HtmlEmbeddedContent {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for HtmlOpeningElement {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/biome_html_syntax/src/generated/nodes_mut.rs b/crates/biome_html_syntax/src/generated/nodes_mut.rs
index 3a0ef8e5326b..35e79229c06f 100644
--- a/crates/biome_html_syntax/src/generated/nodes_mut.rs
+++ b/crates/biome_html_syntax/src/generated/nodes_mut.rs
@@ -3,6 +3,14 @@
use crate::{HtmlSyntaxToken as SyntaxToken, generated::nodes::*};
use biome_rowan::AstNode;
use std::iter::once;
+impl AstroEmbeddedContent {
+ pub fn with_content_token(self, element: Option) -> Self {
+ Self::unwrap_cast(
+ self.syntax
+ .splice_slots(0usize..=0usize, once(element.map(|element| element.into()))),
+ )
+ }
+}
impl AstroFrontmatterElement {
pub fn with_l_fence_token(self, element: SyntaxToken) -> Self {
Self::unwrap_cast(
@@ -10,10 +18,10 @@ impl AstroFrontmatterElement {
.splice_slots(0usize..=0usize, once(Some(element.into()))),
)
}
- pub fn with_content_token(self, element: Option) -> Self {
+ pub fn with_content(self, element: AstroEmbeddedContent) -> Self {
Self::unwrap_cast(
self.syntax
- .splice_slots(1usize..=1usize, once(element.map(|element| element.into()))),
+ .splice_slots(1usize..=1usize, once(Some(element.into_syntax().into()))),
)
}
pub fn with_r_fence_token(self, element: SyntaxToken) -> Self {
@@ -203,6 +211,14 @@ impl HtmlElement {
)
}
}
+impl HtmlEmbeddedContent {
+ pub fn with_value_token(self, element: SyntaxToken) -> Self {
+ Self::unwrap_cast(
+ self.syntax
+ .splice_slots(0usize..=0usize, once(Some(element.into()))),
+ )
+ }
+}
impl HtmlOpeningElement {
pub fn with_l_angle_token(self, element: SyntaxToken) -> Self {
Self::unwrap_cast(
diff --git a/crates/biome_html_syntax/src/lib.rs b/crates/biome_html_syntax/src/lib.rs
index f659581049fe..4dea369c5860 100644
--- a/crates/biome_html_syntax/src/lib.rs
+++ b/crates/biome_html_syntax/src/lib.rs
@@ -1,14 +1,17 @@
#![deny(clippy::use_self)]
#[macro_use]
-mod generated;
+mod attr_ext;
pub mod element_ext;
mod file_source;
+mod generated;
+mod script_type;
mod syntax_node;
-pub use self::generated::*;
pub use biome_rowan::{TextLen, TextRange, TextSize, TokenAtOffset, TriviaPieceKind, WalkEvent};
pub use file_source::{HtmlFileSource, HtmlTextExpressions, HtmlVariant};
+pub use generated::*;
+pub use script_type::*;
pub use syntax_node::*;
use crate::HtmlSyntaxKind::{
diff --git a/crates/biome_html_syntax/src/script_type.rs b/crates/biome_html_syntax/src/script_type.rs
new file mode 100644
index 000000000000..8e8da598be1a
--- /dev/null
+++ b/crates/biome_html_syntax/src/script_type.rs
@@ -0,0 +1,70 @@
+/// Determines the kind of script that is contained in a `
+
+
+