fix(resolver): resolve typed package main entries#10125
Conversation
Made-with: Cursor
🦋 Changeset detectedLatest commit: 07394c4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughWhen type-aware resolution is enabled, the resolver now prefers Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/biome_resolver/src/lib.rs (1)
734-743: Tiny redundancy in the predicate.The
ends_with(".d.ts" | ".d.cts" | ".d.mts")checks are subsumed by theextension()match below (e.g.Utf8Path::new("foo.d.ts").extension() == Some("ts")). Harmless, just a touch belt-and-braces. Feel free to leave as-is for readability, or tighten:♻️ Optional simplification
fn is_type_resolution_path(path: &Utf8Path) -> bool { - let path = path.as_str(); - path.ends_with(".d.ts") - || path.ends_with(".d.cts") - || path.ends_with(".d.mts") - || matches!( - Utf8Path::new(path).extension(), - Some("ts" | "tsx" | "cts" | "mts") - ) + matches!( + path.extension(), + Some("ts" | "tsx" | "cts" | "mts") + ) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_resolver/src/lib.rs` around lines 734 - 743, The predicate in is_type_resolution_path redundantly checks for ".d.ts", ".d.cts", ".d.mts" via ends_with(...) even though Utf8Path::new(path).extension() already yields "ts"/"cts"/"mts" for those files; remove the explicit ends_with checks and simplify the function to only test the extension (using Utf8Path::new(path).extension() matches Some("ts" | "tsx" | "cts" | "mts")) so the logic is correct and non-redundant while keeping the Utf8Path usage intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@crates/biome_resolver/src/lib.rs`:
- Around line 734-743: The predicate in is_type_resolution_path redundantly
checks for ".d.ts", ".d.cts", ".d.mts" via ends_with(...) even though
Utf8Path::new(path).extension() already yields "ts"/"cts"/"mts" for those files;
remove the explicit ends_with checks and simplify the function to only test the
extension (using Utf8Path::new(path).extension() matches Some("ts" | "tsx" |
"cts" | "mts")) so the logic is correct and non-redundant while keeping the
Utf8Path usage intact.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0a836284-678f-4477-93ac-670af0ce1301
⛔ Files ignored due to path filters (10)
crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/runtime-main/dist/index.d.tsis excluded by!**/dist/**,!**/node_modules/**and included by**crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/runtime-main/dist/index.jsis excluded by!**/dist/**,!**/node_modules/**and included by**crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/runtime-main/package.jsonis excluded by!**/node_modules/**and included by**crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/source-main/package.jsonis excluded by!**/node_modules/**and included by**crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/source-main/src/index.tsis excluded by!**/node_modules/**and included by**crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/types-and-main/package.jsonis excluded by!**/node_modules/**and included by**crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/types-and-main/src/index.tsis excluded by!**/node_modules/**and included by**crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/types-and-main/types/index.d.tsis excluded by!**/node_modules/**and included by**crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/untyped-main/dist/index.jsis excluded by!**/dist/**,!**/node_modules/**and included by**crates/biome_resolver/tests/fixtures/resolver_cases_5/node_modules/untyped-main/package.jsonis excluded by!**/node_modules/**and included by**
📒 Files selected for processing (3)
.changeset/long-boxes-walk.mdcrates/biome_resolver/src/lib.rscrates/biome_resolver/tests/spec_tests.rs
Made-with: Cursor
There was a problem hiding this comment.
🧹 Nitpick comments (3)
crates/biome_resolver/src/lib.rs (3)
734-736: Subtle but correct — worth a comment for posterity.This works for both raw TS sources (
.ts/.tsx/.cts/.mts) and declaration files, becauseUtf8Path::extension()returns just the part after the last dot — sofoo.d.tsreports"ts",foo.d.cts→"cts", etc. That's the very reason the fallback at lines 665–676 still works whenmainpoints at a.jsfile butresolve_path_infoswaps it for a sibling.d.ts.It's a pleasant little coincidence, but easy to break with a future refactor. A one-line comment would save the next traveller from doing the same head-scratching:
📝 Suggested comment
fn is_type_resolution_path(path: &Utf8Path) -> bool { + // Note: `Utf8Path::extension()` returns the substring after the last + // dot, so declaration files (`.d.ts`, `.d.cts`, `.d.mts`) also match + // here via their `ts`/`cts`/`mts` extensions. matches!(path.extension(), Some("ts" | "tsx" | "cts" | "mts")) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_resolver/src/lib.rs` around lines 734 - 736, Add a one-line explanatory comment above the is_type_resolution_path function noting that Utf8Path::extension() returns only the substring after the last dot (so files like "foo.d.ts" yield "ts", "foo.d.cts" → "cts"), which is why this matcher correctly treats declaration files as TypeScript and why resolve_path_info's fallback still works when main points to a .js but a sibling .d.ts is used; reference the function name is_type_resolution_path and Utf8Path::extension in the comment for future clarity.
884-885: Doc nit: tighten themainfallback description.The new wording suggests
mainis used as a fallback "if it resolves", but the implementation actually requires it to resolve to a TypeScript source or declaration file. Worth aligning the comment with reality so future readers don't get a nasty surprise.📝 Suggested wording
- /// - If the `package.json`'s `types` field is not configured, the `main` - /// field is used as a fallback if it resolves. + /// - If the `package.json`'s `types` field is not configured, the `main` + /// field is used as a fallback only when it resolves to a TypeScript + /// source file or a declaration file (e.g. `.ts`, `.tsx`, `.d.ts`). + /// Untyped runtime JavaScript is intentionally rejected.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_resolver/src/lib.rs` around lines 884 - 885, The doc comment about package.json fallback is misleading: update the sentence that currently says "`main` field is used as a fallback if it resolves" to explicitly state that `main` is only used as a fallback when it resolves to a TypeScript source or declaration file (e.g. .ts, .tsx, or .d.ts). Edit the comment in crates/biome_resolver/src/lib.rs alongside the existing paragraph so it references the exact condition (resolves to a TS source or declaration) and aligns with the logic in the resolver functions that check file extensions before accepting `main`.
665-676: Logic looks good — one minor consideration on swallowed errors.The
if let Ok(path) = ...happily discards every error variant fromresolve_relative_path, not justNotFound. In practice that means aBrokenSymlinkor other propagatable error on themaintarget would be silently dropped, and resolution falls through toresolve_relative_path(subpath, ...)at line 684 with an emptysubpath, ultimately returningNotFound/DirectoryWithoutDefault.That's almost certainly fine (and arguably desirable — a broken
mainshouldn't necessarily fail type resolution), but it's a slight behavioural divergence from the non-types branch at lines 677–680, which propagates errors. If that's intentional, no action needed. Otherwise, consider matchingNotFoundexplicitly and bubbling other errors:♻️ Optional tightening
if let Some(target) = &package_json.main { let options = options.without_extensions_or_manifests(); // In type-resolution mode, `main` is only useful if it // points at TypeScript source or lets us discover a // declaration file. Avoid returning untyped runtime // JavaScript when no type entrypoint exists. - if let Ok(path) = resolve_relative_path(target, &package_path, fs, &options) - && is_type_resolution_path(&path) - { - return Ok(path); + match resolve_relative_path(target, &package_path, fs, &options) { + Ok(path) if is_type_resolution_path(&path) => return Ok(path), + Ok(_) | Err(ResolveError::NotFound) => { /* fall through */ } + Err(error) => return Err(error), } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_resolver/src/lib.rs` around lines 665 - 676, The current code uses `if let Ok(path) = resolve_relative_path(target, &package_path, fs, &options)` which swallows every error from `resolve_relative_path`; change this to explicitly handle errors so only `NotFound` (or whichever non-fatal error you choose) is ignored while other errors are propagated: call `resolve_relative_path(target, &package_path, fs, &options)` and `match` on the Result, returning `Ok(path)` only when `is_type_resolution_path(&path)` holds, ignoring `Err(NotFound)` but returning `Err(e)` for other error variants (keep references to `package_json.main`, `options.without_extensions_or_manifests()`, `package_path`, `fs`, and `is_type_resolution_path` to locate the change).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@crates/biome_resolver/src/lib.rs`:
- Around line 734-736: Add a one-line explanatory comment above the
is_type_resolution_path function noting that Utf8Path::extension() returns only
the substring after the last dot (so files like "foo.d.ts" yield "ts",
"foo.d.cts" → "cts"), which is why this matcher correctly treats declaration
files as TypeScript and why resolve_path_info's fallback still works when main
points to a .js but a sibling .d.ts is used; reference the function name
is_type_resolution_path and Utf8Path::extension in the comment for future
clarity.
- Around line 884-885: The doc comment about package.json fallback is
misleading: update the sentence that currently says "`main` field is used as a
fallback if it resolves" to explicitly state that `main` is only used as a
fallback when it resolves to a TypeScript source or declaration file (e.g. .ts,
.tsx, or .d.ts). Edit the comment in crates/biome_resolver/src/lib.rs alongside
the existing paragraph so it references the exact condition (resolves to a TS
source or declaration) and aligns with the logic in the resolver functions that
check file extensions before accepting `main`.
- Around line 665-676: The current code uses `if let Ok(path) =
resolve_relative_path(target, &package_path, fs, &options)` which swallows every
error from `resolve_relative_path`; change this to explicitly handle errors so
only `NotFound` (or whichever non-fatal error you choose) is ignored while other
errors are propagated: call `resolve_relative_path(target, &package_path, fs,
&options)` and `match` on the Result, returning `Ok(path)` only when
`is_type_resolution_path(&path)` holds, ignoring `Err(NotFound)` but returning
`Err(e)` for other error variants (keep references to `package_json.main`,
`options.without_extensions_or_manifests()`, `package_path`, `fs`, and
`is_type_resolution_path` to locate the change).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6c5be92c-eea2-4943-b697-5e92f00be35f
📒 Files selected for processing (1)
crates/biome_resolver/src/lib.rs
Made-with: Cursor
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/biome_resolver/src/lib.rs (1)
734-738: Optional: consider matching declaration extensions explicitly.Relying on
Utf8Path::extension()returning"ts"forindex.d.tsworks (and the comment helpfully calls this out), but it also means a file literally namedfoo.tsis treated identically to a true declaration file. That's intentional here — TS source is a valid type entrypoint — so this is fine as-is. If you ever want to distinguish "definitely a declaration" from "TS source", you'd need afile_name().ends_with(".d.ts")-style check. Just flagging in case it matters down the line; no action required.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_resolver/src/lib.rs` around lines 734 - 738, The current is_type_resolution_path uses Utf8Path::extension() which treats both ".d.ts" and ".ts" the same; if you want to distinguish true declaration files, change is_type_resolution_path to first check path.file_name().map(|n| n.ends_with(".d.ts") || n.ends_with(".d.tsx") || n.ends_with(".d.cts") || n.ends_with(".d.mts")).unwrap_or(false) to detect explicit declaration filenames, and fall back to the existing Utf8Path::extension() matches for TS source files; update the function body in is_type_resolution_path to combine the file_name().ends_with(...) check with the extension match accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@crates/biome_resolver/src/lib.rs`:
- Around line 734-738: The current is_type_resolution_path uses
Utf8Path::extension() which treats both ".d.ts" and ".ts" the same; if you want
to distinguish true declaration files, change is_type_resolution_path to first
check path.file_name().map(|n| n.ends_with(".d.ts") || n.ends_with(".d.tsx") ||
n.ends_with(".d.cts") || n.ends_with(".d.mts")).unwrap_or(false) to detect
explicit declaration filenames, and fall back to the existing
Utf8Path::extension() matches for TS source files; update the function body in
is_type_resolution_path to combine the file_name().ends_with(...) check with the
extension match accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 566dce6e-2a5f-4cf6-83be-55f36f42a85b
📒 Files selected for processing (1)
crates/biome_resolver/src/lib.rs
|
I was under the impression that the |
Good question. I noticed this pattern in my company's large pnpm workspace where our private workspace packages (which we reference via It looks like The TypeScript docs describe package type resolution as checking optional I also verified this with TypeScript’s resolver API: with no |
|
ahh, ok. that makes sense. thanks for the explanation. |
dyc3
left a comment
There was a problem hiding this comment.
The change makes sense to me at a glance, but I'd like a second opinion.
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.4.13` -> `2.4.14`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.4.13/2.4.14) | --- ### Release Notes <details> <summary>biomejs/biome (@​biomejs/biome)</summary> ### [`v2.4.14`](https://github.com/biomejs/biome/blob/HEAD/packages/@​biomejs/biome/CHANGELOG.md#2414) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.13...@biomejs/biome@2.4.14) ##### Patch Changes - [#​9393](biomejs/biome#9393) [`491b171`](biomejs/biome@491b171) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`useTestHooksOnTop`](https://biomejs.dev/linter/rules/use-test-hooks-on-top) in the `test` domain. The rule flags lifecycle hooks (`beforeEach`, `beforeAll`, `afterEach`, `afterAll`) that appear after test cases in the same block, enforcing that hooks are defined before any test case. - [#​10157](biomejs/biome#10157) [`eefc5ab`](biomejs/biome@eefc5ab) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​7882](biomejs/biome#7882): The HTML parser will now emit better diagnostics when it encounters a void element with a closing tag, such as `<br></br>`. Previously, the parser would emit multiple diagnostics with conflicting advice. Now it emits a single diagnostic that clearly states that void elements should not have closing tags. - [#​10054](biomejs/biome#10054) [`0e9f569`](biomejs/biome@0e9f569) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) no longer misses widening from concrete object types, class instances, object literals, tuples, functions, and regular expressions to `: object`. A function annotated `: object` returning an object literal: ```ts function f(): object { return { retry: true }; } ``` - [#​10116](biomejs/biome#10116) [`53269eb`](biomejs/biome@53269eb) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​6201](biomejs/biome#6201): [`noUselessEscapeInRegex`](https://biomejs.dev/linter/rules/no-useless-escape-in-regex/) no longer flags an escaped backslash followed by `-` as a useless escape. Patterns like `/[\\-]/` are now considered valid because the second `\` is the escaped backslash, not an unnecessary escape of the trailing dash. - [#​10092](biomejs/biome#10092) [`33d8543`](biomejs/biome@33d8543) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​9097](biomejs/biome#9097): [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) no longer adds a blank line between a never-matched group and a matched group. Given the following `organizeImports` options: ```json { "groups": [":NODE:", ":BLANK_LINE:", ":PACKAGE:", ":BLANK_LINE:", ":PATH:"] } ``` The following code... ```js // Comment import "package"; import "./file.js"; ``` ...was organized as: ```diff + // Comment import "package"; + import "./file.js"; ``` A blank line was added even though the group ':NODE:' doesn't match any imports here. `:BLANK_LINE:` between never-matched groups and matched groups are now ignored. The code is now organized as: ```diff // Comment import "package"; + import "./file.js"; ``` - [#​10138](biomejs/biome#10138) [`a10b6c1`](biomejs/biome@a10b6c1) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed Vue `v-for` handling for [`noUndeclaredVariables`](https://biomejs.dev/linter/rules/no-undeclared-variables/) and [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/). Biome now recognizes variables declared by `v-for` directives and references to iterated values in Vue templates. - [#​10115](biomejs/biome#10115) [`d428d76`](biomejs/biome@d428d76) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) no longer reports false positives when a union return type's `boolean` variant is covered by both `true` and `false` returns. - [#​9922](biomejs/biome#9922) [`7acf1e0`](biomejs/biome@7acf1e0) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`noReactStringRefs`](https://biomejs.dev/linter/rules/no-react-string-refs/), which disallows legacy React string refs such as `ref="hello"` and `this.refs.hello`. Biome also reports template-literal refs such as ``ref={`hello`}``, so React code can consistently migrate to callback refs, `createRef()`, or `useRef()`. - [#​10010](biomejs/biome#10010) [`f3e76ab`](biomejs/biome@f3e76ab) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed a bug in the LSP file watcher registration so Biome now watches `.biome.json` and `.biome.jsonc` configuration files and reloads workspace settings when they change. - [#​10176](biomejs/biome#10176) [`8a40ef8`](biomejs/biome@8a40ef8) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10011](biomejs/biome#10011): The [`noThisInStatic`](https://biomejs.dev/linter/rules/no-this-in-static/) rule no longer reports `this` when it is used as the constructor target in `new this(...)`, which is required for inherited static factory methods. - [#​10163](biomejs/biome#10163) [`6867e96`](biomejs/biome@6867e96) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​9884](biomejs/biome#9884): The [`useSortedAttributes`](https://biomejs.dev/assist/actions/use-sorted-attributes/) auto-fix no longer corrupts source code when both an outer JSX element and a nested JSX-valued attribute have unsorted attributes in the same pass. Multiple unsorted groups separated by spread or shorthand attributes within the same JSX element are now reported as a single diagnostic. - [#​10079](biomejs/biome#10079) [`d29dd19`](biomejs/biome@d29dd19) Thanks [@​Damix48](https://github.com/Damix48)! - Fixed false positive in `noAssignInExpressions` for Svelte `{@​const}` blocks. Assignments in `{@​const name = value}` are now correctly recognized as declarations rather than accidental assignments in expressions. - [#​10080](biomejs/biome#10080) [`5d8fdac`](biomejs/biome@5d8fdac) Thanks [@​Damix48](https://github.com/Damix48)! - Fixed parsing of closing parentheses in Svelte `{#each}` block key expressions. Biome now correctly parses method calls and other parenthesised expressions used as keys. For example, the following snippets are now parsed correctly: ```svelte {#each numbers as number, index (number.toString())} <p>{number}</p> {/each} {#each numbers as number (key(number))} <p>{number}</p> {/each} ``` - [#​10140](biomejs/biome#10140) [`e7024b9`](biomejs/biome@e7024b9) Thanks [@​solithcy](https://github.com/solithcy)! - Fixed [#​10135](biomejs/biome#10135): Biome no longer crashes on missing Svelte template expressions. The following code snippet longer panics: ```svelte {#if } <p>^ this would previously crash</p> {/if} {@​const } <p> ^ this would also crash</p> ``` - [#​10111](biomejs/biome#10111) [`7818009`](biomejs/biome@7818009) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​9997](biomejs/biome#9997): [`noDuplicateSelectors`](https://biomejs.dev/linter/rules/no-duplicate-selectors/) no longer reports false positives for selectors inside `@scope` queries. Biome now treats `@scope` as a separate at-rule context, like `@media`, `@supports`, `@container`, and `@starting-style`. The following snippet is no longer flagged as a duplicate: ```css .Example { padding: 0; } @​scope (.theme-dark) { .Example { color: white; } } ``` - [#​9926](biomejs/biome#9926) [`d62b331`](biomejs/biome@d62b331) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery lint rule [`useMathMinMax`](https://biomejs.dev/linter/rules/use-math-min-max/), which prefers `Math.min()` and `Math.max()` over equivalent ternary comparisons. For example, this code: ```js const min = a < b ? a : b; ``` is much more readable when rewritten as: ```js const min = Math.min(a, b); ``` - [#​10115](biomejs/biome#10115) [`d428d76`](biomejs/biome@d428d76) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/) now flags missing `true`/`false` cases for `boolean` discriminants, including when `boolean` is a union variant. - [#​10125](biomejs/biome#10125) [`a55a0b6`](biomejs/biome@a55a0b6) Thanks [@​bmish](https://github.com/bmish)! - Fixed a resolver bug where packages that define a typed entry point through `package.json`'s `main` field but omit `types` were ignored during type-aware resolution. Type-aware rules such as [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) can now inspect imports from those packages. - [#​10117](biomejs/biome#10117) [`895e809`](biomejs/biome@895e809) Thanks [@​denizdogan](https://github.com/denizdogan)! - Added support for the `corner-shape` family of CSS properties and the `superellipse()`/`squircle()` value functions, so [`noUnknownProperty`](https://biomejs.dev/linter/rules/no-unknown-property/) and [`noUnknownFunction`](https://biomejs.dev/linter/rules/no-unknown-function/) no longer flag them as unknown. New known properties: `corner-shape`, `corner-block-end-shape`, `corner-block-start-shape`, `corner-bottom-left-shape`, `corner-bottom-right-shape`, `corner-bottom-shape`, `corner-end-end-shape`, `corner-end-start-shape`, `corner-inline-end-shape`, `corner-inline-start-shape`, `corner-left-shape`, `corner-right-shape`, `corner-start-end-shape`, `corner-start-start-shape`, `corner-top-left-shape`, `corner-top-right-shape`, `corner-top-shape`. New known value functions: `superellipse()`, `squircle()`. - [#​8620](biomejs/biome#8620) [`8df8f73`](biomejs/biome@8df8f73) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​8062](biomejs/biome#8062): Added support for parsing Vue `v-for` directives more accurately. - [#​10191](biomejs/biome#10191) [`aa055cd`](biomejs/biome@aa055cd) Thanks [@​guney](https://github.com/guney)! - Now the rule [`noStaticElementInteractions`](https://biomejs.dev/linter/rules/no-static-element-interactions/) doesn't trigger custom elements. - [#​9757](biomejs/biome#9757) [`2c62594`](biomejs/biome@2c62594) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​9099](biomejs/biome#9099): the HTML formatter collapsing non-text children (inline elements, Svelte expressions, comments) onto a single line when the source had them on separate lines. Biome now preserves the user's intended line breaks for exclusively non-text children. For example, the following Svelte snippet is now preserved instead of being collapsed to `<div>{name}<!-- comment --></div>`: ```svelte <div> {name}<!-- comment --> </div> ``` Similarly, HTML elements like `<span>` inside a `<div>` are now preserved when written on their own line: ```html <div> <span>text</span> </div> ``` - [#​10105](biomejs/biome#10105) [`e7c1a6d`](biomejs/biome@e7c1a6d) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​10039](biomejs/biome#10039): [`useReadonlyClassProperties`](https://biomejs.dev/linter/rules/use-readonly-class-properties/) now detects unreassigned private members in class expressions and export default classes, not only in class declarations. The following patterns are now correctly flagged: ```ts const AnonClass = class { #prop = 123; constructor() { console.log(this.#prop); } }; export default class { #prop = 123; constructor() { console.log(this.#prop); } } ``` - [#​10141](biomejs/biome#10141) [`46a77d0`](biomejs/biome@46a77d0) Thanks [@​minseong0324](https://github.com/minseong0324)! - Improved [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/) to detect conditions that are always truthy because they check built-in global class instances such as `Date`, `Map`, `Set`, `WeakMap`, and `Error`. - [#​10178](biomejs/biome#10178) [`7b05a89`](biomejs/biome@7b05a89) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10177](biomejs/biome#10177): The HTML parser no longer reports lowercase `html` or `doctype` text as invalid after void elements such as `<br>`. - [#​10155](biomejs/biome#10155) [`0d4595d`](biomejs/biome@0d4595d) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​10045](biomejs/biome#10045): the CSS formatter no longer compounds indentation inside nested functional pseudo-classes such as `:not(:where(...))`, `:is(:where(...))`, and similar combinations. The same fix also removes one level of unnecessary indentation that was added inside any pseudo-class function whose argument list wrapped onto multiple lines, including `:nth-child(... of ...)`, `::part(...)`, and `:active-view-transition-type(...)`. The following snippet is now correctly formatted, matching Prettier. ```css input:not( :where( [type="submit"], [type="checkbox"], [type="radio"], [type="button"], [type="reset"] ) ) { inline-size: 100%; } ``` - [#​10112](biomejs/biome#10112) [`6f0251e`](biomejs/biome@6f0251e) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10110](biomejs/biome#10110): Biome's parser now accepts surrogate code points in JavaScript string `\u{...}` escapes. - [#​10141](biomejs/biome#10141) [`46a77d0`](biomejs/biome@46a77d0) Thanks [@​minseong0324](https://github.com/minseong0324)! - Improved [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) to detect `object` return annotations that hide built-in global class instances such as `Date`, `Map`, `Set`, `WeakMap`, and `Error`. - [#​10083](biomejs/biome#10083) [`4a664c1`](biomejs/biome@4a664c1) Thanks [@​ematipico](https://github.com/ematipico)! - Added two new options to [`noShadow`](https://biomejs.dev/linter/rules/no-shadow/), both defaulting to `true` to match typescript-eslint's behavior. Fixed [#​9482](biomejs/biome#9482): Added `ignoreFunctionTypeParameterNameValueShadow` option. When enabled, parameter names inside function type annotations (e.g. `(options: unknown) => void`) are not flagged as shadowing outer variables. Fixed [#​7812](biomejs/biome#7812): Added `ignoreTypeValueShadow` option. When enabled, a value binding that shares its name with a type-only declaration (type alias or interface) is not flagged, since types and values occupy separate namespaces in TypeScript. - [#​9286](biomejs/biome#9286) [`52695cf`](biomejs/biome@52695cf) Thanks [@​Hugo-Polloli](https://github.com/Hugo-Polloli)! - Fixed [#​6316](biomejs/biome#6316): Biome now resolves Svelte `$store` references to the underlying `store` binding in semantic analysis, preventing false `noUndeclaredVariables` diagnostics when the store is declared. - [#​10188](biomejs/biome#10188) [`ae659dd`](biomejs/biome@ae659dd) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`noExcessiveNestedCallbacks`](https://biomejs.dev/linter/rules/no-excessive-nested-callbacks/), which disallows callbacks nested deeper than the configured maximum. - [#​9757](biomejs/biome#9757) [`2c62594`](biomejs/biome@2c62594) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​9450](biomejs/biome#9450): the HTML formatter now correctly preserves multiline formatting for nested `<template>` elements (e.g. `<template #body>`) when the source has children on separate lines. Previously, the children were collapsed onto a single line. ```diff <template> <UModal> - <template #body> <p>content</p> </template> + <template #body> + <p>content</p> + </template> </UModal> </template> ``` - [#​10118](biomejs/biome#10118) [`c6edcb4`](biomejs/biome@c6edcb4) Thanks [@​Netail](https://github.com/Netail)! - Fixed [#​10024](biomejs/biome#10024): `biome migrate eslint` correctly migrates `eslint` rules that belong to multiple Biome rules. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNjAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE2MC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Client/pulls/2
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.4.13` -> `2.4.14`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.4.13/2.4.14) | --- ### Release Notes <details> <summary>biomejs/biome (@​biomejs/biome)</summary> ### [`v2.4.14`](https://github.com/biomejs/biome/blob/HEAD/packages/@​biomejs/biome/CHANGELOG.md#2414) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.13...@biomejs/biome@2.4.14) ##### Patch Changes - [#​9393](biomejs/biome#9393) [`491b171`](biomejs/biome@491b171) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`useTestHooksOnTop`](https://biomejs.dev/linter/rules/use-test-hooks-on-top) in the `test` domain. The rule flags lifecycle hooks (`beforeEach`, `beforeAll`, `afterEach`, `afterAll`) that appear after test cases in the same block, enforcing that hooks are defined before any test case. - [#​10157](biomejs/biome#10157) [`eefc5ab`](biomejs/biome@eefc5ab) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​7882](biomejs/biome#7882): The HTML parser will now emit better diagnostics when it encounters a void element with a closing tag, such as `<br></br>`. Previously, the parser would emit multiple diagnostics with conflicting advice. Now it emits a single diagnostic that clearly states that void elements should not have closing tags. - [#​10054](biomejs/biome#10054) [`0e9f569`](biomejs/biome@0e9f569) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) no longer misses widening from concrete object types, class instances, object literals, tuples, functions, and regular expressions to `: object`. A function annotated `: object` returning an object literal: ```ts function f(): object { return { retry: true }; } ``` - [#​10116](biomejs/biome#10116) [`53269eb`](biomejs/biome@53269eb) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​6201](biomejs/biome#6201): [`noUselessEscapeInRegex`](https://biomejs.dev/linter/rules/no-useless-escape-in-regex/) no longer flags an escaped backslash followed by `-` as a useless escape. Patterns like `/[\\-]/` are now considered valid because the second `\` is the escaped backslash, not an unnecessary escape of the trailing dash. - [#​10092](biomejs/biome#10092) [`33d8543`](biomejs/biome@33d8543) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​9097](biomejs/biome#9097): [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) no longer adds a blank line between a never-matched group and a matched group. Given the following `organizeImports` options: ```json { "groups": [":NODE:", ":BLANK_LINE:", ":PACKAGE:", ":BLANK_LINE:", ":PATH:"] } ``` The following code... ```js // Comment import "package"; import "./file.js"; ``` ...was organized as: ```diff + // Comment import "package"; + import "./file.js"; ``` A blank line was added even though the group ':NODE:' doesn't match any imports here. `:BLANK_LINE:` between never-matched groups and matched groups are now ignored. The code is now organized as: ```diff // Comment import "package"; + import "./file.js"; ``` - [#​10138](biomejs/biome#10138) [`a10b6c1`](biomejs/biome@a10b6c1) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed Vue `v-for` handling for [`noUndeclaredVariables`](https://biomejs.dev/linter/rules/no-undeclared-variables/) and [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/). Biome now recognizes variables declared by `v-for` directives and references to iterated values in Vue templates. - [#​10115](biomejs/biome#10115) [`d428d76`](biomejs/biome@d428d76) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) no longer reports false positives when a union return type's `boolean` variant is covered by both `true` and `false` returns. - [#​9922](biomejs/biome#9922) [`7acf1e0`](biomejs/biome@7acf1e0) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`noReactStringRefs`](https://biomejs.dev/linter/rules/no-react-string-refs/), which disallows legacy React string refs such as `ref="hello"` and `this.refs.hello`. Biome also reports template-literal refs such as ``ref={`hello`}``, so React code can consistently migrate to callback refs, `createRef()`, or `useRef()`. - [#​10010](biomejs/biome#10010) [`f3e76ab`](biomejs/biome@f3e76ab) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed a bug in the LSP file watcher registration so Biome now watches `.biome.json` and `.biome.jsonc` configuration files and reloads workspace settings when they change. - [#​10176](biomejs/biome#10176) [`8a40ef8`](biomejs/biome@8a40ef8) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10011](biomejs/biome#10011): The [`noThisInStatic`](https://biomejs.dev/linter/rules/no-this-in-static/) rule no longer reports `this` when it is used as the constructor target in `new this(...)`, which is required for inherited static factory methods. - [#​10163](biomejs/biome#10163) [`6867e96`](biomejs/biome@6867e96) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​9884](biomejs/biome#9884): The [`useSortedAttributes`](https://biomejs.dev/assist/actions/use-sorted-attributes/) auto-fix no longer corrupts source code when both an outer JSX element and a nested JSX-valued attribute have unsorted attributes in the same pass. Multiple unsorted groups separated by spread or shorthand attributes within the same JSX element are now reported as a single diagnostic. - [#​10079](biomejs/biome#10079) [`d29dd19`](biomejs/biome@d29dd19) Thanks [@​Damix48](https://github.com/Damix48)! - Fixed false positive in `noAssignInExpressions` for Svelte `{@​const}` blocks. Assignments in `{@​const name = value}` are now correctly recognized as declarations rather than accidental assignments in expressions. - [#​10080](biomejs/biome#10080) [`5d8fdac`](biomejs/biome@5d8fdac) Thanks [@​Damix48](https://github.com/Damix48)! - Fixed parsing of closing parentheses in Svelte `{#each}` block key expressions. Biome now correctly parses method calls and other parenthesised expressions used as keys. For example, the following snippets are now parsed correctly: ```svelte {#each numbers as number, index (number.toString())} <p>{number}</p> {/each} {#each numbers as number (key(number))} <p>{number}</p> {/each} ``` - [#​10140](biomejs/biome#10140) [`e7024b9`](biomejs/biome@e7024b9) Thanks [@​solithcy](https://github.com/solithcy)! - Fixed [#​10135](biomejs/biome#10135): Biome no longer crashes on missing Svelte template expressions. The following code snippet longer panics: ```svelte {#if } <p>^ this would previously crash</p> {/if} {@​const } <p> ^ this would also crash</p> ``` - [#​10111](biomejs/biome#10111) [`7818009`](biomejs/biome@7818009) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​9997](biomejs/biome#9997): [`noDuplicateSelectors`](https://biomejs.dev/linter/rules/no-duplicate-selectors/) no longer reports false positives for selectors inside `@scope` queries. Biome now treats `@scope` as a separate at-rule context, like `@media`, `@supports`, `@container`, and `@starting-style`. The following snippet is no longer flagged as a duplicate: ```css .Example { padding: 0; } @​scope (.theme-dark) { .Example { color: white; } } ``` - [#​9926](biomejs/biome#9926) [`d62b331`](biomejs/biome@d62b331) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery lint rule [`useMathMinMax`](https://biomejs.dev/linter/rules/use-math-min-max/), which prefers `Math.min()` and `Math.max()` over equivalent ternary comparisons. For example, this code: ```js const min = a < b ? a : b; ``` is much more readable when rewritten as: ```js const min = Math.min(a, b); ``` - [#​10115](biomejs/biome#10115) [`d428d76`](biomejs/biome@d428d76) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/) now flags missing `true`/`false` cases for `boolean` discriminants, including when `boolean` is a union variant. - [#​10125](biomejs/biome#10125) [`a55a0b6`](biomejs/biome@a55a0b6) Thanks [@​bmish](https://github.com/bmish)! - Fixed a resolver bug where packages that define a typed entry point through `package.json`'s `main` field but omit `types` were ignored during type-aware resolution. Type-aware rules such as [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) can now inspect imports from those packages. - [#​10117](biomejs/biome#10117) [`895e809`](biomejs/biome@895e809) Thanks [@​denizdogan](https://github.com/denizdogan)! - Added support for the `corner-shape` family of CSS properties and the `superellipse()`/`squircle()` value functions, so [`noUnknownProperty`](https://biomejs.dev/linter/rules/no-unknown-property/) and [`noUnknownFunction`](https://biomejs.dev/linter/rules/no-unknown-function/) no longer flag them as unknown. New known properties: `corner-shape`, `corner-block-end-shape`, `corner-block-start-shape`, `corner-bottom-left-shape`, `corner-bottom-right-shape`, `corner-bottom-shape`, `corner-end-end-shape`, `corner-end-start-shape`, `corner-inline-end-shape`, `corner-inline-start-shape`, `corner-left-shape`, `corner-right-shape`, `corner-start-end-shape`, `corner-start-start-shape`, `corner-top-left-shape`, `corner-top-right-shape`, `corner-top-shape`. New known value functions: `superellipse()`, `squircle()`. - [#​8620](biomejs/biome#8620) [`8df8f73`](biomejs/biome@8df8f73) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​8062](biomejs/biome#8062): Added support for parsing Vue `v-for` directives more accurately. - [#​10191](biomejs/biome#10191) [`aa055cd`](biomejs/biome@aa055cd) Thanks [@​guney](https://github.com/guney)! - Now the rule [`noStaticElementInteractions`](https://biomejs.dev/linter/rules/no-static-element-interactions/) doesn't trigger custom elements. - [#​9757](biomejs/biome#9757) [`2c62594`](biomejs/biome@2c62594) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​9099](biomejs/biome#9099): the HTML formatter collapsing non-text children (inline elements, Svelte expressions, comments) onto a single line when the source had them on separate lines. Biome now preserves the user's intended line breaks for exclusively non-text children. For example, the following Svelte snippet is now preserved instead of being collapsed to `<div>{name}<!-- comment --></div>`: ```svelte <div> {name}<!-- comment --> </div> ``` Similarly, HTML elements like `<span>` inside a `<div>` are now preserved when written on their own line: ```html <div> <span>text</span> </div> ``` - [#​10105](biomejs/biome#10105) [`e7c1a6d`](biomejs/biome@e7c1a6d) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​10039](biomejs/biome#10039): [`useReadonlyClassProperties`](https://biomejs.dev/linter/rules/use-readonly-class-properties/) now detects unreassigned private members in class expressions and export default classes, not only in class declarations. The following patterns are now correctly flagged: ```ts const AnonClass = class { #prop = 123; constructor() { console.log(this.#prop); } }; export default class { #prop = 123; constructor() { console.log(this.#prop); } } ``` - [#​10141](biomejs/biome#10141) [`46a77d0`](biomejs/biome@46a77d0) Thanks [@​minseong0324](https://github.com/minseong0324)! - Improved [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/) to detect conditions that are always truthy because they check built-in global class instances such as `Date`, `Map`, `Set`, `WeakMap`, and `Error`. - [#​10178](biomejs/biome#10178) [`7b05a89`](biomejs/biome@7b05a89) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10177](biomejs/biome#10177): The HTML parser no longer reports lowercase `html` or `doctype` text as invalid after void elements such as `<br>`. - [#​10155](biomejs/biome#10155) [`0d4595d`](biomejs/biome@0d4595d) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​10045](biomejs/biome#10045): the CSS formatter no longer compounds indentation inside nested functional pseudo-classes such as `:not(:where(...))`, `:is(:where(...))`, and similar combinations. The same fix also removes one level of unnecessary indentation that was added inside any pseudo-class function whose argument list wrapped onto multiple lines, including `:nth-child(... of ...)`, `::part(...)`, and `:active-view-transition-type(...)`. The following snippet is now correctly formatted, matching Prettier. ```css input:not( :where( [type="submit"], [type="checkbox"], [type="radio"], [type="button"], [type="reset"] ) ) { inline-size: 100%; } ``` - [#​10112](biomejs/biome#10112) [`6f0251e`](biomejs/biome@6f0251e) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10110](biomejs/biome#10110): Biome's parser now accepts surrogate code points in JavaScript string `\u{...}` escapes. - [#​10141](biomejs/biome#10141) [`46a77d0`](biomejs/biome@46a77d0) Thanks [@​minseong0324](https://github.com/minseong0324)! - Improved [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) to detect `object` return annotations that hide built-in global class instances such as `Date`, `Map`, `Set`, `WeakMap`, and `Error`. - [#​10083](biomejs/biome#10083) [`4a664c1`](biomejs/biome@4a664c1) Thanks [@​ematipico](https://github.com/ematipico)! - Added two new options to [`noShadow`](https://biomejs.dev/linter/rules/no-shadow/), both defaulting to `true` to match typescript-eslint's behavior. Fixed [#​9482](biomejs/biome#9482): Added `ignoreFunctionTypeParameterNameValueShadow` option. When enabled, parameter names inside function type annotations (e.g. `(options: unknown) => void`) are not flagged as shadowing outer variables. Fixed [#​7812](biomejs/biome#7812): Added `ignoreTypeValueShadow` option. When enabled, a value binding that shares its name with a type-only declaration (type alias or interface) is not flagged, since types and values occupy separate namespaces in TypeScript. - [#​9286](biomejs/biome#9286) [`52695cf`](biomejs/biome@52695cf) Thanks [@​Hugo-Polloli](https://github.com/Hugo-Polloli)! - Fixed [#​6316](biomejs/biome#6316): Biome now resolves Svelte `$store` references to the underlying `store` binding in semantic analysis, preventing false `noUndeclaredVariables` diagnostics when the store is declared. - [#​10188](biomejs/biome#10188) [`ae659dd`](biomejs/biome@ae659dd) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`noExcessiveNestedCallbacks`](https://biomejs.dev/linter/rules/no-excessive-nested-callbacks/), which disallows callbacks nested deeper than the configured maximum. - [#​9757](biomejs/biome#9757) [`2c62594`](biomejs/biome@2c62594) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​9450](biomejs/biome#9450): the HTML formatter now correctly preserves multiline formatting for nested `<template>` elements (e.g. `<template #body>`) when the source has children on separate lines. Previously, the children were collapsed onto a single line. ```diff <template> <UModal> - <template #body> <p>content</p> </template> + <template #body> + <p>content</p> + </template> </UModal> </template> ``` - [#​10118](biomejs/biome#10118) [`c6edcb4`](biomejs/biome@c6edcb4) Thanks [@​Netail](https://github.com/Netail)! - Fixed [#​10024](biomejs/biome#10024): `biome migrate eslint` correctly migrates `eslint` rules that belong to multiple Biome rules. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNjAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE2MC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Server/pulls/10
Summary
Fixes type-aware package resolution for packages that omit
typesbut pointpackage.json'smainfield at a typed entry point.Before this change, type-resolution mode ignored
mainentirely whentypeswas absent. That meant workspace/source packages such as packages withmain: "./src/index.ts"could not be resolved by type-aware rules. The resolver now still preferstypes, but can fall back tomainwhen it resolves to TypeScript source or a declaration file, while avoiding untyped runtime JavaScript.Context
typesis recommended for published packages, but TypeScript does not require it for package resolution.The TypeScript docs describe package type resolution as checking optional
types, thenmain, then rootindex.d.ts: https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html#editing-the-packagejson. Extension substitution also explains why a JavaScriptmaincan resolve to a sibling.d.ts: https://www.typescriptlang.org/docs/handbook/modules/reference.html#file-extension-substitution.This matters for pnpm workspaces because local workspace packages can be linked into
node_modulesviaworkspace:*, so TypeScript sees them as packages and applies package resolution. In a large private pnpm workspace I checked, many internal packages usemain: "./src/index.ts"withouttypes.This PR keeps Biome narrower than TypeScript: it only accepts the
mainfallback when it resolves to TypeScript source or declarations, and still rejects untyped runtime JavaScript.Test Plan
Added resolver coverage for typed
mainfallback,typesprecedence, JavaScriptmaindeclaration discovery, and untyped JavaScript rejection.cargo test -p biome_resolverRelated
Builds on a related improvement I made recently:
Potentially related issue:
Docs
N/A