contract schema

This commit is contained in:
Florian Dold 2016-02-17 17:51:25 +01:00
parent 874d083ec3
commit 059de061ab
5 changed files with 48 additions and 11 deletions

View File

@ -77,6 +77,15 @@ export namespace Checkable {
}
function checkOptional(target, prop, path): any {
console.assert(prop.propertyKey);
prop.elementChecker(target,
prop.elementProp,
path.concat([prop.propertyKey]));
return target;
}
function checkValue(target, prop, path): any {
let type = prop.type;
if (!type) {
@ -84,7 +93,8 @@ export namespace Checkable {
}
let v = target;
if (!v || typeof v !== "object") {
throw new SchemaError(`expected object for ${path}, got ${typeof v} instead`);
throw new SchemaError(
`expected object for ${path.join(".")}, got ${typeof v} instead`);
}
let props = type.prototype[chkSym].props;
let remainingPropNames = new Set(Object.getOwnPropertyNames(v));
@ -119,7 +129,7 @@ export namespace Checkable {
propertyKey: "(root)",
type: target,
checker: checkValue
}, []);
}, ["(root)"]);
};
return target;
}
@ -164,6 +174,29 @@ export namespace Checkable {
}
export function Optional(type) {
let stub = {};
type(stub, "(optional-element)");
let elementProp = mkChk(stub).props[0];
let elementChecker = elementProp.checker;
if (!elementChecker) {
throw Error("assertion failed");
}
function deco(target: Object, propertyKey: string | symbol): void {
let chk = mkChk(target);
chk.props.push({
elementChecker,
elementProp,
propertyKey: propertyKey,
checker: checkOptional,
optional: true,
});
}
return deco;
}
export function Number(target: Object, propertyKey: string | symbol): void {
let chk = mkChk(target);
chk.props.push({propertyKey: propertyKey, checker: checkNumber});

View File

@ -162,6 +162,9 @@ export class Contract {
@Checkable.String
fulfillment_url: string;
@Checkable.Optional(Checkable.String)
repurchase_correlation_id: string;
static checked: (obj: any) => Contract;
}
@ -761,6 +764,7 @@ export class Wallet {
* Withdraw one coins of the given denomination from the given reserve.
*/
private withdraw(denom: Denomination, reserve: Reserve): Promise<void> {
console.log("creating pre coin at", new Date());
let preCoin = createPreCoin(denom, reserve);
return Query(this.db)
.put("precoins", preCoin)

View File

@ -61,7 +61,7 @@ System.register(["./wallet", "./db", "./http", "./checkable"], function(exports_
catch (e) {
if (e instanceof checkable_1.Checkable.SchemaError) {
console.error("schema error:", e.message);
return Promise.resolve({ error: "invalid contract", hint: e.message });
return Promise.resolve({ error: "invalid contract", hint: e.message, detail: detail });
}
else {
throw e;
@ -80,12 +80,12 @@ System.register(["./wallet", "./db", "./http", "./checkable"], function(exports_
);
var _a;
}
function dispatch(handlers, db, req, sendResponse) {
function dispatch(handlers, req, sendResponse) {
if (req.type in handlers) {
Promise
.resolve()
.then(function () {
var p = handlers[req.type](db, req.detail);
var p = handlers[req.type](req.detail);
return p.then(function (r) {
sendResponse(r);
});
@ -125,7 +125,7 @@ System.register(["./wallet", "./db", "./http", "./checkable"], function(exports_
var wallet = new wallet_1.Wallet(db, http, badge);
var handlers = makeHandlers(db, wallet);
chrome.runtime.onMessage.addListener(function (req, sender, sendResponse) {
return dispatch(handlers, db, req, sendResponse);
return dispatch(handlers, req, sendResponse);
});
})
.catch(function (e) {

View File

@ -77,7 +77,7 @@ function makeHandlers(db: IDBDatabase,
} catch (e) {
if (e instanceof Checkable.SchemaError) {
console.error("schema error:", e.message);
return Promise.resolve({error: "invalid contract", hint: e.message});
return Promise.resolve({error: "invalid contract", hint: e.message, detail: detail});
} else {
throw e;
}
@ -107,12 +107,12 @@ class ChromeBadge implements Badge {
}
function dispatch(handlers, db, req, sendResponse) {
function dispatch(handlers, req, sendResponse) {
if (req.type in handlers) {
Promise
.resolve()
.then(() => {
const p = handlers[req.type](db, req.detail);
const p = handlers[req.type](req.detail);
return p.then((r) => {
sendResponse(r);
@ -155,7 +155,7 @@ export function wxMain() {
let wallet = new Wallet(db, http, badge);
let handlers = makeHandlers(db, wallet);
chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
return dispatch(handlers, db, req, sendResponse)
return dispatch(handlers, req, sendResponse)
});
})
.catch((e) => {

View File

@ -21,7 +21,7 @@
</aside>
<section id="main">
<article id="contract"></article>
<article id="contract" class="fade"></article>
</section>
</body>