@proddata/node-cratedb
Version:
Node.js client for CrateDB
84 lines • 3.12 kB
JavaScript
import { ColumnTypes } from './utils/ColumnTypes.js';
import { DeserializationError } from './utils/Error.js';
export class Serializer {
static serialize(obj) {
return JSON.stringify(obj, this.replacer);
}
static replacer(_, value) {
if (typeof value === 'bigint') {
return JSON.rawJSON(value.toString());
}
if (value instanceof Map) {
return Object.fromEntries(value);
}
if (value instanceof Set) {
return Array.from(value);
}
return value;
}
static deserialize(str, config) {
try {
return this._deserialize(str, config);
}
catch {
throw new DeserializationError('Deserialization of response body failed');
}
}
static _deserialize(str, config) {
const obj = config.long === 'bigint' ? JSON.parse(str, this.reviver) : JSON.parse(str);
obj.col_types?.forEach((type, index) => {
// Extract the base type even from nested arrays
const baseType = this.extractBaseType(type);
switch (baseType) {
case ColumnTypes.BIGINT:
if (config.long === 'bigint') {
obj.rows?.forEach((row) => {
row[index] = this.recursiveConvert(row[index], (val) => BigInt(String(val)));
});
}
break;
case ColumnTypes.DATE:
if (config.date === 'date') {
obj.rows?.forEach((row) => {
row[index] = this.recursiveConvert(row[index], (val) => new Date(val));
});
}
break;
case ColumnTypes.TIMESTAMP_WITH_TIME_ZONE:
case ColumnTypes.TIMESTAMP_WITHOUT_TIME_ZONE:
if (config.timestamp === 'date') {
obj.rows?.forEach((row) => {
row[index] = this.recursiveConvert(row[index], (val) => new Date(val));
});
}
break;
default:
// No special handling for other types
}
});
return obj;
}
static extractBaseType(type) {
return Array.isArray(type) ? this.extractBaseType(type[1]) : type;
}
static recursiveConvert(cell, converter) {
if (Array.isArray(cell)) {
return cell.map((item) => this.recursiveConvert(item, converter));
}
if (typeof cell === 'number') {
return converter(cell);
}
return cell;
}
static reviver(_, value, context = null) {
//if number is greater than Number.MAX_SAFE_INTEGER and not a float
if (typeof value === 'number' &&
value > Number.MAX_SAFE_INTEGER &&
context !== null &&
!context.source.includes('.')) {
return BigInt(context.source);
}
return value;
}
}
//# sourceMappingURL=Serializer.js.map