json-helpers
Version:
JSON stringify/parser managing 'undefined, Date and Buffer.
129 lines • 4.27 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JSONReplacerToJSONImpl = void 0;
const json_parser_1 = require("./json-parser");
function findFunctionPrototype(objectConstructor, name) {
let proto = objectConstructor.prototype;
let toJSONDescriptor = Object.getOwnPropertyDescriptor(proto, name);
if (toJSONDescriptor) {
return [proto, toJSONDescriptor];
}
else {
proto = Object.getPrototypeOf(objectConstructor);
while (proto) {
toJSONDescriptor = Object.getOwnPropertyDescriptor(proto, name);
if (toJSONDescriptor) {
return [proto, toJSONDescriptor];
}
proto = Object.getPrototypeOf(proto);
}
}
return null;
}
class JSONReplacerSetup {
constructor(replacer) {
this.objectType = replacer.objectType;
this.objectConstructor = replacer.objectConstructor;
this.serialize = replacer.serialize;
const objectConstructor = this.objectConstructor;
this._toOriginalDescriptor = findFunctionPrototype(objectConstructor, 'toJSON');
if (this._toOriginalDescriptor == null) {
this._toOriginalDescriptor = [
objectConstructor.prototype,
{
value: undefined,
configurable: true,
enumerable: false,
writable: true
}
];
}
if (this.serialize) {
const self = this;
this._toJSONDescriptor = {
value: function () {
return { type: self.objectType, data: self.serialize(this) };
},
configurable: true,
enumerable: false,
writable: true
};
}
}
install() {
if (this.serialize) {
try {
Object.defineProperty(this._toOriginalDescriptor[0], 'toJSON', this._toJSONDescriptor);
}
catch (err) {
console.error(`${err}`);
}
}
}
uninstall() {
if (this.serialize) {
try {
Object.defineProperty(this._toOriginalDescriptor[0], 'toJSON', this._toOriginalDescriptor[1]);
}
catch (err) {
}
}
}
}
class JSONReplacerToJSONImpl {
constructor() {
this._jsonReplacerSetupsMap = new Map();
this._installed = 0;
this._replacer = this._replacer.bind(this);
}
replacer(replacer) {
const setup = new JSONReplacerSetup(replacer);
if (replacer.serialize) {
this._jsonReplacerSetupsMap.set(setup.objectConstructor, setup);
}
else {
this._jsonReplacerSetupsMap.delete(setup.objectConstructor);
}
}
_replacer(key, value) {
if (typeof key === 'undefined') {
return json_parser_1.ToJSONConstants.JSON_TOKEN_UNDEFINED;
}
return value;
}
_replacerChain(replacer, key, value) {
if (typeof key === 'undefined') {
return json_parser_1.ToJSONConstants.JSON_TOKEN_UNDEFINED;
}
return replacer(key, value);
}
install() {
if (this._installed++ === 0) {
this._jsonReplacerSetupsMap.forEach((item) => {
item.install();
});
}
}
uninstall() {
if (--this._installed === 0) {
this._jsonReplacerSetupsMap.forEach((item) => {
item.uninstall();
});
}
}
stringify(value, replacer, space) {
try {
this.install();
const replacerCb = replacer ? this._replacerChain.bind(this, replacer) : this._replacer;
const result = JSON.stringify(value, replacerCb, space);
this.uninstall();
return result;
}
catch (err) {
this.uninstall();
throw err;
}
}
}
exports.JSONReplacerToJSONImpl = JSONReplacerToJSONImpl;
//# sourceMappingURL=json-replacer-tojson-impl.js.map