Comparing version 0.0.7 to 0.0.8
@@ -6,12 +6,4 @@ 'use strict'; | ||
const DEFAULT_ATTR_SCHEMA = { | ||
key: Joi.string(), | ||
type: Joi.string().required(), | ||
default: Joi.any().when('static', { is:true, then: Joi.required() }), | ||
static: Joi.boolean().default(false), | ||
required: Joi.boolean().default(false) | ||
}; | ||
module.exports = class Message { | ||
@@ -42,14 +34,4 @@ | ||
this.config.schema = this.config.schema.map(schema => { | ||
let type = protocol._getType(schema.type); | ||
let vschema = Object.assign({}, DEFAULT_ATTR_SCHEMA, type._config.schemaValidation || {}); | ||
let res = Joi.validate(schema, Joi.object().keys(vschema)); | ||
if(res.error) { | ||
throw res.error; | ||
} | ||
return type.transformSchema(res.value, protocol); | ||
return type.transformSchema(schema, protocol); | ||
}); | ||
@@ -68,4 +50,11 @@ | ||
let res = ctx.data[key] = type.match(buf, ctx, schema, protocol); | ||
let res; | ||
try { | ||
res = ctx.data[key] = type.match(buf, ctx, schema, protocol); | ||
} catch(e) { | ||
console.log(e); | ||
return false; | ||
} | ||
if(res === null) { | ||
@@ -82,3 +71,2 @@ return false; | ||
return Buffer.concat(this.config.schema.map(schema => { | ||
let type = protocol._getType(schema.type); | ||
@@ -85,0 +73,0 @@ |
'use strict'; | ||
const Joi = require('joi'); | ||
const is = require('is'); | ||
@@ -10,4 +11,59 @@ module.exports = function(protocol, options) { | ||
schemaValidation: { | ||
bits: Joi.object() | ||
bits: Joi.object().pattern(/.*/, Joi.alternatives().try( | ||
// single bit value | ||
Joi.object().keys({ | ||
bit: Joi.number().required(), | ||
slice: Joi.forbidden(), | ||
values: Joi.array().max(2).default([true, false]) | ||
}), | ||
// multi bits value | ||
Joi.object().keys({ | ||
bit: Joi.forbidden(), | ||
shift: Joi.number().default(0), | ||
values: Joi.object().default({}).required(), | ||
_values: Joi.object().required(), | ||
size: Joi.number().default(2), | ||
default: Joi.string() | ||
}), | ||
)) | ||
}, | ||
transformSchema(schema, protocol) { | ||
if(schema.bits) { | ||
let bits = {}; | ||
Object.keys(schema.bits).forEach(key => { | ||
let input = schema.bits[key]; | ||
if(is.number(input)) { | ||
return bits[key] = { bit: input }; | ||
} | ||
if(is.object(input)) { | ||
bits[key] = input; | ||
} | ||
// turn values obje | ||
// key:val -> val:key | ||
// | ||
// for faster access during composing/parsing | ||
if(is.object(bits[key].values)) { | ||
let _values = bits[key]._values = {}; | ||
Object.keys(bits[key].values).forEach(_key => { | ||
_values[bits[key].values[_key]] = _key; | ||
}); | ||
} | ||
}); | ||
schema.bits = bits; | ||
} | ||
return schema; | ||
}, | ||
parse: (buf, ctx, schema) => { | ||
@@ -24,8 +80,27 @@ let res = buf['read'+type](ctx.offset); | ||
Object.keys(schema.bits).forEach(key => { | ||
let bit = schema.bits[key]; | ||
let val = res & 1 << bit; | ||
let bitSchema = schema.bits[key]; | ||
obj[key] = val !== 0; | ||
if(is.number(bitSchema.bit) && Array.isArray(bitSchema.values)) { | ||
let bit = schema.bits[key].bit; | ||
let values = schema.bits[key].values; | ||
let val = res & 1 << bit; | ||
obj[key] = (val !== 0) ? values[0] : values[1]; | ||
} | ||
if(is.object(bitSchema.values)) { | ||
let bit = bitSchema.shift; | ||
// TODO: find a neater way to create mask length from given size | ||
// something like this: 0x((FF)*size) | ||
let mask = (0xFFFFFF) ^ (0xFFFFFF << (bitSchema.size)); | ||
let value = mask & (res >> bit); | ||
obj[key] = bitSchema._values[value]; | ||
} | ||
}); | ||
@@ -47,6 +122,34 @@ | ||
Object.keys(schema.bits).forEach(key => { | ||
let bit = schema.bits[key]; | ||
if(value[key] === true) { | ||
store |= 1 << bit; | ||
let bitSchema = schema.bits[key]; | ||
if(is.number(bitSchema.bit) && Array.isArray(bitSchema.values)) { | ||
let bit = bitSchema.bit; | ||
let values = bitSchema.values; | ||
if(value && value[key] === values[0]) { | ||
store |= 1 << bit; | ||
} | ||
return; | ||
} | ||
if(is.object(bitSchema.values)) { | ||
let bit = bitSchema.shift; | ||
let setValue = 0; | ||
if(is.object(value)) { | ||
if(!value[key] && bitSchema.default) { | ||
setValue = bitSchema.values[bitSchema.default]; | ||
} else { | ||
setValue = bitSchema.values[value[key]]; | ||
} | ||
} | ||
store |= setValue << bit; | ||
} | ||
}); | ||
@@ -214,6 +317,12 @@ | ||
transformSchema(schema, protocol) { | ||
if(typeof schema.items === 'string') { | ||
if(!schema.items) { | ||
schema.items = 'uint8'; | ||
} | ||
if(is.string(schema.items)) { | ||
schema.items = { type: schema.items }; | ||
} | ||
let type = protocol._getType(schema.items.type); | ||
@@ -220,0 +329,0 @@ schema.items = type.transformSchema(schema.items); |
@@ -5,4 +5,10 @@ 'use strict'; | ||
const DEFAULT_ATTR_SCHEMA = { | ||
key: Joi.string(), | ||
type: Joi.string().required(), | ||
default: Joi.any().when('static', { is:true, then: Joi.required() }), | ||
static: Joi.boolean().default(false), | ||
required: Joi.boolean().default(false) | ||
}; | ||
module.exports = class Type { | ||
@@ -19,4 +25,4 @@ | ||
} catch(e) { | ||
console.log(e); | ||
console.log(`\nError in schema with value ${value}\n\n` , schema); | ||
console.log(`\nError in schema with value ${value}\n\n` , schema.key); | ||
throw e; | ||
} | ||
@@ -39,21 +45,37 @@ } | ||
if(this._config.schemaValidation) { | ||
let res = Joi.validate(schema, this._config.schemaValidation, {allowUnknown:true}); | ||
if(this._config.transformSchema) { | ||
schema = this._config.transformSchema(schema, protocol); | ||
} | ||
if(res.error) { | ||
throw res.error; | ||
} | ||
let vschema = Object.assign({}, DEFAULT_ATTR_SCHEMA, this._config.schemaValidation || {}); | ||
schema = res.value; | ||
} | ||
let res = Joi.validate(schema, Joi.object().keys(vschema)); | ||
if(this._config.transformSchema) { | ||
schema = this._config.transformSchema(schema, protocol); | ||
if(res.error) { | ||
throw res.error; | ||
} | ||
return res.value; | ||
// if(this._config.schemaValidation) { | ||
// let res = Joi.validate(schema, this._config.schemaValidation, {allowUnknown:true}); | ||
// if(res.error) { | ||
// throw res.error; | ||
// } | ||
// schema = res.value; | ||
// } | ||
return schema; | ||
} | ||
// validateSchema(schema) { | ||
@@ -60,0 +82,0 @@ // if(this._config.schemaValidation) { |
@@ -5,5 +5,6 @@ { | ||
"author": "Christian Blaschke <mail@platdesign.de>", | ||
"version": "0.0.7", | ||
"version": "0.0.8", | ||
"main": "./lib/bipro.js", | ||
"dependencies": { | ||
"is": "^3.2.1", | ||
"joi": "^10.6.0" | ||
@@ -21,5 +22,5 @@ }, | ||
"test:w": "mocha -w", | ||
"release:patch": "npm run coverage && git commit -a -m \"Build for release\" && npm-release patch", | ||
"release:patch": "npm run coverage && git commit -a -m \"Prepare for build\" && npm-release patch", | ||
"coverage": "mkdir -p .nyc_output && npm run test && nyc report --reporter=html" | ||
} | ||
} |
57895
2
14
450