@airgap/serializer
Version:
The @airgap/serializer provides serializers used in AirGap applications.
177 lines • 7.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.rlpArrayToJson = exports.jsonToArray = exports.unwrapSchema = exports.getDefinitionByRefPath = void 0;
var errors_1 = require("@airgap/coinlib-core/errors");
var coinlib_error_1 = require("@airgap/coinlib-core/errors/coinlib-error");
var assert_1 = require("@airgap/coinlib-core/utils/assert");
var schema_1 = require("../schemas/schema");
function log() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var loggingEnabled = false;
if (loggingEnabled) {
// tslint:disable-next-line:no-console
console.log.apply(console, args);
}
}
function getDefinitionByRefPath(schema, refPath) {
var mainDefinitionName = refPath.split('/').slice(-1)[0];
var definitions = schema.definitions;
return definitions[mainDefinitionName];
}
exports.getDefinitionByRefPath = getDefinitionByRefPath;
function unwrapSchema(schema) {
log('UNWRAPPING SCHEMA', schema);
return getDefinitionByRefPath(schema, schema.$ref);
}
exports.unwrapSchema = unwrapSchema;
function typeError(key, expectedType, value) {
return new errors_1.InvalidSchemaType("".concat(key, ": expected type \"").concat(expectedType, "\", but got \"").concat(typeof value, "\", value: ").concat(typeof value === 'object' ? JSON.stringify(value) : value));
}
function checkType(key, expectedType, value, callback) {
if (expectedType === 'array' && Array.isArray(value)) {
return callback(value);
}
else if (typeof value === expectedType && !Array.isArray(value)) {
return callback(value);
}
else {
throw typeError(key, expectedType, value);
}
}
function getTypeFromSchemaDefinition(schema) {
var _a;
return (_a = schema === null || schema === void 0 ? void 0 : schema.type) !== null && _a !== void 0 ? _a : ((schema === null || schema === void 0 ? void 0 : schema.$ref) === '#/definitions/HexString' ? schema_1.SchemaTypes.HEX_STRING : schema_1.SchemaTypes.STRING);
}
function jsonToArray(key, schema, value) {
var type = getTypeFromSchemaDefinition(schema);
switch (type) {
case schema_1.SchemaTypes.STRING:
return checkType(key, 'string', value, function (arg) {
log("Parsing key ".concat(key, " as string, which results in ").concat(arg));
if (arg.startsWith('0x')) {
throw new errors_1.InvalidString("string \"".concat(value, "\" starts with \"0x\". This causes problems with RLP. Please use the \"HexString\" type instead of \"string\""));
}
return arg;
});
case schema_1.SchemaTypes.HEX_STRING:
return checkType(key, 'string', value, function (arg) {
log("Parsing key ".concat(key, " as hex-string, which results in ").concat(arg));
if (!arg.startsWith('0x')) {
throw new errors_1.InvalidHexString("\"".concat(value, "\" does not start with \"0x\""));
}
return arg.substr(2); // Remove the '0x'
});
case schema_1.SchemaTypes.NUMBER:
case schema_1.SchemaTypes.INTEGER:
return checkType(key, 'number', value, function (arg) {
log("Parsing key ".concat(key, " as number, which results in ").concat(arg.toString()));
return arg.toString();
});
case schema_1.SchemaTypes.BOOLEAN:
return checkType(key, 'boolean', value, function (arg) {
log("Parsing key ".concat(key, " as boolean, which results in ").concat(arg ? '1' : '0'));
return arg ? '1' : '0';
});
case schema_1.SchemaTypes.NULL:
if (typeof value === 'undefined') {
log("Parsing key ".concat(key, " as undefined, which results in ''"));
return '';
}
else {
throw typeError(key, 'undefined', value);
}
case schema_1.SchemaTypes.ARRAY:
return checkType(key, 'array', value, function (arg) {
return arg.map(function (element, index) {
var items = schema.items;
if (Array.isArray(items)) {
return jsonToArray(key, items[index], element);
}
else {
return jsonToArray(key, items, element);
}
});
});
case schema_1.SchemaTypes.OBJECT:
return checkType(key, 'object', value, function (arg) {
var properties = schema.properties;
var keys = Object.keys(properties).sort();
var out = [];
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
var propertyKey = keys_1[_i];
out.push(jsonToArray(propertyKey, properties[propertyKey], arg[propertyKey]));
}
log("Parsing key ".concat(key, " as object, which results in ").concat(out));
return out;
});
default:
(0, assert_1.assertNever)(type);
throw new errors_1.InvalidSchemaType();
}
}
exports.jsonToArray = jsonToArray;
function decode(schemaItem, decoded) {
if (typeof decoded === 'undefined') {
throw new errors_1.InvalidPayloadError();
}
var type = getTypeFromSchemaDefinition(schemaItem);
switch (type) {
case schema_1.SchemaTypes.BOOLEAN:
if (decoded.toString() !== '') {
return decoded.toString() === '1';
}
break;
case schema_1.SchemaTypes.STRING:
return decoded.toString();
case schema_1.SchemaTypes.HEX_STRING:
return "0x".concat(decoded.toString());
case schema_1.SchemaTypes.NUMBER:
case schema_1.SchemaTypes.INTEGER:
if (decoded.toString() !== '') {
return parseInt(decoded.toString(), 10);
}
break;
case schema_1.SchemaTypes.NULL:
return undefined;
case schema_1.SchemaTypes.ARRAY:
return decoded.map(function (decodedElement, index) {
var items = schemaItem.items;
if (Array.isArray(items)) {
return decode(items[index], decodedElement);
}
else {
return decode(items, decodedElement);
}
});
case schema_1.SchemaTypes.OBJECT:
return rlpArrayToJson(schemaItem.properties, decoded);
default:
(0, assert_1.assertNever)(type);
throw new errors_1.InvalidSchemaType();
}
}
function rlpArrayToJson(schema, decoded) {
var outObject = {};
if (schema.type === schema_1.SchemaTypes.OBJECT) {
var newShema = schema.properties;
if (newShema) {
return rlpArrayToJson(newShema, decoded);
}
else {
throw new errors_1.NotFoundError(coinlib_error_1.Domain.SERIALIZER, 'Schema not available.');
}
}
var keys = Object.keys(schema).sort();
log(keys);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
log(schema);
outObject[key] = decode(schema[key], decoded[i]);
}
return outObject;
}
exports.rlpArrayToJson = rlpArrayToJson;
//# sourceMappingURL=json-to-rlp.js.map