From fe41c42ec5247fd47a0bd3f31a7ced1e2573d025 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Tue, 19 May 2026 14:13:36 +0800 Subject: [PATCH] chore: switch code formatter from Prettier to Biome (#4223) Replace Prettier with Biome for formatting JS/TS/JSX/CSS/JSON. The CI format check drops from ~23s to ~0.4s. - Unify config into a single root biome.json (formatter + linter); the former apps/readest-app/biome.json was linter-only - Mirror the old .prettierrc.json style: 100 line width, 2-space indent, LF, single quotes, trailing commas - Enable the CSS tailwindDirectives parser for @apply in globals.css - Convert // prettier-ignore comments to // biome-ignore format: - Root scripts and lint-staged now run biome; apps/readest-app lint runs `biome lint` (lint-only) so formatting stays a separate CI step - Drop prettier + prettier-plugin-tailwindcss dependencies Markdown/YAML are no longer format-checked (Biome does not format them) and Tailwind class sorting is no longer enforced. Co-authored-by: Claude Opus 4.7 (1M context) --- .prettierignore | 40 ----- .prettierrc.json | 10 -- .vscode/extensions.json | 2 +- .vscode/settings.json | 13 +- CONTRIBUTING.md | 2 +- apps/readest-app/AGENTS.md | 4 +- apps/readest-app/package.json | 2 +- .../services/sync/replicaSettingsSync.test.ts | 10 +- .../services/translators/providers.test.ts | 10 +- .../src/__tests__/utils/txt.test.ts | 163 +++++++++++------- .../src/components/primitives/button.tsx | 3 +- .../src/services/translators/cache.ts | 7 +- apps/readest-app/src/types/book.ts | 3 +- apps/readest-app/src/types/system.ts | 2 +- apps/readest-app/src/utils/book.ts | 2 +- apps/readest-app/src/utils/validation.ts | 2 +- apps/readest-app/biome.json => biome.json | 79 +++++++-- package.json | 10 +- pnpm-lock.yaml | 78 --------- 19 files changed, 199 insertions(+), 243 deletions(-) delete mode 100644 .prettierignore delete mode 100644 .prettierrc.json rename apps/readest-app/biome.json => biome.json (67%) diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index e45fcd25..00000000 --- a/.prettierignore +++ /dev/null @@ -1,40 +0,0 @@ -# Dependencies -node_modules -pnpm-lock.yaml - -# Build Artifacts (Web & Rust) -.next -.open-next -.build -.tauri -out -build -dist -target -fastlane -.wrangler - -# Autogenerated Tauri files -gen -**/autogenerated -**/schemas - -# Submodules (External Repos) -packages - -# Claude Code Skills & Config -apps/readest-app/.claude - -# Vendored Assets (Generated/External Code) -apps/readest-app/public/*.js -apps/readest-app/public/vendor -apps/readest-app/src-tauri/plugins/tauri-plugin-turso -apps/readest-app/src-tauri/plugins/tauri-plugin-webview-upgrade - -# Environment & Editor -.github -.env -.env.* -.vscode -.idea -*.log diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 5f19d4e2..00000000 --- a/.prettierrc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "trailingComma": "all", - "printWidth": 100, - "semi": true, - "tabWidth": 2, - "singleQuote": true, - "jsxSingleQuote": true, - "endOfLine": "lf", - "plugins": ["prettier-plugin-tailwindcss"] -} diff --git a/.vscode/extensions.json b/.vscode/extensions.json index fab1098c..77980092 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,7 +2,7 @@ "recommendations": [ "ms-vscode.vscode-typescript-next", "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode", + "biomejs.biome", "rust-lang.rust-analyzer" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index f0d8e61d..1bc0d4a7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,19 +13,20 @@ "javascript.validate.enable": false, "javascript.format.enable": false, "typescript.format.enable": false, - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "biomejs.biome", "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "[css]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "biomejs.biome" }, "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "biomejs.biome" }, "[typescriptreact]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "biomejs.biome" }, - "prettier.requireConfig": true, - "prettier.documentSelectors": ["**/*.{js,jsx,ts,tsx,css,json,md,html,yml}"] + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + } } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3b1c718b..2dc9f3f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,7 +86,7 @@ Recommended Visual Studio Code plugins for development: - JavaScript and TypeScript Nightly (ms-vscode.vscode-typescript-next) - VS Code ESLint extension (dbaeumer.vscode-eslint) -- Prettier - Code formatter (esbenp.prettier-vscode) +- Biome - Code formatter and linter (biomejs.biome) - rust-analyzer (rust-lang.rust-analyzer) (for Tauri development only) ### When you're done diff --git a/apps/readest-app/AGENTS.md b/apps/readest-app/AGENTS.md index 5843e961..9ba0519b 100644 --- a/apps/readest-app/AGENTS.md +++ b/apps/readest-app/AGENTS.md @@ -23,8 +23,8 @@ pnpm test:tauri # Run Tauri integration tests # Linting & Formatting pnpm lint # Biome (linter) + tsgo (type check) -pnpm format # Prettier (runs from monorepo root) -pnpm format:check # Check formatting without writing +pnpm format # Biome formatter (runs from monorepo root) +pnpm format:check # Check formatting without writing (Biome) # Rust pnpm fmt:check # Check formatting Rust code (src-tauri) diff --git a/apps/readest-app/package.json b/apps/readest-app/package.json index 570a1d44..bbac2111 100644 --- a/apps/readest-app/package.json +++ b/apps/readest-app/package.json @@ -17,7 +17,7 @@ "dev-android": "tauri android build -t aarch64 -- --features devtools && adb install -r src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk", "dev-ios": "tauri ios build -- --features devtools && ideviceinstaller -i src-tauri/gen/apple/build/arm64/Readest.ipa", "i18n:extract": "i18next-scanner --config i18next-scanner.config.cjs", - "lint": "tsgo --noEmit && biome check . && pnpm lint:lua", + "lint": "tsgo --noEmit && biome lint . && pnpm lint:lua", "lint:lua": "node ../readest.koplugin/scripts/lint-koplugin.mjs", "test:lua": "node ../readest.koplugin/scripts/test-koplugin.mjs", "test": "dotenv -e .env -e .env.test.local -- vitest", diff --git a/apps/readest-app/src/__tests__/services/sync/replicaSettingsSync.test.ts b/apps/readest-app/src/__tests__/services/sync/replicaSettingsSync.test.ts index 5ffe072a..4189bfcf 100644 --- a/apps/readest-app/src/__tests__/services/sync/replicaSettingsSync.test.ts +++ b/apps/readest-app/src/__tests__/services/sync/replicaSettingsSync.test.ts @@ -166,8 +166,9 @@ describe('publishSettingsIfChanged', () => { }); test('publishes dictionarySettings.providerOrder when markExplicitProviderOrderPublish was called', async () => { - const { markExplicitProviderOrderPublish } = - await import('@/services/sync/replicaSettingsSync'); + const { markExplicitProviderOrderPublish } = await import( + '@/services/sync/replicaSettingsSync' + ); markExplicitProviderOrderPublish(); await publishSettingsIfChanged( makeSettings({ @@ -184,8 +185,9 @@ describe('publishSettingsIfChanged', () => { }); test('explicit-publish opt-in is consumed after one publish (no carryover)', async () => { - const { markExplicitProviderOrderPublish } = - await import('@/services/sync/replicaSettingsSync'); + const { markExplicitProviderOrderPublish } = await import( + '@/services/sync/replicaSettingsSync' + ); markExplicitProviderOrderPublish(); const settings1 = makeSettings({ dictionarySettings: { diff --git a/apps/readest-app/src/__tests__/services/translators/providers.test.ts b/apps/readest-app/src/__tests__/services/translators/providers.test.ts index 2573b773..aa7e66b9 100644 --- a/apps/readest-app/src/__tests__/services/translators/providers.test.ts +++ b/apps/readest-app/src/__tests__/services/translators/providers.test.ts @@ -352,8 +352,9 @@ describe('provider registry disabled handling', () => { }); it('isTranslatorAvailable returns false for disabled providers', async () => { - const { getTranslator, isTranslatorAvailable } = - await import('@/services/translators/providers'); + const { getTranslator, isTranslatorAvailable } = await import( + '@/services/translators/providers' + ); const yandex = getTranslator('yandex')!; expect(isTranslatorAvailable(yandex, true)).toBe(false); expect(isTranslatorAvailable(yandex, false)).toBe(false); @@ -373,8 +374,9 @@ describe('provider registry disabled handling', () => { }); it('getTranslatorDisplayLabel returns the plain label for healthy providers', async () => { - const { getTranslator, getTranslatorDisplayLabel } = - await import('@/services/translators/providers'); + const { getTranslator, getTranslatorDisplayLabel } = await import( + '@/services/translators/providers' + ); const google = getTranslator('google')!; expect(getTranslatorDisplayLabel(google, true, (s) => s)).toBe('Google Translate'); }); diff --git a/apps/readest-app/src/__tests__/utils/txt.test.ts b/apps/readest-app/src/__tests__/utils/txt.test.ts index b16232ad..84cca16f 100644 --- a/apps/readest-app/src/__tests__/utils/txt.test.ts +++ b/apps/readest-app/src/__tests__/utils/txt.test.ts @@ -76,23 +76,38 @@ describe('createChapterRegexps — Chinese (zh) regex matching', () => { }); describe('第N[卷节回讲篇封本册部话] variants', () => { - it.each(['卷', '节', '回', '讲', '篇', '封', '本', '册', '部', '话'])( - 'should match 第一%s', - (suffix) => { - const regex = getFirstRegex('zh'); - expect(regex.test(`\n第一${suffix}\n`)).toBe(true); - }, - ); + it.each([ + '卷', + '节', + '回', + '讲', + '篇', + '封', + '本', + '册', + '部', + '话', + ])('should match 第一%s', (suffix) => { + const regex = getFirstRegex('zh'); + expect(regex.test(`\n第一${suffix}\n`)).toBe(true); + }); }); describe('Chinese preface keywords', () => { - it.each(['楔子', '前言', '简介', '引言', '序言', '序章', '总论', '概论', '后记'])( - 'should match %s', - (keyword) => { - const regex = getFirstRegex('zh'); - expect(regex.test(`\n${keyword}\n`)).toBe(true); - }, - ); + it.each([ + '楔子', + '前言', + '简介', + '引言', + '序言', + '序章', + '总论', + '概论', + '后记', + ])('should match %s', (keyword) => { + const regex = getFirstRegex('zh'); + expect(regex.test(`\n${keyword}\n`)).toBe(true); + }); it('should match 前言 with title', () => { const regex = getFirstRegex('zh'); @@ -106,13 +121,15 @@ describe('createChapterRegexps — Chinese (zh) regex matching', () => { }); describe('"chapter" keyword in Chinese context', () => { - it.each(['Chapter 1', 'CHAPTER 10', 'chapter.5', 'chapter 2: The Beginning'])( - 'should match "%s" (case-insensitive)', - (heading) => { - const regex = getFirstRegex('zh'); - expect(regex.test(`\n${heading}\n`)).toBe(true); - }, - ); + it.each([ + 'Chapter 1', + 'CHAPTER 10', + 'chapter.5', + 'chapter 2: The Beginning', + ])('should match "%s" (case-insensitive)', (heading) => { + const regex = getFirstRegex('zh'); + expect(regex.test(`\n${heading}\n`)).toBe(true); + }); }); describe('番外 (bonus) prefix variants', () => { @@ -167,13 +184,16 @@ describe('createChapterRegexps — Chinese (zh) second regex', () => { // --------------------------------------------------------------------------- describe('createChapterRegexps — English (en) regex matching', () => { describe('Chapter keyword', () => { - it.each(['Chapter 1', 'Chapter 12', 'Chapter 999', 'CHAPTER 5', 'chapter 3'])( - 'should match "%s"', - (heading) => { - const regex = getFirstRegex('en'); - expect(regex.test(`\n${heading}\n`)).toBe(true); - }, - ); + it.each([ + 'Chapter 1', + 'Chapter 12', + 'Chapter 999', + 'CHAPTER 5', + 'chapter 3', + ])('should match "%s"', (heading) => { + const regex = getFirstRegex('en'); + expect(regex.test(`\n${heading}\n`)).toBe(true); + }); it('should match "Chapter 1: Title" with title', () => { const regex = getFirstRegex('en'); @@ -187,21 +207,30 @@ describe('createChapterRegexps — English (en) regex matching', () => { }); describe('Roman numeral chapters', () => { - it.each(['V', 'X', 'L', 'C', 'D', 'M'])( - 'should match single Roman numeral "Chapter %s"', - (numeral) => { - const regex = getFirstRegex('en'); - expect(regex.test(`\nChapter ${numeral}\n`)).toBe(true); - }, - ); + it.each([ + 'V', + 'X', + 'L', + 'C', + 'D', + 'M', + ])('should match single Roman numeral "Chapter %s"', (numeral) => { + const regex = getFirstRegex('en'); + expect(regex.test(`\nChapter ${numeral}\n`)).toBe(true); + }); - it.each(['II', 'III', 'IV', 'VII', 'XII', 'XIV', 'XLII'])( - 'should match multi-char Roman numeral "Chapter %s"', - (numeral) => { - const regex = getFirstRegex('en'); - expect(regex.test(`\nChapter ${numeral}\n`)).toBe(true); - }, - ); + it.each([ + 'II', + 'III', + 'IV', + 'VII', + 'XII', + 'XIV', + 'XLII', + ])('should match multi-char Roman numeral "Chapter %s"', (numeral) => { + const regex = getFirstRegex('en'); + expect(regex.test(`\nChapter ${numeral}\n`)).toBe(true); + }); it('should not match single "I" as Roman numeral (not in allowed set)', () => { const regex = getFirstRegex('en'); @@ -223,31 +252,39 @@ describe('createChapterRegexps — English (en) regex matching', () => { expect(regex.test(`\n${keyword} 1\n`)).toBe(true); }); - it.each(['Part', 'Section', 'Book', 'Volume', 'Act'])( - 'should match "%s 3: A New Beginning" with title', - (keyword) => { - const regex = getFirstRegex('en'); - expect(regex.test(`\n${keyword} 3: A New Beginning\n`)).toBe(true); - }, - ); + it.each([ + 'Part', + 'Section', + 'Book', + 'Volume', + 'Act', + ])('should match "%s 3: A New Beginning" with title', (keyword) => { + const regex = getFirstRegex('en'); + expect(regex.test(`\n${keyword} 3: A New Beginning\n`)).toBe(true); + }); }); describe('preface keywords', () => { - it.each(['Prologue', 'Epilogue', 'Introduction', 'Foreword', 'Preface', 'Afterword'])( - 'should match "%s"', - (keyword) => { - const regex = getFirstRegex('en'); - expect(regex.test(`\n${keyword}\n`)).toBe(true); - }, - ); + it.each([ + 'Prologue', + 'Epilogue', + 'Introduction', + 'Foreword', + 'Preface', + 'Afterword', + ])('should match "%s"', (keyword) => { + const regex = getFirstRegex('en'); + expect(regex.test(`\n${keyword}\n`)).toBe(true); + }); - it.each(['PROLOGUE', 'prologue', 'Prologue'])( - 'should match "%s" case-insensitively', - (keyword) => { - const regex = getFirstRegex('en'); - expect(regex.test(`\n${keyword}\n`)).toBe(true); - }, - ); + it.each([ + 'PROLOGUE', + 'prologue', + 'Prologue', + ])('should match "%s" case-insensitively', (keyword) => { + const regex = getFirstRegex('en'); + expect(regex.test(`\n${keyword}\n`)).toBe(true); + }); it('should match "Prologue: The Beginning"', () => { const regex = getFirstRegex('en'); diff --git a/apps/readest-app/src/components/primitives/button.tsx b/apps/readest-app/src/components/primitives/button.tsx index fc744165..eb6278a5 100644 --- a/apps/readest-app/src/components/primitives/button.tsx +++ b/apps/readest-app/src/components/primitives/button.tsx @@ -33,7 +33,8 @@ const buttonVariants = cva( ); export interface ButtonProps - extends React.ButtonHTMLAttributes, VariantProps { + extends React.ButtonHTMLAttributes, + VariantProps { asChild?: boolean; } diff --git a/apps/readest-app/src/services/translators/cache.ts b/apps/readest-app/src/services/translators/cache.ts index f09cf0cb..76c3f706 100644 --- a/apps/readest-app/src/services/translators/cache.ts +++ b/apps/readest-app/src/services/translators/cache.ts @@ -424,12 +424,7 @@ export const getCacheStats = async ( }; export const pruneCache = async ( - options: { - maxAge?: number; - maxEntries?: number; - maxSizeInBytes?: number; - dryRun?: boolean; - } = {}, + options: { maxAge?: number; maxEntries?: number; maxSizeInBytes?: number; dryRun?: boolean } = {}, ): Promise => { const { maxAge, maxEntries, maxSizeInBytes, dryRun = false } = options; diff --git a/apps/readest-app/src/types/book.ts b/apps/readest-app/src/types/book.ts index 5761a346..9cbd868d 100644 --- a/apps/readest-app/src/types/book.ts +++ b/apps/readest-app/src/types/book.ts @@ -340,8 +340,7 @@ export interface ViewSettingsConfig { } export interface ViewSettings - extends - BookLayout, + extends BookLayout, BookStyle, BookFont, BookLanguage, diff --git a/apps/readest-app/src/types/system.ts b/apps/readest-app/src/types/system.ts index 0978428d..b8062fb7 100644 --- a/apps/readest-app/src/types/system.ts +++ b/apps/readest-app/src/types/system.ts @@ -13,7 +13,7 @@ import type { SelectedFile } from '@/hooks/useFileSelector'; export type AppPlatform = 'web' | 'tauri' | 'node'; export type OsPlatform = 'android' | 'ios' | 'macos' | 'windows' | 'linux' | 'unknown'; -// prettier-ignore +// biome-ignore format: keep the union members compact on a single line export type BaseDir = | 'Books' | 'Settings' | 'Data' | 'Fonts' | 'Images' | 'Dictionaries' | 'Log' | 'Cache' | 'Temp' | 'None'; export type DeleteAction = 'cloud' | 'local' | 'both'; export type SelectDirectoryMode = 'read' | 'write'; diff --git a/apps/readest-app/src/utils/book.ts b/apps/readest-app/src/utils/book.ts index 7281bb42..6c8cf663 100644 --- a/apps/readest-app/src/utils/book.ts +++ b/apps/readest-app/src/utils/book.ts @@ -112,7 +112,7 @@ export const flattenContributors = ( : formatLanguageMap(contributors?.name); }; -// prettier-ignore +// biome-ignore format: keep the language codes compact on a single line const LASTNAME_AUTHOR_SORT_LANGS = [ 'ar', 'bo', 'de', 'en', 'es', 'fr', 'hi', 'it', 'nl', 'pl', 'pt', 'ru', 'th', 'tr', 'uk' ]; const formatAuthorName = (name: string, lastNameFirst: boolean) => { diff --git a/apps/readest-app/src/utils/validation.ts b/apps/readest-app/src/utils/validation.ts index 86ac3342..0d1b90c1 100644 --- a/apps/readest-app/src/utils/validation.ts +++ b/apps/readest-app/src/utils/validation.ts @@ -3,7 +3,7 @@ */ // ISO 639-1 language codes (2-letter codes) -// prettier-ignore +// biome-ignore format: keep the ISO codes grouped by first letter const ISO_639_1_CODES = new Set([ 'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av', 'ay', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br', 'bs', diff --git a/apps/readest-app/biome.json b/biome.json similarity index 67% rename from apps/readest-app/biome.json rename to biome.json index c94c5d7c..8353872f 100644 --- a/apps/readest-app/biome.json +++ b/biome.json @@ -1,25 +1,68 @@ { "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json", "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }, - "files": { "ignoreUnknown": true }, - "formatter": { "enabled": false }, + "files": { + "ignoreUnknown": true, + "includes": [ + "**", + "!**/node_modules/**", + "!**/packages/**", + "!**/.claude/**", + "!**/gen/**", + "!**/autogenerated/**", + "!**/schemas/**" + ] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 100, + "lineEnding": "lf", + "includes": [ + "**", + "!**/.next/**", + "!**/.open-next/**", + "!**/.build/**", + "!**/.tauri/**", + "!**/.wrangler/**", + "!**/.vercel/**", + "!**/out/**", + "!**/build/**", + "!**/dist/**", + "!**/target/**", + "!**/fastlane/**", + "!apps/readest-app/public/*.js", + "!apps/readest-app/public/vendor/**", + "!apps/readest-app/src-tauri/plugins/tauri-plugin-turso/**", + "!apps/readest-app/src-tauri/plugins/tauri-plugin-webview-upgrade/**", + "!**/*.mjs", + "!**/*.cjs", + "!**/*.mts", + "!pnpm-lock.yaml" + ] + }, "assist": { "enabled": false }, - "css": { "linter": { "enabled": false } }, + "css": { + "parser": { "tailwindDirectives": true }, + "linter": { "enabled": false }, + "formatter": { "enabled": true, "quoteStyle": "single" } + }, "linter": { "enabled": true, "includes": [ "**", - "!.next/**", - "!.open-next/**", - "!.wrangler/**", - "!.claude/**", - "!dist/**", - "!out/**", - "!build/**", - "!public/**", - "!src-tauri/**", - "!next-env.d.ts", - "!i18next-scanner.config.cjs" + "!apps/readest-app/.next/**", + "!apps/readest-app/.open-next/**", + "!apps/readest-app/.wrangler/**", + "!apps/readest-app/.claude/**", + "!apps/readest-app/dist/**", + "!apps/readest-app/out/**", + "!apps/readest-app/build/**", + "!apps/readest-app/public/**", + "!apps/readest-app/src-tauri/**", + "!apps/readest-app/next-env.d.ts", + "!apps/readest-app/i18next-scanner.config.cjs" ], "rules": { "recommended": true, @@ -120,6 +163,12 @@ } }, "javascript": { - "globals": ["React"] + "globals": ["React"], + "formatter": { + "quoteStyle": "single", + "jsxQuoteStyle": "single", + "trailingCommas": "all", + "semicolons": "always" + } } } diff --git a/package.json b/package.json index 9d5624d4..08ac40a4 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "prepare": "husky", "fmt:check": "pnpm --filter @readest/readest-app fmt:check", "clippy:check": "pnpm --filter @readest/readest-app clippy:check", - "format": "prettier --write \"**/*.{js,jsx,ts,tsx,css,json,md,html,yml}\"", - "format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,css,json,md,html,yml}\"" + "format": "biome format --write .", + "format:check": "biome format ." }, "packageManager": "pnpm@11.1.1", "devDependencies": { @@ -21,13 +21,11 @@ "@sindresorhus/tsconfig": "^6.0.0", "husky": "^9.1.6", "lint-staged": "^16.2.7", - "prettier": "^3.3.3", - "prettier-plugin-tailwindcss": "^0.6.8", "typescript": "^5" }, "lint-staged": { - "**/*.{js,jsx,ts,tsx,css,json,md,html,yml}": [ - "prettier --write" + "**/*.{js,jsx,ts,tsx,css,json}": [ + "biome format --write --no-errors-on-unmatched" ] } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae5c3dab..402e4729 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,12 +52,6 @@ importers: lint-staged: specifier: ^16.2.7 version: 16.4.0 - prettier: - specifier: ^3.3.3 - version: 3.8.3 - prettier-plugin-tailwindcss: - specifier: ^0.6.8 - version: 0.6.14(prettier@3.8.3) typescript: specifier: ^5 version: 5.9.3 @@ -7072,72 +7066,6 @@ packages: preact@10.29.1: resolution: {integrity: sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg==} - prettier-plugin-tailwindcss@0.6.14: - resolution: {integrity: sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==} - engines: {node: '>=14.21.3'} - peerDependencies: - '@ianvs/prettier-plugin-sort-imports': '*' - '@prettier/plugin-hermes': '*' - '@prettier/plugin-oxc': '*' - '@prettier/plugin-pug': '*' - '@shopify/prettier-plugin-liquid': '*' - '@trivago/prettier-plugin-sort-imports': '*' - '@zackad/prettier-plugin-twig': '*' - prettier: ^3.0 - prettier-plugin-astro: '*' - prettier-plugin-css-order: '*' - prettier-plugin-import-sort: '*' - prettier-plugin-jsdoc: '*' - prettier-plugin-marko: '*' - prettier-plugin-multiline-arrays: '*' - prettier-plugin-organize-attributes: '*' - prettier-plugin-organize-imports: '*' - prettier-plugin-sort-imports: '*' - prettier-plugin-style-order: '*' - prettier-plugin-svelte: '*' - peerDependenciesMeta: - '@ianvs/prettier-plugin-sort-imports': - optional: true - '@prettier/plugin-hermes': - optional: true - '@prettier/plugin-oxc': - optional: true - '@prettier/plugin-pug': - optional: true - '@shopify/prettier-plugin-liquid': - optional: true - '@trivago/prettier-plugin-sort-imports': - optional: true - '@zackad/prettier-plugin-twig': - optional: true - prettier-plugin-astro: - optional: true - prettier-plugin-css-order: - optional: true - prettier-plugin-import-sort: - optional: true - prettier-plugin-jsdoc: - optional: true - prettier-plugin-marko: - optional: true - prettier-plugin-multiline-arrays: - optional: true - prettier-plugin-organize-attributes: - optional: true - prettier-plugin-organize-imports: - optional: true - prettier-plugin-sort-imports: - optional: true - prettier-plugin-style-order: - optional: true - prettier-plugin-svelte: - optional: true - - prettier@3.8.3: - resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} - engines: {node: '>=14'} - hasBin: true - pretty-bytes@6.1.1: resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} engines: {node: ^14.13.1 || >=16.0.0} @@ -16113,12 +16041,6 @@ snapshots: preact@10.29.1: {} - prettier-plugin-tailwindcss@0.6.14(prettier@3.8.3): - dependencies: - prettier: 3.8.3 - - prettier@3.8.3: {} - pretty-bytes@6.1.1: {} pretty-format@27.5.1: