mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-02 22:17:14 +00:00
fix(jsonl): add explicit UTF-8 BOM stripping
Strip BOM character before JSON parsing to ensure robust cross-platform JSONL file handling.
This commit is contained in:
@@ -70,10 +70,12 @@ export interface ParserOptions {
|
|||||||
* Returns null for non-assistant entries or entries without usage data
|
* Returns null for non-assistant entries or entries without usage data
|
||||||
*/
|
*/
|
||||||
export function parseUsageEntry(line: string, projectPath: string): RawUsageEntry | null {
|
export function parseUsageEntry(line: string, projectPath: string): RawUsageEntry | null {
|
||||||
if (!line.trim()) return null;
|
// Strip UTF-8 BOM if present (can occur on first line of some files)
|
||||||
|
const cleanLine = line.replace(/^\uFEFF/, '').trim();
|
||||||
|
if (!cleanLine) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const entry = JSON.parse(line);
|
const entry = JSON.parse(cleanLine);
|
||||||
|
|
||||||
// Only process assistant entries with usage data
|
// Only process assistant entries with usage data
|
||||||
if (entry.type !== 'assistant') return null;
|
if (entry.type !== 'assistant') return null;
|
||||||
|
|||||||
@@ -133,6 +133,16 @@ describe('parseUsageEntry', () => {
|
|||||||
expect(parseUsageEntry('not json at all', '/test')).toBeNull();
|
expect(parseUsageEntry('not json at all', '/test')).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('strips UTF-8 BOM from line before parsing', () => {
|
||||||
|
// UTF-8 BOM character (\uFEFF) can appear at start of files
|
||||||
|
const bomEntry = '\uFEFF' + VALID_ASSISTANT_ENTRY;
|
||||||
|
const result = parseUsageEntry(bomEntry, '/test');
|
||||||
|
|
||||||
|
expect(result).not.toBeNull();
|
||||||
|
expect(result!.model).toBe('claude-sonnet-4-5');
|
||||||
|
expect(result!.inputTokens).toBe(1000);
|
||||||
|
});
|
||||||
|
|
||||||
test('includes project path in result', () => {
|
test('includes project path in result', () => {
|
||||||
const result = parseUsageEntry(VALID_ASSISTANT_ENTRY, '/custom/project/path');
|
const result = parseUsageEntry(VALID_ASSISTANT_ENTRY, '/custom/project/path');
|
||||||
expect(result!.projectPath).toBe('/custom/project/path');
|
expect(result!.projectPath).toBe('/custom/project/path');
|
||||||
|
|||||||
Reference in New Issue
Block a user