@airgap/serializer
Version:
The @airgap/serializer provides serializers used in AirGap applications.
235 lines • 9.73 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");
var isHexString = function (str) {
var regexp = /^[0-9a-fA-F]+$/;
if (regexp.test(str)) {
return true;
}
else {
return false;
}
};
var StringType;
(function (StringType) {
StringType[StringType["STRING_WITH_HEX_PREFIX"] = 0] = "STRING_WITH_HEX_PREFIX";
StringType[StringType["HEX_WITH_PREFIX_EVEN"] = 1] = "HEX_WITH_PREFIX_EVEN";
StringType[StringType["HEX_WITHOUT_PREFIX_EVEN"] = 2] = "HEX_WITHOUT_PREFIX_EVEN";
StringType[StringType["HEX_WITH_PREFIX_ODD"] = 3] = "HEX_WITH_PREFIX_ODD";
StringType[StringType["HEX_WITHOUT_PREFIX_ODD"] = 4] = "HEX_WITHOUT_PREFIX_ODD";
})(StringType || (StringType = {}));
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_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));
var buf;
var type;
if (arg.startsWith('0x')) {
var argWithoutPrefix = arg.slice(2);
if (isHexString(argWithoutPrefix)) {
if (argWithoutPrefix.length % 2 === 0) {
type = StringType.HEX_WITH_PREFIX_EVEN;
buf = Buffer.from(argWithoutPrefix, 'hex');
}
else {
type = StringType.HEX_WITH_PREFIX_ODD;
buf = Buffer.from('0' + argWithoutPrefix, 'hex');
}
}
else {
type = StringType.STRING_WITH_HEX_PREFIX;
buf = Buffer.from(argWithoutPrefix);
}
}
else {
if (isHexString(arg)) {
if (arg.length % 2 === 0) {
type = StringType.HEX_WITHOUT_PREFIX_EVEN;
buf = Buffer.from(arg, 'hex');
}
else {
type = StringType.HEX_WITHOUT_PREFIX_ODD;
buf = Buffer.from('0' + arg, 'hex');
}
}
else {
return arg;
}
}
var typeBuffer = Buffer.from(type.toString(16).padStart(2, '0'), 'hex');
var concat = Buffer.concat([typeBuffer, buf]);
return concat;
});
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;
});
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;
});
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;
}
break;
case schema_1.SchemaTypes.STRING:
if (typeof decoded === 'string') {
return decoded;
}
var stringType = parseInt(decoded.slice(0, 1).toString('hex'), 16);
switch (stringType) {
case StringType.STRING_WITH_HEX_PREFIX:
return "0x".concat(decoded.slice(1).toString());
case StringType.HEX_WITH_PREFIX_EVEN:
return "0x".concat(decoded.slice(1).toString('hex'));
case StringType.HEX_WITHOUT_PREFIX_EVEN:
return decoded.slice(1).toString('hex');
case StringType.HEX_WITH_PREFIX_ODD:
return "0x".concat(decoded.slice(1).toString('hex').slice(1));
case StringType.HEX_WITHOUT_PREFIX_ODD:
return decoded.slice(1).toString('hex').slice(1);
default:
(0, assert_1.assertNever)(stringType);
throw new Error('Cannot decode!');
}
case schema_1.SchemaTypes.NUMBER:
case schema_1.SchemaTypes.INTEGER:
if (decoded.toString() !== '') {
return decoded;
}
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