63 lines
3 KiB
JavaScript
63 lines
3 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.serializeWith = serializeWith;
|
|
const options_1 = require("../options");
|
|
const utils_1 = require("../utils");
|
|
const unhandledType = (serializer, value) => new TypeError(`'${serializer.constructor.name}' has no method for value type '${typeof value}'`);
|
|
function serializeEntries(serializer, value, options) {
|
|
var _a;
|
|
let state;
|
|
for (const [key, val] of value) {
|
|
if (options === null || options === void 0 ? void 0 : options.shouldSkipSerializing(key, val)) {
|
|
continue;
|
|
}
|
|
const name = (_a = options === null || options === void 0 ? void 0 : options.getPropertyName(key, options_1.Stage.Serialize)) !== null && _a !== void 0 ? _a : key;
|
|
state = serializer.serializeKey(name);
|
|
state = serializer.serializeValue(val);
|
|
}
|
|
return serializer.end();
|
|
}
|
|
function serializeClass(serializer, value, options) {
|
|
const ser = serializer.serializeClass(value.constructor.name);
|
|
return serializeEntries(ser, Object.entries(value), options);
|
|
}
|
|
function serializeObject(serializer, value, options) {
|
|
const ser = serializer.serializeObject();
|
|
return serializeEntries(ser, Object.entries(value), options);
|
|
}
|
|
function serializeIter(serializer, value, options) {
|
|
let state;
|
|
for (const val of value) {
|
|
state = serializer.serializeElement(val);
|
|
}
|
|
return serializer.end();
|
|
}
|
|
function defaultOptions(value) {
|
|
return value.constructor[Symbol.metadata].serde;
|
|
}
|
|
// dispatches in the order of serializeType -> serializeAny -> throw TypeError
|
|
function serializeWith(serializer, value, optionsGetter = defaultOptions) {
|
|
// prepare fallback methods
|
|
const serializeAny = (0, utils_1.orElse)(serializer, serializer.serializeAny, (value) => unhandledType(serializer, value));
|
|
const serialize = (0, utils_1.ifNull)(serializer, serializeAny, value);
|
|
switch (typeof value) {
|
|
case 'string': return serialize(serializer.serializeString);
|
|
case 'number': return serialize(serializer.serializeNumber);
|
|
case 'bigint': return serialize(serializer.serializeBigInt);
|
|
case 'boolean': return serialize(serializer.serializeBoolean);
|
|
case 'symbol': return serialize(serializer.serializeSymbol);
|
|
case 'undefined': return serialize(serializer.serializeNull);
|
|
case 'object':
|
|
const options = optionsGetter(value);
|
|
if ((0, utils_1.isIterable)(value) && (0, utils_1.isFunction)(serializer.serializeIterable)) {
|
|
return serializeIter(serializer.serializeIterable(), value, options);
|
|
}
|
|
else if (!(0, utils_1.isPlainObject)(value)) {
|
|
return serializeClass(serializer, value, options);
|
|
}
|
|
else if ((0, utils_1.isFunction)(serializer.serializeObject)) {
|
|
return serializeObject(serializer, value, options);
|
|
} // deliberate fallthrough when the above fail
|
|
default: return serializeAny(value);
|
|
}
|
|
}
|