UNPKG

@taquito/michelson-encoder

Version:

converts michelson data and types into convenient JS/TS objects

283 lines (282 loc) 10.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OrToken = exports.OrValidationError = void 0; const token_1 = require("./token"); /** * @category Error * @description Error that indicates a failure happening when parsing encoding/executing an OrToken */ class OrValidationError extends token_1.TokenValidationError { constructor(value, token, message) { super(value, token, message); this.value = value; this.token = token; this.name = 'OrValidationError'; } } exports.OrValidationError = OrValidationError; class OrToken extends token_1.ComparableToken { constructor(val, idx, fac, parentTokenType) { super(val, idx, fac, parentTokenType); this.val = val; this.idx = idx; this.fac = fac; this.parentTokenType = parentTokenType; } Encode(args) { const label = args[args.length - 1]; const leftToken = this.createToken(this.val.args[0], this.getIdxForChildren(), 'Or'); let keyCount = 1; if (leftToken instanceof OrToken) { keyCount = Object.keys(leftToken.ExtractSchema()).length; } const rightToken = this.createToken(this.val.args[1], this.getIdxForChildren() + keyCount, 'Or'); if (String(leftToken.annot()) === String(label) && !(leftToken instanceof OrToken)) { args.pop(); return { prim: 'Left', args: [leftToken.Encode(args)] }; } else if (String(rightToken.annot()) === String(label) && !(rightToken instanceof OrToken)) { args.pop(); return { prim: 'Right', args: [rightToken.Encode(args)] }; } else { if (leftToken instanceof OrToken) { const val = leftToken.Encode(args); if (val) { return { prim: 'Left', args: [val] }; } } if (rightToken instanceof OrToken) { const val = rightToken.Encode(args); if (val) { return { prim: 'Right', args: [val] }; } } return null; } } ExtractSignature() { const leftToken = this.createToken(this.val.args[0], this.getIdxForChildren(), 'Or'); let keyCount = 1; if (leftToken instanceof OrToken) { keyCount = Object.keys(leftToken.ExtractSchema()).length; } const rightToken = this.createToken(this.val.args[1], this.getIdxForChildren() + keyCount, 'Or'); const newSig = []; if (leftToken instanceof OrToken) { newSig.push(...leftToken.ExtractSignature()); } else { for (const sig of leftToken.ExtractSignature()) { newSig.push([leftToken.annot(), ...sig]); } } if (rightToken instanceof OrToken) { newSig.push(...rightToken.ExtractSignature()); } else { for (const sig of rightToken.ExtractSignature()) { newSig.push([rightToken.annot(), ...sig]); } } return newSig; } /** * @throws {@link OrValidationError} */ EncodeObject(args, semantic) { this.validateJavascriptObject(args); const label = Object.keys(args)[0]; const leftToken = this.createToken(this.val.args[0], this.getIdxForChildren(), 'Or'); let keyCount = 1; if (leftToken instanceof OrToken) { keyCount = Object.keys(leftToken.ExtractSchema()).length; } const rightToken = this.createToken(this.val.args[1], this.getIdxForChildren() + keyCount, 'Or'); if (String(leftToken.annot()) === String(label) && !(leftToken instanceof OrToken)) { return { prim: 'Left', args: [leftToken.EncodeObject(args[label], semantic)] }; } else if (String(rightToken.annot()) === String(label) && !(rightToken instanceof OrToken)) { return { prim: 'Right', args: [rightToken.EncodeObject(args[label], semantic)] }; } else { if (leftToken instanceof OrToken) { const val = leftToken.EncodeObject(args, semantic); if (val) { return { prim: 'Left', args: [val] }; } } if (rightToken instanceof OrToken) { const val = rightToken.EncodeObject(args, semantic); if (val) { return { prim: 'Right', args: [val] }; } } return null; } } /** * @throws {@link OrValidationError} */ validateJavascriptObject(args) { if (typeof args !== 'object' || Array.isArray(args) || args === null || Object.keys(args).length !== 1) { throw new OrValidationError(args, this, `EncodeObject expects an object with a single key but got: ${JSON.stringify(args)}`); } } /** * @throws {@link OrValidationError} */ Execute(val, semantics) { const leftToken = this.createToken(this.val.args[0], this.getIdxForChildren(), 'Or'); let keyCount = 1; if (leftToken instanceof OrToken) { keyCount = Object.keys(leftToken.ExtractSchema()).length; } const rightToken = this.createToken(this.val.args[1], this.getIdxForChildren() + keyCount, 'Or'); if (val.prim === 'Right') { if (rightToken instanceof OrToken) { return rightToken.Execute(val.args[0], semantics); } else { return { [rightToken.annot()]: rightToken.Execute(val.args[0], semantics), }; } } else if (val.prim === 'Left') { if (leftToken instanceof OrToken) { return leftToken.Execute(val.args[0], semantics); } return { [leftToken.annot()]: leftToken.Execute(val.args[0], semantics), }; } else { throw new OrValidationError(val, this, `Was expecting Left or Right prim but got: ${JSON.stringify(val.prim)}`); } } traversal(getLeftValue, getRightValue, concat) { const leftToken = this.createToken(this.val.args[0], this.getIdxForChildren(), 'Or'); let keyCount = 1; let leftValue; if (leftToken instanceof OrToken) { leftValue = getLeftValue(leftToken); keyCount = Object.keys(leftToken.ExtractSchema()).length; } else { leftValue = { [leftToken.annot()]: getLeftValue(leftToken) }; } const rightToken = this.createToken(this.val.args[1], this.getIdxForChildren() + keyCount, 'Or'); let rightValue; if (rightToken instanceof OrToken) { rightValue = getRightValue(rightToken); } else { rightValue = { [rightToken.annot()]: getRightValue(rightToken) }; } const res = concat(leftValue, rightValue); return res; } /** * @deprecated ExtractSchema has been deprecated in favor of generateSchema * */ ExtractSchema() { return this.traversal((leftToken) => leftToken.ExtractSchema(), (rightToken) => rightToken.ExtractSchema(), (leftValue, rightValue) => (Object.assign(Object.assign({}, leftValue), rightValue))); } generateSchema() { return { __michelsonType: OrToken.prim, schema: this.traversal((leftToken) => { if (leftToken instanceof OrToken) { return leftToken.generateSchema().schema; } else { return leftToken.generateSchema(); } }, (rightToken) => { if (rightToken instanceof OrToken) { return rightToken.generateSchema().schema; } else { return rightToken.generateSchema(); } }, (leftValue, rightValue) => (Object.assign(Object.assign({}, leftValue), rightValue))), }; } findToken(label) { const leftToken = this.createToken(this.val.args[0], this.getIdxForChildren(), 'Or'); let keyCount = 1; if (leftToken instanceof OrToken) { keyCount = Object.keys(leftToken.ExtractSchema()).length; } const rightToken = this.createToken(this.val.args[1], this.getIdxForChildren() + keyCount, 'Or'); if (String(leftToken.annot()) === String(label) && !(leftToken instanceof OrToken) && leftToken instanceof token_1.ComparableToken) { return leftToken; } else if (String(rightToken.annot()) === String(label) && !(rightToken instanceof OrToken) && rightToken instanceof token_1.ComparableToken) { return rightToken; } else { if (leftToken instanceof OrToken) { const tok = leftToken.findToken(label); if (tok) { return tok; } } if (rightToken instanceof OrToken) { const tok = rightToken.findToken(label); if (tok) { return tok; } } return null; } } compare(val1, val2) { const labelVal1 = Object.keys(val1)[0]; const labelVal2 = Object.keys(val2)[0]; if (labelVal1 === labelVal2) { const token = this.findToken(labelVal1); if (token instanceof token_1.ComparableToken) { return token.compare(val1[labelVal1], val2[labelVal1]); } } else { const encoded1 = JSON.stringify(this.EncodeObject(val1)); const encoded2 = JSON.stringify(this.EncodeObject(val2)); return encoded1 < encoded2 ? -1 : 1; } } ToKey(val) { return this.Execute(val); } ToBigMapKey(val) { return { key: this.EncodeObject(val), type: this.typeWithoutAnnotations(), }; } findAndReturnTokens(tokenToFind, tokens) { if (OrToken.prim === tokenToFind) { tokens.push(this); } this.traversal((leftToken) => leftToken.findAndReturnTokens(tokenToFind, tokens), (rightToken) => rightToken.findAndReturnTokens(tokenToFind, tokens), (leftValue, rightValue) => (Object.assign(Object.assign({}, leftValue), rightValue))); return tokens; } getIdxForChildren() { if (token_1.Token.fieldNumberingStrategy === 'Legacy') { return this.idx; } return this.parentTokenType === 'Or' ? this.idx : 0; } } exports.OrToken = OrToken; OrToken.prim = 'or';