hadron-document
Version:
Hadron Document
100 lines • 3.53 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fieldStringLen = fieldStringLen;
exports.objectToIdiomaticEJSON = objectToIdiomaticEJSON;
exports.getDefaultValueForType = getDefaultValueForType;
const bson_1 = require("bson");
const hadron_type_checker_1 = __importDefault(require("hadron-type-checker"));
const UNCASTED_EMPTY_TYPE_VALUE = {
Array: [],
Object: {},
Decimal128: 0,
Int32: 0,
Int64: 0,
Double: 0,
MaxKey: 0,
MinKey: 0,
Timestamp: 0,
Date: 0,
String: '',
Code: '',
Binary: '',
ObjectId: '',
BSONRegExp: '',
BSONSymbol: '',
Boolean: false,
Undefined: undefined,
Null: null,
};
const maxFourYearDate = new Date('9999-12-31T23:59:59.999Z').valueOf();
function fieldStringLen(value) {
const length = String(value).length;
return length === 0 ? 1 : length;
}
/**
* Turn a BSON value into what we consider idiomatic extended JSON.
*
* This differs from both the relaxed and strict mode of the 'bson'
* package's EJSON class: We preserve the type information for longs
* via $numberLong, but redact it for $numberInt and $numberDouble.
*
* This may seem inconsistent, but considering that the latter two
* types are exactly representable in JS and $numberLong is not,
* in addition to the fact that this has been historic behavior
* in Compass for a long time, this seems like a reasonable choice.
*
* Also turns $date.$numberLong into a date so that it will be
* displayed as an iso date string since this is what Compass did
* historically. Unless it is outside of the safe range.
*
* @param value Any BSON value.
* @returns A serialized, human-readable and human-editable string.
*/
function objectToIdiomaticEJSON(value, options = {}) {
const serialized = bson_1.EJSON.serialize(value, {
relaxed: false,
});
makeEJSONIdiomatic(serialized);
return JSON.stringify(serialized, null, 'indent' in options ? options.indent : 2);
}
function makeEJSONIdiomatic(value) {
if (!value || typeof value !== 'object')
return;
for (const key of Object.keys(value)) {
const entry = value[key];
// We are only interested in object-like values, skip everything else
if (typeof entry !== 'object' || entry === null) {
continue;
}
if (entry.$numberInt) {
value[key] = +entry.$numberInt;
continue;
}
if (entry.$numberDouble) {
if (Number.isFinite(+entry.$numberDouble) &&
!Object.is(+entry.$numberDouble, -0)) {
// EJSON can represent +/-Infinity or NaN values but JSON can't
// (and -0 can be parsed from JSON but not serialized by JSON.stringify).
value[key] = +entry.$numberDouble;
}
continue;
}
if (entry.$date && entry.$date.$numberLong) {
const number = entry.$date.$numberLong;
if (number >= 0 && number <= maxFourYearDate) {
entry.$date = new Date(+number).toISOString();
}
}
makeEJSONIdiomatic(entry);
}
}
/**
* Returns a default value for the BSON type passed in.
*/
function getDefaultValueForType(type) {
return hadron_type_checker_1.default.cast(UNCASTED_EMPTY_TYPE_VALUE[type], type);
}
//# sourceMappingURL=utils.js.map