Extract isomorphic @getpaseo/highlight package with syntax-highlighted file preview

- Create packages/highlight with shared Lezer-based syntax highlighting (types, parsers, highlighter, color maps)
- Add syntax highlighting and line numbers to file-pane.tsx with memoized CodeLine component
- Import shared highlight colors in git-diff-pane.tsx instead of local definitions
- Delete duplicated syntax-highlighter.ts from both app and server
- Fix TSX dialect to "ts jsx" (correct per Lezer docs)
This commit is contained in:
Mohamed Boudra
2026-03-21 19:56:49 +07:00
parent 6b50ace2bd
commit 5f065c2685
20 changed files with 1978 additions and 1376 deletions
@@ -0,0 +1,74 @@
import { describe, it, expect } from 'vitest'
import { isLanguageSupported, getSupportedExtensions, getParserForFile } from '../parsers.js'
describe('isLanguageSupported', () => {
it('returns true for supported file extensions', () => {
expect(isLanguageSupported('test.js')).toBe(true)
expect(isLanguageSupported('test.ts')).toBe(true)
expect(isLanguageSupported('test.tsx')).toBe(true)
expect(isLanguageSupported('test.py')).toBe(true)
expect(isLanguageSupported('test.go')).toBe(true)
expect(isLanguageSupported('test.rs')).toBe(true)
expect(isLanguageSupported('test.json')).toBe(true)
expect(isLanguageSupported('test.css')).toBe(true)
expect(isLanguageSupported('test.html')).toBe(true)
expect(isLanguageSupported('test.java')).toBe(true)
expect(isLanguageSupported('test.ex')).toBe(true)
})
it('returns false for unsupported file extensions', () => {
expect(isLanguageSupported('test.xyz')).toBe(false)
expect(isLanguageSupported('test.txt')).toBe(false)
expect(isLanguageSupported('test.csv')).toBe(false)
})
it('returns false for files without extensions', () => {
expect(isLanguageSupported('Makefile')).toBe(false)
})
it('handles nested paths', () => {
expect(isLanguageSupported('src/utils/test.ts')).toBe(true)
expect(isLanguageSupported('deep/nested/path/file.py')).toBe(true)
})
})
describe('getSupportedExtensions', () => {
it('returns an array of extension strings', () => {
const extensions = getSupportedExtensions()
expect(Array.isArray(extensions)).toBe(true)
expect(extensions.length).toBeGreaterThan(0)
})
it('includes common extensions', () => {
const extensions = getSupportedExtensions()
expect(extensions).toContain('js')
expect(extensions).toContain('ts')
expect(extensions).toContain('tsx')
expect(extensions).toContain('py')
expect(extensions).toContain('go')
expect(extensions).toContain('rs')
expect(extensions).toContain('json')
})
})
describe('getParserForFile', () => {
it('returns a parser for supported files', () => {
expect(getParserForFile('test.js')).not.toBeNull()
expect(getParserForFile('test.py')).not.toBeNull()
})
it('returns null for unsupported files', () => {
expect(getParserForFile('test.xyz')).toBeNull()
})
it('returns null for files without extension', () => {
expect(getParserForFile('noext')).toBeNull()
})
it('is case-insensitive for extensions', () => {
expect(getParserForFile('test.JS')).not.toBeNull()
expect(getParserForFile('test.Py')).not.toBeNull()
})
})