@harmoniclabs/plu-ts-onchain
Version:
An embedded DSL for Cardano smart contracts creation coupled with a library for Cardano transactions, all in Typescript
313 lines (312 loc) • 15 kB
JavaScript
;
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.pappArgToTerm = void 0;
var utils_1 = require("../type_system/utils.js");
var pfn_1 = require("./pfn.js");
var const_1 = require("./std/list/const/index.js");
var pPair_1 = require("./std/pair/pPair.js");
var pByteString_1 = require("./std/bs/pByteString.js");
var pStr_1 = require("./std/str/pStr.js");
var pBool_1 = require("./std/bool/pBool.js");
var pInt_1 = require("./std/int/pInt.js");
var pmakeUnit_1 = require("./std/unit/pmakeUnit.js");
var Term_1 = require("../Term/index.js");
var type_system_1 = require("../type_system/index.js");
var uint8array_utils_1 = require("@harmoniclabs/uint8array-utils");
var bytestring_1 = require("@harmoniclabs/bytestring");
var cbor_1 = require("@harmoniclabs/cbor");
var obj_utils_1 = require("@harmoniclabs/obj-utils");
var pair_1 = require("@harmoniclabs/pair");
var assert_1 = require("../../utils/assert.js");
var clearAsData_1 = require("../type_system/tyArgs/clearAsData.js");
function pappArgToTerm(arg, mustExtend) {
if (mustExtend === void 0) { mustExtend = (0, type_system_1.tyVar)("pappArgToTerm_mustExtend_any"); }
if (!(0, type_system_1.isWellFormedGenericType)(mustExtend)) {
throw new Error("can't convert argument for `papp` to invalid type");
}
// same of `arg instanceof Term` but typescript doesn't knows it
// ( after `arg instanceof Term` typescript marked arg as `never` )
if (Term_1.Term.prototype.isPrototypeOf(arg)) {
if (!(0, type_system_1.typeExtends)(arg.type, mustExtend)) {
// TODO: add proper error
throw new Error("pappArgToTerm :: `arg` was a term of type " +
(0, utils_1.termTypeToString)(arg.type) +
"; which doesn't extends expected `" +
(0, utils_1.termTypeToString)(mustExtend) + "`");
}
return arg;
}
// PUnit
if (arg === undefined || arg === null) {
if (!(0, type_system_1.typeExtends)(mustExtend, type_system_1.unit) || typeof mustExtend[0] === "symbol") {
// TODO: add proper error
throw new Error("pappArgToTerm :: `arg` was `undefined` (a possible `unit`); which doesn't extends expected type `" +
(0, utils_1.termTypeToString)(mustExtend) + "`");
}
return (0, pmakeUnit_1.pmakeUnit)();
}
// PInt
if (typeof arg === "number" ||
typeof arg === "bigint") {
if (!(0, type_system_1.typeExtends)(type_system_1.int, mustExtend)) {
// TODO: add proper error
throw new Error("pappArgToTerm :: `arg` was a possible `int`; which doesn't extends expected type " +
(0, utils_1.termTypeToString)(mustExtend));
}
return (0, pInt_1.pInt)(arg);
}
// PBool
if (typeof arg === "boolean") {
if (!(0, type_system_1.typeExtends)(type_system_1.bool, mustExtend)) {
// TODO: add proper error
throw new Error("pappArgToTerm :: `arg` was a possible `bool`; which doesn't extends expected type " +
(0, utils_1.termTypeToString)(mustExtend));
}
return (0, pBool_1.pBool)(arg);
}
// PStr
if (typeof arg === "string") {
// if must extend any
if ((0, type_system_1.isTypeParam)(mustExtend)) {
// first try ByteStrings
if (bytestring_1.ByteString.isValidHexValue(arg) && arg.length % 2 === 0) {
return (0, pByteString_1.pByteString)((0, uint8array_utils_1.fromHex)(arg));
}
// otherwise return plain string
return (0, pStr_1.pStr)(arg);
}
// if must be a bytestring
if ((0, type_system_1.typeExtends)(mustExtend, type_system_1.bs)) {
// first tries plain hex
if (bytestring_1.ByteString.isValidHexValue(arg) && arg.length % 2 === 0) {
return (0, pByteString_1.pByteString)((0, uint8array_utils_1.fromHex)(arg));
}
// otherwise interpret as ascii
return (0, pByteString_1.pByteString)(bytestring_1.ByteString.fromAscii(arg));
}
// if must be a string
if ((0, type_system_1.typeExtends)(mustExtend, type_system_1.str)) {
return (0, pStr_1.pStr)(arg);
}
// TODO: add proper error
throw new Error("pappArgToTerm :: `arg` was a possible `str` or `bs`; which doesn't extends expected type " +
(0, utils_1.termTypeToString)(mustExtend));
}
// PByteString
if ((0, uint8array_utils_1.isUint8Array)(arg) ||
arg instanceof Uint8Array ||
arg instanceof ArrayBuffer ||
(arg instanceof bytestring_1.ByteString &&
!(arg instanceof cbor_1.CborString))) {
if (!(0, type_system_1.typeExtends)(type_system_1.bs, mustExtend)) {
// TODO: add proper error
throw new Error("pappArgToTerm :: `arg` was a possible `bs`; which doesn't extends expected type " +
(0, utils_1.termTypeToString)(mustExtend));
}
if (arg instanceof bytestring_1.ByteString) {
return (0, pByteString_1.pByteString)(arg);
}
return (0, pByteString_1.pByteString)((0, uint8array_utils_1.isUint8Array)(arg) ? arg : new Uint8Array(arg));
}
// PLam
if (typeof arg === "function") {
var funcNArgs = arg.length;
if (
// if must extend any
(0, type_system_1.isTypeParam)(mustExtend) ||
// or must extend something different than a function
mustExtend[0] !== type_system_1.PrimType.Lambda ||
// or missing args
funcNArgs <= 0) {
throw new Error("pappArgToTerm :: `arg` was a possible `lam` or `fn`; however it was not possible to check the type");
}
;
var nLambdaArgs = (0, utils_1.getNRequiredLambdaArgs)(mustExtend);
if (!(funcNArgs <= nLambdaArgs))
throw new Error("can't convert a ts function expecting ".concat(funcNArgs, " arguments ") +
"to a plu-ts function that requires ".concat(nLambdaArgs, " arguments; ") +
"expected lambda type was: ".concat((0, utils_1.termTypeToString)(mustExtend)));
var outTy = mustExtend;
var fnInputsTys = [];
for (var i = 0; i < funcNArgs; i++) {
if (outTy[0] !== type_system_1.PrimType.Lambda) {
throw new Error("unexpected `outTy` while constructing `pfn`; " +
"only ".concat(fnInputsTys.length, " inputs out of ").concat(funcNArgs, " expected where collected") +
"`outTy`: ".concat((0, utils_1.termTypeToString)(outTy), "; ") +
"`inputsTypes`:".concat(fnInputsTys.map(utils_1.termTypeToString)) +
"target function type: ".concat((0, utils_1.termTypeToString)(mustExtend)));
}
fnInputsTys.push(outTy[1]);
outTy = outTy[2];
}
return (0, pfn_1.pfn)(fnInputsTys, outTy)(arg);
}
if (Array.isArray(arg)) {
if (!(arg.every(function (elem) {
return elem instanceof Term_1.Term ?
elem.isConstant === true :
true;
})))
throw new Error("pappArgToTerm :: `arg` was a possible `list` or `pair`; " +
"however not all the elments of the array where constants; " +
"plu-ts is only able to automatically trasform constant values");
// if must extend any
if ((0, type_system_1.isTypeParam)(mustExtend)) {
if (arg.length === 2) // might be pair
{
var _a = __read(arg, 2), fst = _a[0], snd = _a[1];
var fstT = tryGetConstantableType(fst);
var sndT = tryGetConstantableType(snd);
return (0, pPair_1.pPair)(fstT, sndT)(pappArgToTerm(fst, fstT), pappArgToTerm(snd, sndT));
}
// try list
var elemsT_1 = tryInferElemsT(arg);
return (0, const_1.pList)(elemsT_1)(arg.map(function (elem) { return pappArgToTerm(elem, elemsT_1); }));
}
if (mustExtend[0] === type_system_1.PrimType.Pair) {
if (arg.length !== 2)
throw new Error("an array that doesn't have exactly two elements can't be converted to pair");
var _b = __read(arg, 2), fst = _b[0], snd = _b[1];
var fstT = (0, type_system_1.isWellFormedType)(mustExtend[1]) ? mustExtend[1] : tryGetConstantableType(fst);
var sndT = (0, type_system_1.isWellFormedType)(mustExtend[2]) ? mustExtend[2] : tryGetConstantableType(snd);
// maybe ????
fstT = (0, clearAsData_1.clearAsData)(fstT);
sndT = (0, clearAsData_1.clearAsData)(sndT);
return (0, pPair_1.pPair)(fstT, sndT)(pappArgToTerm(fst, fstT), pappArgToTerm(snd, sndT));
}
if (mustExtend[0] === type_system_1.PrimType.List) {
var elemsT_2 = (0, type_system_1.isWellFormedType)(mustExtend[1]) ? mustExtend[1] : tryInferElemsT(arg);
return (0, const_1.pList)(elemsT_2)(arg.map(function (elem) { return pappArgToTerm(elem, elemsT_2); }));
}
}
if (arg instanceof pair_1.Pair ||
(0, obj_utils_1.has_n_determined_keys)(arg, 2, "fst", "snd")) {
var _c = (arg instanceof pair_1.Pair ? { fst: arg.fst, snd: arg.snd } : arg), fst = _c.fst, snd = _c.snd;
//if must extend any
if ((0, type_system_1.isTypeParam)(mustExtend)) {
var fstT = tryGetConstantableType(fst);
var sndT = tryGetConstantableType(snd);
return (0, pPair_1.pPair)(fstT, sndT)(pappArgToTerm(fst, fstT), pappArgToTerm(snd, sndT));
}
if (mustExtend[0] === type_system_1.PrimType.Pair) {
var fstT = (0, type_system_1.isWellFormedType)(mustExtend[1]) ? mustExtend[1] : tryGetConstantableType(fst);
var sndT = (0, type_system_1.isWellFormedType)(mustExtend[2]) ? mustExtend[2] : tryGetConstantableType(snd);
return (0, pPair_1.pPair)(fstT, sndT)(pappArgToTerm(fst, fstT), pappArgToTerm(snd, sndT));
}
}
console.error(arg, arg.type);
throw new Error("pappArgToTerm :: it was not possible to transform `arg` to a plu-ts value" +
"; `arg` was " + arg +
"; `mustExtend` plu-ts type was: " + (0, utils_1.termTypeToString)(mustExtend));
}
exports.pappArgToTerm = pappArgToTerm;
function getPossiblePlutsTypesOf(value) {
if (Term_1.Term.prototype.isPrototypeOf(value)) {
return [value.type];
}
if (value === undefined ||
value === null)
return [type_system_1.unit];
if (typeof value === "number" ||
typeof value === "bigint")
return [type_system_1.int];
if (typeof value === "boolean")
return [type_system_1.bool];
if (
// hex string case covered below
(0, uint8array_utils_1.isUint8Array)(value) ||
value instanceof Uint8Array ||
value instanceof ArrayBuffer)
return [type_system_1.bs];
if (typeof value === "function" && value.length !== 0) {
return [
(0, type_system_1.fn)((new Array(value.length))
.map(function (_, i) { return (0, type_system_1.tyVar)("arg_" + i); }), (0, type_system_1.tyVar)("fn_output"))
];
}
var types = [];
if (typeof value === "string") {
types.push(type_system_1.str);
// normal strings also can be byetstrings (ascii) if specified
//
// if( ByteString.isValidHexValue( value ) && (value as string).length % 2 === 0 )
types.push(type_system_1.bs);
return types;
}
return types;
}
function tryGetConstantableType(someValue) {
var tys = getPossiblePlutsTypesOf(someValue);
if (tys.length !== 1)
throw new Error("pappArgToTerm :: `arg` type was ambigous; try to specify a plu-ts type");
var t = tys[0];
if (!(0, type_system_1.isWellFormedType)(t))
throw new Error("inferred type was not constantable: type: " + (0, utils_1.termTypeToString)(t));
return t;
}
function tryInferElemsT(arg) {
if (arg.length === 0)
throw new Error("it was not possible to infer the type of the element of a possible plu-ts `list`; try to specify a type");
var elemsT = undefined;
var inferrefOptions;
for (var i = 0; i < arg.length; i++) {
inferrefOptions = getPossiblePlutsTypesOf(arg[i]);
if (inferrefOptions.length === 1) {
elemsT = inferrefOptions[0];
break;
}
}
;
if (elemsT === undefined)
throw new Error("elements type of a possible plu-ts `list` was ambigous; try to specify a type");
if (!(0, type_system_1.isWellFormedType)(elemsT))
throw new Error("inferred type was not constantable: type: " + (0, utils_1.termTypeToString)(elemsT));
(0, assert_1.assert)(arg.every(function (elem) {
// @ts-ignore Type instantiation is excessively deep and possibly infinite.
return isTsValueAssignableToPlutsType(elem, elemsT);
}), "types in the array where incongruent; expected type was: " + (0, utils_1.termTypeToString)((0, type_system_1.list)(elemsT)));
return elemsT;
}
function isTsValueAssignableToPlutsType(value, plutsType) {
if (!(0, type_system_1.isWellFormedType)(plutsType))
return false;
// same of `value instanceof Term` but typescript doesn't knows it
// ( after `value instanceof Term` typescript marked arg as `never` )
if (Term_1.Term.prototype.isPrototypeOf(value)) {
return (0, type_system_1.typeExtends)(value.type, plutsType);
}
if ((0, type_system_1.typeExtends)(plutsType, type_system_1.int)) {
return (typeof value === "number" ||
typeof value === "bigint");
}
if ((0, type_system_1.typeExtends)(plutsType, type_system_1.unit)) {
return (value === undefined ||
value === null);
}
if ((0, type_system_1.typeExtends)(plutsType, type_system_1.bool)) {
return typeof value === "boolean";
}
if ((0, type_system_1.typeExtends)(plutsType, type_system_1.bs)) {
return ((typeof value === "string" && bytestring_1.ByteString.isValidHexValue(value) && value.length % 2 === 0) ||
(0, uint8array_utils_1.isUint8Array)(value) ||
value instanceof Uint8Array ||
value instanceof ArrayBuffer);
}
return false;
}