diff options
author | Florian Dold <florian.dold@gmail.com> | 2016-11-13 23:30:18 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2016-11-13 23:31:17 +0100 |
commit | f3fb8be7db6de87dae40d41bd5597a735c800ca1 (patch) | |
tree | 1a061db04de8f5bb5a6b697fa56a9948f67fac2f /lib/wallet/checkable.ts | |
parent | 200d83c3886149ebb3f018530302079e12a81f6b (diff) | |
download | wallet-core-f3fb8be7db6de87dae40d41bd5597a735c800ca1.tar.xz |
restructuring
Diffstat (limited to 'lib/wallet/checkable.ts')
-rw-r--r-- | lib/wallet/checkable.ts | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/lib/wallet/checkable.ts b/lib/wallet/checkable.ts deleted file mode 100644 index 89d0c7150..000000000 --- a/lib/wallet/checkable.ts +++ /dev/null @@ -1,262 +0,0 @@ -/* - This file is part of TALER - (C) 2016 GNUnet e.V. - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - - -"use strict"; - -/** - * Decorators for type-checking JSON into - * an object. - * @module Checkable - * @author Florian Dold - */ - -export namespace Checkable { - - type Path = (number | string)[]; - - interface SchemaErrorConstructor { - new (err: string): SchemaError; - } - - interface SchemaError { - name: string; - message: string; - } - - interface Prop { - propertyKey: any; - checker: any; - type: any; - elementChecker?: any; - elementProp?: any; - } - - export let SchemaError = (function SchemaError(message: string) { - this.name = 'SchemaError'; - this.message = message; - this.stack = (<any>new Error()).stack; - }) as any as SchemaErrorConstructor; - - - SchemaError.prototype = new Error; - - let chkSym = Symbol("checkable"); - - - function checkNumber(target: any, prop: Prop, path: Path): any { - if ((typeof target) !== "number") { - throw new SchemaError(`expected number for ${path}`); - } - return target; - } - - - function checkString(target: any, prop: Prop, path: Path): any { - if (typeof target !== "string") { - throw new SchemaError(`expected string for ${path}, got ${typeof target} instead`); - } - return target; - } - - - function checkAnyObject(target: any, prop: Prop, path: Path): any { - if (typeof target !== "object") { - throw new SchemaError(`expected (any) object for ${path}, got ${typeof target} instead`); - } - return target; - } - - - function checkAny(target: any, prop: Prop, path: Path): any { - return target; - } - - - function checkList(target: any, prop: Prop, path: Path): any { - if (!Array.isArray(target)) { - throw new SchemaError(`array expected for ${path}, got ${typeof target} instead`); - } - for (let i = 0; i < target.length; i++) { - let v = target[i]; - prop.elementChecker(v, prop.elementProp, path.concat([i])); - } - return target; - } - - - function checkOptional(target: any, prop: Prop, path: Path): any { - console.assert(prop.propertyKey); - prop.elementChecker(target, - prop.elementProp, - path.concat([prop.propertyKey])); - return target; - } - - - function checkValue(target: any, prop: Prop, path: Path): any { - let type = prop.type; - if (!type) { - throw Error(`assertion failed (prop is ${JSON.stringify(prop)})`); - } - let v = target; - if (!v || typeof v !== "object") { - 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)); - let obj = new type(); - for (let prop of props) { - if (!remainingPropNames.has(prop.propertyKey)) { - if (prop.optional) { - continue; - } - throw new SchemaError("Property missing: " + prop.propertyKey); - } - if (!remainingPropNames.delete(prop.propertyKey)) { - throw new SchemaError("assertion failed"); - } - let propVal = v[prop.propertyKey]; - obj[prop.propertyKey] = prop.checker(propVal, - prop, - path.concat([prop.propertyKey])); - } - - if (remainingPropNames.size != 0) { - throw new SchemaError("superfluous properties " + JSON.stringify(Array.from( - remainingPropNames.values()))); - } - return obj; - } - - - export function Class(target: any) { - target.checked = (v: any) => { - return checkValue(v, { - propertyKey: "(root)", - type: target, - checker: checkValue - }, ["(root)"]); - }; - return target; - } - - - export function Value(type: any) { - if (!type) { - throw Error("Type does not exist yet (wrong order of definitions?)"); - } - function deco(target: Object, propertyKey: string | symbol): void { - let chk = mkChk(target); - chk.props.push({ - propertyKey: propertyKey, - checker: checkValue, - type: type - }); - } - - return deco; - } - - - export function List(type: any) { - let stub = {}; - type(stub, "(list-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: checkList, - }); - } - - return deco; - } - - - export function Optional(type: any) { - 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 }); - } - - - export function AnyObject(target: Object, - propertyKey: string | symbol): void { - let chk = mkChk(target); - chk.props.push({ - propertyKey: propertyKey, - checker: checkAnyObject - }); - } - - - export function Any(target: Object, - propertyKey: string | symbol): void { - let chk = mkChk(target); - chk.props.push({ - propertyKey: propertyKey, - checker: checkAny, - optional: true - }); - } - - - export function String(target: Object, propertyKey: string | symbol): void { - let chk = mkChk(target); - chk.props.push({ propertyKey: propertyKey, checker: checkString }); - } - - - function mkChk(target: any) { - let chk = target[chkSym]; - if (!chk) { - chk = { props: [] }; - target[chkSym] = chk; - } - return chk; - } -}
\ No newline at end of file |