You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
58 lines
1.6 KiB
58 lines
1.6 KiB
import { readFile } from "fs/promises"; |
|
|
|
import { CSVParser } from "../utils/csv_parser/csv_parser.js"; |
|
import { GamesLogError } from "./errors/games_log_error.js"; |
|
|
|
export type LogData = { |
|
eventType: string; |
|
eventPayload: { [key: string]: any }; |
|
}[]; |
|
|
|
export class GamesLogParser { |
|
async parseFile(filename: string, encoding: BufferEncoding = "utf-8") { |
|
let data; |
|
try { |
|
data = await readFile(filename, { encoding }); |
|
} catch (err) { |
|
throw new GamesLogError(`Unable to read log file: ${filename}`, { |
|
cause: err instanceof Error ? err : undefined, |
|
}); |
|
} |
|
return this.parse(data); |
|
} |
|
|
|
parse(data: string): LogData { |
|
const parser = new CSVParser({ headers: true }); |
|
const csvData = parser.parse(data); |
|
|
|
return csvData.map((row, rowNumber) => { |
|
if (!("event_type" in row)) { |
|
throw new GamesLogError(`Missing event type on row: ${rowNumber}`); |
|
} |
|
if (!("event_payload" in row)) { |
|
throw new GamesLogError(`Missing event payload on row: ${rowNumber}`); |
|
} |
|
|
|
let eventPayload; |
|
try { |
|
eventPayload = JSON.parse(row.event_payload); |
|
} catch (err) { |
|
throw new GamesLogError( |
|
"Unable to parse event payload on row: ${rowNumber}", |
|
{ |
|
cause: err instanceof Error ? err : undefined, |
|
} |
|
); |
|
} |
|
|
|
if (typeof eventPayload !== "object") { |
|
throw new GamesLogError("Invalid event payload on row: ${rowNumber}"); |
|
} |
|
|
|
return { |
|
eventType: row.event_type, |
|
eventPayload, |
|
}; |
|
}); |
|
} |
|
}
|
|
|