function check(schema, msg) { /* Primitives */ if (schema === 'id' || schema === 'nat') return typeof msg == 'number' && (msg || msg === 0) && msg >= (schema == 'id' ? 1 : 0) && Math.round(msg) === msg; else if (schema === 'string') return typeof msg == 'string'; else if (schema === 'boolean') return typeof msg == 'boolean'; /* Arrays */ if (schema instanceof Array) { if (!(msg instanceof Array) || msg.length != schema.length) return false; for (var i = 0; i < schema.length; i++) if (!check(schema[i], msg[i])) return false; return true; } else if (schema === 'id...') { if (!(msg instanceof Array) || !msg.length) return false; return msg.every(check.bind(null, 'id')); } else if (msg instanceof Array) return false; /* Hashes */ if (typeof schema == 'object') { if (typeof msg != 'object' || msg === null || msg instanceof Array) return false; for (var k in schema) { var spec = schema[k]; /* optional key */ if (typeof spec == 'string' && /^opt /.test(spec)) { if (!(k in msg)) continue; spec = spec.slice(4); } else if (!(k in msg)) return false; /* otherwise mandatory */ if (!check(spec, msg[k])) return false; } return true; } else if (schema === 'id=>nat') { if (typeof msg != 'object' || msg instanceof Array) return false; for (var k in msg) { if (!/^[1-9]\d*$/.test(k)) return false; if (!check('nat', msg[k])) return false; } return true; } throw new Error("Unknown schema: " + schema); } exports.check = check;