@decaf-ts/decorator-validation
Version:
simple decorator based validation engine
96 lines • 3.47 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Serialization = exports.JSONSerializer = exports.DefaultSerializationMethod = void 0;
const Model_1 = require("./../model/Model.cjs");
const constants_1 = require("./constants.cjs");
const utils_1 = require("./../model/utils.cjs");
exports.DefaultSerializationMethod = "json";
/**
* @summary Concrete implementation of a {@link Serializer} in JSON format
* @description JS's native JSON.stringify (used here) is not deterministic
* and therefore should not be used for hashing purposes
*
* To keep dependencies low, we will not implement this, but we recommend
* implementing a similar {@link JSONSerializer} using 'deterministic-json' libraries
*
* @class JSONSerializer
* @implements Serializer
*
* @category Model
*/
class JSONSerializer {
constructor() { }
/**
* @summary prepares the model for serialization
* @description returns a shallow copy of the object, containing an enumerable {@link ModelKeys#ANCHOR} property
* so the object can be recognized upon deserialization
*
* @param {T} model
* @protected
*/
preSerialize(model) {
// TODO: nested preserialization (so increase performance when deserializing)
const toSerialize = Object.assign({}, model);
const metadata = (0, utils_1.getMetadata)(model);
toSerialize[constants_1.ModelKeys.ANCHOR] = metadata || model.constructor.name;
return toSerialize;
}
/**
* @summary Rebuilds a model from a serialization
* @param {string} str
*
* @throws {Error} If it fails to parse the string, or to build the model
*/
deserialize(str) {
const deserialization = JSON.parse(str);
const className = deserialization[constants_1.ModelKeys.ANCHOR];
if (!className)
throw new Error("Could not find class reference in serialized model");
const model = Model_1.Model.build(deserialization, className);
return model;
}
/**
* @summary Serializes a model
* @param {T} model
*
* @throws {Error} if fails to serialize
*/
serialize(model) {
return JSON.stringify(this.preSerialize(model));
}
}
exports.JSONSerializer = JSONSerializer;
class Serialization {
static { this.current = exports.DefaultSerializationMethod; }
static { this.cache = {
json: new JSONSerializer(),
}; }
constructor() { }
static get(key) {
if (key in this.cache)
return this.cache[key];
throw new Error(`No serialization method registered under ${key}`);
}
static register(key, func, setDefault = false) {
if (key in this.cache)
throw new Error(`Serialization method ${key} already registered`);
this.cache[key] = new func();
if (setDefault)
this.current = key;
}
static serialize(obj, method, ...args) {
if (!method)
return this.get(this.current).serialize(obj, ...args);
return this.get(method).serialize(obj, ...args);
}
static deserialize(obj, method, ...args) {
if (!method)
return this.get(this.current).deserialize(obj, ...args);
return this.get(method).deserialize(obj, ...args);
}
static setDefault(method) {
this.current = this.get(method);
}
}
exports.Serialization = Serialization;
//# sourceMappingURL=serialization.js.map