diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts new file mode 100644 index 00000000000000..52ee14e52ba9c2 --- /dev/null +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -0,0 +1,42 @@ +import { injectQuery } from '../utils' + +const isWindows = process.platform === 'win32' + +if (isWindows) { + // this test will work incorrectly on unix systems + test('normalize windows path', () => { + expect(injectQuery('C:\\User\\Vite\\Project', 'direct')).toEqual( + 'C:/User/Vite/Project?direct' + ) + }) +} + +test('path with multiple spaces', () => { + expect(injectQuery('/usr/vite/path with space', 'direct')).toEqual( + '/usr/vite/path with space?direct' + ) +}) + +test('path with multiple % characters', () => { + expect(injectQuery('/usr/vite/not%20a%20space', 'direct')).toEqual( + '/usr/vite/not%20a%20space?direct' + ) +}) + +test('path with %25', () => { + expect(injectQuery('/usr/vite/%25hello%25', 'direct')).toEqual( + '/usr/vite/%25hello%25?direct' + ) +}) + +test('path with unicode', () => { + expect(injectQuery('/usr/vite/東京', 'direct')).toEqual( + '/usr/vite/東京?direct' + ) +}) + +test('path with unicode, space, and %', () => { + expect(injectQuery('/usr/vite/東京 %20 hello', 'direct')).toEqual( + '/usr/vite/東京 %20 hello?direct' + ) +}) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 1c728af6c3d9e8..79ad4c033fd624 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -124,7 +124,7 @@ export function removeImportQuery(url: string) { } export function injectQuery(url: string, queryToInject: string) { - let resolvedUrl = new URL(url, 'relative:///') + let resolvedUrl = new URL(url.replace(/%/g, '%25'), 'relative:///') if (resolvedUrl.protocol !== 'relative:') { resolvedUrl = pathToFileURL(url) } @@ -132,6 +132,7 @@ export function injectQuery(url: string, queryToInject: string) { if (protocol === 'file:') { pathname = pathname.slice(1) } + pathname = decodeURIComponent(pathname) return `${pathname}?${queryToInject}${search ? `&` + search.slice(1) : ''}${ hash || '' }`