ejson2
Version:
Extended JSON Evolved
139 lines • 4.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.builtinConverters = void 0;
const utils_1 = require("../utils");
const index_1 = require("./index");
const custom_types_1 = require("./custom-types");
const base64_js_1 = require("base64-js");
exports.builtinConverters = [
{
// Date
matchJSONValue(obj) {
return (0, utils_1.hasOwn)(obj, '$date') && (0, utils_1.lengthOf)(obj) === 1;
},
matchObject(obj) {
return obj instanceof Date;
},
toJSONValue(obj) {
return { $date: obj.getTime() };
},
fromJSONValue(obj) {
return new Date(obj.$date);
},
},
{
// RegExp
matchJSONValue(obj) {
return ((0, utils_1.hasOwn)(obj, '$regexp') && (0, utils_1.hasOwn)(obj, '$flags') && (0, utils_1.lengthOf)(obj) === 2);
},
matchObject(obj) {
return obj instanceof RegExp;
},
toJSONValue(regexp) {
return {
$regexp: regexp.source,
$flags: regexp.flags,
};
},
fromJSONValue(obj) {
// Replaces duplicate / invalid flags.
return new RegExp(obj.$regexp, obj.$flags
// Cut off flags at 50 chars to avoid abusing RegExp for DOS.
.slice(0, 50)
.replace(/[^gimuy]/g, '')
.replace(/(.)(?=.*\1)/g, ''));
},
},
{
// NaN, Inf, -Inf. (These are the only objects with typeof !== 'object'
// which we match.)
matchJSONValue(obj) {
return (0, utils_1.hasOwn)(obj, '$InfNaN') && (0, utils_1.lengthOf)(obj) === 1;
},
matchObject: utils_1.isInfOrNaN,
toJSONValue(obj) {
let sign;
if (Number.isNaN(obj)) {
sign = 0;
}
else if (obj === Infinity) {
sign = 1;
}
else {
sign = -1;
}
return { $InfNaN: sign };
},
fromJSONValue(obj) {
return obj.$InfNaN / 0;
},
},
{
// Binary
matchJSONValue(obj) {
return (0, utils_1.hasOwn)(obj, '$binary') && (0, utils_1.lengthOf)(obj) === 1;
},
matchObject(obj) {
return ((typeof Uint8Array !== 'undefined' && obj instanceof Uint8Array) ||
(obj && (0, utils_1.hasOwn)(obj, '$Uint8ArrayPolyfill')));
},
toJSONValue(obj) {
return { $binary: (0, base64_js_1.fromByteArray)(obj) };
},
fromJSONValue(obj) {
return (0, base64_js_1.toByteArray)(obj.$binary);
},
},
{
// Escaping one level
matchJSONValue(obj) {
return (0, utils_1.hasOwn)(obj, '$escape') && (0, utils_1.lengthOf)(obj) === 1;
},
matchObject(obj) {
let match = false;
if (obj) {
const keyCount = (0, utils_1.lengthOf)(obj);
if (keyCount === 1 || keyCount === 2) {
match = exports.builtinConverters.some(converter => converter.matchJSONValue(obj));
}
}
return match;
},
toJSONValue(obj) {
const newObj = {};
(0, utils_1.keysOf)(obj).forEach(key => {
newObj[key] = index_1.EJSON.toJSONValue(obj[key]);
});
return { $escape: newObj };
},
fromJSONValue(obj) {
const newObj = {};
(0, utils_1.keysOf)(obj.$escape).forEach(key => {
newObj[key] = index_1.EJSON.fromJSONValue(obj.$escape[key]);
});
return newObj;
},
},
{
// Custom
matchJSONValue(obj) {
return ((0, utils_1.hasOwn)(obj, '$type') && (0, utils_1.hasOwn)(obj, '$value') && (0, utils_1.lengthOf)(obj) === 2);
},
matchObject(obj) {
return index_1.EJSON._isCustomType(obj);
},
toJSONValue(obj) {
const jsonValue = obj.toJSONValue();
return { $type: obj.typeName(), $value: jsonValue };
},
fromJSONValue(obj) {
const typeName = obj.$type;
if (!custom_types_1.customTypes.has(typeName)) {
throw new Error(`Custom EJSON type ${typeName} is not defined`);
}
const converter = custom_types_1.customTypes.get(typeName);
return converter(obj.$value);
},
},
];
//# sourceMappingURL=built-in-converters.js.map