/* eslint-disable @typescript-eslint/naming-convention */ import Papa, { ParseResult } from "papaparse"; export type CSVType = { name: string | null; email: string | null; role: number | null; author_id: string | null; auto_assign: number | null; notification: number; encryption: number | null; encryption_password: string | null; prompt: number | null; }; // CSVTypeのプロパティ名を文字列の配列で定義する const CSVTypeFields: (keyof CSVType)[] = [ "name", "email", "role", "author_id", "auto_assign", "notification", "encryption", "encryption_password", "prompt", ]; // 2つの配列が等しいかどうかを判定する const equals = (lhs: string[], rhs: string[]) => { if (lhs.length !== rhs.length) return false; for (let i = 0; i < lhs.length; i += 1) { if (lhs[i] !== rhs[i]) return false; } return true; }; /** CSVファイルをCSVType型に変換するパーサー */ export const parseCSV = async (csvString: string): Promise => new Promise((resolve, reject) => { Papa.parse(csvString, { download: false, worker: false, // XXX: workerを使うとエラーが発生するためfalseに設定 header: true, dynamicTyping: { // author_id, encryption_passwordは数値のみの場合、numberに変換されたくないためdynamicTypingをtrueにしない role: true, auto_assign: true, notification: true, encryption: true, prompt: true, }, // dynamicTypingがfalseの場合、空文字をnullに変換できないためtransformを使用する transform: (value, field) => { if (field === "author_id" || field === "encryption_password") { // 空文字の場合はnullに変換する if (value === "") { return null; } } return value; }, complete: (results: ParseResult) => { // ヘッダーがCSVTypeFieldsと一致しない場合はエラーを返す if (!equals(results.meta.fields ?? [], CSVTypeFields)) { reject(new Error("Invalid CSV format")); } resolve(results.data); }, error: (error: Error) => { reject(error); }, }); });