From a5c4b9db18e681b5199a8758e0bbb1d2cda5a458 Mon Sep 17 00:00:00 2001 From: Charan Rathore <180254320+charan-rathore@users.noreply.github.com> Date: Thu, 1 Oct 2026 09:36:35 +0530 Subject: [PATCH] fix: decode diagnostic file URLs before reading sources --- .../__tests__/sources.spec.ts | 36 +++++++++++++++++++ packages/vite-plugin-checker/src/sources.ts | 7 ++-- 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 packages/vite-plugin-checker/__tests__/sources.spec.ts diff --git a/packages/vite-plugin-checker/__tests__/sources.spec.ts b/packages/vite-plugin-checker/__tests__/sources.spec.ts new file mode 100644 index 00000000..451c31e9 --- /dev/null +++ b/packages/vite-plugin-checker/__tests__/sources.spec.ts @@ -0,0 +1,36 @@ +import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import path from 'node:path' +import { pathToFileURL } from 'node:url' +import { expect, it } from 'vitest' +import { normalizePath, readSources } from '../src/sources' + +it.each([ + 'with space.ts', + 'percent%.ts', + 'hash#.ts', + '中文.ts', +])('reads a diagnostic file URL for %s', async (name) => { + const root = await mkdtemp(path.join(tmpdir(), 'checker-url-')) + try { + const file = path.join(root, name) + await writeFile(file, 'debugger;\n') + const normalized = normalizePath(pathToFileURL(file).href, root) + expect(normalized).toBe(file) + expect((await readSources([normalized])).get(normalized)).toBe( + await readFile(file, 'utf8'), + ) + } finally { + await rm(root, { recursive: true, force: true }) + } +}) + +it('leaves ordinary relative and absolute paths unchanged', () => { + const root = path.resolve('/project') + expect(normalizePath('src/a%20.ts', root)).toBe( + path.join(root, 'src/a%20.ts'), + ) + expect(normalizePath(path.join(root, 'src/a.ts'), root)).toBe( + path.join(root, 'src/a.ts'), + ) +}) diff --git a/packages/vite-plugin-checker/src/sources.ts b/packages/vite-plugin-checker/src/sources.ts index 99ab8335..5db65f9a 100644 --- a/packages/vite-plugin-checker/src/sources.ts +++ b/packages/vite-plugin-checker/src/sources.ts @@ -1,11 +1,12 @@ import fs from 'node:fs/promises' import path from 'node:path' +import { fileURLToPath } from 'node:url' export function normalizePath(p: string, cwd: string) { let filename = p - // Strip file:// URL scheme (oxlint outputs file:// URLs in JSON format) - if (filename && filename.startsWith('file://')) { - filename = filename.slice(7) + // Decode file URLs, including escaped characters and platform-specific paths. + if (filename.startsWith('file://')) { + filename = fileURLToPath(filename) } if (filename) { filename = path.isAbsolute(filename)