@taquito/michelson-encoder
Version:
converts michelson data and types into convenient JS/TS objects
238 lines (237 loc) • 8.07 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PairToken = exports.TokenComparisonError = exports.TokenArgumentValidationError = void 0;
const token_1 = require("./token");
const or_1 = require("./or");
const core_1 = require("@taquito/core");
/**
* @category Error
* @description Error that indicates in invalid token argument being passed
*/
class TokenArgumentValidationError extends core_1.TaquitoError {
constructor(message) {
super(message);
this.message = message;
this.name = 'TokenArgumentValidationError';
}
}
exports.TokenArgumentValidationError = TokenArgumentValidationError;
/**
* @category Error
* @description Error that indicates a failure occurring when doing a comparison of tokens
*/
class TokenComparisonError extends core_1.TaquitoError {
constructor(val1, val2) {
super();
this.val1 = val1;
this.val2 = val2;
this.name = 'TokenComparisonError';
this.message = `Tokens ${JSON.stringify(val1)} and ${JSON.stringify(val2)} are not comparable`;
}
}
exports.TokenComparisonError = TokenComparisonError;
// collapse comb pair
/**
* @throws {@link TokenArgumentValidationError}
*/
function collapse(val, prim = PairToken.prim) {
if (Array.isArray(val)) {
return collapse({
prim: prim,
args: val,
}, prim);
}
if (val.args === undefined) {
throw new TokenArgumentValidationError(`The value ${JSON.stringify(val)} is an invalid PairToken with no arguments, a pair must have two or more arguments.`);
}
if (val.args.length > 2) {
return [
val.args[0],
{
prim: prim,
args: val.args.slice(1),
},
];
}
return [val.args[0], val.args[1]];
}
class PairToken extends token_1.ComparableToken {
constructor(val, idx, fac, parentTokenType) {
super(Array.isArray(val)
? {
prim: PairToken.prim,
args: val,
}
: val.prim
? val
: {
prim: PairToken.prim,
args: val,
}, idx, fac, parentTokenType);
}
args() {
// collapse comb pair
return collapse(this.val);
}
tokens() {
let cnt = 0;
return this.args().map((a) => {
const tok = this.createToken(a, this.getIdxForChildren() + cnt, 'Pair');
if (tok instanceof PairToken) {
cnt += Object.keys(tok.ExtractSchema()).length;
}
else {
cnt++;
}
return tok;
});
}
Encode(args) {
return {
prim: 'Pair',
args: this.tokens().map((t) => t.Encode(args)),
};
}
ExtractSignature() {
const args = this.args();
const leftToken = this.createToken(args[0], this.getIdxForChildren(), 'Pair');
let keyCount = 1;
if (leftToken instanceof or_1.OrToken) {
keyCount = Object.keys(leftToken.ExtractSchema()).length;
}
const rightToken = this.createToken(args[1], this.getIdxForChildren() + keyCount, 'Pair');
const newSig = [];
for (const leftSig of leftToken.ExtractSignature()) {
for (const rightSig of rightToken.ExtractSignature()) {
newSig.push([...leftSig, ...rightSig]);
}
}
return newSig;
}
ToBigMapKey(val) {
return {
key: this.EncodeObject(val),
type: this.typeWithoutAnnotations(),
};
}
ToKey(val) {
return this.Execute(val);
}
EncodeObject(args, semantic) {
const [leftToken, rightToken] = this.tokens();
let leftValue;
if (leftToken instanceof PairToken && !leftToken.hasAnnotations()) {
leftValue = args;
}
else {
leftValue = args[leftToken.annot()];
}
let rightValue;
if (rightToken instanceof PairToken && !rightToken.hasAnnotations()) {
rightValue = args;
}
else {
rightValue = args[rightToken.annot()];
}
return {
prim: 'Pair',
args: [
leftToken.EncodeObject(leftValue, semantic),
rightToken.EncodeObject(rightValue, semantic),
],
};
}
traversal(getLeftValue, getRightValue) {
const args = this.args();
const leftToken = this.createToken(args[0], this.getIdxForChildren(), 'Pair');
let keyCount = 1;
let leftValue;
if (leftToken instanceof PairToken && !leftToken.hasAnnotations()) {
leftValue = getLeftValue(leftToken);
if (leftToken instanceof PairToken) {
keyCount = Object.keys(leftToken.ExtractSchema()).length;
}
}
else {
leftValue = { [leftToken.annot()]: getLeftValue(leftToken) };
}
const rightToken = this.createToken(args[1], this.getIdxForChildren() + keyCount, 'Pair');
let rightValue;
if (rightToken instanceof PairToken && !rightToken.hasAnnotations()) {
rightValue = getRightValue(rightToken);
}
else {
rightValue = { [rightToken.annot()]: getRightValue(rightToken) };
}
const res = Object.assign(Object.assign({}, leftValue), rightValue);
return res;
}
Execute(val, semantics) {
const args = collapse(val, 'Pair');
return this.traversal((leftToken) => leftToken.Execute(args[0], semantics), (rightToken) => rightToken.Execute(args[1], semantics));
}
/**
* @deprecated ExtractSchema has been deprecated in favor of generateSchema
*
*/
ExtractSchema() {
return this.traversal((leftToken) => leftToken.ExtractSchema(), (rightToken) => rightToken.ExtractSchema());
}
generateSchema() {
return {
__michelsonType: PairToken.prim,
schema: this.traversal((leftToken) => {
if (leftToken instanceof PairToken && !leftToken.hasAnnotations()) {
return leftToken.generateSchema().schema;
}
else {
return leftToken.generateSchema();
}
}, (rightToken) => {
if (rightToken instanceof PairToken && !rightToken.hasAnnotations()) {
return rightToken.generateSchema().schema;
}
else {
return rightToken.generateSchema();
}
}),
};
}
/**
* @throws {@link TokenComparisonError}
*/
compare(val1, val2) {
const [leftToken, rightToken] = this.tokens();
const getValue = (token, args) => {
if (token instanceof PairToken && !token.hasAnnotations()) {
return args;
}
else {
return args[token.annot()];
}
};
if (leftToken instanceof token_1.ComparableToken && rightToken instanceof token_1.ComparableToken) {
const result = leftToken.compare(getValue(leftToken, val1), getValue(leftToken, val2));
if (result === 0) {
return rightToken.compare(getValue(rightToken, val1), getValue(rightToken, val2));
}
return result;
}
throw new TokenComparisonError(val1, val2);
}
findAndReturnTokens(tokenToFind, tokens) {
if (PairToken.prim === tokenToFind) {
tokens.push(this);
}
this.tokens().map((t) => t.findAndReturnTokens(tokenToFind, tokens));
return tokens;
}
getIdxForChildren() {
if (token_1.Token.fieldNumberingStrategy === 'Legacy') {
return this.idx;
}
return this.parentTokenType === 'Pair' ? this.idx : 0;
}
}
exports.PairToken = PairToken;
PairToken.prim = 'pair';