From 202e6654c6dc82dde4263244382c3f967237c34c Mon Sep 17 00:00:00 2001 From: Jesse Katsumata Date: Sun, 15 Nov 2026 15:46:23 +0900 Subject: [PATCH 1/3] chore: upgrade biome to 2.6.7 Dependabot's #1243 bumps the dependency alone, which is why its lint job fails with "Biome exited because the configuration resulted in errors": biome 2 cannot read a v1 config. The upgrade needs the config migration and two code changes alongside it. biome.json, via `biome migrate`: - $schema 1.9.4 -> 2.6.7 - files.ignore: ["lib"] -> files.includes: ["**", "!**/lib"] - organizeImports -> assist.actions.source.organizeImports - linter.rules.recommended: true -> linter.rules.preset: "recommended" biome 2 then surfaced two real findings: `noReactNativeDeepImports` is new, and flags the three deep react-native imports. These are deliberate: UIMenuNativeComponent.ts is a codegen spec, and React Native's codegen expects CodegenTypes and codegenNativeComponent on those exact paths. react-native/index.js does re-export codegenNativeComponent and codegenNativeCommands, so the rule's advice is technically actionable, but rewriting imports the codegen parses risks breaking native builds for no gain. Suppressed with the reasoning recorded inline, so the rule stays active for genuinely accidental deep imports. The spec file needs a file-level `biome-ignore-all` rather than a line suppression, because biome anchors the multi-line type import's diagnostic on the closing `from` line. `noUnusedVariables` flags the unused catch binding in react-native.config.js. Fixed with an optional catch binding, since the error was never used. Verified beyond CI, which covers less of this than it appears to: `yarn lint` clean, `yarn typescript` clean, `yarn test` passes (1 suite, 1 todo -- CI has no test job), and `yarn prepare` builds all three bob targets (CI never runs prepare). Left alone deliberately: `yarn format` reports drift in the markdown files, package.json, plugin/withAndroidDrawables.js and the spec file. The markdown is new scope -- biome 2 formats Markdown and 1.9 did not. The spec file's drift is pre-existing and unrelated: biome 1.9.4 flags the same two lines (a missing trailing comma and `'large'` from #1202) on master. `yarn format` is not part of CI, so none of it gates anything, and reformatting it here would bury the upgrade in an unrelated diff. Co-Authored-By: Claude Opus 5 (1M context) --- biome.json | 10 +- package.json | 2 +- react-native.config.js | 2 +- .../UIMenuNativeComponent.ts | 5 + src/UIMenuView.android.tsx | 1 + yarn.lock | 96 +++++++++++-------- 6 files changed, 70 insertions(+), 46 deletions(-) diff --git a/biome.json b/biome.json index b410c360..db3de939 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.6.7/schema.json", "vcs": { "enabled": false, "clientKind": "git", @@ -7,19 +7,17 @@ }, "files": { "ignoreUnknown": false, - "ignore": ["lib"] + "includes": ["**", "!**/lib"] }, "formatter": { "enabled": true, "indentStyle": "tab" }, - "organizeImports": { - "enabled": true - }, + "assist": { "actions": { "source": { "organizeImports": "on" } } }, "linter": { "enabled": true, "rules": { - "recommended": true + "preset": "recommended" } }, "javascript": { diff --git a/package.json b/package.json index bc37346e..658fb1dc 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ }, "homepage": "https://github.com/react-native-menu/menu#readme", "devDependencies": { - "@biomejs/biome": "1.9.4", + "@biomejs/biome": "2.6.7", "@callstack/react-native-visionos": "^0.79.6", "@react-native-community/cli": "^20.0.2", "@react-native/babel-preset": "^0.81.1", diff --git a/react-native.config.js b/react-native.config.js index 2755895f..00dafb81 100644 --- a/react-native.config.js +++ b/react-native.config.js @@ -12,7 +12,7 @@ const project = (() => { sourceDir: path.join("example", "ios"), }, }); - } catch (e) { + } catch { return undefined; } })(); diff --git a/src/NativeModuleSpecs/UIMenuNativeComponent.ts b/src/NativeModuleSpecs/UIMenuNativeComponent.ts index e065a154..3f871580 100644 --- a/src/NativeModuleSpecs/UIMenuNativeComponent.ts +++ b/src/NativeModuleSpecs/UIMenuNativeComponent.ts @@ -1,3 +1,8 @@ +// biome-ignore-all lint/suspicious/noReactNativeDeepImports: this is a codegen spec file. +// React Native's codegen parses these imports directly and expects CodegenTypes and +// codegenNativeComponent on these exact paths. The top-level entry point does re-export +// codegenNativeComponent, but rewriting the import risks breaking native codegen for no +// benefit -- see the note on this file in CLAUDE.md. import type { DirectEventHandler, Int32, diff --git a/src/UIMenuView.android.tsx b/src/UIMenuView.android.tsx index 0c426304..d7b146de 100644 --- a/src/UIMenuView.android.tsx +++ b/src/UIMenuView.android.tsx @@ -6,6 +6,7 @@ import { } from "react-native"; import type { MenuComponentRef, NativeMenuComponentProps } from "./types"; import { forwardRef, useImperativeHandle, useRef } from "react"; +// biome-ignore lint/suspicious/noReactNativeDeepImports: paired with the codegen spec's own deep import. Kept on this path so the Fabric command dispatch matches what codegen generates. import codegenNativeCommands from "react-native/Libraries/Utilities/codegenNativeCommands"; const NativeMenuComponent = requireNativeComponent( diff --git a/yarn.lock b/yarn.lock index c4f34047..81d9902d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3415,19 +3415,25 @@ __metadata: languageName: node linkType: hard -"@biomejs/biome@npm:1.9.4": - version: 1.9.4 - resolution: "@biomejs/biome@npm:1.9.4" - dependencies: - "@biomejs/cli-darwin-arm64": "npm:1.9.4" - "@biomejs/cli-darwin-x64": "npm:1.9.4" - "@biomejs/cli-linux-arm64": "npm:1.9.4" - "@biomejs/cli-linux-arm64-musl": "npm:1.9.4" - "@biomejs/cli-linux-x64": "npm:1.9.4" - "@biomejs/cli-linux-x64-musl": "npm:1.9.4" - "@biomejs/cli-win32-arm64": "npm:1.9.4" - "@biomejs/cli-win32-x64": "npm:1.9.4" +"@biomejs/biome@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/biome@npm:2.6.7" + dependencies: + "@biomejs/cli-android-arm64": "npm:2.6.7" + "@biomejs/cli-android-x64": "npm:2.6.7" + "@biomejs/cli-darwin-arm64": "npm:2.6.7" + "@biomejs/cli-darwin-x64": "npm:2.6.7" + "@biomejs/cli-linux-arm64": "npm:2.6.7" + "@biomejs/cli-linux-arm64-musl": "npm:2.6.7" + "@biomejs/cli-linux-x64": "npm:2.6.7" + "@biomejs/cli-linux-x64-musl": "npm:2.6.7" + "@biomejs/cli-win32-arm64": "npm:2.6.7" + "@biomejs/cli-win32-x64": "npm:2.6.7" dependenciesMeta: + "@biomejs/cli-android-arm64": + optional: true + "@biomejs/cli-android-x64": + optional: true "@biomejs/cli-darwin-arm64": optional: true "@biomejs/cli-darwin-x64": @@ -3446,62 +3452,76 @@ __metadata: optional: true bin: biome: bin/biome - checksum: 10c0/b5655c5aed9a6fffe24f7d04f15ba4444389d0e891c9ed9106fab7388ac9b4be63185852cc2a937b22940dac3e550b71032a4afd306925cfea436c33e5646b3e + checksum: 10c0/2ad0a8076ce352386dd14f6170eb1ddd8e9ef5b21d6b195a0b92e0a0216b541b85d51eb41432767d00f756c20c47960ca50c475369626117c9e4dc4d12174f91 + languageName: node + linkType: hard + +"@biomejs/cli-android-arm64@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-android-arm64@npm:2.6.7" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@biomejs/cli-android-x64@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-android-x64@npm:2.6.7" + conditions: os=android & cpu=x64 languageName: node linkType: hard -"@biomejs/cli-darwin-arm64@npm:1.9.4": - version: 1.9.4 - resolution: "@biomejs/cli-darwin-arm64@npm:1.9.4" +"@biomejs/cli-darwin-arm64@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-darwin-arm64@npm:2.6.7" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@biomejs/cli-darwin-x64@npm:1.9.4": - version: 1.9.4 - resolution: "@biomejs/cli-darwin-x64@npm:1.9.4" +"@biomejs/cli-darwin-x64@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-darwin-x64@npm:2.6.7" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@biomejs/cli-linux-arm64-musl@npm:1.9.4": - version: 1.9.4 - resolution: "@biomejs/cli-linux-arm64-musl@npm:1.9.4" +"@biomejs/cli-linux-arm64-musl@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-linux-arm64-musl@npm:2.6.7" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@biomejs/cli-linux-arm64@npm:1.9.4": - version: 1.9.4 - resolution: "@biomejs/cli-linux-arm64@npm:1.9.4" +"@biomejs/cli-linux-arm64@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-linux-arm64@npm:2.6.7" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@biomejs/cli-linux-x64-musl@npm:1.9.4": - version: 1.9.4 - resolution: "@biomejs/cli-linux-x64-musl@npm:1.9.4" +"@biomejs/cli-linux-x64-musl@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-linux-x64-musl@npm:2.6.7" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@biomejs/cli-linux-x64@npm:1.9.4": - version: 1.9.4 - resolution: "@biomejs/cli-linux-x64@npm:1.9.4" +"@biomejs/cli-linux-x64@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-linux-x64@npm:2.6.7" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@biomejs/cli-win32-arm64@npm:1.9.4": - version: 1.9.4 - resolution: "@biomejs/cli-win32-arm64@npm:1.9.4" +"@biomejs/cli-win32-arm64@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-win32-arm64@npm:2.6.7" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@biomejs/cli-win32-x64@npm:1.9.4": - version: 1.9.4 - resolution: "@biomejs/cli-win32-x64@npm:1.9.4" +"@biomejs/cli-win32-x64@npm:2.6.7": + version: 2.6.7 + resolution: "@biomejs/cli-win32-x64@npm:2.6.7" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4768,7 +4788,7 @@ __metadata: version: 0.0.0-use.local resolution: "@react-native-menu/menu@workspace:." dependencies: - "@biomejs/biome": "npm:1.9.4" + "@biomejs/biome": "npm:2.6.7" "@callstack/react-native-visionos": "npm:^0.79.6" "@react-native-community/cli": "npm:^20.0.2" "@react-native/babel-preset": "npm:^0.81.1" From 517bba3c939cbfa61bd17ebc85685f63677cad54 Mon Sep 17 00:00:00 2001 From: Jesse Katsumata Date: Sun, 15 Nov 2026 16:29:33 +0900 Subject: [PATCH 2/3] chore: scope the codegen deep-import suppression to the import block Self-review of the previous commit: `biome-ignore-all` switched noReactNativeDeepImports off for the entire spec file, so a genuinely accidental deep import added later would go unreported. biome 2 supports range suppressions, which are a better fit. Verified empirically rather than assumed: with biome-ignore-start/-end around the codegen import block, the two intended imports are suppressed while a probe deep import added after the end marker is still flagged. Co-Authored-By: Claude Opus 5 (1M context) --- src/NativeModuleSpecs/UIMenuNativeComponent.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/NativeModuleSpecs/UIMenuNativeComponent.ts b/src/NativeModuleSpecs/UIMenuNativeComponent.ts index 3f871580..d0deaa6f 100644 --- a/src/NativeModuleSpecs/UIMenuNativeComponent.ts +++ b/src/NativeModuleSpecs/UIMenuNativeComponent.ts @@ -1,8 +1,9 @@ -// biome-ignore-all lint/suspicious/noReactNativeDeepImports: this is a codegen spec file. +// biome-ignore-start lint/suspicious/noReactNativeDeepImports: this is a codegen spec file. // React Native's codegen parses these imports directly and expects CodegenTypes and -// codegenNativeComponent on these exact paths. The top-level entry point does re-export -// codegenNativeComponent, but rewriting the import risks breaking native codegen for no -// benefit -- see the note on this file in CLAUDE.md. +// codegenNativeComponent on these exact paths. react-native/index.js does re-export +// codegenNativeComponent, but rewriting an import that codegen parses risks breaking native +// builds for no benefit -- see the note on this file in CLAUDE.md. Scoped to this import +// block rather than the whole file, so accidental deep imports below are still caught. import type { DirectEventHandler, Int32, @@ -10,6 +11,7 @@ import type { } from "react-native/Libraries/Types/CodegenTypes"; import type { HostComponent, ViewProps } from "react-native"; import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent"; +// biome-ignore-end lint/suspicious/noReactNativeDeepImports: end of the codegen import block. /* Caution, those below are not just typescript types. From 38f8368e4d9c3210d995ed6a8f8de4deff3c295d Mon Sep 17 00:00:00 2001 From: Jesse Katsumata Date: Sun, 15 Nov 2026 16:40:01 +0900 Subject: [PATCH 3/3] fix(android): import codegenNativeCommands from react-native's public entry Review of the previous commit found the suppression on this import was justified by a false claim. UIMenuView.android.tsx is not a codegen spec: RN 0.81 selects spec files by content, matching /export\s+default\s+\(?codegenNativeComponent --- biome.json | 3 ++- src/UIMenuView.android.tsx | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/biome.json b/biome.json index db3de939..3971d3c8 100644 --- a/biome.json +++ b/biome.json @@ -11,7 +11,8 @@ }, "formatter": { "enabled": true, - "indentStyle": "tab" + "indentStyle": "tab", + "includes": ["**", "!**/*.md", "!**/*.yml", "!**/*.yaml"] }, "assist": { "actions": { "source": { "organizeImports": "on" } } }, "linter": { diff --git a/src/UIMenuView.android.tsx b/src/UIMenuView.android.tsx index d7b146de..5fef294d 100644 --- a/src/UIMenuView.android.tsx +++ b/src/UIMenuView.android.tsx @@ -1,4 +1,5 @@ import { + codegenNativeCommands, findNodeHandle, type HostComponent, requireNativeComponent, @@ -6,8 +7,6 @@ import { } from "react-native"; import type { MenuComponentRef, NativeMenuComponentProps } from "./types"; import { forwardRef, useImperativeHandle, useRef } from "react"; -// biome-ignore lint/suspicious/noReactNativeDeepImports: paired with the codegen spec's own deep import. Kept on this path so the Fabric command dispatch matches what codegen generates. -import codegenNativeCommands from "react-native/Libraries/Utilities/codegenNativeCommands"; const NativeMenuComponent = requireNativeComponent( "MenuView",