@chainsafe/ssz-type-schema
Version:
Utility methods and types for describing an ssz object
173 lines (143 loc) • 4.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.copyType = copyType;
exports.parseType = parseType;
exports.isFullSSZType = isFullSSZType;
exports.isBasicType = isBasicType;
exports.isCompositeType = isCompositeType;
exports.isVariableSizeType = isVariableSizeType;
var _assert = _interopRequireDefault(require("assert"));
var _types = require("./types");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable @typescript-eslint/no-explicit-any */
/** @module ssz */
// regex to identify a bytesN type
const bytesPattern = /^bytes\d+$/; // regex to identify digits
const digitsPattern = /\d+$/; // regex to identify a uint type
const uintPattern = /^(number|bigint|bn)\d+$/;
function copyType(type) {
return JSON.parse(JSON.stringify(type));
}
/**
* Recursively expand an [[AnySSZType]] into a [[FullSSZType]]
*/
function parseType(type) {
if (isFullSSZType(type)) {
return type;
}
if (typeof type === "string") {
// bit
if (type === "bool") {
return _types.bit;
} // bytesN
if (type.match(bytesPattern)) {
const length = parseInt(type.match(digitsPattern));
return {
type: _types.Type.byteVector,
length
};
} // uint
if (type === "byte") {
return _types.byte;
} // uint
const uintMatch = type.match(uintPattern);
if (uintMatch) {
const use = uintMatch[1];
const bits = parseInt(type.match(digitsPattern));
(0, _assert.default)([8, 16, 32, 64, 128, 256].find(b => b === bits), "Invalid uint type: ".concat(type));
return {
type: _types.Type.uint,
byteLength: bits / 8,
use
};
}
} else if (type === Object(type)) {
if (Number.isSafeInteger(type.maxLength)) {
type = type;
const elementType = parseType(type.elementType);
const maxLength = type.maxLength;
if (elementType.type === _types.Type.bool) {
return {
type: _types.Type.bitList,
maxLength
};
} else if (elementType.type === _types.Type.uint && elementType.byteLength === 1) {
return {
type: _types.Type.byteList,
maxLength
};
} else {
return {
type: _types.Type.list,
elementType,
maxLength
};
}
} else if (Number.isSafeInteger(type.length)) {
type = type;
const elementType = parseType(type.elementType);
const length = type.length;
if (elementType.type === _types.Type.bool) {
return {
type: _types.Type.bitVector,
length
};
} else if (elementType.type === _types.Type.uint && elementType.byteLength === 1) {
return {
type: _types.Type.byteVector,
length
};
} else {
return {
type: _types.Type.vector,
elementType,
length
};
}
} else if (Array.isArray(type.fields)) {
type = type;
return {
type: _types.Type.container,
fields: type.fields.map(([fieldName, fieldType]) => {
(0, _assert.default)(typeof fieldName === "string", "Container field name must be a string");
return [fieldName, parseType(fieldType)];
})
};
}
}
throw new Error("Invalid type: ".concat(JSON.stringify(type)));
}
function isFullSSZType(type) {
return type === Object(type) && Object.values(_types.Type).includes(type.type);
}
function isBasicType(type) {
return [_types.Type.uint, _types.Type.bool].includes(type.type);
}
function isCompositeType(type) {
return [_types.Type.bitList, _types.Type.bitVector, _types.Type.byteList, _types.Type.byteVector, _types.Type.list, _types.Type.vector, _types.Type.container].includes(type.type);
}
/**
* A variable-size type is a list and all types that contain a variable-size type.
*
* All other types are said to be fixed-size
*/
function isVariableSizeType(type) {
switch (type.type) {
case _types.Type.bool:
case _types.Type.uint:
case _types.Type.bitVector:
case _types.Type.byteVector:
return false;
case _types.Type.bitList:
case _types.Type.byteList:
case _types.Type.list:
return true;
case _types.Type.vector:
return isVariableSizeType(type.elementType);
case _types.Type.container:
return type.fields.some(([, fieldType]) => isVariableSizeType(fieldType));
}
}
//# sourceMappingURL=utils.js.map