abi-util-lite
Version:
A light impletation to parse abi string array to abi json
282 lines • 10.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParamType = exports.parseParams = void 0;
var Checkers_1 = require("./Checkers");
var Logger_1 = require("./Logger");
var Utils_1 = require("./Utils");
var Format_1 = require("./Format");
var paramTypeArray = new RegExp(/^(.*)\[([0-9]*)\]$/);
function parseParams(value, allowIndex) {
return (0, Utils_1.splitNesting)(value).map(function (param) { return ParamType.fromString(param, allowIndex); });
}
exports.parseParams = parseParams;
// @TODO: Make sure that children of an indexed tuple are marked with a null indexed
function parseParamType(param, allowIndexed) {
var originalParam = param;
function throwError(i) {
Logger_1.logger.throwArgumentError("unexpected character at position " + i, "param", param);
}
param = param.replace(/\s/g, " ");
function newNode(parent) {
var node = { type: "", name: "", parent: parent, state: { allowType: true } };
if (allowIndexed) {
node.indexed = false;
}
return node;
}
var parent = { type: "", name: "", state: { allowType: true } };
var node = parent;
for (var i = 0; i < param.length; i++) {
var c = param[i];
switch (c) {
case "(":
if (node.state.allowType && node.type === "") {
node.type = "tuple";
}
else if (!node.state.allowParams) {
throwError(i);
}
node.state.allowType = false;
node.type = (0, Checkers_1.verifyType)(node.type);
node.components = [newNode(node)];
node = node.components[0];
break;
case ")":
delete node.state;
if (node.name === "indexed") {
if (!allowIndexed) {
throwError(i);
}
node.indexed = true;
node.name = "";
}
if ((0, Checkers_1.checkModifier)(node.type, node.name)) {
node.name = "";
}
node.type = (0, Checkers_1.verifyType)(node.type);
var child = node;
node = node.parent;
if (!node) {
throwError(i);
}
delete child.parent;
node.state.allowParams = false;
node.state.allowName = true;
node.state.allowArray = true;
break;
case ",":
delete node.state;
if (node.name === "indexed") {
if (!allowIndexed) {
throwError(i);
}
node.indexed = true;
node.name = "";
}
if ((0, Checkers_1.checkModifier)(node.type, node.name)) {
node.name = "";
}
node.type = (0, Checkers_1.verifyType)(node.type);
var sibling = newNode(node.parent);
//{ type: "", name: "", parent: node.parent, state: { allowType: true } };
node.parent.components.push(sibling);
delete node.parent;
node = sibling;
break;
// Hit a space...
case " ":
// If reading type, the type is done and may read a param or name
if (node.state.allowType) {
if (node.type !== "") {
node.type = (0, Checkers_1.verifyType)(node.type);
delete node.state.allowType;
node.state.allowName = true;
node.state.allowParams = true;
}
}
// If reading name, the name is done
if (node.state.allowName) {
if (node.name !== "") {
if (node.name === "indexed") {
if (!allowIndexed) {
throwError(i);
}
if (node.indexed) {
throwError(i);
}
node.indexed = true;
node.name = "";
}
else if ((0, Checkers_1.checkModifier)(node.type, node.name)) {
node.name = "";
}
else {
node.state.allowName = false;
}
}
}
break;
case "[":
if (!node.state.allowArray) {
throwError(i);
}
node.type += c;
node.state.allowArray = false;
node.state.allowName = false;
node.state.readArray = true;
break;
case "]":
if (!node.state.readArray) {
throwError(i);
}
node.type += c;
node.state.readArray = false;
node.state.allowArray = true;
node.state.allowName = true;
break;
default:
if (node.state.allowType) {
node.type += c;
node.state.allowParams = true;
node.state.allowArray = true;
}
else if (node.state.allowName) {
node.name += c;
delete node.state.allowArray;
}
else if (node.state.readArray) {
node.type += c;
}
else {
throwError(i);
}
}
}
if (node.parent) {
Logger_1.logger.throwArgumentError("unexpected eof", "param", param);
}
delete parent.state;
if (node.name === "indexed") {
if (!allowIndexed) {
throwError(originalParam.length - 7);
}
if (node.indexed) {
throwError(originalParam.length - 7);
}
node.indexed = true;
node.name = "";
}
else if ((0, Checkers_1.checkModifier)(node.type, node.name)) {
node.name = "";
}
parent.type = (0, Checkers_1.verifyType)(parent.type);
return parent;
}
var ParamType = /** @class */ (function () {
function ParamType(constructorGuard, params) {
if (constructorGuard !== Utils_1._constructorGuard) {
Logger_1.logger.throwError("use fromString");
}
(0, Utils_1.populate)(this, params);
var match = this.type.match(paramTypeArray);
if (match) {
(0, Utils_1.populate)(this, {
arrayLength: parseInt(match[2] || "-1"),
arrayChildren: ParamType.fromObject({
type: match[1],
components: this.components
}),
baseType: "array"
});
}
else {
(0, Utils_1.populate)(this, {
arrayLength: null,
arrayChildren: null,
baseType: ((this.components != null) ? "tuple" : this.type)
});
}
this._isParamType = true;
Object.freeze(this);
}
// Format the parameter fragment
// - sighash: "(uint256,address)"
// - minimal: "tuple(uint256,address) indexed"
// - full: "tuple(uint256 foo, address bar) indexed baz"
ParamType.prototype.format = function (format) {
if (!format) {
format = Format_1.FormatTypes.sighash;
}
if (!Format_1.FormatTypes[format]) {
Logger_1.logger.throwArgumentError("invalid format type", "format", format);
}
if (format === Format_1.FormatTypes.json) {
var result_1 = {
type: ((this.baseType === "tuple") ? "tuple" : this.type),
name: (this.name || undefined)
};
if (typeof (this.indexed) === "boolean") {
result_1.indexed = this.indexed;
}
if (this.components) {
result_1.components = this.components.map(function (comp) { return JSON.parse(comp.format(format)); });
}
return JSON.stringify(result_1);
}
var result = "";
// Array
if (this.baseType === "array") {
result += this.arrayChildren.format(format);
result += "[" + (this.arrayLength < 0 ? "" : String(this.arrayLength)) + "]";
}
else {
if (this.baseType === "tuple") {
if (format !== Format_1.FormatTypes.sighash) {
result += this.type;
}
result += "(" + this.components.map(function (comp) { return comp.format(format); }).join((format === Format_1.FormatTypes.full) ? ", " : ",") + ")";
}
else {
result += this.type;
}
}
if (format !== Format_1.FormatTypes.sighash) {
if (this.indexed === true) {
result += " indexed";
}
if (format === Format_1.FormatTypes.full && this.name) {
result += " " + this.name;
}
}
return result;
};
ParamType.fromObject = function (value) {
if (ParamType.isParamType(value)) {
return value;
}
return new ParamType(Utils_1._constructorGuard, {
name: (value.name || null),
type: (0, Checkers_1.verifyType)(value.type),
indexed: ((value.indexed == null) ? null : !!value.indexed),
components: (value.components ? value.components.map(ParamType.fromObject) : null)
});
};
ParamType.fromString = function (value, allowIndexed) {
function ParamTypify(node) {
return ParamType.fromObject({
name: node.name,
type: node.type,
indexed: node.indexed,
components: node.components
});
}
return ParamTypify(parseParamType(value, !!allowIndexed));
};
ParamType.isParamType = function (value) {
return !!(value != null && value._isParamType);
};
return ParamType;
}());
exports.ParamType = ParamType;
;
//# sourceMappingURL=ParamType.js.map
;