From 7b2c566cad36a00bbbcf0beb05731020787b08e0 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 5 Jan 2016 20:09:15 +0100 Subject: [PATCH] make Checkables work --- extension/background/checkable.ts | 76 +++++++++++++++++++++++-------- extension/background/wallet.js | 22 ++++++++- extension/background/wallet.ts | 36 ++++++++++----- 3 files changed, 103 insertions(+), 31 deletions(-) diff --git a/extension/background/checkable.ts b/extension/background/checkable.ts index 63fbd3646..f7e99df92 100644 --- a/extension/background/checkable.ts +++ b/extension/background/checkable.ts @@ -27,41 +27,81 @@ namespace Checkable { let chkSym = Symbol("checkable"); - function checkNumber(target, prop) { - return true; + function checkNumber(target, prop): any { + if ((typeof target) !== "number") { + throw Error("number expected for " + prop.propertyKey); + } + return target; } - function checkString(target, prop) { - return true; + function checkString(target, prop): any { + if (typeof target !== "string") { + throw Error("string expected for " + prop.propertyKey); + } + return target; + } + + function checkValue(target, prop): any { + let type = prop.type; + if (!type) { + throw Error("assertion failed"); + } + let v = target; + if (!v || typeof v !== "object") { + throw Error("expected object for " + prop.propertyKey); + } + let props = type.prototype[chkSym].props; + let remainingPropNames = new Set(Object.getOwnPropertyNames(v)); + let obj = new type(); + for (let prop of props) { + if (!remainingPropNames.has(prop.propertyKey)) { + throw Error("Property missing: " + prop.propertyKey); + } + if (!remainingPropNames.delete(prop.propertyKey)) { + throw Error("assertion failed"); + } + let propVal = v[prop.propertyKey]; + obj[prop.propertyKey] = prop.checker(propVal, prop); + } + + if (remainingPropNames.size != 0) { + throw Error("superfluous properties " + JSON.stringify(Array.from( + remainingPropNames.values()))); + } + return obj; } export function Class(target) { target.checked = (v) => { - let props = target.prototype[chkSym].props; - console.log("hello, world"); - let remainingPropNames = new Set(Object.getOwnPropertyNames(v)); - - for (let prop of props) { - remainingPropNames.delete(prop); - console.log("prop", prop); - } - - if (remainingPropNames.size != 0) { - throw Error("superfluous properties " + JSON.stringify(remainingPropNames.values())); - } + return checkValue(v, { + propertyKey: "(root)", + type: target, + checker: checkValue + }); }; return target; } export function Value(type) { - function deco(target) { + function deco(target: Object, propertyKey: string | symbol): void { + let chk = target[chkSym]; + if (!chk) { + chk = {props: []}; + target[chkSym] = chk; + } + chk.props.push({ + propertyKey: propertyKey, + checker: checkValue, + type: type + }); } return deco; } export function List(type) { - function deco(target) { + function deco(target: Object, propertyKey: string | symbol): void { + throw Error("not implemented"); } return deco; diff --git a/extension/background/wallet.js b/extension/background/wallet.js index 120d177eb..0962961d6 100644 --- a/extension/background/wallet.js +++ b/extension/background/wallet.js @@ -28,8 +28,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; -class MyClass { -} let AmountJson = class { }; __decorate([ @@ -44,6 +42,26 @@ __decorate([ AmountJson = __decorate([ Checkable.Class ], AmountJson); +let CoinPaySig = class { +}; +__decorate([ + Checkable.String +], CoinPaySig.prototype, "coin_sig", void 0); +__decorate([ + Checkable.String +], CoinPaySig.prototype, "coin_pub", void 0); +__decorate([ + Checkable.String +], CoinPaySig.prototype, "ub_sig", void 0); +__decorate([ + Checkable.String +], CoinPaySig.prototype, "denom_pub", void 0); +__decorate([ + Checkable.Value(AmountJson) +], CoinPaySig.prototype, "f", void 0); +CoinPaySig = __decorate([ + Checkable.Class +], CoinPaySig); /** * See http://api.taler.net/wallet.html#general */ diff --git a/extension/background/wallet.ts b/extension/background/wallet.ts index bb4326ec5..d9187f14a 100644 --- a/extension/background/wallet.ts +++ b/extension/background/wallet.ts @@ -26,14 +26,6 @@ /// "use strict"; - -class MyClass { - value: number; - fraction: number; - currency: string; -} - - @Checkable.Class class AmountJson { @Checkable.Number @@ -48,6 +40,27 @@ class AmountJson { static check: (v: any) => AmountJson; } + +@Checkable.Class +class CoinPaySig { + @Checkable.String + coin_sig: string; + + @Checkable.String + coin_pub: string; + + @Checkable.String + ub_sig: string; + + @Checkable.String + denom_pub: string; + + @Checkable.Value(AmountJson) + f: AmountJson; + + static check: (v: any) => CoinPaySig; +} + interface AmountJson_interface { value: number; fraction: number @@ -93,7 +106,8 @@ interface Contract { transaction_id: number; } -interface CoinPaySig { + +interface CoinPaySig_interface { coin_sig: string; coin_pub: string; ub_sig: string; @@ -117,7 +131,7 @@ interface Reserve { } -type PayCoinInfo = Array<{ updatedCoin: Db.Coin, sig: CoinPaySig }>; +type PayCoinInfo = Array<{ updatedCoin: Db.Coin, sig: CoinPaySig_interface }>; /** @@ -180,7 +194,7 @@ function signDeposit(db: IDBDatabase, EddsaPrivateKey.fromCrock(cd.coin.coinPriv)) .toCrock(); - let s: CoinPaySig = { + let s: CoinPaySig_interface = { coin_sig: coinSig, coin_pub: cd.coin.coinPub, ub_sig: cd.coin.denomSig,