diff --git a/lib/native-browser.js b/lib/native-browser.js deleted file mode 100644 index 8f8d0686..00000000 --- a/lib/native-browser.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -exports.binding = null; diff --git a/lib/native.js b/lib/native.js deleted file mode 100644 index cdd37639..00000000 --- a/lib/native.js +++ /dev/null @@ -1,17 +0,0 @@ -/*! - * native.js - native bindings for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -exports.binding = null; - -if (Number(process.env.BCOIN_NO_NATIVE) !== 1) { - try { - exports.binding = require('bcoin-native'); - } catch (e) { - ; - } -} diff --git a/lib/node/http.js b/lib/node/http.js index 25617d43..49b60e72 100644 --- a/lib/node/http.js +++ b/lib/node/http.js @@ -19,7 +19,7 @@ const digest = require('bcrypto/lib/digest'); const random = require('bcrypto/lib/random'); const ccmp = require('bcrypto/lib/ccmp'); const Network = require('../protocol/network'); -const Validator = require('../utils/validator'); +const Validator = require('bval/lib/validator'); const encoding = require('bbuf/lib/encoding'); const pkg = require('../pkg'); diff --git a/lib/node/rpc.js b/lib/node/rpc.js index a9076eda..74080077 100644 --- a/lib/node/rpc.js +++ b/lib/node/rpc.js @@ -31,7 +31,7 @@ const TX = require('../primitives/tx'); const IP = require('binet'); const encoding = require('bbuf/lib/encoding'); const consensus = require('../protocol/consensus'); -const Validator = require('../utils/validator'); +const Validator = require('bval/lib/validator'); const pkg = require('../pkg'); const Lock = require('../utils/lock'); const RPCBase = bweb.RPC; diff --git a/lib/utils/index.js b/lib/utils/index.js index e561c415..d51b2d2a 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -22,4 +22,3 @@ exports.Lock = require('./lock'); exports.LRU = require('./lru'); exports.MappedLock = require('./mappedlock'); exports.util = require('./util'); -exports.Validator = require('./validator'); diff --git a/lib/utils/validator.js b/lib/utils/validator.js deleted file mode 100644 index 114ce7a4..00000000 --- a/lib/utils/validator.js +++ /dev/null @@ -1,965 +0,0 @@ -/*! - * validator.js - validator for bcoin - * Copyright (c) 2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const assert = require('assert'); -const {fromFloat} = require('../utils/fixed'); - -/** - * Validator - * @alias module:utils.Validator - * @constructor - * @param {Object} map - * @param {Boolean} [loose=false] - */ - -function Validator(map, loose) { - if (!(this instanceof Validator)) - return new Validator(map, loose); - - if (!map || typeof map !== 'object') - throw new ValidationError('map', 'object'); - - this.map = map; - this.loose = loose || false; -} - -/** - * Create a multi validator. - * @param {Object[]} maps - * @param {Boolean} [loose=false] - * @returns {MultiValidator} - */ - -Validator.multi = function multi(maps, loose) { - return new MultiValidator(maps, loose); -}; - -/** - * Create a multi validator from an http request. - * @param {Object} req - * @returns {MultiValidator} - */ - -Validator.fromRequest = function fromRequest(req) { - const query = new Validator(req.query, true); - const params = new Validator(req.params, true); - const body = new Validator(req.body, false); - return new MultiValidator([query, params, body]); -}; - -/** - * Create a child validator. - * @param {String} key - * @returns {Validator} - */ - -Validator.prototype.child = function child(key) { - return new Validator(this.get(key)); -}; - -/** - * Test whether value is present. - * @param {String} key - * @returns {Boolean} - */ - -Validator.prototype.has = function has(key) { - return this.get(key) != null; -}; - -/** - * Get a value (no type validation). - * @param {String} key - * @param {Object?} fallback - * @returns {Object|null} - */ - -Validator.prototype.get = function get(key, fallback) { - if (fallback === undefined) - fallback = null; - - if (Array.isArray(key)) { - const keys = key; - for (const key of keys) { - const value = this.get(key); - if (value !== null) - return value; - } - return fallback; - } - - assert(typeof key === 'string' || typeof key === 'number', - 'Key must be a string or number.'); - - const value = this.map[key]; - - if (value != null) - return value; - - return fallback; -}; - -/** - * Get a value's type. - * @param {String} key - * @returns {String} - */ - -Validator.prototype.typeOf = function typeOf(key) { - const value = this.get(key); - - if (value == null) - return 'null'; - - return typeof value; -}; - -/** - * Get a value (as a string). - * @param {String} key - * @param {Object?} fallback - * @returns {String|null} - */ - -Validator.prototype.str = function str(key, fallback) { - const value = this.get(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (typeof value !== 'string') - throw new ValidationError(key, 'number'); - - return value; -}; - -/** - * Get a value (as an integer). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.int = function int(key, fallback) { - const value = this.get(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (typeof value !== 'string') { - if (typeof value !== 'number') - throw new ValidationError(key, 'int'); - - if (!Number.isSafeInteger(value)) - throw new ValidationError(key, 'int'); - - return value; - } - - if (!this.loose) - throw new ValidationError(key, 'int'); - - if (!/^\-?\d+$/.test(value)) - throw new ValidationError(key, 'int'); - - const num = parseInt(value, 10); - - if (!Number.isSafeInteger(num)) - throw new ValidationError(key, 'int'); - - return num; -}; - -/** - * Get a value (as a signed integer). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.uint = function uint(key, fallback) { - const value = this.int(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (value < 0) - throw new ValidationError(key, 'uint'); - - return value; -}; - -/** - * Get a value (as a float). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.float = function float(key, fallback) { - const value = this.get(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (typeof value !== 'string') { - if (typeof value !== 'number') - throw new ValidationError(key, 'float'); - - if (!isFinite(value)) - throw new ValidationError(key, 'float'); - - return value; - } - - if (!this.loose) - throw new ValidationError(key, 'float'); - - if (!/^\-?\d*(?:\.\d*)?$/.test(value)) - throw new ValidationError(key, 'float'); - - if (!/\d/.test(value)) - throw new ValidationError(key, 'float'); - - const num = parseFloat(value); - - if (!isFinite(num)) - throw new ValidationError(key, 'float'); - - return num; -}; - -/** - * Get a value (as a positive float). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.ufloat = function ufloat(key, fallback) { - const value = this.float(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (value < 0) - throw new ValidationError(key, 'positive float'); - - return value; -}; - -/** - * Get a value (as a fixed number). - * @param {String} key - * @param {Number?} exp - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.fixed = function fixed(key, exp, fallback) { - const value = this.float(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - try { - return fromFloat(value, exp || 0); - } catch (e) { - throw new ValidationError(key, 'fixed number'); - } -}; - -/** - * Get a value (as a positive fixed number). - * @param {String} key - * @param {Number?} exp - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.ufixed = function ufixed(key, exp, fallback) { - const value = this.fixed(key, exp); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (value < 0) - throw new ValidationError(key, 'positive fixed number'); - - return value; -}; - -/** - * Get a value (as an int32). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.i8 = function i8(key, fallback) { - const value = this.int(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (value < -0x80 || value > 0x7f) - throw new ValidationError(key, 'i8'); - - return value; -}; - -/** - * Get a value (as an int32). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.i16 = function i16(key, fallback) { - const value = this.int(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (value < -0x8000 || value > 0x7fff) - throw new ValidationError(key, 'i16'); - - return value; -}; - -/** - * Get a value (as an int32). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.i32 = function i32(key, fallback) { - const value = this.int(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if ((value | 0) !== value) - throw new ValidationError(key, 'int32'); - - return value; -}; - -/** - * Get a value (as an int64). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.i64 = function i64(key, fallback) { - return this.int(key, fallback); -}; - -/** - * Get a value (as a uint32). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.u8 = function u8(key, fallback) { - const value = this.uint(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if ((value & 0xff) !== value) - throw new ValidationError(key, 'uint8'); - - return value; -}; - -/** - * Get a value (as a uint16). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.u16 = function u16(key, fallback) { - const value = this.uint(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if ((value & 0xffff) !== value) - throw new ValidationError(key, 'uint16'); - - return value; -}; - -/** - * Get a value (as a uint32). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.u32 = function u32(key, fallback) { - const value = this.uint(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if ((value >>> 0) !== value) - throw new ValidationError(key, 'uint32'); - - return value; -}; - -/** - * Get a value (as a uint64). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|null} - */ - -Validator.prototype.u64 = function u64(key, fallback) { - return this.uint(key, fallback); -}; - -/** - * Get a value (as a reverse hash). - * @param {String} key - * @param {Object?} fallback - * @returns {Hash|null} - */ - -Validator.prototype.hash = function hash(key, fallback) { - const value = this.get(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (typeof value !== 'string') { - if (!Buffer.isBuffer(value)) - throw new ValidationError(key, 'hash'); - - if (value.length !== 32) - throw new ValidationError(key, 'hash'); - - return value.toString('hex'); - } - - if (value.length !== 64) - throw new ValidationError(key, 'hex string'); - - if (!/^[0-9a-f]+$/i.test(value)) - throw new ValidationError(key, 'hex string'); - - return value.toLowerCase(); -}; - -/** - * Get a value (as a number or hash). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|Hash|null} - */ - -Validator.prototype.uinthash = function uinthash(key, fallback) { - const value = this.get(key); - - if (fallback == null) - fallback = null; - - if (value == null) - return fallback; - - if (Buffer.isBuffer(value)) - return this.hash(key, fallback); - - if (typeof value === 'string') { - if (!this.loose || value.length === 64) - return this.hash(key, fallback); - } - - return this.uint(key, fallback); -}; - -/** - * Get a value (as a reverse hash). - * @param {String} key - * @param {Object?} fallback - * @returns {Hash|null} - */ - -Validator.prototype.rhash = function rhash(key, fallback) { - const value = this.get(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (typeof value !== 'string') { - if (!Buffer.isBuffer(value)) - throw new ValidationError(key, 'hash'); - - if (value.length !== 32) - throw new ValidationError(key, 'hash'); - - return value.toString('hex'); - } - - if (value.length !== 64) - throw new ValidationError(key, 'hex string'); - - if (!/^[0-9a-f]+$/i.test(value)) - throw new ValidationError(key, 'hex string'); - - let out = ''; - - for (let i = 0; i < value.length; i += 2) - out = value.slice(i, i + 2) + out; - - return out.toLowerCase(); -}; - -/** - * Get a value (as a number or reverse hash). - * @param {String} key - * @param {Object?} fallback - * @returns {Number|Hash|null} - */ - -Validator.prototype.uintrhash = function uintrhash(key, fallback) { - const value = this.get(key); - - if (fallback == null) - fallback = null; - - if (value == null) - return fallback; - - if (Buffer.isBuffer(value)) - return this.rhash(key, fallback); - - if (typeof value === 'string') { - if (!this.loose || value.length === 64) - return this.rhash(key, fallback); - } - - return this.uint(key, fallback); -}; - -/** - * Get a value (as a boolean). - * @param {String} key - * @param {Object?} fallback - * @returns {Boolean|null} - */ - -Validator.prototype.bool = function bool(key, fallback) { - const value = this.get(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - // Bitcoin Core compat. - if (typeof value === 'number') { - if (value === 1) - return true; - - if (value === 0) - return false; - } - - if (typeof value !== 'string') { - if (typeof value !== 'boolean') - throw new ValidationError(key, 'boolean'); - return value; - } - - if (!this.loose) - throw new ValidationError(key, 'hash'); - - if (value === 'true' || value === '1') - return true; - - if (value === 'false' || value === '0') - return false; - - throw new ValidationError(key, 'boolean'); -}; - -/** - * Get a value (as a buffer). - * @param {String} key - * @param {Object?} fallback - * @param {String?} enc - * @returns {Buffer|null} - */ - -Validator.prototype.buf = function buf(key, fallback, enc) { - const value = this.get(key); - - if (!enc) - enc = 'hex'; - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (typeof value !== 'string') { - if (!Buffer.isBuffer(value)) - throw new ValidationError(key, 'buffer'); - return value; - } - - const data = Buffer.from(value, enc); - - if (data.length !== Buffer.byteLength(value, enc)) - throw new ValidationError(key, `${enc} string`); - - return data; -}; - -/** - * Get a value (as an array). - * @param {String} key - * @param {Object?} fallback - * @returns {Array|String[]|null} - */ - -Validator.prototype.array = function array(key, fallback) { - const value = this.get(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (typeof value !== 'string') { - if (!Array.isArray(value)) - throw new ValidationError(key, 'list/array'); - return value; - } - - if (!this.loose) - throw new ValidationError(key, 'hash'); - - const parts = value.trim().split(/\s*,\s*/); - const result = []; - - for (const part of parts) { - if (part.length === 0) - continue; - - result.push(part); - } - - return result; -}; - -/** - * Get a value (as an object). - * @param {String} key - * @param {Object?} fallback - * @returns {Object|null} - */ - -Validator.prototype.obj = function obj(key, fallback) { - const value = this.get(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (typeof value !== 'object' || Array.isArray(value)) - throw new ValidationError(key, 'object'); - - return value; -}; - -/** - * Get a value (as a function). - * @param {String} key - * @param {Object?} fallback - * @returns {Function|null} - */ - -Validator.prototype.func = function func(key, fallback) { - const value = this.get(key); - - if (fallback === undefined) - fallback = null; - - if (value === null) - return fallback; - - if (typeof value !== 'function') - throw new ValidationError(key, 'function'); - - return value; -}; - -/* - * Constants - */ - -const SENTINEL = new Validator(Object.create(null)); - -/** - * MultiValidator - * @alias module:utils.MultiValidator - * @constructor - * @extends Validator - * @param {Object[]} maps - * @param {Boolean} [loose=false] - */ - -function MultiValidator(maps, loose) { - if (!(this instanceof MultiValidator)) - return new MultiValidator(maps, loose); - - this.maps = []; - - this.init(maps, loose); -} - -/** - * Initialize the validator. - * @private - * @param {Object[]} maps - * @param {Boolean} [loose=false] - */ - -MultiValidator.prototype.init = function init(maps, loose) { - assert(Array.isArray(maps)); - assert(maps.length > 0); - - for (const map of maps) { - if (!(map instanceof Validator)) { - assert(map && typeof map === 'object'); - this.maps.push(new Validator(map, loose)); - continue; - } - this.maps.push(map); - } -}; - -/** - * Get a validator. - * @private - * @param {String} key - * @returns {Validator} - */ - -MultiValidator.prototype.find = function find(key) { - for (const map of this.maps) { - if (map.has(key)) - return map; - } - return SENTINEL; -}; - -MultiValidator.prototype.child = function child(key) { - return this.find(key).child(key); -}; - -MultiValidator.prototype.has = function has(key) { - return this.find(key).has(key); -}; - -MultiValidator.prototype.get = function get(key, fallback) { - return this.find(key).get(key, fallback); -}; - -MultiValidator.prototype.typeOf = function typeOf(key) { - return this.find(key).typeOf(key); -}; - -MultiValidator.prototype.str = function str(key, fallback) { - return this.find(key).str(key, fallback); -}; - -MultiValidator.prototype.int = function int(key, fallback) { - return this.find(key).int(key, fallback); -}; - -MultiValidator.prototype.uint = function uint(key, fallback) { - return this.find(key).uint(key, fallback); -}; - -MultiValidator.prototype.float = function float(key, fallback) { - return this.find(key).float(key, fallback); -}; - -MultiValidator.prototype.ufloat = function ufloat(key, fallback) { - return this.find(key).ufloat(key, fallback); -}; - -MultiValidator.prototype.fixed = function fixed(key, exp, fallback) { - return this.find(key).fixed(key, exp, fallback); -}; - -MultiValidator.prototype.ufixed = function ufixed(key, exp, fallback) { - return this.find(key).ufixed(key, exp, fallback); -}; - -MultiValidator.prototype.i8 = function i8(key, fallback) { - return this.find(key).i8(key, fallback); -}; - -MultiValidator.prototype.i16 = function i16(key, fallback) { - return this.find(key).i16(key, fallback); -}; - -MultiValidator.prototype.i32 = function i32(key, fallback) { - return this.find(key).i32(key, fallback); -}; - -MultiValidator.prototype.i64 = function i64(key, fallback) { - return this.find(key).i64(key, fallback); -}; - -MultiValidator.prototype.u8 = function u8(key, fallback) { - return this.find(key).u8(key, fallback); -}; - -MultiValidator.prototype.u16 = function u16(key, fallback) { - return this.find(key).u16(key, fallback); -}; - -MultiValidator.prototype.u32 = function u32(key, fallback) { - return this.find(key).u32(key, fallback); -}; - -MultiValidator.prototype.u64 = function u64(key, fallback) { - return this.find(key).u64(key, fallback); -}; - -MultiValidator.prototype.hash = function hash(key, fallback) { - return this.find(key).hash(key, fallback); -}; - -MultiValidator.prototype.uinthash = function uinthash(key, fallback) { - return this.find(key).uinthash(key, fallback); -}; - -MultiValidator.prototype.rhash = function rhash(key, fallback) { - return this.find(key).rhash(key, fallback); -}; - -MultiValidator.prototype.uintrhash = function uintrhash(key, fallback) { - return this.find(key).uintrhash(key, fallback); -}; - -MultiValidator.prototype.bool = function bool(key, fallback) { - return this.find(key).bool(key, fallback); -}; - -MultiValidator.prototype.buf = function buf(key, fallback, enc) { - return this.find(key).buf(key, fallback, enc); -}; - -MultiValidator.prototype.array = function array(key, fallback) { - return this.find(key).array(key, fallback); -}; - -MultiValidator.prototype.obj = function obj(key, fallback) { - return this.find(key).obj(key, fallback); -}; - -MultiValidator.prototype.func = function func(key, fallback) { - return this.find(key).func(key, fallback); -}; - -/* - * Helpers - */ - -function fmt(key) { - if (Array.isArray(key)) - key = key[0]; - - if (typeof key === 'number') - return `Param #${key}`; - - return key; -} - -function ValidationError(key, type) { - if (!(this instanceof ValidationError)) - return new ValidationError(key, type); - - Error.call(this); - - this.type = 'ValidationError'; - this.message = `${fmt(key)} must be a ${type}.`; - - if (Error.captureStackTrace) - Error.captureStackTrace(this, ValidationError); -} - -Object.setPrototypeOf(ValidationError.prototype, Error.prototype); - -/* - * Expose - */ - -module.exports = Validator; diff --git a/lib/wallet/http.js b/lib/wallet/http.js index c2551033..b2c28028 100644 --- a/lib/wallet/http.js +++ b/lib/wallet/http.js @@ -18,7 +18,7 @@ const digest = require('bcrypto/lib/digest'); const random = require('bcrypto/lib/random'); const ccmp = require('bcrypto/lib/ccmp'); const Network = require('../protocol/network'); -const Validator = require('../utils/validator'); +const Validator = require('bval/lib/validator'); const Address = require('../primitives/address'); const KeyRing = require('../primitives/keyring'); const Mnemonic = require('../hd/mnemonic'); diff --git a/lib/wallet/rpc.js b/lib/wallet/rpc.js index 510e1690..51bd83a6 100644 --- a/lib/wallet/rpc.js +++ b/lib/wallet/rpc.js @@ -23,7 +23,7 @@ const Output = require('../primitives/output'); const TX = require('../primitives/tx'); const encoding = require('bbuf/lib/encoding'); const pkg = require('../pkg'); -const Validator = require('../utils/validator'); +const Validator = require('bval/lib/validator'); const Lock = require('../utils/lock'); const common = require('./common'); const RPCBase = bweb.RPC; diff --git a/test/utils-test.js b/test/utils-test.js index 49ac7beb..e3282b2f 100644 --- a/test/utils-test.js +++ b/test/utils-test.js @@ -8,7 +8,7 @@ const {U64, I64} = require('n64'); const base58 = require('bstr/lib/base58'); const encoding = require('bbuf/lib/encoding'); const Amount = require('../lib/btc/amount'); -const Validator = require('../lib/utils/validator'); +const Validator = require('bval/lib/validator'); const fixed = require('../lib/utils/fixed'); const base58Tests = [