json-canonicalize
Version:
JSON canonicalize function
79 lines • 3.03 kB
JavaScript
export function canonicalize(obj, allowCircular) {
let buffer = '';
const visited = new WeakMap();
serialize(obj);
return buffer;
function serialize(object) {
if (object === null ||
typeof object !== 'object' ||
object.toJSON != null) {
/////////////////////////////////////////////////
// Primitive data type - Use ES6/JSON //
/////////////////////////////////////////////////
buffer += JSON.stringify(object);
// } else if (object instanceof Date) {
// buffer += JSON.stringify(object);
}
else if (Array.isArray(object)) {
/////////////////////////////////////////////////
// Array - Maintain element order //
/////////////////////////////////////////////////
if (visited.has(object)) {
if (!allowCircular) {
throw new Error('Circular reference detected');
}
buffer += '"[Circular]"';
return;
}
visited.set(object, true);
buffer += '[';
let next = false;
object.forEach((element) => {
if (next) {
buffer += ',';
}
next = true;
if (element === undefined) {
element = null;
}
/////////////////////////////////////////
// Array element - Recursive expansion //
/////////////////////////////////////////
serialize(element);
});
buffer += ']';
}
else {
/////////////////////////////////////////////////
// Object - Sort properties before serializing //
/////////////////////////////////////////////////
if (visited.has(object)) {
if (!allowCircular) {
throw new Error('Circular reference detected');
}
buffer += '"[Circular]"';
return;
}
visited.set(object, true);
buffer += '{';
const vKeys = Object.keys(object).filter((k) => object[k] !== undefined).sort();
vKeys.forEach((property, index) => addProp(object, property, index));
buffer += '}';
}
}
function addProp(object, property, index) {
if (index > 0) {
buffer += ',';
}
///////////////////////////////////////////////
// Property names are strings - Use ES6/JSON //
///////////////////////////////////////////////
buffer += JSON.stringify(property);
buffer += ':';
//////////////////////////////////////////
// Property value - Recursive expansion //
//////////////////////////////////////////
serialize(object[property]);
}
}
//# sourceMappingURL=canonicalize.js.map