github biomejs/biome @biomejs/biome@2.5.7
Biome CLI v2.5.7

11 hours ago

2.5.7

Patch Changes

  • #10822 c171b3b Thanks @pkallos! - Added the option ignoreIfStatements to useNullishCoalescing. Biome now flags if statements that only assign to a nullish variable (such as if (!a) { a = b }) and can rewrite them to ??=. When enabled, Biome ignores those if statements.

  • #11136 e63354c Thanks @AkashNaickar! - Added a new nursery rule noExtendNative, which reports extending the prototype of a built-in object.

  • #10094 e007143 Thanks @THEjacob1000! - Added the nursery rule noTailwindArbitraryValue. Biome now reports Tailwind CSS arbitrary values such as w-[400px], including in HTML/JSX class attributes, configured utility functions, and tagged templates.

  • #11184 135f476 Thanks @subotac! - Fixed #11176: noUnknownPseudoClass now recognizes Vue's :deep() pseudo-class inside .vue style blocks.

  • #8239 a519f9d Thanks @cormacrelf! - Fixed #8233, where Biome CLI in
    stdin mode didn't work correctly when handling files in projects with nested
    configurations. For example, with the following structure,
    --stdin-file-path=subdirectory/... would not use the nested configuration in
    subdirectory/biome.json:

    ├── biome.json
    └── subdirectory
        ├── biome.json
        └── lib.js
    
    biome format --write --stdin-file-path=subdirectory/lib.js < subdirectory/lib.js

    Now, the nested configuration is correctly picked up and applied.

    In addition, Biome now shows a warning if --stdin-file-path is provided but
    that path is ignored and therefore not formatted or fixed.

  • #11138 8c2c6bd Thanks @ematipico! - Fixed noUnnecessaryConditions: Biome now chooses the same function overload as TypeScript when an argument is a callback, so conditions that were previously missed are reported.

    The following code is now invalid, because a parameter typed () => void accepts an async callback and schedule therefore returns string:

    declare function schedule(handler: () => void): string;
    declare function schedule(handler: () => Promise<void>): string | undefined;
    
    schedule(async () => {}) ?? "fallback";

    The following code is also now invalid, because map(() => 42) returns 42:

    type Mapper<T> = () => T;
    declare function map<T>(mapper: Mapper<T>): T;
    
    map(() => 42) || flag;
  • #11138 8c2c6bd Thanks @ematipico! - Fixed #11087: noUnnecessaryConditions no longer reports optional chains and nullish coalescing whose receiver can be nullish.

    For example, the optional chain and fallback in the following code are no longer reported:

    declare const usage: { range: { startDate: string } } | null;
    const startDate = usage?.range.startDate ?? "N/A";
  • #11118 9c16840 Thanks @subotac! - Fixed #11098: The HTML formatter now preserves the configured trailing newline when a file ends with a comment.

    -<!-- trailing comment -->
    \ No newline at end of file
    +<!-- trailing comment -->
  • #11201 0e80610 Thanks @Bishwas-py! - Fixed #11182: suppression comments for noPositiveTabindex now suppress the rule in HTML files when the attributes of the element span multiple lines.

  • #11079 607afd2 Thanks @dyc3! - The HTML formatter now lays out the srcset attribute of <img> and <source> as the list of candidates it is. Runs of whitespace between candidates collapse, and once the list no longer fits on one line each candidate goes on its own line with the descriptors aligned:

    - <img srcset="/visual@0.5.png  400w, /visual.png 805w, /visual@2x.png 1610w, /visual@3x.png 2415w" />
    + <img
    +   srcset="
    +     /visual@0.5.png  400w,
    +     /visual.png      805w,
    +     /visual@2x.png  1610w,
    +     /visual@3x.png  2415w
    +   "
    + />
  • #11156 fed72c7 Thanks @saberoueslati! - Fixed #11129: noUnusedVariables no longer reports Vue bindings as unused when they are assigned through automatically unwrapped template refs.

  • #11124 d890b39 Thanks @denbezrukov! - Fixed CSS formatting of line comments between a declaration colon and value to preserve their source indentation.

     .test {
       background:
    -  /////// foo
    -  // bar
    +        /////// foo
    +        // bar
         radial-gradient(circle, #000, transparent);
     }
  • #11113 3d8ab73 Thanks @denbezrukov! - Fixed CSS formatting of long block comments between comma-separated property values:

     .foo {
       box-shadow:
    -    1000px /* long long long long long long long long long long long long comment */ 1000px /* long long long long long long long long long comment */ 2px color(srgb 0.555555555 0.555555555 0.555555555),
    +    1000px
    +      /* long long long long long long long long long long long long comment */
    +      1000px /* long long long long long long long long long comment */ 2px
    +      color(srgb 0.555555555 0.555555555 0.555555555),
         1px 1px black;
     }
  • #11127 da5c1a5 Thanks @dyc3! - The HTML formatter now picks the quote character for an attribute by counting the quotes in the value rather than looking only for a double quote. &apos; and &quot; count as the characters they stand for, and only the character that ends up as the delimiter stays escaped:

    - <div title='123 &apos;&quot; 456'></div>
    + <div title="123 '&quot; 456"></div>

    Entities that are not quotes, such as &amp; or &[#39](https://github.com/biomejs/biome/issues/39);, are left exactly as written.

  • #11193 77035bb Thanks @dyc3! - Fixed the HTML formatter collapsing the blank line between an element and the text that follows it. A blank line before text is now kept, the way one before another element already was:

      <div>foo</div>
    -
      text
  • #11106 ad80f57 Thanks @dyc3! - The HTML formatter now writes the HTML5 doctype in lowercase, matching Prettier:

    - <!DOCTYPE html>
    + <!doctype html>

    This only applies to a plain .html file whose doctype stands alone. A doctype that names a DTD keeps the case it was written with, since the rest of the declaration is not lowercased either:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

    A .vue, .svelte, or .astro file keeps whatever the author wrote.

  • #11188 60679db Thanks @dyc3! - Fixed the HTML formatter printing a comment twice when it ended the line of the last element in a document:

    - text<!-- a --><!-- a -->
    + text<!-- a -->
  • #11077 4dcd0d9 Thanks @dyc3! - Fixed a bug where the HTML formatter collapsed the whitespace inside <textarea>, <xmp> and <plaintext>, changing what the page renders.

    - <textarea>
    -  line one
    - line two </textarea>
    + <textarea>line one line two</textarea>

    Biome now prints the content of these elements exactly as it appears in the source, matching the existing behavior for <pre>.

  • #11194 abfbb11 Thanks @dyc3! - Fixed the HTML formatter refusing to format a Svelte file containing an array pattern that skips a position:

    {#each animals as [, value]}
    	<p>{value}</p>
    {/each}
  • #10094 e007143 Thanks @THEjacob1000! - Fixed useSortedClasses to correctly detect unsorted classes in static member expression tagged templates (e.g. tw.div\...``). Previously, these were silently skipped due to surrounding whitespace trivia not being stripped from the tag name.

  • #11078 10da30e Thanks @dyc3! - Fixed Vue single-file components failing to parse when they contain a custom block such as <i18n> or <docs>, or a <template> written in another language. Their content is no longer read as HTML, so a block may hold whatever its own tooling expects:

    <docs>
    This block is prose, and it may mention a `<my-component>` without closing it.
    </docs>
    
    <template lang="pug">
      .test
        #foo
    </template>

    Previously both blocks produced a parse error and the whole file was left unformatted. Biome now prints their content unchanged while still formatting the opening tag.

  • #11231 4afd901 Thanks @ematipico! - Improved the performance of the following lint rules:

  • #11134 2fa0a62 Thanks @yanthomasdev! - Clarified the warning emitted when using the experimental json and json-pretty reporters.

  • #11198 ed88b13 Thanks @saberoueslati! - Fixed #11171: variables referenced only inside a Svelte attachment ({@attach ...}) are no longer reported as unused by noUnusedVariables and noUnusedImports.

  • #11155 6ee17ea Thanks @dyc3! - Improved performance when printing diagnostics to the console.

  • #11160 217f8ad Thanks @dyc3! - Improved the performance of noFloatingPromises by skipping type inference for assignment statements, which are always considered handled.

  • #11159 26c23d9 Thanks @saberoueslati! - Fixed #11144: noFloatingPromises no longer reports already-awaited optional Promise values.

  • #11138 8c2c6bd Thanks @ematipico! - Fixed #11121: noUnnecessaryConditions no longer reports conditions based on an inapplicable function overload.

    For example, the condition in the following code is no longer reported because query({}) selects the overload that returns boolean:

    declare function query(options: { initial: string }): { isPending: false };
    declare function query(options: { initial?: string }): { isPending: boolean };
    
    const { isPending } = query({});
    isPending || fallback;
  • #11152 c4fc6a9 Thanks @dyc3! - Improved the performance of collecting rule timings with --profile-rules in heavily multithreaded environments.

  • #11128 4d3ff76 Thanks @ematipico! - Fixed #7635: noDeprecatedImports now detects deprecated ambient declarations that are exported separately.

  • #11117 01f7ef5 Thanks @subotac! - Fixed #11014: noDelete no longer reports process.env["FOO"] style property deletions.

  • #11168 9847e68 Thanks @saberoueslati! - Added the nursery rule noNonScalableViewport, which reports viewport metadata that disables user scaling with user-scalable=no.

    For example:

    <meta name="viewport" content="width=device-width, user-scalable=no" />
  • #11154 a1d6b1f Thanks @dyc3! - Improved the performance of noImportCycles by skipping graph traversals for imports that cannot be part of a cycle.

  • #11175 d96d6dd Thanks @ematipico! - Fixed CSS parsing of registered custom properties: Biome now correctly validates the syntax descriptor of @property rules.

What's Changed

  • fix(html): preserve trailing newline after comments by @subotac in #11118
  • fix(format/html): preserve the content of preformatted elements by @dyc3 in #11077
  • feat(format/yaml): explicit block mapping entries by @dyc3 in #11053
  • feat(format/yaml): normalize scalar quotes by @dyc3 in #11054
  • fix(parser/yaml): plain scalar # and alias name lexing by @dyc3 in #11061
  • feat(format/yaml): normalize node property placement by @dyc3 in #11062
  • feat(format/yaml): middle comments by @dyc3 in #11063
  • feat(css_formatter): scss and css comments inside declarations by @denbezrukov in #11113
  • chore: trim published crate sizes with cargo diet by @dreyfus92 in #11123
  • feat(useSortedClasses): resolve bare functional utilities with defaults in sort_v4 by @johncarmack1984 in #11120
  • feat(lint): add ignoreIfStatements option to useNullishCoalescing by @pkallos in #10822
  • feat(md/fmt): dedent code blocks, normalize strings, indentation fixes by @ematipico in #11111
  • fix: --stdin-file-path with nested configuration by @cormacrelf in #8239
  • fix(noDelete): allow computed process.env deletion by @subotac in #11117
  • chore(xtask): migrate Date global type by @minseong0324 in #11107
  • feat(format/yaml): flow collection blank lines and spacing by @dyc3 in #11064
  • feat(format/yaml): explicit-form mapping keys by @dyc3 in #11065
  • feat(format/yaml): document separation and trailing newlines by @dyc3 in #11066
  • feat(format/yaml): block scalar trailing comment lines by @dyc3 in #11058
  • fix(css_formatter): preserve property value comment indentation by @denbezrukov in #11124
  • feat(fmt/md): prose-wrap formatting for markdown by @ematipico in #11115
  • feat(lint): add nursery rule noTailwindArbitraryValue by @THEjacob1000 in #10094
  • fix(parser/yaml): property attachment across lines in block mappings by @dyc3 in #11057
  • fix(css): resolve empty syntax node pointers by @denbezrukov in #11132
  • fix(inference): regression in optional chain types by @ematipico in #11138
  • docs: rework CLI by @yanthomasdev in #11134
  • fix(html): track Vue template assignment references by @saberoueslati in #11156
  • feat(css): property syntax value codec by @ematipico in #11148
  • feat(lint): add noExtendNative nursery rule by @AkashNaickar in #11136
  • feat(css): property semantic model by @ematipico in #11149
  • perf(console): batch writes when printing instead of one char at a time by @dyc3 in #11155
  • fix(lint): detect deprecated ambient imports by @ematipico in #11128
  • chore(xtask): migrate RegExp global types by @minseong0324 in #11108
  • perf(rule_profiler): thread local profilers, aggregate at the end by @dyc3 in #11152
  • perf(noFloatingPromises): short circuit assignment statements by @dyc3 in #11160
  • feat(module-graph): css traversal for properties by @ematipico in #11153
  • fix(inference): collapse instance wrappers around unions by @saberoueslati in #11159
  • fix(parse/html): read Vue SFC custom blocks as opaque text by @dyc3 in #11078
  • feat(format/html): lay out the srcset attribute by @dyc3 in #11079
  • fix(format/html): write the HTML5 doctype in lowercase by @dyc3 in #11106
  • fix(format/html): pick attribute quotes by counting them by @dyc3 in #11127
  • chore(xtask): migrate Map and Set global types by @minseong0324 in #11109
  • feat(lint): add noNonScalableViewport rule by @saberoueslati in #11168
  • chore(xtask): migrate Array global types by @minseong0324 in #11125
  • fix(css_parser): tighten interpolated identifier boundaries by @denbezrukov in #11181
  • fix(analyze): recognize references in Svelte attachments by @saberoueslati in #11198
  • fix(lint/css): recognize Vue :deep() pseudo-class by @subotac in #11184
  • chore(deps): update rust crate serde to 1.0.229 by @renovate[bot] in #11200
  • chore(deps): update rust crate camino to 1.2.5 by @renovate[bot] in #11197
  • chore(deps): update rust crate schemars to 1.2.2 by @renovate[bot] in #11199
  • chore(deps): update rust crate serde_json to 1.0.151 by @renovate[bot] in #11203
  • chore(deps): update rust crate bpaf to 0.9.27 by @renovate[bot] in #11196
  • chore(deps): update github-actions by @renovate[bot] in #11204
  • chore(deps): update pnpm to v11.18.0 by @renovate[bot] in #11205
  • test(format/html): enable html_embeds feature for tests by @dyc3 in #11216
  • perf(noImportCycles): prune DFS traversals by grouping strongly connected components by @dyc3 in #11154
  • feat(graph): traversal of HTML-ish files by @ematipico in #11158
  • feat(css): js traverse, source order paths, cache traverse by @ematipico in #11169
  • fix(css): validate @Property syntax descriptors by @ematipico in #11175
  • test(format/html): run the prettier-plugin-svelte suite by @dyc3 in #11130
  • fix(format/html): stop printing a document's last comment twice by @dyc3 in #11188
  • fix(noPositiveTabindex): make suppression comments work on multiline HTML tags by @Bishwas-py in #11201
  • perf(lint): reduce trigger of rules by @ematipico in #11231
  • fix(format/html): keep the blank line before text by @dyc3 in #11193
  • fix(format/html): format a Svelte array pattern that skips a position by @dyc3 in #11194
  • ci: release by @github-actions[bot] in #11119

New Contributors

Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.6...@biomejs/biome@2.5.7

Don't miss a new biome release

NewReleases is sending notifications on new releases.