@bjesuiter/serializr-helpers
Version:
Provides some helper functions and serialization PropertySchemas for mobxjs/serializr - library
93 lines (92 loc) • 4.68 kB
JavaScript
/**
* This serializr PropertySchema can be used with @serializable(MomentSerializationSchema)
* to make moment.js Moment objects serializable
* @type {PropSchema}
*/
import { custom, SKIP } from 'serializr';
import moment from 'moment';
import { MomentSerializationDefaults } from "./moment-serialization-options";
import { log } from "./logger";
export function buildSerializer(valueIfUndefined, useUtc, serializationFormat) {
if (useUtc === void 0) { useUtc = false; }
if (serializationFormat === void 0) { serializationFormat = 'ISO'; }
return function (value) {
//value.format is used here to output a datetime with attached offset to utc
//value.toJson would normalize the output to utc,
// which would make it impossible to reconstruct the original timezone
// intended use of == vs. === to include null when checking for undefined
if (value == undefined) {
if (!moment.isMoment(valueIfUndefined)) {
// Moment object will be skipped in serialization if no default value is set
// or json-compatible default value will be returned
return (valueIfUndefined) ? valueIfUndefined : SKIP;
}
else {
// default value is a moment object => serialize as normal moment object
value = valueIfUndefined;
}
}
if (serializationFormat === 'ISO') {
// see documentation for toISO String for keepOffset explanation:
// https://momentjs.com/docs/#/displaying/as-iso-string/
return (useUtc) ? value.toISOString() : value.toISOString(true);
}
value = (useUtc) ? value.utc() : value;
return value.format(serializationFormat);
};
}
export function validateDefaultDeserializeValue(defaultRestoreValue) {
if (!defaultRestoreValue.isValid()) {
throw new Error("Default Moment deserialization value is invalid. " +
("Got input string \"" + defaultRestoreValue.creationData().input + "\""));
}
return true;
}
export function buildDeserializer(handleErrorPolicy, useUtc, defaultRestoreValue, logger) {
if (handleErrorPolicy === void 0) { handleErrorPolicy = 'log-error'; }
if (useUtc === void 0) { useUtc = false; }
return function (jsonValue, callback, context) {
// const isoFormat = 'YYYY-MM-DDTHH:mm:ss.sssZZ';
// const isoUtcFormat = 'YYYY-MM-DDTHH:mm:ss.sssZ';
//Note: passing the iso format avoids deprecation notices about format detection
var restoredMoment = (useUtc) ? moment.utc(jsonValue) : moment(jsonValue);
if (logger === undefined) {
logger = log;
}
if (!restoredMoment.isValid()) {
if (defaultRestoreValue !== undefined && validateDefaultDeserializeValue(defaultRestoreValue)) {
// set the error Policy to silent when default value for decode was set explicitly.
handleErrorPolicy = 'silent';
restoredMoment = defaultRestoreValue;
}
var errorText = "Moment js serialized json value is invalid! \n Got the value \"" + jsonValue + "\" which does not decode into a valid Moment object.\n You can change the handling of this message by setting the 'deserializationErrorPolicy' in \n MomentSerializationOptions";
switch (handleErrorPolicy) {
case "throw":
throw new Error(errorText);
case "log-error":
logger.error(errorText);
break;
case "log-warn":
logger.warn(errorText);
break;
case "silent":
break;
}
}
return restoredMoment;
};
}
/**
* This factory function returns a serialization schema for Moment objects.
*
* @default The default schema skips undefined moment objects in serialization and
* keeps timezone offset while serialization and deserialization.
* This differs from default moment.toIsoString() behavior, which converts local timestamps (with like +02:00 offset)
* to UTC in serialization (Strings with Z as offset)
* @param options
* @constructor
*/
export function MomentSerializationSchema(options) {
if (options === void 0) { options = MomentSerializationDefaults; }
return custom(buildSerializer(options.valueIfUndefined, options.useUtc, options.serializationFormat), buildDeserializer(options.deserializationErrorPolicy, options.useUtc, options.deserializationDefault));
}