UNPKG

abi-util-lite

Version:

A light impletation to parse abi string array to abi json

282 lines 10.6 kB
"use strict"; 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