import { ValueTransformer } from 'typeorm'; // DBのbigint型をnumber型に変換するためのtransformer // DBのBigInt型をそのまま扱うと、JSのNumber型の最大値を超えると誤差が発生するため、本来はNumber型に変換すべきではないが、 // 影響範囲を最小限に抑えるため、Number型に変換する。使用するのはAutoIncrementされるIDのみの想定のため、 // Number.MAX_SAFE_INTEGERより大きい値は現実的には発生しない想定で変換する。 export const bigintTransformer: ValueTransformer = { from: (value: any): number | null => { // valueがnullであればそのまま返す if (value === null) { return value; } // valueがnumber型かどうかを判定 // 利用DBによってはbigint型であってもnumber型で返ってくる場合があるため、number型の場合はそのまま返す(sqliteの場合) if (typeof value === 'number') { return value; } // valueが文字列かどうかを判定 if (typeof value !== 'string') { throw new Error(`${value} is not string.`); } // 数値に変換可能な文字列かどうかを判定 if (Number.isNaN(parseInt(value))) { throw new Error(`${value} is not int.`); } // 文字列ならbigintに変換 // valueが整数でない場合は値が丸められてしまうが、TypeORMのEntityの定義上、整数を表す文字列以外はありえないため、少数点は考慮しない const bigIntValue = BigInt(value); // bigIntValueがNumber.MAX_SAFE_INTEGERより大きいかどうかを判定 if (bigIntValue > Number.MAX_SAFE_INTEGER) { throw new Error(`${value} is greater than ${Number.MAX_SAFE_INTEGER}.`); } // number型で表現できる整数であればnumber型に変換して返す return Number(bigIntValue); }, to: (value: any): string | null | undefined => { // valueがnullまたはundefinedであればそのまま返す if (value === null || value === undefined) { return value; } // valueがnumber型かどうかを判定 if (typeof value !== 'number') { throw new Error(`${value} is not number.`); } // valueがNumber.MAX_SAFE_INTEGERより大きいかどうかを判定 if (value > Number.MAX_SAFE_INTEGER) { throw new Error(`value is greater than ${Number.MAX_SAFE_INTEGER}.`); } // valueが整数かどうかを判定 if (!Number.isInteger(value)) { throw new Error(`${value} is not integer.`); } return value.toString(); }, };