From c6e284222d3e81005b16b0e2c53065bbbb1ca659 Mon Sep 17 00:00:00 2001 From: Gokhan Kurt Date: Mon, 6 May 2024 15:41:40 +0300 Subject: [PATCH 1/8] feat: add basic support for Biome --- README.md | 2 +- docs/.vitepress/config.ts | 3 +- docs/checkers/biome.md | 34 ++ docs/checkers/overview.md | 2 +- .../runtime/src/components/Diagnostic.ce.vue | 1 + packages/vite-plugin-checker/package.json | 5 + .../src/FileDiagnosticManager.ts | 3 +- .../src/checkers/biome/cli.ts | 68 +++ .../src/checkers/biome/main.ts | 148 +++++ .../src/checkers/biome/types.ts | 67 +++ packages/vite-plugin-checker/src/logger.ts | 2 +- packages/vite-plugin-checker/src/main.ts | 1 + packages/vite-plugin-checker/src/types.ts | 13 + pnpm-lock.yaml | 514 ++++++++++++++++++ 14 files changed, 857 insertions(+), 6 deletions(-) create mode 100644 docs/checkers/biome.md create mode 100644 packages/vite-plugin-checker/src/checkers/biome/cli.ts create mode 100644 packages/vite-plugin-checker/src/checkers/biome/main.ts create mode 100644 packages/vite-plugin-checker/src/checkers/biome/types.ts diff --git a/README.md b/README.md index 60b7d0ae..f049b358 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Visit [documentation](https://vite-plugin-checker.netlify.app) for usage -A Vite plugin that can run TypeScript, VLS, vue-tsc, ESLint, Stylelint in worker thread. +A Vite plugin that can run TypeScript, VLS, vue-tsc, ESLint, Biome, Stylelint in worker thread.

screenshot diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index d55723e6..5ec661f6 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -3,7 +3,7 @@ import { defineConfig } from 'vitepress' export default defineConfig({ lang: 'en-US', title: 'vite-plugin-checker', - description: 'Vite plugin that provide checks of TypeScript, ESLint, vue-tsc, and more.', + description: 'Vite plugin that provide checks of TypeScript, ESLint, Biome, vue-tsc, and more.', lastUpdated: true, themeConfig: { outline: 'deep', @@ -46,6 +46,7 @@ function sidebar() { { text: 'TypeScript', link: '/checkers/typescript' }, { text: 'vue-tsc', link: '/checkers/vue-tsc' }, { text: 'ESLint', link: '/checkers/eslint' }, + { text: 'Biome', link: '/checkers/biome' }, { text: 'Stylelint', link: '/checkers/stylelint' }, { text: 'VLS', link: '/checkers/vls' }, ], diff --git a/docs/checkers/biome.md b/docs/checkers/biome.md new file mode 100644 index 00000000..d0dfd2b7 --- /dev/null +++ b/docs/checkers/biome.md @@ -0,0 +1,34 @@ +# Biome + +## Installation + +1. Make sure [@biomejs/biome](https://www.npmjs.com/package/@biomejs/biome) is installed as peer dependency. + +2. Add `biome` field to plugin config. The exact command to be run can be further configured with `command` and `flags` parameters. See [the documentation](https://biomejs.dev/reference/cli/) for CLI reference. The default root of the command uses Vite's [root](https://vitejs.dev/config/#root). + + :::tip + Do not add `--apply` to the flags since the plugin is only aiming at checking issues. + ::: + + ```js + // e.g. + export default { + plugins: [ + checker({ + biome: { + command: 'check', + }, + }), + ], + } + ``` + +## Configuration + +Advanced object configuration table of `options.biome` + +| field | Type | Default value | Description | +| :----------- | --------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------- | +| command | `'check' \| 'lint' \| 'format' \| 'ci'` | `'lint'` in dev, `'check'` in build | The command to execute biome with | +| flags | `string` | `''` | CLI flags to pass to the command | +| dev.logLevel | `('error' \| 'warning')[]` | `['error', 'warning']` | **(Only in dev mode)** Which level of Biome diagnostics should be emitted to terminal and overlay in dev mode | diff --git a/docs/checkers/overview.md b/docs/checkers/overview.md index 0f38f1d9..e2941baa 100644 --- a/docs/checkers/overview.md +++ b/docs/checkers/overview.md @@ -1,6 +1,6 @@ # Checkers overview -vite-plugin-checkers provide built-in checkers. For now, it supports [TypeScript](/checkers/typescript), [ESLint](/checkers/eslint), [vue-tsc](/checkers/vue-tsc), [VLS](/checkers/vls), [Stylelint](/checkers/stylelint). +vite-plugin-checkers provide built-in checkers. For now, it supports [TypeScript](/checkers/typescript), [ESLint](/checkers/eslint), [Biome](/checkers/biome), [vue-tsc](/checkers/vue-tsc), [VLS](/checkers/vls), [Stylelint](/checkers/stylelint). ## How to add a checker diff --git a/packages/runtime/src/components/Diagnostic.ce.vue b/packages/runtime/src/components/Diagnostic.ce.vue index ca48b39d..ee8ba890 100644 --- a/packages/runtime/src/components/Diagnostic.ce.vue +++ b/packages/runtime/src/components/Diagnostic.ce.vue @@ -36,6 +36,7 @@ function calcLink(text: string) { const checkerColorMap: Record = { TypeScript: '#3178c6', ESLint: '#7b7fe3', + Biome: '#60a5fa', VLS: '#64b587', 'vue-tsc': '#64b587', Stylelint: '#ffffff', diff --git a/packages/vite-plugin-checker/package.json b/packages/vite-plugin-checker/package.json index b2ac98d5..809846b7 100644 --- a/packages/vite-plugin-checker/package.json +++ b/packages/vite-plugin-checker/package.json @@ -55,6 +55,7 @@ "vscode-uri": "^3.0.2" }, "peerDependencies": { + "@biomejs/biome": ">=1.7", "eslint": ">=7", "meow": "^9.0.0", "optionator": "^0.9.1", @@ -66,6 +67,9 @@ "vue-tsc": ">=2.0.0" }, "peerDependenciesMeta": { + "@biomejs/biome": { + "optional": true + }, "eslint": { "optional": true }, @@ -92,6 +96,7 @@ } }, "devDependencies": { + "@biomejs/biome": "^1.7.2", "@types/eslint": "^7.2.14", "@types/fs-extra": "^11.0.1", "@vue/language-core": "^2.0.14", diff --git a/packages/vite-plugin-checker/src/FileDiagnosticManager.ts b/packages/vite-plugin-checker/src/FileDiagnosticManager.ts index 8ecf62ab..6f693c23 100644 --- a/packages/vite-plugin-checker/src/FileDiagnosticManager.ts +++ b/packages/vite-plugin-checker/src/FileDiagnosticManager.ts @@ -2,10 +2,9 @@ import type { NormalizedDiagnostic } from './logger.js' class FileDiagnosticManager { public diagnostics: NormalizedDiagnostic[] = [] - private initialized = false /** - * Only used when initializing the manager + * Resets the diagnostics array */ public initWith(diagnostics: NormalizedDiagnostic[]) { if (this.initialized) { diff --git a/packages/vite-plugin-checker/src/checkers/biome/cli.ts b/packages/vite-plugin-checker/src/checkers/biome/cli.ts new file mode 100644 index 00000000..e2575d10 --- /dev/null +++ b/packages/vite-plugin-checker/src/checkers/biome/cli.ts @@ -0,0 +1,68 @@ +import { exec } from 'child_process' +import { type NormalizedDiagnostic } from '../../logger.js' +import { DiagnosticLevel } from '../../types.js' +import type { BiomeOutput } from './types.js' + +export const severityMap = { + error: DiagnosticLevel.Error, + warning: DiagnosticLevel.Warning, + info: DiagnosticLevel.Suggestion, +} as const + +export function getBiomeCommand(command: string, flags: string, files: string) { + const defaultFlags = '--reporter json' + return ['biome', command || 'lint', flags, defaultFlags, files].filter(Boolean).join(' ') +} + +export function runBiome(command: string) { + return new Promise((resolve, reject) => { + exec(command, (error, stdout, stderr) => { + resolve([...parseBiomeOutput(stdout)]) + }) + }) +} + +function parseBiomeOutput(output: string) { + let parsed: BiomeOutput + try { + parsed = JSON.parse(output) + } catch (e) { + return [] + } + + const diagnostics: NormalizedDiagnostic[] = parsed.diagnostics.map((d) => { + return { + level: severityMap[d.severity as keyof typeof severityMap] ?? DiagnosticLevel.Error, + message: `[${d.category}] ${d.description}`, + conclusion: '', + checker: 'Biome', + id: d.location.path.file, + codeFrame: d.source || '', + loc: { + file: d.location.path.file, + start: getLineAndColumn(d.location.sourceCode, d.location.span?.[0]), + end: getLineAndColumn(d.location.sourceCode, d.location.span?.[1]), + }, + } + }) + + return diagnostics +} + +function getLineAndColumn(text?: string, offset?: number) { + if (!text || !offset) return { line: 0, column: 0 } + + let line = 1 + let column = 1 + + for (let i = 0; i < offset; i++) { + if (text[i] === '\n') { + line++ + column = 1 + } else { + column++ + } + } + + return { line, column } +} diff --git a/packages/vite-plugin-checker/src/checkers/biome/main.ts b/packages/vite-plugin-checker/src/checkers/biome/main.ts new file mode 100644 index 00000000..79fb7f28 --- /dev/null +++ b/packages/vite-plugin-checker/src/checkers/biome/main.ts @@ -0,0 +1,148 @@ +import { fileURLToPath } from 'url' +import chokidar from 'chokidar' + +import { Checker } from '../../Checker.js' +import { ACTION_TYPES, DiagnosticLevel, type CreateDiagnostic } from '../../types.js' +import { + composeCheckerSummary, + consoleLog, + diagnosticToRuntimeError, + diagnosticToTerminalLog, + filterLogLevel, + toClientPayload, +} from '../../logger.js' +import { FileDiagnosticManager } from '../../FileDiagnosticManager.js' +import { parentPort } from 'worker_threads' +import path from 'path' +import { getBiomeCommand, runBiome, severityMap } from './cli.js' + +const __filename = fileURLToPath(import.meta.url) + +const manager = new FileDiagnosticManager() +let createServeAndBuild + +const createDiagnostic: CreateDiagnostic<'biome'> = (pluginConfig) => { + let overlay = true + let terminal = true + + let command = '' + let flags = '' + + if (typeof pluginConfig.biome === 'object') { + command = pluginConfig.biome.command || '' + flags = pluginConfig.biome.flags || '' + } + + return { + config: async ({ enableOverlay, enableTerminal }) => { + overlay = enableOverlay + terminal = enableTerminal + }, + async configureServer({ root }) { + if (!pluginConfig.biome) return + + const logLevel = (() => { + if (typeof pluginConfig.biome !== 'object') return undefined + const userLogLevel = pluginConfig.biome.dev?.logLevel + if (!userLogLevel) return undefined + + return userLogLevel.map((l) => severityMap[l]) + })() + + const dispatchDiagnostics = () => { + const diagnostics = filterLogLevel(manager.getDiagnostics(), logLevel) + + if (terminal) { + diagnostics.forEach((d) => { + consoleLog(diagnosticToTerminalLog(d, 'Biome')) + }) + const errorCount = diagnostics.filter((d) => d.level === DiagnosticLevel.Error).length + const warningCount = diagnostics.filter((d) => d.level === DiagnosticLevel.Warning).length + consoleLog(composeCheckerSummary('Biome', errorCount, warningCount)) + } + + if (overlay) { + parentPort?.postMessage({ + type: ACTION_TYPES.overlayError, + payload: toClientPayload( + 'biome', + diagnostics.map((d) => diagnosticToRuntimeError(d)) + ), + }) + } + } + + const handleFileChange = async (filePath: string, type: 'change' | 'unlink') => { + const absPath = path.resolve(root, filePath) + if (type === 'unlink') { + manager.updateByFileId(absPath, []) + } else if (type === 'change') { + const isConfigFile = path.basename(absPath) === 'biome.json' + + if (isConfigFile) { + const runCommand = getBiomeCommand(command, flags, root) + const diagnostics = await runBiome(runCommand) + manager.initWith(diagnostics) + } else { + const runCommand = getBiomeCommand(command, flags, absPath) + const diagnosticsOfChangedFile = await runBiome(runCommand) + manager.updateByFileId(absPath, diagnosticsOfChangedFile) + } + } + + dispatchDiagnostics() + } + + // initial check + const runCommand = getBiomeCommand(command, flags, root) + const diagnostics = await runBiome(runCommand) + + manager.initWith(diagnostics) + + dispatchDiagnostics() + + // watch lint + const watcher = chokidar.watch([], { + cwd: root, + ignored: (path: string) => path.includes('node_modules'), + }) + watcher.on('change', async (filePath) => { + handleFileChange(filePath, 'change') + }) + watcher.on('unlink', async (filePath) => { + handleFileChange(filePath, 'unlink') + }) + watcher.add('.') + }, + } +} + +export class BiomeChecker extends Checker<'biome'> { + public constructor() { + super({ + name: 'biome', + absFilePath: __filename, + build: { + buildBin: (pluginConfig) => { + if (typeof pluginConfig.biome === 'object') { + const { command, flags } = pluginConfig.biome + return ['biome', [command || 'check', flags || ''] as const] + } + return ['biome', ['check']] + }, + }, + createDiagnostic, + }) + } + + public init() { + const _createServeAndBuild = super.initMainThread() + createServeAndBuild = _createServeAndBuild + super.initWorkerThread() + } +} + +export { createServeAndBuild } +const biomeChecker = new BiomeChecker() +biomeChecker.prepare() +biomeChecker.init() diff --git a/packages/vite-plugin-checker/src/checkers/biome/types.ts b/packages/vite-plugin-checker/src/checkers/biome/types.ts new file mode 100644 index 00000000..5eba0061 --- /dev/null +++ b/packages/vite-plugin-checker/src/checkers/biome/types.ts @@ -0,0 +1,67 @@ +export interface BiomeOutput { + summary: { + changed: number + unchanged: number + duration: { + secs: number + nanos: number + } + errors: number + warnings: number + skipped: number + suggestedFixesSkipped: number + diagnosticsNotPrinted: number + } + diagnostics: Array<{ + category: string + severity: string + description: string + message: Array<{ + elements: Array + content: string + }> + advices: { + advices: Array<{ + diff?: { + dictionary: string + ops: Array<{ + diffOp?: { + equal?: { + range: Array + } + delete?: { + range: Array + } + insert?: { + range: Array + } + } + equalLines?: { + line_count: number + } + }> + } + log?: [ + string, + Array<{ + elements: Array + content: string + }> + ] + }> + } + verboseAdvices: { + advices: Array + } + location: { + path: { + file: string + } + span?: Array + sourceCode?: string + } + tags: Array + source: any + }> + command: string +} diff --git a/packages/vite-plugin-checker/src/logger.ts b/packages/vite-plugin-checker/src/logger.ts index f2f7419d..958d4387 100644 --- a/packages/vite-plugin-checker/src/logger.ts +++ b/packages/vite-plugin-checker/src/logger.ts @@ -88,7 +88,7 @@ export function filterLogLevel( export function diagnosticToTerminalLog( d: NormalizedDiagnostic, - name?: 'TypeScript' | 'vue-tsc' | 'VLS' | 'ESLint' | 'Stylelint' + name?: 'TypeScript' | 'vue-tsc' | 'VLS' | 'ESLint' | 'Stylelint' | 'Biome' ): string { const nameInLabel = name ? `(${name})` : '' const boldBlack = chalk.bold.rgb(0, 0, 0) diff --git a/packages/vite-plugin-checker/src/main.ts b/packages/vite-plugin-checker/src/main.ts index fd52d92e..6bded6e7 100644 --- a/packages/vite-plugin-checker/src/main.ts +++ b/packages/vite-plugin-checker/src/main.ts @@ -30,6 +30,7 @@ const buildInCheckerKeys: BuildInCheckerNames[] = [ 'vls', 'eslint', 'stylelint', + 'biome', ] async function createCheckers( diff --git a/packages/vite-plugin-checker/src/types.ts b/packages/vite-plugin-checker/src/types.ts index 8ae50cbf..8c22b61d 100644 --- a/packages/vite-plugin-checker/src/types.ts +++ b/packages/vite-plugin-checker/src/types.ts @@ -81,6 +81,18 @@ export type StylelintConfig = }> } +/** Biome checker configuration */ +export type BiomeConfig = + | boolean + | { + command?: 'lint' | 'check' | 'format' | 'ci' + flags?: string + dev?: Partial<{ + /** which level of the diagnostic will be emitted from plugin */ + logLevel: ('error' | 'warning' | 'info')[] + }> + } + export enum DiagnosticLevel { Warning = 0, Error = 1, @@ -177,6 +189,7 @@ export interface BuildInCheckers { vls: VlsConfig eslint: EslintConfig stylelint: StylelintConfig + biome: BiomeConfig } export type BuildInCheckerNames = keyof BuildInCheckers diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 869dd3ac..fdff0ebc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -142,6 +142,7 @@ importers: packages/runtime: devDependencies: +<<<<<<< HEAD '@unplugin-vue-ce/sub-style': specifier: 1.0.0-beta.14 version: 1.0.0-beta.14(ansi-colors@4.1.3)(vue@3.4.29(typescript@5.5.3)) @@ -157,8 +158,86 @@ importers: vue-tsc: specifier: ^2.0.14 version: 2.0.21(typescript@5.5.3) +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + '@unplugin-vue-ce/sub-style': 1.0.0-beta.14 + '@vitejs/plugin-vue': 2.3.4_vite@4.3.1+vue@3.3.4 + vite: 4.3.1 + vue: 3.3.4 + vue-tsc: 1.6.1 +======= + '@unplugin-vue-ce/sub-style': 1.0.0-beta.14_vue@3.3.4 + '@vitejs/plugin-vue': 2.3.4_vite@4.3.1+vue@3.3.4 + vite: 4.3.1 + vue: 3.3.4 + vue-tsc: 1.6.1 +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) packages/vite-plugin-checker: +<<<<<<< HEAD +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + specifiers: + '@babel/code-frame': ^7.12.13 + '@types/eslint': ^7.2.14 + '@types/fs-extra': ^11.0.1 + '@types/semver': ^7.3.13 + '@volar/vue-typescript': ^0.33.0 + ansi-escapes: ^4.3.0 + chalk: ^4.1.1 + chokidar: ^3.5.1 + commander: ^8.0.0 + esbuild: ^0.14.27 + fast-glob: ^3.2.7 + fs-extra: ^11.1.0 + meow: ^9.0.0 + npm-run-all: ^4.1.5 + npm-run-path: ^4.0.1 + optionator: ^0.9.1 + semver: ^7.5.0 + strip-ansi: ^6.0.0 + stylelint: ^14.0.0 + tiny-invariant: ^1.1.0 + tsup: ^6.7.0 + typescript: ^5.0.4 + vls: ^0.7.6 + vscode-languageclient: ^7.0.0 + vscode-languageserver: ^7.0.0 + vscode-languageserver-textdocument: ^1.0.1 + vscode-uri: ^3.0.2 + vti: ^0.1.7 + vue-tsc: ^1.6.1 +======= + specifiers: + '@babel/code-frame': ^7.12.13 + '@biomejs/biome': ^1.7.2 + '@types/eslint': ^7.2.14 + '@types/fs-extra': ^11.0.1 + '@types/semver': ^7.3.13 + '@volar/vue-typescript': ^0.33.0 + ansi-escapes: ^4.3.0 + chalk: ^4.1.1 + chokidar: ^3.5.1 + commander: ^8.0.0 + esbuild: ^0.14.27 + fast-glob: ^3.2.7 + fs-extra: ^11.1.0 + meow: ^9.0.0 + npm-run-all: ^4.1.5 + npm-run-path: ^4.0.1 + optionator: ^0.9.1 + semver: ^7.5.0 + strip-ansi: ^6.0.0 + stylelint: ^14.0.0 + tiny-invariant: ^1.1.0 + tsup: ^6.7.0 + typescript: ^5.0.4 + vls: ^0.7.6 + vscode-languageclient: ^7.0.0 + vscode-languageserver: ^7.0.0 + vscode-languageserver-textdocument: ^1.0.1 + vscode-uri: ^3.0.2 + vti: ^0.1.7 + vue-tsc: ^1.6.1 +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) dependencies: '@babel/code-frame': specifier: ^7.12.13 @@ -203,6 +282,7 @@ importers: specifier: ^3.0.2 version: 3.0.8 devDependencies: +<<<<<<< HEAD '@types/eslint': specifier: ^7.2.14 version: 7.29.0 @@ -239,6 +319,38 @@ importers: vue-tsc: specifier: ^2.0.14 version: 2.0.21(typescript@5.5.3) +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + '@types/eslint': 7.29.0 + '@types/fs-extra': 11.0.1 + '@types/semver': 7.3.13 + '@volar/vue-typescript': 0.33.9 + esbuild: 0.14.54 + meow: 9.0.0 + npm-run-all: 4.1.5 + optionator: 0.9.1 + stylelint: 14.13.0 + tsup: 6.7.0_typescript@5.0.4 + typescript: 5.0.4 + vls: 0.7.6 + vti: 0.1.7 + vue-tsc: 1.6.1_typescript@5.0.4 +======= + '@biomejs/biome': 1.7.2 + '@types/eslint': 7.29.0 + '@types/fs-extra': 11.0.1 + '@types/semver': 7.3.13 + '@volar/vue-typescript': 0.33.9 + esbuild: 0.14.54 + meow: 9.0.0 + npm-run-all: 4.1.5 + optionator: 0.9.1 + stylelint: 14.13.0 + tsup: 6.7.0_typescript@5.0.4 + typescript: 5.0.4 + vls: 0.7.6 + vti: 0.1.7 + vue-tsc: 1.6.1_typescript@5.0.4 +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) playground/backend-integration: dependencies: @@ -823,6 +935,7 @@ importers: playground/vls-vue2: dependencies: +<<<<<<< HEAD vue: specifier: ^2.6.14 version: 2.7.16 @@ -838,6 +951,19 @@ importers: vuex: specifier: 3.6.2 version: 3.6.2(vue@2.7.16) +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + vue: 2.7.8 + vue-class-component: 7.2.6_vue@2.7.8 + vue-property-decorator: 9.1.2_chk7q7rgeabwy64hfqmb36krqe + vue-router: 3.5.4 + vuex: 3.6.2_vue@2.7.8 +======= + vue: 2.7.8 + vue-class-component: 7.2.6_vue@2.7.8 + vue-property-decorator: 9.1.2_chk7q7rgeabwy64hfqmb36krqe + vue-router: 3.5.4_vue@2.7.8 + vuex: 3.6.2_vue@2.7.8 +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) devDependencies: '@types/node': specifier: ^15.0.0 @@ -1197,9 +1323,175 @@ packages: '@baiwusanyu/utils-task@1.0.18': resolution: {integrity: sha512-/0hlK00c3vje4XtOUW2UTrhneAYopX/vEqN5OcpZLGppstU02Fo82QpyJUSVZgO2XH3fGouJl/97bTmWjuFXsA==} +<<<<<<< HEAD '@biomejs/biome@1.8.3': resolution: {integrity: sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==} engines: {node: '>=14.21.3'} +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + /@changesets/apply-release-plan/6.1.3: + resolution: {integrity: sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/config': 2.3.0 + '@changesets/get-version-range-type': 0.3.2 + '@changesets/git': 2.0.0 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.7.1 + resolve-from: 5.0.0 + semver: 5.7.1 + dev: true + + /@changesets/assemble-release-plan/5.2.3: + resolution: {integrity: sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.5 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + semver: 5.7.1 + dev: true + + /@changesets/changelog-git/0.1.14: + resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} + dependencies: + '@changesets/types': 5.2.1 + dev: true + + /@changesets/cli/2.26.1: + resolution: {integrity: sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==} +======= + /@biomejs/biome/1.7.2: + resolution: {integrity: sha512-6Skx9N47inLQzYi9RKgJ7PBnUnaHnMe/imqX43cOcJjZtfMnQLxEvfM2Eyo7gChkwrZlwc+VbA4huFRjw2fsYA==} + engines: {node: '>=14.21.3'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.7.2 + '@biomejs/cli-darwin-x64': 1.7.2 + '@biomejs/cli-linux-arm64': 1.7.2 + '@biomejs/cli-linux-arm64-musl': 1.7.2 + '@biomejs/cli-linux-x64': 1.7.2 + '@biomejs/cli-linux-x64-musl': 1.7.2 + '@biomejs/cli-win32-arm64': 1.7.2 + '@biomejs/cli-win32-x64': 1.7.2 + dev: true + + /@biomejs/cli-darwin-arm64/1.7.2: + resolution: {integrity: sha512-CrldIueHivWEWmeTkK8bTXajeX53F8i2Rrkkt8cPZyMtzkrwxf8Riq4a/jz3SQBHkxHFT4TqGbSTNMXe3X1ogA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-darwin-x64/1.7.2: + resolution: {integrity: sha512-UELnLJuJOsTL9meArvn8BtiXDURyPil2Ej9me2uVpEvee8UQdqd/bssP5we400OWShlL1AAML4fn6d2WX5332g==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-linux-arm64-musl/1.7.2: + resolution: {integrity: sha512-kKYZiem7Sj7wI0dpVxJlK7C+TFQwzO/ctufIGXGJAyEmUe9vEKSzV8CXpv+JIRiTWyqaZJ4K+eHz4SPdPCv05w==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-linux-arm64/1.7.2: + resolution: {integrity: sha512-Z1CSGQE6fHz55gkiFHv9E8wEAaSUd7dHSRaxSCBa7utonHqpIeMbvj3Evm1w0WfGLFDtRXLV1fTfEdM0FMTOhA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-linux-x64-musl/1.7.2: + resolution: {integrity: sha512-x10LpGMepDrLS+h2TZ6/T7egpHjGKtiI4GuShNylmBQJWfTotbFf9eseHggrqJ4WZf9yrGoVYrtbxXftuB95sQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-linux-x64/1.7.2: + resolution: {integrity: sha512-vXXyox8/CQijBxAu0+r8FfSO7JlC4tob3PbaFda8gPJFRz2uFJw39HtxVUwbTV1EcU6wSPh4SiRu5sZfP1VHrQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-win32-arm64/1.7.2: + resolution: {integrity: sha512-kRXdlKzcU7INf6/ldu0nVmkOgt7bKqmyXRRCUqqaJfA32+9InTbkD8tGrHZEVYIWr+eTuKcg16qZVDsPSDFZ8g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-win32-x64/1.7.2: + resolution: {integrity: sha512-qHTtpAs+CNglAAuaTy09htoqUhrQyd3nd0aGTuLNqD10h1llMVi8WFZfoa+e5MuDSfYtMK6nW2Tbf6WgzzR1Qw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@changesets/apply-release-plan/6.1.3: + resolution: {integrity: sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/config': 2.3.0 + '@changesets/get-version-range-type': 0.3.2 + '@changesets/git': 2.0.0 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.7.1 + resolve-from: 5.0.0 + semver: 5.7.1 + dev: true + + /@changesets/assemble-release-plan/5.2.3: + resolution: {integrity: sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.5 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + semver: 5.7.1 + dev: true + + /@changesets/changelog-git/0.1.14: + resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} + dependencies: + '@changesets/types': 5.2.1 + dev: true + + /@changesets/cli/2.26.1: + resolution: {integrity: sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==} +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) hasBin: true '@biomejs/cli-darwin-arm64@1.8.3': @@ -2031,18 +2323,90 @@ packages: resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} +<<<<<<< HEAD '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} '@unplugin-vue-ce/sub-style@1.0.0-beta.14': +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + /@unplugin-vue-ce/sub-style/1.0.0-beta.14: +======= + /@unplugin-vue-ce/sub-style/1.0.0-beta.14_vue@3.3.4: +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) resolution: {integrity: sha512-ya79LwoSEdxNeUY8QBD9vfF1iGfOflSS1IpOejU6eKAr3Bkyr1uBbjWgC3NmiK3k4U7XDUJiVQL9TBXs45RRPg==} +<<<<<<< HEAD + peerDependencies: + vue: ^3.3.2 +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + dependencies: + '@babel/parser': 7.22.11 + '@babel/types': 7.22.11 + '@unplugin-vue-ce/utils': 1.0.0-beta.14 + baiwusanyu-utils: 1.0.15 + estree-walker-ts: 1.0.1 + fast-glob: 3.3.1 + fs-extra: 11.1.1 + magic-string: 0.30.3 + unplugin: 1.4.0 + vue: 3.3.4 + transitivePeerDependencies: + - ansi-colors + dev: true +======= peerDependencies: vue: ^3.3.2 + dependencies: + '@babel/parser': 7.22.11 + '@babel/types': 7.22.11 + '@unplugin-vue-ce/utils': 1.0.0-beta.14_vue@3.3.4 + baiwusanyu-utils: 1.0.15 + estree-walker-ts: 1.0.1 + fast-glob: 3.3.1 + fs-extra: 11.1.1 + magic-string: 0.30.3 + unplugin: 1.4.0 + vue: 3.3.4 + transitivePeerDependencies: + - ansi-colors + dev: true +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) +<<<<<<< HEAD '@unplugin-vue-ce/utils@1.0.0-beta.21': resolution: {integrity: sha512-XvIVOO2D8+6u3bywJf/rWXXLecSo82AdI2SRo95HyP0s7v4uoXM+WrABW+6CfZNoScgLFcizujl5OyjruPJ1+A==} peerDependencies: vue: ^3.3.2 +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + /@unplugin-vue-ce/utils/1.0.0-beta.14: + resolution: {integrity: sha512-mjvrdOMoONBQVxHR67zkKhPcds9SEkUe7fd6QjMVpE9XmYDGqU8ZlhZen8TqYy69VaDIZfvjaTUaGy/jVGoowg==} + dependencies: + baiwusanyu-utils: 1.0.15 + estree-walker-ts: 1.0.1 + fast-glob: 3.3.1 + fs-extra: 11.1.1 + magic-string: 0.30.3 + unplugin: 1.4.0 + vue: 3.3.4 + transitivePeerDependencies: + - ansi-colors + dev: true +======= + /@unplugin-vue-ce/utils/1.0.0-beta.14_vue@3.3.4: + resolution: {integrity: sha512-mjvrdOMoONBQVxHR67zkKhPcds9SEkUe7fd6QjMVpE9XmYDGqU8ZlhZen8TqYy69VaDIZfvjaTUaGy/jVGoowg==} + peerDependencies: + vue: ^3.3.2 + dependencies: + baiwusanyu-utils: 1.0.15 + estree-walker-ts: 1.0.1 + fast-glob: 3.3.1 + fs-extra: 11.1.1 + magic-string: 0.30.3 + unplugin: 1.4.0 + vue: 3.3.4 + transitivePeerDependencies: + - ansi-colors + dev: true +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) '@vitejs/plugin-react@2.2.0': resolution: {integrity: sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==} @@ -2152,6 +2516,142 @@ packages: '@vue/component-compiler-utils@3.3.0': resolution: {integrity: sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==} +<<<<<<< HEAD +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + dependencies: + consolidate: 0.15.1 + hash-sum: 1.0.2 + lru-cache: 4.1.5 + merge-source-map: 1.1.0 + postcss: 7.0.39 + postcss-selector-parser: 6.0.10 + source-map: 0.6.1 + vue-template-es2015-compiler: 1.9.1 + optionalDependencies: + prettier: 2.7.1 + transitivePeerDependencies: + - arc-templates + - atpl + - babel-core + - bracket-template + - coffee-script + - dot + - dust + - dustjs-helpers + - dustjs-linkedin + - eco + - ect + - ejs + - haml-coffee + - hamlet + - hamljs + - handlebars + - hogan.js + - htmling + - jade + - jazz + - jqtpl + - just + - liquid-node + - liquor + - lodash + - marko + - mote + - mustache + - nunjucks + - plates + - pug + - qejs + - ractive + - razor-tmpl + - react + - react-dom + - slm + - squirrelly + - swig + - swig-templates + - teacup + - templayed + - then-jade + - then-pug + - tinyliquid + - toffee + - twig + - twing + - underscore + - vash + - velocityjs + - walrus + - whiskers + dev: true +======= + dependencies: + consolidate: 0.15.1 + hash-sum: 1.0.2 + lru-cache: 4.1.5 + merge-source-map: 1.1.0 + postcss: 7.0.39 + postcss-selector-parser: 6.0.10 + source-map: 0.6.1 + vue-template-es2015-compiler: 1.9.1 + optionalDependencies: + prettier: 2.6.0 + transitivePeerDependencies: + - arc-templates + - atpl + - babel-core + - bracket-template + - coffee-script + - dot + - dust + - dustjs-helpers + - dustjs-linkedin + - eco + - ect + - ejs + - haml-coffee + - hamlet + - hamljs + - handlebars + - hogan.js + - htmling + - jade + - jazz + - jqtpl + - just + - liquid-node + - liquor + - lodash + - marko + - mote + - mustache + - nunjucks + - plates + - pug + - qejs + - ractive + - razor-tmpl + - react + - react-dom + - slm + - squirrelly + - swig + - swig-templates + - teacup + - templayed + - then-jade + - then-pug + - tinyliquid + - toffee + - twig + - twing + - underscore + - vash + - velocityjs + - walrus + - whiskers + dev: true +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) '@vue/devtools-api@7.3.2': resolution: {integrity: sha512-qFCm12te9rG0XWLCHm3x8TiZLULEP5s7Ruaadi5jAogwZ5qF7QH7tKc6yXZGV96uM+y1FUlbK+QwVbWgMfXEhQ==} @@ -10309,10 +10809,24 @@ snapshots: transitivePeerDependencies: - supports-color +<<<<<<< HEAD vue-property-decorator@9.1.2(vue-class-component@7.2.6(vue@2.7.16))(vue@2.7.16): dependencies: vue: 2.7.16 vue-class-component: 7.2.6(vue@2.7.16) +||||||| parent of 8c5f5e6 (feat: add basic support for Biome) + /vue-router/3.5.4: + resolution: {integrity: sha512-x+/DLAJZv2mcQ7glH2oV9ze8uPwcI+H+GgTgTmb5I55bCgY3+vXWIsqbYUzbBSZnwFHEJku4eoaH/x98veyymQ==} + dev: false +======= + /vue-router/3.5.4_vue@2.7.8: + resolution: {integrity: sha512-x+/DLAJZv2mcQ7glH2oV9ze8uPwcI+H+GgTgTmb5I55bCgY3+vXWIsqbYUzbBSZnwFHEJku4eoaH/x98veyymQ==} + peerDependencies: + vue: ^2 + dependencies: + vue: 2.7.8 + dev: false +>>>>>>> 8c5f5e6 (feat: add basic support for Biome) vue-router@3.5.1(vue@2.7.16): dependencies: From 672a9766a26d93632df1514262db84c546f36121 Mon Sep 17 00:00:00 2001 From: Gokhan Kurt Date: Mon, 6 May 2024 15:49:57 +0300 Subject: [PATCH 2/8] add changeset --- .changeset/new-kangaroos-hang.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/new-kangaroos-hang.md diff --git a/.changeset/new-kangaroos-hang.md b/.changeset/new-kangaroos-hang.md new file mode 100644 index 00000000..b1806274 --- /dev/null +++ b/.changeset/new-kangaroos-hang.md @@ -0,0 +1,5 @@ +--- +'vite-plugin-checker': minor +--- + +Added basic support for Biome From cd4e2b6b27d28ecc452d295d7072c55eafb8b020 Mon Sep 17 00:00:00 2001 From: fi3ework Date: Sun, 7 Jul 2024 18:09:57 +0800 Subject: [PATCH 3/8] fix: tweak --- packages/vite-plugin-checker/package.json | 2 +- .../src/FileDiagnosticManager.ts | 7 +- .../src/checkers/biome/cli.ts | 41 +- .../src/checkers/biome/main.ts | 28 +- .../src/checkers/biome/types.ts | 452 ++++++++++++--- .../__tests__/__snapshots__/test.spec.ts.snap | 45 ++ .../biome-default/__tests__/test.spec.ts | 38 ++ playground/biome-default/biome.json | 9 + playground/biome-default/index.html | 13 + playground/biome-default/package.json | 17 + playground/biome-default/src/index.js | 4 + playground/biome-default/tsconfig.json | 19 + playground/biome-default/vite.config.js | 11 + pnpm-lock.yaml | 529 +----------------- 14 files changed, 601 insertions(+), 614 deletions(-) create mode 100644 playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap create mode 100644 playground/biome-default/__tests__/test.spec.ts create mode 100644 playground/biome-default/biome.json create mode 100644 playground/biome-default/index.html create mode 100644 playground/biome-default/package.json create mode 100644 playground/biome-default/src/index.js create mode 100644 playground/biome-default/tsconfig.json create mode 100644 playground/biome-default/vite.config.js diff --git a/packages/vite-plugin-checker/package.json b/packages/vite-plugin-checker/package.json index 809846b7..92c144eb 100644 --- a/packages/vite-plugin-checker/package.json +++ b/packages/vite-plugin-checker/package.json @@ -96,7 +96,7 @@ } }, "devDependencies": { - "@biomejs/biome": "^1.7.2", + "@biomejs/biome": "^1.8.3", "@types/eslint": "^7.2.14", "@types/fs-extra": "^11.0.1", "@vue/language-core": "^2.0.14", diff --git a/packages/vite-plugin-checker/src/FileDiagnosticManager.ts b/packages/vite-plugin-checker/src/FileDiagnosticManager.ts index 6f693c23..c8f8514a 100644 --- a/packages/vite-plugin-checker/src/FileDiagnosticManager.ts +++ b/packages/vite-plugin-checker/src/FileDiagnosticManager.ts @@ -4,15 +4,10 @@ class FileDiagnosticManager { public diagnostics: NormalizedDiagnostic[] = [] /** - * Resets the diagnostics array + * Initialize and reset the diagnostics array */ public initWith(diagnostics: NormalizedDiagnostic[]) { - if (this.initialized) { - throw new Error('FileDiagnosticManager is already initialized') - } - this.diagnostics = [...diagnostics] - this.initialized = true } public getDiagnostics(fileName?: string) { diff --git a/packages/vite-plugin-checker/src/checkers/biome/cli.ts b/packages/vite-plugin-checker/src/checkers/biome/cli.ts index e2575d10..419330c8 100644 --- a/packages/vite-plugin-checker/src/checkers/biome/cli.ts +++ b/packages/vite-plugin-checker/src/checkers/biome/cli.ts @@ -1,5 +1,7 @@ -import { exec } from 'child_process' -import { type NormalizedDiagnostic } from '../../logger.js' +import { exec } from 'node:child_process' +import strip from 'strip-ansi' +import { createFrame } from '../../codeFrame.js' +import type { NormalizedDiagnostic } from '../../logger.js' import { DiagnosticLevel } from '../../types.js' import type { BiomeOutput } from './types.js' @@ -14,11 +16,17 @@ export function getBiomeCommand(command: string, flags: string, files: string) { return ['biome', command || 'lint', flags, defaultFlags, files].filter(Boolean).join(' ') } -export function runBiome(command: string) { +export function runBiome(command: string, cwd: string) { return new Promise((resolve, reject) => { - exec(command, (error, stdout, stderr) => { - resolve([...parseBiomeOutput(stdout)]) - }) + exec( + command, + { + cwd, + }, + (error, stdout, stderr) => { + resolve([...parseBiomeOutput(stdout)]) + } + ) }) } @@ -31,18 +39,23 @@ function parseBiomeOutput(output: string) { } const diagnostics: NormalizedDiagnostic[] = parsed.diagnostics.map((d) => { + const loc = { + file: d.location.path || '', + start: getLineAndColumn(d.location.sourceCode, d.location.span?.[0]), + end: getLineAndColumn(d.location.sourceCode, d.location.span?.[1]), + } + + const codeFrame = createFrame(d.location.sourceCode || '', loc) + return { - level: severityMap[d.severity as keyof typeof severityMap] ?? DiagnosticLevel.Error, message: `[${d.category}] ${d.description}`, conclusion: '', + level: severityMap[d.severity as keyof typeof severityMap] ?? DiagnosticLevel.Error, checker: 'Biome', - id: d.location.path.file, - codeFrame: d.source || '', - loc: { - file: d.location.path.file, - start: getLineAndColumn(d.location.sourceCode, d.location.span?.[0]), - end: getLineAndColumn(d.location.sourceCode, d.location.span?.[1]), - }, + id: d.location.path?.file, + codeFrame, + stripedCodeFrame: codeFrame && strip(codeFrame), + loc, } }) diff --git a/packages/vite-plugin-checker/src/checkers/biome/main.ts b/packages/vite-plugin-checker/src/checkers/biome/main.ts index 79fb7f28..ef015721 100644 --- a/packages/vite-plugin-checker/src/checkers/biome/main.ts +++ b/packages/vite-plugin-checker/src/checkers/biome/main.ts @@ -1,8 +1,10 @@ -import { fileURLToPath } from 'url' +import { fileURLToPath } from 'node:url' import chokidar from 'chokidar' +import path from 'node:path' +import { parentPort } from 'node:worker_threads' import { Checker } from '../../Checker.js' -import { ACTION_TYPES, DiagnosticLevel, type CreateDiagnostic } from '../../types.js' +import { FileDiagnosticManager } from '../../FileDiagnosticManager.js' import { composeCheckerSummary, consoleLog, @@ -11,15 +13,13 @@ import { filterLogLevel, toClientPayload, } from '../../logger.js' -import { FileDiagnosticManager } from '../../FileDiagnosticManager.js' -import { parentPort } from 'worker_threads' -import path from 'path' +import { ACTION_TYPES, type CreateDiagnostic, DiagnosticLevel } from '../../types.js' import { getBiomeCommand, runBiome, severityMap } from './cli.js' const __filename = fileURLToPath(import.meta.url) const manager = new FileDiagnosticManager() -let createServeAndBuild +let createServeAndBuild: any const createDiagnostic: CreateDiagnostic<'biome'> = (pluginConfig) => { let overlay = true @@ -53,9 +53,10 @@ const createDiagnostic: CreateDiagnostic<'biome'> = (pluginConfig) => { const diagnostics = filterLogLevel(manager.getDiagnostics(), logLevel) if (terminal) { - diagnostics.forEach((d) => { + for (const d of diagnostics) { consoleLog(diagnosticToTerminalLog(d, 'Biome')) - }) + } + const errorCount = diagnostics.filter((d) => d.level === DiagnosticLevel.Error).length const warningCount = diagnostics.filter((d) => d.level === DiagnosticLevel.Warning).length consoleLog(composeCheckerSummary('Biome', errorCount, warningCount)) @@ -81,11 +82,11 @@ const createDiagnostic: CreateDiagnostic<'biome'> = (pluginConfig) => { if (isConfigFile) { const runCommand = getBiomeCommand(command, flags, root) - const diagnostics = await runBiome(runCommand) + const diagnostics = await runBiome(runCommand, root) manager.initWith(diagnostics) } else { const runCommand = getBiomeCommand(command, flags, absPath) - const diagnosticsOfChangedFile = await runBiome(runCommand) + const diagnosticsOfChangedFile = await runBiome(runCommand, root) manager.updateByFileId(absPath, diagnosticsOfChangedFile) } } @@ -95,10 +96,9 @@ const createDiagnostic: CreateDiagnostic<'biome'> = (pluginConfig) => { // initial check const runCommand = getBiomeCommand(command, flags, root) - const diagnostics = await runBiome(runCommand) + const diagnostics = await runBiome(runCommand, root) manager.initWith(diagnostics) - dispatchDiagnostics() // watch lint @@ -126,9 +126,9 @@ export class BiomeChecker extends Checker<'biome'> { buildBin: (pluginConfig) => { if (typeof pluginConfig.biome === 'object') { const { command, flags } = pluginConfig.biome - return ['biome', [command || 'check', flags || ''] as const] + return ['biome', [command || 'lint', flags || ''] as const] } - return ['biome', ['check']] + return ['biome', ['lint']] }, }, createDiagnostic, diff --git a/packages/vite-plugin-checker/src/checkers/biome/types.ts b/packages/vite-plugin-checker/src/checkers/biome/types.ts index 5eba0061..91d67ba7 100644 --- a/packages/vite-plugin-checker/src/checkers/biome/types.ts +++ b/packages/vite-plugin-checker/src/checkers/biome/types.ts @@ -1,67 +1,389 @@ export interface BiomeOutput { - summary: { - changed: number - unchanged: number - duration: { - secs: number - nanos: number - } - errors: number - warnings: number - skipped: number - suggestedFixesSkipped: number - diagnosticsNotPrinted: number - } - diagnostics: Array<{ - category: string - severity: string - description: string - message: Array<{ - elements: Array - content: string - }> - advices: { - advices: Array<{ - diff?: { - dictionary: string - ops: Array<{ - diffOp?: { - equal?: { - range: Array - } - delete?: { - range: Array - } - insert?: { - range: Array - } - } - equalLines?: { - line_count: number - } - }> - } - log?: [ - string, - Array<{ - elements: Array - content: string - }> - ] - }> - } - verboseAdvices: { - advices: Array - } - location: { - path: { - file: string - } - span?: Array - sourceCode?: string - } - tags: Array - source: any - }> - command: string + diagnostics: Diagnostic[] +} + +/** + * The following code are copied from https://www.npmjs.com/package/@biomejs/wasm-nodejs/v/1.8.3?activeTab=code + */ + +type DiagnosticTag = 'fixable' | 'internal' | 'unnecessaryCode' | 'deprecatedCode' | 'verbose' +type DiagnosticTags = DiagnosticTag[] +// NOTE: only use { file: string } for now +// type Resource_for_String = 'argv' | 'memory' | { file: string } +type Resource_for_String = { file: string } +type TextSize = number +type TextRange = [TextSize, TextSize] +type MarkupBuf = MarkupNodeBuf[] + +interface MarkupNodeBuf { + content: string + elements: MarkupElement[] +} + +type MarkupElement = + | 'Emphasis' + | 'Dim' + | 'Italic' + | 'Underline' + | 'Error' + | 'Success' + | 'Warn' + | 'Info' + | 'Debug' + | 'Trace' + | 'Inverse' + | { Hyperlink: { href: string } } + +type Category = + | 'lint/a11y/noAccessKey' + | 'lint/a11y/noAriaHiddenOnFocusable' + | 'lint/a11y/noAriaUnsupportedElements' + | 'lint/a11y/noAutofocus' + | 'lint/a11y/noBlankTarget' + | 'lint/a11y/noDistractingElements' + | 'lint/a11y/noHeaderScope' + | 'lint/a11y/noInteractiveElementToNoninteractiveRole' + | 'lint/a11y/noNoninteractiveElementToInteractiveRole' + | 'lint/a11y/noNoninteractiveTabindex' + | 'lint/a11y/noPositiveTabindex' + | 'lint/a11y/noRedundantAlt' + | 'lint/a11y/noRedundantRoles' + | 'lint/a11y/noSvgWithoutTitle' + | 'lint/a11y/useAltText' + | 'lint/a11y/useAnchorContent' + | 'lint/a11y/useAriaActivedescendantWithTabindex' + | 'lint/a11y/useAriaPropsForRole' + | 'lint/a11y/useButtonType' + | 'lint/a11y/useHeadingContent' + | 'lint/a11y/useHtmlLang' + | 'lint/a11y/useIframeTitle' + | 'lint/a11y/useKeyWithClickEvents' + | 'lint/a11y/useKeyWithMouseEvents' + | 'lint/a11y/useMediaCaption' + | 'lint/a11y/useValidAnchor' + | 'lint/a11y/useValidAriaProps' + | 'lint/a11y/useValidAriaRole' + | 'lint/a11y/useValidAriaValues' + | 'lint/a11y/useValidLang' + | 'lint/complexity/noBannedTypes' + | 'lint/complexity/noEmptyTypeParameters' + | 'lint/complexity/noExcessiveCognitiveComplexity' + | 'lint/complexity/noExcessiveNestedTestSuites' + | 'lint/complexity/noExtraBooleanCast' + | 'lint/complexity/noForEach' + | 'lint/complexity/noMultipleSpacesInRegularExpressionLiterals' + | 'lint/complexity/noStaticOnlyClass' + | 'lint/complexity/noThisInStatic' + | 'lint/complexity/noUselessCatch' + | 'lint/complexity/noUselessConstructor' + | 'lint/complexity/noUselessEmptyExport' + | 'lint/complexity/noUselessFragments' + | 'lint/complexity/noUselessLabel' + | 'lint/complexity/noUselessLoneBlockStatements' + | 'lint/complexity/noUselessRename' + | 'lint/complexity/noUselessSwitchCase' + | 'lint/complexity/noUselessTernary' + | 'lint/complexity/noUselessThisAlias' + | 'lint/complexity/noUselessTypeConstraint' + | 'lint/complexity/noVoid' + | 'lint/complexity/noWith' + | 'lint/complexity/useArrowFunction' + | 'lint/complexity/useFlatMap' + | 'lint/complexity/useLiteralKeys' + | 'lint/complexity/useOptionalChain' + | 'lint/complexity/useRegexLiterals' + | 'lint/complexity/useSimpleNumberKeys' + | 'lint/complexity/useSimplifiedLogicExpression' + | 'lint/correctness/noChildrenProp' + | 'lint/correctness/noConstAssign' + | 'lint/correctness/noConstantCondition' + | 'lint/correctness/noConstantMathMinMaxClamp' + | 'lint/correctness/noConstructorReturn' + | 'lint/correctness/noEmptyCharacterClassInRegex' + | 'lint/correctness/noEmptyPattern' + | 'lint/correctness/noFlatMapIdentity' + | 'lint/correctness/noGlobalObjectCalls' + | 'lint/correctness/noInnerDeclarations' + | 'lint/correctness/noInvalidConstructorSuper' + | 'lint/correctness/noInvalidNewBuiltin' + | 'lint/correctness/noInvalidUseBeforeDeclaration' + | 'lint/correctness/noNewSymbol' + | 'lint/correctness/noNodejsModules' + | 'lint/correctness/noNonoctalDecimalEscape' + | 'lint/correctness/noPrecisionLoss' + | 'lint/correctness/noRenderReturnValue' + | 'lint/correctness/noSelfAssign' + | 'lint/correctness/noSetterReturn' + | 'lint/correctness/noStringCaseMismatch' + | 'lint/correctness/noSwitchDeclarations' + | 'lint/correctness/noUndeclaredVariables' + | 'lint/correctness/noUnnecessaryContinue' + | 'lint/correctness/noUnreachable' + | 'lint/correctness/noUnreachableSuper' + | 'lint/correctness/noUnsafeFinally' + | 'lint/correctness/noUnsafeOptionalChaining' + | 'lint/correctness/noUnusedImports' + | 'lint/correctness/noUnusedLabels' + | 'lint/correctness/noUnusedPrivateClassMembers' + | 'lint/correctness/noUnusedVariables' + | 'lint/correctness/noVoidElementsWithChildren' + | 'lint/correctness/noVoidTypeReturn' + | 'lint/correctness/useArrayLiterals' + | 'lint/correctness/useExhaustiveDependencies' + | 'lint/correctness/useHookAtTopLevel' + | 'lint/correctness/useIsNan' + | 'lint/correctness/useJsxKeyInIterable' + | 'lint/correctness/useValidForDirection' + | 'lint/correctness/useYield' + | 'lint/nursery/colorNoInvalidHex' + | 'lint/nursery/noColorInvalidHex' + | 'lint/nursery/noConsole' + | 'lint/nursery/noDoneCallback' + | 'lint/nursery/noDuplicateAtImportRules' + | 'lint/nursery/noDuplicateElseIf' + | 'lint/nursery/noDuplicateFontNames' + | 'lint/nursery/noDuplicateJsonKeys' + | 'lint/nursery/noDuplicateSelectorsKeyframeBlock' + | 'lint/nursery/noEmptyBlock' + | 'lint/nursery/noEvolvingTypes' + | 'lint/nursery/noExportedImports' + | 'lint/nursery/noImportantInKeyframe' + | 'lint/nursery/noInvalidDirectionInLinearGradient' + | 'lint/nursery/noInvalidPositionAtImportRule' + | 'lint/nursery/noLabelWithoutControl' + | 'lint/nursery/noMisplacedAssertion' + | 'lint/nursery/noMissingGenericFamilyKeyword' + | 'lint/nursery/noReactSpecificProps' + | 'lint/nursery/noRestrictedImports' + | 'lint/nursery/noShorthandPropertyOverrides' + | 'lint/nursery/noSubstr' + | 'lint/nursery/noTypeOnlyImportAttributes' + | 'lint/nursery/noUndeclaredDependencies' + | 'lint/nursery/noUnknownFunction' + | 'lint/nursery/noUnknownMediaFeatureName' + | 'lint/nursery/noUnknownProperty' + | 'lint/nursery/noUnknownPseudoClassSelector' + | 'lint/nursery/noUnknownSelectorPseudoElement' + | 'lint/nursery/noUnknownUnit' + | 'lint/nursery/noUnmatchableAnbSelector' + | 'lint/nursery/noUnusedFunctionParameters' + | 'lint/nursery/noUselessStringConcat' + | 'lint/nursery/noUselessUndefinedInitialization' + | 'lint/nursery/noYodaExpression' + | 'lint/nursery/useAdjacentOverloadSignatures' + | 'lint/nursery/useBiomeSuppressionComment' + | 'lint/nursery/useConsistentBuiltinInstantiation' + | 'lint/nursery/useConsistentGridAreas' + | 'lint/nursery/useDateNow' + | 'lint/nursery/useDefaultSwitchClause' + | 'lint/nursery/useDeprecatedReason' + | 'lint/nursery/useErrorMessage' + | 'lint/nursery/useExplicitLengthCheck' + | 'lint/nursery/useFocusableInteractive' + | 'lint/nursery/useGenericFontNames' + | 'lint/nursery/useImportExtensions' + | 'lint/nursery/useImportRestrictions' + | 'lint/nursery/useNumberToFixedDigitsArgument' + | 'lint/nursery/useSemanticElements' + | 'lint/nursery/useSortedClasses' + | 'lint/nursery/useThrowNewError' + | 'lint/nursery/useThrowOnlyError' + | 'lint/nursery/useTopLevelRegex' + | 'lint/nursery/useValidAutocomplete' + | 'lint/performance/noAccumulatingSpread' + | 'lint/performance/noBarrelFile' + | 'lint/performance/noDelete' + | 'lint/performance/noReExportAll' + | 'lint/security/noDangerouslySetInnerHtml' + | 'lint/security/noDangerouslySetInnerHtmlWithChildren' + | 'lint/security/noGlobalEval' + | 'lint/style/noArguments' + | 'lint/style/noCommaOperator' + | 'lint/style/noDefaultExport' + | 'lint/style/noImplicitBoolean' + | 'lint/style/noInferrableTypes' + | 'lint/style/noNamespace' + | 'lint/style/noNamespaceImport' + | 'lint/style/noNegationElse' + | 'lint/style/noNonNullAssertion' + | 'lint/style/noParameterAssign' + | 'lint/style/noParameterProperties' + | 'lint/style/noRestrictedGlobals' + | 'lint/style/noShoutyConstants' + | 'lint/style/noUnusedTemplateLiteral' + | 'lint/style/noUselessElse' + | 'lint/style/noVar' + | 'lint/style/useAsConstAssertion' + | 'lint/style/useBlockStatements' + | 'lint/style/useCollapsedElseIf' + | 'lint/style/useConsistentArrayType' + | 'lint/style/useConst' + | 'lint/style/useDefaultParameterLast' + | 'lint/style/useEnumInitializers' + | 'lint/style/useExponentiationOperator' + | 'lint/style/useExportType' + | 'lint/style/useFilenamingConvention' + | 'lint/style/useForOf' + | 'lint/style/useFragmentSyntax' + | 'lint/style/useImportType' + | 'lint/style/useLiteralEnumMembers' + | 'lint/style/useNamingConvention' + | 'lint/style/useNodeAssertStrict' + | 'lint/style/useNodejsImportProtocol' + | 'lint/style/useNumberNamespace' + | 'lint/style/useNumericLiterals' + | 'lint/style/useSelfClosingElements' + | 'lint/style/useShorthandArrayType' + | 'lint/style/useShorthandAssign' + | 'lint/style/useShorthandFunctionType' + | 'lint/style/useSingleCaseStatement' + | 'lint/style/useSingleVarDeclarator' + | 'lint/style/useTemplate' + | 'lint/style/useWhile' + | 'lint/suspicious/noApproximativeNumericConstant' + | 'lint/suspicious/noArrayIndexKey' + | 'lint/suspicious/noAssignInExpressions' + | 'lint/suspicious/noAsyncPromiseExecutor' + | 'lint/suspicious/noCatchAssign' + | 'lint/suspicious/noClassAssign' + | 'lint/suspicious/noCommentText' + | 'lint/suspicious/noCompareNegZero' + | 'lint/suspicious/noConfusingLabels' + | 'lint/suspicious/noConfusingVoidType' + | 'lint/suspicious/noConsoleLog' + | 'lint/suspicious/noConstEnum' + | 'lint/suspicious/noControlCharactersInRegex' + | 'lint/suspicious/noDebugger' + | 'lint/suspicious/noDoubleEquals' + | 'lint/suspicious/noDuplicateCase' + | 'lint/suspicious/noDuplicateClassMembers' + | 'lint/suspicious/noDuplicateJsxProps' + | 'lint/suspicious/noDuplicateObjectKeys' + | 'lint/suspicious/noDuplicateParameters' + | 'lint/suspicious/noDuplicateTestHooks' + | 'lint/suspicious/noEmptyBlockStatements' + | 'lint/suspicious/noEmptyInterface' + | 'lint/suspicious/noExplicitAny' + | 'lint/suspicious/noExportsInTest' + | 'lint/suspicious/noExtraNonNullAssertion' + | 'lint/suspicious/noFallthroughSwitchClause' + | 'lint/suspicious/noFocusedTests' + | 'lint/suspicious/noFunctionAssign' + | 'lint/suspicious/noGlobalAssign' + | 'lint/suspicious/noGlobalIsFinite' + | 'lint/suspicious/noGlobalIsNan' + | 'lint/suspicious/noImplicitAnyLet' + | 'lint/suspicious/noImportAssign' + | 'lint/suspicious/noLabelVar' + | 'lint/suspicious/noMisleadingCharacterClass' + | 'lint/suspicious/noMisleadingInstantiator' + | 'lint/suspicious/noMisrefactoredShorthandAssign' + | 'lint/suspicious/noPrototypeBuiltins' + | 'lint/suspicious/noRedeclare' + | 'lint/suspicious/noRedundantUseStrict' + | 'lint/suspicious/noSelfCompare' + | 'lint/suspicious/noShadowRestrictedNames' + | 'lint/suspicious/noSkippedTests' + | 'lint/suspicious/noSparseArray' + | 'lint/suspicious/noSuspiciousSemicolonInJsx' + | 'lint/suspicious/noThenProperty' + | 'lint/suspicious/noUnsafeDeclarationMerging' + | 'lint/suspicious/noUnsafeNegation' + | 'lint/suspicious/useAwait' + | 'lint/suspicious/useDefaultSwitchClauseLast' + | 'lint/suspicious/useGetterReturn' + | 'lint/suspicious/useIsArray' + | 'lint/suspicious/useNamespaceKeyword' + | 'lint/suspicious/useValidTypeof' + | 'assists/nursery/useSortedKeys' + | 'files/missingHandler' + | 'format' + | 'check' + | 'ci' + | 'configuration' + | 'organizeImports' + | 'migrate' + | 'deserialize' + | 'project' + | 'search' + | 'internalError/io' + | 'internalError/fs' + | 'internalError/panic' + | 'parse' + | 'parse/noSuperWithoutExtends' + | 'parse/noInitializerWithDefinite' + | 'parse/noDuplicatePrivateClassMembers' + | 'lint' + | 'lint/a11y' + | 'lint/complexity' + | 'lint/correctness' + | 'lint/nursery' + | 'lint/performance' + | 'lint/security' + | 'lint/style' + | 'lint/suspicious' + | 'suppressions/parse' + | 'suppressions/unknownGroup' + | 'suppressions/unknownRule' + | 'suppressions/unused' + | 'suppressions/deprecatedSuppressionComment' + | 'args/fileNotFound' + | 'flags/invalid' + | 'semanticTests' + +interface Location { + path?: Resource_for_String + sourceCode?: string + span?: TextRange +} + +export interface Diagnostic { + advices: Advices + category?: Category + description: string + location: Location + message: MarkupBuf + severity: Severity + source?: Diagnostic + tags: DiagnosticTags + verboseAdvices: Advices +} + +interface Advices { + advices: Advice[] +} + +type Severity = 'hint' | 'information' | 'warning' | 'error' | 'fatal' +type Advice = + | { log: [LogCategory, MarkupBuf] } + | { list: MarkupBuf[] } + | { frame: Location } + | { diff: TextEdit } + | { backtrace: [MarkupBuf, Backtrace] } + | { command: string } + | { group: [MarkupBuf, Advices] } + +type LogCategory = 'none' | 'info' | 'warn' | 'error' +interface TextEdit { + dictionary: string + ops: CompressedOp[] +} +type Backtrace = BacktraceFrame[] +type CompressedOp = { diffOp: DiffOp } | { equalLines: { line_count: number } } + +type DiffOp = + | { equal: { range: TextRange } } + | { insert: { range: TextRange } } + | { delete: { range: TextRange } } + +interface BacktraceFrame { + ip: number + symbols: BacktraceSymbol[] +} + +interface BacktraceSymbol { + colno?: number + filename?: string + lineno?: number + name?: string } diff --git a/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap new file mode 100644 index 00000000..db14ef89 --- /dev/null +++ b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap @@ -0,0 +1,45 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`biome > serve > get initial error and subsequent error 1`] = `"[{"checkerId":"Biome","frame":" 1 | const a = 'hello'/n > 2 | var b = 'world'/n | ^^^^^^^^^^^^^^^/n 3 | const c = '!'/n 4 | var d = a + b + c/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":2},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | var b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; + +exports[`biome > serve > get initial error and subsequent error 2`] = ` +[ + " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. + FILE /src/index.js:2:1 + + 1 | const a = 'hello' + > 2 | var b = 'world' + | ^^^^^^^^^^^^^^^ + 3 | const c = '!' + 4 | var d = a + b + c + 5 | +", + " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. + FILE /src/index.js:4:1 + + 2 | var b = 'world' + 3 | const c = '!' + > 4 | var d = a + b + c + | ^^^^^^^^^^^^^^^^^ + 5 | +", + "[Biome] Found 2 errors and 0 warning", +] +`; + +exports[`biome > serve > get initial error and subsequent error 3`] = `"[{"checkerId":"Biome","frame":" 1 | const a = 'hello'/n > 2 | var b = 'world'/n | ^^^^^^^^^^^^^^^/n 3 | const c = '!'/n 4 | var d = a + b + c/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":2},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | var b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | const b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; + +exports[`biome > serve > get initial error and subsequent error 4`] = ` +[ + " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. + FILE /src/index.js:4:1 + + 2 | const b = 'world' + 3 | const c = '!' + > 4 | var d = a + b + c + | ^^^^^^^^^^^^^^^^^ + 5 | +", + "[Biome] Found 1 error and 0 warning", +] +`; diff --git a/playground/biome-default/__tests__/test.spec.ts b/playground/biome-default/__tests__/test.spec.ts new file mode 100644 index 00000000..abe6c97c --- /dev/null +++ b/playground/biome-default/__tests__/test.spec.ts @@ -0,0 +1,38 @@ +import stringify from 'fast-json-stable-stringify' +import { describe, expect, it } from 'vitest' +import { + diagnostics, + editFile, + expectStderrContains, + isBuild, + isServe, + log, + resetReceivedLog, + sleepForEdit, + sleepForServerReady, + stripedLog, +} from '../../testUtils' + +describe('biome', () => { + describe.runIf(isServe)('serve', () => { + it('get initial error and subsequent error', async () => { + await sleepForServerReady() + expect(stringify(diagnostics)).toMatchSnapshot() + expect(stripedLog).toMatchSnapshot() + + console.log('-- edit error file --') + resetReceivedLog() + editFile('src/index.js', (code) => code.replace(`var b = 'world'`, `const b = 'world'`)) + await sleepForEdit() + expect(stringify(diagnostics)).toMatchSnapshot() + expect(stripedLog).toMatchSnapshot() + }) + }) + + describe.runIf(isBuild)('build', () => { + it('should fail', async () => { + const expectedMsg = ['Use let or const instead of var', 'Found 2 errors'] + expectStderrContains(log, expectedMsg) + }) + }) +}) diff --git a/playground/biome-default/biome.json b/playground/biome-default/biome.json new file mode 100644 index 00000000..0f6e1ba4 --- /dev/null +++ b/playground/biome-default/biome.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json", + "linter": { + "include": ["./src/**/*.js"], + "rules": { + "recommended": true + } + } +} diff --git a/playground/biome-default/index.html b/playground/biome-default/index.html new file mode 100644 index 00000000..081c166a --- /dev/null +++ b/playground/biome-default/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite App + + +

+ + + diff --git a/playground/biome-default/package.json b/playground/biome-default/package.json new file mode 100644 index 00000000..1c2b3314 --- /dev/null +++ b/playground/biome-default/package.json @@ -0,0 +1,17 @@ +{ + "private": true, + "name": "@playground/biome-default", + "type": "module", + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "serve": "vite preview", + "lint": "biome lint" + }, + "devDependencies": { + "vite": "^5.3.2", + "@biomejs/biome": "^1.8.3", + "vite-plugin-checker": "workspace:*" + } +} diff --git a/playground/biome-default/src/index.js b/playground/biome-default/src/index.js new file mode 100644 index 00000000..0236708a --- /dev/null +++ b/playground/biome-default/src/index.js @@ -0,0 +1,4 @@ +const a = 'hello' +var b = 'world' +const c = '!' +var d = a + b + c diff --git a/playground/biome-default/tsconfig.json b/playground/biome-default/tsconfig.json new file mode 100644 index 00000000..36f84d9e --- /dev/null +++ b/playground/biome-default/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "types": ["vite/client"], + "allowJs": false, + "skipLibCheck": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true + }, + "include": ["./src"] +} diff --git a/playground/biome-default/vite.config.js b/playground/biome-default/vite.config.js new file mode 100644 index 00000000..c49ba040 --- /dev/null +++ b/playground/biome-default/vite.config.js @@ -0,0 +1,11 @@ +// @ts-check +import { defineConfig } from 'vite' +import checker from 'vite-plugin-checker' + +export default defineConfig({ + plugins: [ + checker({ + biome: true, + }), + ], +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fdff0ebc..8a3f3cbe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -142,7 +142,6 @@ importers: packages/runtime: devDependencies: -<<<<<<< HEAD '@unplugin-vue-ce/sub-style': specifier: 1.0.0-beta.14 version: 1.0.0-beta.14(ansi-colors@4.1.3)(vue@3.4.29(typescript@5.5.3)) @@ -158,86 +157,8 @@ importers: vue-tsc: specifier: ^2.0.14 version: 2.0.21(typescript@5.5.3) -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - '@unplugin-vue-ce/sub-style': 1.0.0-beta.14 - '@vitejs/plugin-vue': 2.3.4_vite@4.3.1+vue@3.3.4 - vite: 4.3.1 - vue: 3.3.4 - vue-tsc: 1.6.1 -======= - '@unplugin-vue-ce/sub-style': 1.0.0-beta.14_vue@3.3.4 - '@vitejs/plugin-vue': 2.3.4_vite@4.3.1+vue@3.3.4 - vite: 4.3.1 - vue: 3.3.4 - vue-tsc: 1.6.1 ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) packages/vite-plugin-checker: -<<<<<<< HEAD -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - specifiers: - '@babel/code-frame': ^7.12.13 - '@types/eslint': ^7.2.14 - '@types/fs-extra': ^11.0.1 - '@types/semver': ^7.3.13 - '@volar/vue-typescript': ^0.33.0 - ansi-escapes: ^4.3.0 - chalk: ^4.1.1 - chokidar: ^3.5.1 - commander: ^8.0.0 - esbuild: ^0.14.27 - fast-glob: ^3.2.7 - fs-extra: ^11.1.0 - meow: ^9.0.0 - npm-run-all: ^4.1.5 - npm-run-path: ^4.0.1 - optionator: ^0.9.1 - semver: ^7.5.0 - strip-ansi: ^6.0.0 - stylelint: ^14.0.0 - tiny-invariant: ^1.1.0 - tsup: ^6.7.0 - typescript: ^5.0.4 - vls: ^0.7.6 - vscode-languageclient: ^7.0.0 - vscode-languageserver: ^7.0.0 - vscode-languageserver-textdocument: ^1.0.1 - vscode-uri: ^3.0.2 - vti: ^0.1.7 - vue-tsc: ^1.6.1 -======= - specifiers: - '@babel/code-frame': ^7.12.13 - '@biomejs/biome': ^1.7.2 - '@types/eslint': ^7.2.14 - '@types/fs-extra': ^11.0.1 - '@types/semver': ^7.3.13 - '@volar/vue-typescript': ^0.33.0 - ansi-escapes: ^4.3.0 - chalk: ^4.1.1 - chokidar: ^3.5.1 - commander: ^8.0.0 - esbuild: ^0.14.27 - fast-glob: ^3.2.7 - fs-extra: ^11.1.0 - meow: ^9.0.0 - npm-run-all: ^4.1.5 - npm-run-path: ^4.0.1 - optionator: ^0.9.1 - semver: ^7.5.0 - strip-ansi: ^6.0.0 - stylelint: ^14.0.0 - tiny-invariant: ^1.1.0 - tsup: ^6.7.0 - typescript: ^5.0.4 - vls: ^0.7.6 - vscode-languageclient: ^7.0.0 - vscode-languageserver: ^7.0.0 - vscode-languageserver-textdocument: ^1.0.1 - vscode-uri: ^3.0.2 - vti: ^0.1.7 - vue-tsc: ^1.6.1 ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) dependencies: '@babel/code-frame': specifier: ^7.12.13 @@ -282,7 +203,9 @@ importers: specifier: ^3.0.2 version: 3.0.8 devDependencies: -<<<<<<< HEAD + '@biomejs/biome': + specifier: ^1.8.3 + version: 1.8.3 '@types/eslint': specifier: ^7.2.14 version: 7.29.0 @@ -319,38 +242,6 @@ importers: vue-tsc: specifier: ^2.0.14 version: 2.0.21(typescript@5.5.3) -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - '@types/eslint': 7.29.0 - '@types/fs-extra': 11.0.1 - '@types/semver': 7.3.13 - '@volar/vue-typescript': 0.33.9 - esbuild: 0.14.54 - meow: 9.0.0 - npm-run-all: 4.1.5 - optionator: 0.9.1 - stylelint: 14.13.0 - tsup: 6.7.0_typescript@5.0.4 - typescript: 5.0.4 - vls: 0.7.6 - vti: 0.1.7 - vue-tsc: 1.6.1_typescript@5.0.4 -======= - '@biomejs/biome': 1.7.2 - '@types/eslint': 7.29.0 - '@types/fs-extra': 11.0.1 - '@types/semver': 7.3.13 - '@volar/vue-typescript': 0.33.9 - esbuild: 0.14.54 - meow: 9.0.0 - npm-run-all: 4.1.5 - optionator: 0.9.1 - stylelint: 14.13.0 - tsup: 6.7.0_typescript@5.0.4 - typescript: 5.0.4 - vls: 0.7.6 - vti: 0.1.7 - vue-tsc: 1.6.1_typescript@5.0.4 ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) playground/backend-integration: dependencies: @@ -389,6 +280,18 @@ importers: specifier: workspace:* version: link:../../packages/vite-plugin-checker + playground/biome-default: + devDependencies: + '@biomejs/biome': + specifier: ^1.8.3 + version: 1.8.3 + vite: + specifier: ^5.3.2 + version: 5.3.2(@types/node@16.18.101)(sass@1.77.6) + vite-plugin-checker: + specifier: workspace:* + version: link:../../packages/vite-plugin-checker + playground/config-default: dependencies: react: @@ -935,7 +838,6 @@ importers: playground/vls-vue2: dependencies: -<<<<<<< HEAD vue: specifier: ^2.6.14 version: 2.7.16 @@ -951,19 +853,6 @@ importers: vuex: specifier: 3.6.2 version: 3.6.2(vue@2.7.16) -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - vue: 2.7.8 - vue-class-component: 7.2.6_vue@2.7.8 - vue-property-decorator: 9.1.2_chk7q7rgeabwy64hfqmb36krqe - vue-router: 3.5.4 - vuex: 3.6.2_vue@2.7.8 -======= - vue: 2.7.8 - vue-class-component: 7.2.6_vue@2.7.8 - vue-property-decorator: 9.1.2_chk7q7rgeabwy64hfqmb36krqe - vue-router: 3.5.4_vue@2.7.8 - vuex: 3.6.2_vue@2.7.8 ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) devDependencies: '@types/node': specifier: ^15.0.0 @@ -1323,175 +1212,9 @@ packages: '@baiwusanyu/utils-task@1.0.18': resolution: {integrity: sha512-/0hlK00c3vje4XtOUW2UTrhneAYopX/vEqN5OcpZLGppstU02Fo82QpyJUSVZgO2XH3fGouJl/97bTmWjuFXsA==} -<<<<<<< HEAD '@biomejs/biome@1.8.3': resolution: {integrity: sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==} engines: {node: '>=14.21.3'} -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - /@changesets/apply-release-plan/6.1.3: - resolution: {integrity: sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==} - dependencies: - '@babel/runtime': 7.21.5 - '@changesets/config': 2.3.0 - '@changesets/get-version-range-type': 0.3.2 - '@changesets/git': 2.0.0 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.7.1 - resolve-from: 5.0.0 - semver: 5.7.1 - dev: true - - /@changesets/assemble-release-plan/5.2.3: - resolution: {integrity: sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==} - dependencies: - '@babel/runtime': 7.21.5 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.5 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - semver: 5.7.1 - dev: true - - /@changesets/changelog-git/0.1.14: - resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} - dependencies: - '@changesets/types': 5.2.1 - dev: true - - /@changesets/cli/2.26.1: - resolution: {integrity: sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==} -======= - /@biomejs/biome/1.7.2: - resolution: {integrity: sha512-6Skx9N47inLQzYi9RKgJ7PBnUnaHnMe/imqX43cOcJjZtfMnQLxEvfM2Eyo7gChkwrZlwc+VbA4huFRjw2fsYA==} - engines: {node: '>=14.21.3'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.7.2 - '@biomejs/cli-darwin-x64': 1.7.2 - '@biomejs/cli-linux-arm64': 1.7.2 - '@biomejs/cli-linux-arm64-musl': 1.7.2 - '@biomejs/cli-linux-x64': 1.7.2 - '@biomejs/cli-linux-x64-musl': 1.7.2 - '@biomejs/cli-win32-arm64': 1.7.2 - '@biomejs/cli-win32-x64': 1.7.2 - dev: true - - /@biomejs/cli-darwin-arm64/1.7.2: - resolution: {integrity: sha512-CrldIueHivWEWmeTkK8bTXajeX53F8i2Rrkkt8cPZyMtzkrwxf8Riq4a/jz3SQBHkxHFT4TqGbSTNMXe3X1ogA==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-darwin-x64/1.7.2: - resolution: {integrity: sha512-UELnLJuJOsTL9meArvn8BtiXDURyPil2Ej9me2uVpEvee8UQdqd/bssP5we400OWShlL1AAML4fn6d2WX5332g==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-linux-arm64-musl/1.7.2: - resolution: {integrity: sha512-kKYZiem7Sj7wI0dpVxJlK7C+TFQwzO/ctufIGXGJAyEmUe9vEKSzV8CXpv+JIRiTWyqaZJ4K+eHz4SPdPCv05w==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-linux-arm64/1.7.2: - resolution: {integrity: sha512-Z1CSGQE6fHz55gkiFHv9E8wEAaSUd7dHSRaxSCBa7utonHqpIeMbvj3Evm1w0WfGLFDtRXLV1fTfEdM0FMTOhA==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-linux-x64-musl/1.7.2: - resolution: {integrity: sha512-x10LpGMepDrLS+h2TZ6/T7egpHjGKtiI4GuShNylmBQJWfTotbFf9eseHggrqJ4WZf9yrGoVYrtbxXftuB95sQ==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-linux-x64/1.7.2: - resolution: {integrity: sha512-vXXyox8/CQijBxAu0+r8FfSO7JlC4tob3PbaFda8gPJFRz2uFJw39HtxVUwbTV1EcU6wSPh4SiRu5sZfP1VHrQ==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-win32-arm64/1.7.2: - resolution: {integrity: sha512-kRXdlKzcU7INf6/ldu0nVmkOgt7bKqmyXRRCUqqaJfA32+9InTbkD8tGrHZEVYIWr+eTuKcg16qZVDsPSDFZ8g==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-win32-x64/1.7.2: - resolution: {integrity: sha512-qHTtpAs+CNglAAuaTy09htoqUhrQyd3nd0aGTuLNqD10h1llMVi8WFZfoa+e5MuDSfYtMK6nW2Tbf6WgzzR1Qw==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@changesets/apply-release-plan/6.1.3: - resolution: {integrity: sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==} - dependencies: - '@babel/runtime': 7.21.5 - '@changesets/config': 2.3.0 - '@changesets/get-version-range-type': 0.3.2 - '@changesets/git': 2.0.0 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.7.1 - resolve-from: 5.0.0 - semver: 5.7.1 - dev: true - - /@changesets/assemble-release-plan/5.2.3: - resolution: {integrity: sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==} - dependencies: - '@babel/runtime': 7.21.5 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.5 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - semver: 5.7.1 - dev: true - - /@changesets/changelog-git/0.1.14: - resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} - dependencies: - '@changesets/types': 5.2.1 - dev: true - - /@changesets/cli/2.26.1: - resolution: {integrity: sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==} ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) hasBin: true '@biomejs/cli-darwin-arm64@1.8.3': @@ -2323,90 +2046,18 @@ packages: resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} -<<<<<<< HEAD '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} '@unplugin-vue-ce/sub-style@1.0.0-beta.14': -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - /@unplugin-vue-ce/sub-style/1.0.0-beta.14: -======= - /@unplugin-vue-ce/sub-style/1.0.0-beta.14_vue@3.3.4: ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) resolution: {integrity: sha512-ya79LwoSEdxNeUY8QBD9vfF1iGfOflSS1IpOejU6eKAr3Bkyr1uBbjWgC3NmiK3k4U7XDUJiVQL9TBXs45RRPg==} -<<<<<<< HEAD - peerDependencies: - vue: ^3.3.2 -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - dependencies: - '@babel/parser': 7.22.11 - '@babel/types': 7.22.11 - '@unplugin-vue-ce/utils': 1.0.0-beta.14 - baiwusanyu-utils: 1.0.15 - estree-walker-ts: 1.0.1 - fast-glob: 3.3.1 - fs-extra: 11.1.1 - magic-string: 0.30.3 - unplugin: 1.4.0 - vue: 3.3.4 - transitivePeerDependencies: - - ansi-colors - dev: true -======= peerDependencies: vue: ^3.3.2 - dependencies: - '@babel/parser': 7.22.11 - '@babel/types': 7.22.11 - '@unplugin-vue-ce/utils': 1.0.0-beta.14_vue@3.3.4 - baiwusanyu-utils: 1.0.15 - estree-walker-ts: 1.0.1 - fast-glob: 3.3.1 - fs-extra: 11.1.1 - magic-string: 0.30.3 - unplugin: 1.4.0 - vue: 3.3.4 - transitivePeerDependencies: - - ansi-colors - dev: true ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) -<<<<<<< HEAD '@unplugin-vue-ce/utils@1.0.0-beta.21': resolution: {integrity: sha512-XvIVOO2D8+6u3bywJf/rWXXLecSo82AdI2SRo95HyP0s7v4uoXM+WrABW+6CfZNoScgLFcizujl5OyjruPJ1+A==} peerDependencies: vue: ^3.3.2 -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - /@unplugin-vue-ce/utils/1.0.0-beta.14: - resolution: {integrity: sha512-mjvrdOMoONBQVxHR67zkKhPcds9SEkUe7fd6QjMVpE9XmYDGqU8ZlhZen8TqYy69VaDIZfvjaTUaGy/jVGoowg==} - dependencies: - baiwusanyu-utils: 1.0.15 - estree-walker-ts: 1.0.1 - fast-glob: 3.3.1 - fs-extra: 11.1.1 - magic-string: 0.30.3 - unplugin: 1.4.0 - vue: 3.3.4 - transitivePeerDependencies: - - ansi-colors - dev: true -======= - /@unplugin-vue-ce/utils/1.0.0-beta.14_vue@3.3.4: - resolution: {integrity: sha512-mjvrdOMoONBQVxHR67zkKhPcds9SEkUe7fd6QjMVpE9XmYDGqU8ZlhZen8TqYy69VaDIZfvjaTUaGy/jVGoowg==} - peerDependencies: - vue: ^3.3.2 - dependencies: - baiwusanyu-utils: 1.0.15 - estree-walker-ts: 1.0.1 - fast-glob: 3.3.1 - fs-extra: 11.1.1 - magic-string: 0.30.3 - unplugin: 1.4.0 - vue: 3.3.4 - transitivePeerDependencies: - - ansi-colors - dev: true ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) '@vitejs/plugin-react@2.2.0': resolution: {integrity: sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==} @@ -2516,142 +2167,6 @@ packages: '@vue/component-compiler-utils@3.3.0': resolution: {integrity: sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==} -<<<<<<< HEAD -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - dependencies: - consolidate: 0.15.1 - hash-sum: 1.0.2 - lru-cache: 4.1.5 - merge-source-map: 1.1.0 - postcss: 7.0.39 - postcss-selector-parser: 6.0.10 - source-map: 0.6.1 - vue-template-es2015-compiler: 1.9.1 - optionalDependencies: - prettier: 2.7.1 - transitivePeerDependencies: - - arc-templates - - atpl - - babel-core - - bracket-template - - coffee-script - - dot - - dust - - dustjs-helpers - - dustjs-linkedin - - eco - - ect - - ejs - - haml-coffee - - hamlet - - hamljs - - handlebars - - hogan.js - - htmling - - jade - - jazz - - jqtpl - - just - - liquid-node - - liquor - - lodash - - marko - - mote - - mustache - - nunjucks - - plates - - pug - - qejs - - ractive - - razor-tmpl - - react - - react-dom - - slm - - squirrelly - - swig - - swig-templates - - teacup - - templayed - - then-jade - - then-pug - - tinyliquid - - toffee - - twig - - twing - - underscore - - vash - - velocityjs - - walrus - - whiskers - dev: true -======= - dependencies: - consolidate: 0.15.1 - hash-sum: 1.0.2 - lru-cache: 4.1.5 - merge-source-map: 1.1.0 - postcss: 7.0.39 - postcss-selector-parser: 6.0.10 - source-map: 0.6.1 - vue-template-es2015-compiler: 1.9.1 - optionalDependencies: - prettier: 2.6.0 - transitivePeerDependencies: - - arc-templates - - atpl - - babel-core - - bracket-template - - coffee-script - - dot - - dust - - dustjs-helpers - - dustjs-linkedin - - eco - - ect - - ejs - - haml-coffee - - hamlet - - hamljs - - handlebars - - hogan.js - - htmling - - jade - - jazz - - jqtpl - - just - - liquid-node - - liquor - - lodash - - marko - - mote - - mustache - - nunjucks - - plates - - pug - - qejs - - ractive - - razor-tmpl - - react - - react-dom - - slm - - squirrelly - - swig - - swig-templates - - teacup - - templayed - - then-jade - - then-pug - - tinyliquid - - toffee - - twig - - twing - - underscore - - vash - - velocityjs - - walrus - - whiskers - dev: true ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) '@vue/devtools-api@7.3.2': resolution: {integrity: sha512-qFCm12te9rG0XWLCHm3x8TiZLULEP5s7Ruaadi5jAogwZ5qF7QH7tKc6yXZGV96uM+y1FUlbK+QwVbWgMfXEhQ==} @@ -10809,24 +10324,10 @@ snapshots: transitivePeerDependencies: - supports-color -<<<<<<< HEAD vue-property-decorator@9.1.2(vue-class-component@7.2.6(vue@2.7.16))(vue@2.7.16): dependencies: vue: 2.7.16 vue-class-component: 7.2.6(vue@2.7.16) -||||||| parent of 8c5f5e6 (feat: add basic support for Biome) - /vue-router/3.5.4: - resolution: {integrity: sha512-x+/DLAJZv2mcQ7glH2oV9ze8uPwcI+H+GgTgTmb5I55bCgY3+vXWIsqbYUzbBSZnwFHEJku4eoaH/x98veyymQ==} - dev: false -======= - /vue-router/3.5.4_vue@2.7.8: - resolution: {integrity: sha512-x+/DLAJZv2mcQ7glH2oV9ze8uPwcI+H+GgTgTmb5I55bCgY3+vXWIsqbYUzbBSZnwFHEJku4eoaH/x98veyymQ==} - peerDependencies: - vue: ^2 - dependencies: - vue: 2.7.8 - dev: false ->>>>>>> 8c5f5e6 (feat: add basic support for Biome) vue-router@3.5.1(vue@2.7.16): dependencies: From 01190ce195156ab6b2d1ebb3e5484714e90af8d5 Mon Sep 17 00:00:00 2001 From: fi3ework Date: Sun, 7 Jul 2024 23:41:22 +0800 Subject: [PATCH 4/8] chore: should be patch --- .changeset/new-kangaroos-hang.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/new-kangaroos-hang.md b/.changeset/new-kangaroos-hang.md index b1806274..d7a97a28 100644 --- a/.changeset/new-kangaroos-hang.md +++ b/.changeset/new-kangaroos-hang.md @@ -1,5 +1,5 @@ --- -'vite-plugin-checker': minor +'vite-plugin-checker': patch --- Added basic support for Biome From e0462524d70eeb9cd5ccbadaaf0400fa0c15e195 Mon Sep 17 00:00:00 2001 From: fi3ework Date: Mon, 8 Jul 2024 00:03:47 +0800 Subject: [PATCH 5/8] fix: vitest --- .vscode/settings.json | 3 ++- .../__tests__/__snapshots__/test.spec.ts.snap | 10 +++++----- vitest.workspace.js | 3 --- 3 files changed, 7 insertions(+), 9 deletions(-) delete mode 100644 vitest.workspace.js diff --git a/.vscode/settings.json b/.vscode/settings.json index 1616cbcc..403aa00f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,5 @@ { "vetur.experimental.templateInterpolationService": true, - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "vitest.disableWorkspaceWarning": true } diff --git a/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap index db14ef89..389236f0 100644 --- a/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap +++ b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap @@ -1,11 +1,11 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`biome > serve > get initial error and subsequent error 1`] = `"[{"checkerId":"Biome","frame":" 1 | const a = 'hello'/n > 2 | var b = 'world'/n | ^^^^^^^^^^^^^^^/n 3 | const c = '!'/n 4 | var d = a + b + c/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":2},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | var b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; +exports[`biome > serve > get initial error and subsequent error 1`] = `"[{"checkerId":"Biome","frame":" 1 | const a = 'hello'/n > 2 | var b = 'world'/n | ^^^^^^^^^^^^^^^/n 3 | const c = '!'/n 4 | var d = a + b + c/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":2},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | var b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; exports[`biome > serve > get initial error and subsequent error 2`] = ` [ " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. - FILE /src/index.js:2:1 + FILE /playground-temp/biome-default/src/index.js:2:1 1 | const a = 'hello' > 2 | var b = 'world' @@ -15,7 +15,7 @@ exports[`biome > serve > get initial error and subsequent error 2`] = ` 5 | ", " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. - FILE /src/index.js:4:1 + FILE /playground-temp/biome-default/src/index.js:4:1 2 | var b = 'world' 3 | const c = '!' @@ -27,12 +27,12 @@ exports[`biome > serve > get initial error and subsequent error 2`] = ` ] `; -exports[`biome > serve > get initial error and subsequent error 3`] = `"[{"checkerId":"Biome","frame":" 1 | const a = 'hello'/n > 2 | var b = 'world'/n | ^^^^^^^^^^^^^^^/n 3 | const c = '!'/n 4 | var d = a + b + c/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":2},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | var b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | const b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/src/index.js","level":1,"loc":{"column":1,"file":"/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; +exports[`biome > serve > get initial error and subsequent error 3`] = `"[{"checkerId":"Biome","frame":" 1 | const a = 'hello'/n > 2 | var b = 'world'/n | ^^^^^^^^^^^^^^^/n 3 | const c = '!'/n 4 | var d = a + b + c/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":2},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | var b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | const b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; exports[`biome > serve > get initial error and subsequent error 4`] = ` [ " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. - FILE /src/index.js:4:1 + FILE /playground-temp/biome-default/src/index.js:4:1 2 | const b = 'world' 3 | const c = '!' diff --git a/vitest.workspace.js b/vitest.workspace.js deleted file mode 100644 index c59096cb..00000000 --- a/vitest.workspace.js +++ /dev/null @@ -1,3 +0,0 @@ -import { defineWorkspace } from 'vitest/config' - -export default defineWorkspace(['./vitest.config.e2e.ts', './vitest.config.ts']) From 5dfad95439273708bc6b5b0dc768e99968aebf13 Mon Sep 17 00:00:00 2001 From: fi3ework Date: Mon, 8 Jul 2024 00:03:47 +0800 Subject: [PATCH 6/8] fix: Windows --- packages/vite-plugin-checker/src/checkers/biome/cli.ts | 2 +- .../biome-default/__tests__/__snapshots__/test.spec.ts.snap | 2 +- playground/biome-default/__tests__/test.spec.ts | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/vite-plugin-checker/src/checkers/biome/cli.ts b/packages/vite-plugin-checker/src/checkers/biome/cli.ts index 419330c8..8e5da888 100644 --- a/packages/vite-plugin-checker/src/checkers/biome/cli.ts +++ b/packages/vite-plugin-checker/src/checkers/biome/cli.ts @@ -40,7 +40,7 @@ function parseBiomeOutput(output: string) { const diagnostics: NormalizedDiagnostic[] = parsed.diagnostics.map((d) => { const loc = { - file: d.location.path || '', + file: d.location.path?.file || '', start: getLineAndColumn(d.location.sourceCode, d.location.span?.[0]), end: getLineAndColumn(d.location.sourceCode, d.location.span?.[1]), } diff --git a/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap index 389236f0..6f8016b3 100644 --- a/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap +++ b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap @@ -27,7 +27,7 @@ exports[`biome > serve > get initial error and subsequent error 2`] = ` ] `; -exports[`biome > serve > get initial error and subsequent error 3`] = `"[{"checkerId":"Biome","frame":" 1 | const a = 'hello'/n > 2 | var b = 'world'/n | ^^^^^^^^^^^^^^^/n 3 | const c = '!'/n 4 | var d = a + b + c/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":2},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | var b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | const b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; +exports[`biome > serve > get initial error and subsequent error 3`] = `"[{"checkerId":"Biome","frame":" 2 | const b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; exports[`biome > serve > get initial error and subsequent error 4`] = ` [ diff --git a/playground/biome-default/__tests__/test.spec.ts b/playground/biome-default/__tests__/test.spec.ts index abe6c97c..df9b81b6 100644 --- a/playground/biome-default/__tests__/test.spec.ts +++ b/playground/biome-default/__tests__/test.spec.ts @@ -7,6 +7,7 @@ import { isBuild, isServe, log, + resetDiagnostics, resetReceivedLog, sleepForEdit, sleepForServerReady, @@ -22,6 +23,7 @@ describe('biome', () => { console.log('-- edit error file --') resetReceivedLog() + resetDiagnostics() editFile('src/index.js', (code) => code.replace(`var b = 'world'`, `const b = 'world'`)) await sleepForEdit() expect(stringify(diagnostics)).toMatchSnapshot() From e9c47910bf0592542ba3cb86ff66f3d80d05220e Mon Sep 17 00:00:00 2001 From: Gokhan Kurt Date: Mon, 8 Jul 2024 23:55:11 +0300 Subject: [PATCH 7/8] update windows snapshots --- .../__tests__/__snapshots__/test.spec.ts.snap | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap index 6f8016b3..4793d392 100644 --- a/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap +++ b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap @@ -27,11 +27,30 @@ exports[`biome > serve > get initial error and subsequent error 2`] = ` ] `; -exports[`biome > serve > get initial error and subsequent error 3`] = `"[{"checkerId":"Biome","frame":" 2 | const b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; +exports[`biome > serve > get initial error and subsequent error 3`] = `"[{"checkerId":"Biome","frame":" 1 | const a = 'hello'/n > 2 | var b = 'world'/n | ^^^^^^^^^^^^^^^/n 3 | const c = '!'/n 4 | var d = a + b + c/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":2},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | var b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | const b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; exports[`biome > serve > get initial error and subsequent error 4`] = ` [ " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. + FILE /playground-temp/biome-default/src/index.js:2:1 + + 1 | const a = 'hello' + > 2 | var b = 'world' + | ^^^^^^^^^^^^^^^ + 3 | const c = '!' + 4 | var d = a + b + c + 5 | +", + " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. + FILE /playground-temp/biome-default/src/index.js:4:1 + + 2 | var b = 'world' + 3 | const c = '!' + > 4 | var d = a + b + c + | ^^^^^^^^^^^^^^^^^ + 5 | +", + " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. FILE /playground-temp/biome-default/src/index.js:4:1 2 | const b = 'world' @@ -40,6 +59,6 @@ exports[`biome > serve > get initial error and subsequent error 4`] = ` | ^^^^^^^^^^^^^^^^^ 5 | ", - "[Biome] Found 1 error and 0 warning", + "[Biome] Found 3 errors and 0 warning", ] `; From a06f0dfdca17b31e3bdd7df5b388301c9672b6dd Mon Sep 17 00:00:00 2001 From: Gokhan Kurt Date: Tue, 9 Jul 2024 00:10:24 +0300 Subject: [PATCH 8/8] normalize path returned by biome --- .../src/checkers/biome/cli.ts | 8 +++++-- .../src/checkers/biome/main.ts | 5 ++-- .../__tests__/__snapshots__/test.spec.ts.snap | 23 ++----------------- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/packages/vite-plugin-checker/src/checkers/biome/cli.ts b/packages/vite-plugin-checker/src/checkers/biome/cli.ts index 8e5da888..c5b61733 100644 --- a/packages/vite-plugin-checker/src/checkers/biome/cli.ts +++ b/packages/vite-plugin-checker/src/checkers/biome/cli.ts @@ -1,4 +1,5 @@ import { exec } from 'node:child_process' +import path from 'node:path' import strip from 'strip-ansi' import { createFrame } from '../../codeFrame.js' import type { NormalizedDiagnostic } from '../../logger.js' @@ -39,8 +40,11 @@ function parseBiomeOutput(output: string) { } const diagnostics: NormalizedDiagnostic[] = parsed.diagnostics.map((d) => { + let file = d.location.path?.file + if (file) file = path.normalize(file) + const loc = { - file: d.location.path?.file || '', + file: file || '', start: getLineAndColumn(d.location.sourceCode, d.location.span?.[0]), end: getLineAndColumn(d.location.sourceCode, d.location.span?.[1]), } @@ -52,7 +56,7 @@ function parseBiomeOutput(output: string) { conclusion: '', level: severityMap[d.severity as keyof typeof severityMap] ?? DiagnosticLevel.Error, checker: 'Biome', - id: d.location.path?.file, + id: file, codeFrame, stripedCodeFrame: codeFrame && strip(codeFrame), loc, diff --git a/packages/vite-plugin-checker/src/checkers/biome/main.ts b/packages/vite-plugin-checker/src/checkers/biome/main.ts index ef015721..a8abc8ef 100644 --- a/packages/vite-plugin-checker/src/checkers/biome/main.ts +++ b/packages/vite-plugin-checker/src/checkers/biome/main.ts @@ -1,8 +1,7 @@ -import { fileURLToPath } from 'node:url' -import chokidar from 'chokidar' - import path from 'node:path' +import { fileURLToPath } from 'node:url' import { parentPort } from 'node:worker_threads' +import chokidar from 'chokidar' import { Checker } from '../../Checker.js' import { FileDiagnosticManager } from '../../FileDiagnosticManager.js' import { diff --git a/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap index 4793d392..6f8016b3 100644 --- a/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap +++ b/playground/biome-default/__tests__/__snapshots__/test.spec.ts.snap @@ -27,30 +27,11 @@ exports[`biome > serve > get initial error and subsequent error 2`] = ` ] `; -exports[`biome > serve > get initial error and subsequent error 3`] = `"[{"checkerId":"Biome","frame":" 1 | const a = 'hello'/n > 2 | var b = 'world'/n | ^^^^^^^^^^^^^^^/n 3 | const c = '!'/n 4 | var d = a + b + c/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":2},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | var b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""},{"checkerId":"Biome","frame":" 2 | const b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; +exports[`biome > serve > get initial error and subsequent error 3`] = `"[{"checkerId":"Biome","frame":" 2 | const b = 'world'/n 3 | const c = '!'/n > 4 | var d = a + b + c/n | ^^^^^^^^^^^^^^^^^/n 5 |","id":"/playground-temp/biome-default/src/index.js","level":1,"loc":{"column":1,"file":"/playground-temp/biome-default/src/index.js","line":4},"message":"[lint/style/noVar] Use let or const instead of var.","stack":""}]"`; exports[`biome > serve > get initial error and subsequent error 4`] = ` [ " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. - FILE /playground-temp/biome-default/src/index.js:2:1 - - 1 | const a = 'hello' - > 2 | var b = 'world' - | ^^^^^^^^^^^^^^^ - 3 | const c = '!' - 4 | var d = a + b + c - 5 | -", - " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. - FILE /playground-temp/biome-default/src/index.js:4:1 - - 2 | var b = 'world' - 3 | const c = '!' - > 4 | var d = a + b + c - | ^^^^^^^^^^^^^^^^^ - 5 | -", - " ERROR(Biome) [lint/style/noVar] Use let or const instead of var. FILE /playground-temp/biome-default/src/index.js:4:1 2 | const b = 'world' @@ -59,6 +40,6 @@ exports[`biome > serve > get initial error and subsequent error 4`] = ` | ^^^^^^^^^^^^^^^^^ 5 | ", - "[Biome] Found 3 errors and 0 warning", + "[Biome] Found 1 error and 0 warning", ] `;