jinaga
Version:
Data management for web and mobile applications.
103 lines • 3.06 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeObjectHash = exports.canonicalPredecessors = exports.verifyHash = exports.canonicalizeFact = exports.computeHash = void 0;
const encoding_1 = require("../util/encoding");
function computeHash(fields, predecessors) {
return computeObjectHash({
fields: fields,
predecessors: canonicalPredecessors(predecessors)
});
}
exports.computeHash = computeHash;
function canonicalizeFact(fields, predecessors) {
return canonicalize({
fields: fields,
predecessors: canonicalPredecessors(predecessors)
});
}
exports.canonicalizeFact = canonicalizeFact;
function verifyHash(fact) {
const computedHash = computeHash(fact.fields, fact.predecessors);
return fact.hash === computedHash;
}
exports.verifyHash = verifyHash;
function canonicalPredecessors(predecessors) {
const result = {};
for (const role in predecessors) {
const referenceMessages = predecessors[role];
if (Array.isArray(referenceMessages)) {
result[role] = sortedPredecessors(referenceMessages);
}
else {
result[role] = referenceMessages;
}
}
return result;
}
exports.canonicalPredecessors = canonicalPredecessors;
function sortedPredecessors(predecessors) {
return predecessors.slice().sort((a, b) => {
if (a.hash < b.hash)
return -1;
else if (a.hash > b.hash)
return 1;
if (a.type < b.type)
return -1;
else if (a.type > b.type)
return 1;
else
return 0;
});
}
function computeObjectHash(obj) {
if (!obj)
return '';
const str = canonicalize(obj);
return (0, encoding_1.computeStringHash)(str);
}
exports.computeObjectHash = computeObjectHash;
function canonicalize(obj) {
const pairs = [];
for (const key in obj) {
const value = obj[key];
pairs.push({ key, value });
}
pairs.sort((a, b) => {
if (a.key < b.key)
return -1;
else if (a.key > b.key)
return 1;
else
return 0;
});
const members = pairs.reduce((text, pair) => {
if (text.length > 0)
text += ',';
text += '"' + pair.key + '":' + serialize(pair.value);
return text;
}, '');
return '{' + members + '}';
}
function serialize(value) {
if (typeof (value) === 'object') {
if (value instanceof Date) {
return 'Date.parse("' + value.toISOString() + '")';
}
else if (Array.isArray(value)) {
const values = value.reduce((text, element) => {
if (text.length > 0)
text += ',';
text += serialize(element);
return text;
}, '');
return '[' + values + ']';
}
else {
return canonicalize(value);
}
}
else {
return JSON.stringify(value);
}
}
//# sourceMappingURL=hash.js.map