{"_id":"bow","_rev":"32-09a334a2acd8379208dd434220dcf438","name":"bow","description":"Broadcast Over WebSocket","dist-tags":{"latest":"2.3.4"},"versions":{"0.0.1":{"name":"bow","description":"BDD Testing Framework for Arrow","version":"0.0.1","homepage":"https://github.com/bowdev/Bow","repository":{"type":"git","url":"https://github.com/bowdev/Bow.git"},"author":{"name":"Ares Huang","email":"aresyhoo@yahoo-inc.com","url":"https://github.com/bowdev/"},"contributors":[],"bin":{"bow":"bin/bow.js"},"engines":["node >=0.6"],"dependencies":{"glob":"3.1.14","gherkin":"2.11.5"},"devDependencies":{},"_id":"bow@0.0.1","dist":{"shasum":"3d50ec594946d5d9b1d8711fa931c9b028407072","tarball":"https://registry.npmjs.org/bow/-/bow-0.0.1.tgz","integrity":"sha512-5NSsyK437oIkyMsnycmk3D/UyZmSgngDg+rHDluLBJelBLKlv34C3cK6rVv0o0JTmDtXIgpRbFYQNWRdGSRNGg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDlF5htiSH/EOh+h0SM5wlEXSODgkBU09O5F8glnTWzpQIgIyZ+nU01OLPtXSK7QbajtGCyqeCAogmTZLFh4EiRUkE="}]},"maintainers":[{"name":"aresyhoo","email":"aresyhoo@yahoo-inc.com"}],"directories":{}},"1.0.0":{"name":"bow","version":"1.0.0","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.0.1","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.1","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.0.1","socket.io-client":"^2.0.3","supertest":"^3.0.0","supervisor":"^0.12.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"e954c94804cb671acfec96cbe1ef5385e5c726e7","_id":"bow@1.0.0","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-i3IGc572YjGCsvhh7+zw2+mb8D9NZNiIHJTaSkWkLJSgUsv+gNf+222Tc3YKU5pJIQo0lx56vhYsI9rFiIgsMg==","shasum":"2307c2ef6937d4881fb2056872c496041f266ca3","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICORvEjxpbjtyDP6OtfUplG/Rj8PfYyI6EzSMvL5gBlZAiA+FYQq6zrw10IvIMKVG++lznm2JB1M9nBG709nDUE43w=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.0.tgz_1506440513020_0.8616761576849967"},"directories":{}},"1.0.1":{"name":"bow","version":"1.0.1","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.0.1","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.1","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.0.1","socket.io-client":"^2.0.3","supertest":"^3.0.0","supervisor":"^0.12.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"6fdef27148892ae73fd137d46003cf72fafaffb9","_id":"bow@1.0.1","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-Ztg5klYMLr/LV8vTun9yO8ZnNZjzp+LsiwqspK/K3F7lJ8MsGRV7vnH15/4G9rSTLPtYEfn14zIgv3O9K3nx/A==","shasum":"47088d12b276696a0d4d46b12c0c86a353a38e88","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEB05cAXSHvj3j3GWXqUXbEX9y7LU014tBjBrRuIO4q9AiEA9lMywuPdowOfXLON48o4P32tY/7PFXBFlZV+sDOPJHQ="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.1.tgz_1506440804452_0.2277133830357343"},"directories":{}},"1.0.2":{"name":"bow","version":"1.0.2","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.0.1","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.1","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.0.1","socket.io-client":"^2.0.3","supertest":"^3.0.0","supervisor":"^0.12.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"0eb3b716f66ab69db7ff3365776ea9fdd0cdee18","_id":"bow@1.0.2","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-ImIYVK64k4ePNwdtmE3N0yXt+hthhgeiI4poJCS2TsW1xh8pDS2MS3UT+Yx83Y5ZkfGofF1IdHpuPZo8VoQmAQ==","shasum":"88b180270b6bb3dc0d075cedab15290f8a05dc40","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.2.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDCT2Of1/DnkeJrqHVxbzNf68q+oSMsidedgojoaQkEDwIhAOMwxPk8iu37Avhay8Ww8s9eT82990D70HX6iNx485+V"}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.2.tgz_1506712150409_0.03323633433319628"},"directories":{}},"1.0.3":{"name":"bow","version":"1.0.3","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.1","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.0.1","socket.io-client":"^2.0.3","supertest":"^3.0.0","supervisor":"^0.12.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"444a5cfee5e1fa7ccce31066d091df7f7e448181","_id":"bow@1.0.3","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-NNv6k8L2BJzOKqEi9aFaE4R2Dl9X9LfOboTXBbCnLKyULSAguMX+GDmb3nTskRCrSq5J8Wrr1azR7+uRMD7+ew==","shasum":"66e015874b7740b921e006c9f318808af7b8db93","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.3.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCbB9R9WeMDtMgcrAfTdt4k60Pfn2vizwCvaC7hpmE2LAIgdxBsk1WrElTm8327++043kYCJKw4hNaCq/FBPPxZhxk="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.3.tgz_1506713137979_0.44193824962712824"},"directories":{}},"1.0.4":{"name":"bow","version":"1.0.4","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.0","socket.io-client":"^2.0.3","supertest":"^3.0.0","supervisor":"^0.12.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"345e8a0d7522822ca0950a3fe37a6681594e80bc","_id":"bow@1.0.4","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-4R83fTczSzYdX1zHzkr/grQgBYZ6ZEJyRMmOvqemAdu8wtdYYYV1HsRBknCqVXawFbJ8XvoI8ua2mR2hJzYkqA==","shasum":"2eef4b856e91074ddd544029f72c803bc9b64e0b","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.4.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQChhIfTIS2s6gRHko/flKjAKMweGc6P/lJDr536fDB7xgIhAJxsqR1olaMxSYG02UHhAeVHu/Ml5z1ry1GTAhSzGkHm"}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.4.tgz_1506714341320_0.6069236809853464"},"directories":{}},"1.0.5":{"name":"bow","version":"1.0.5","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-ping":"^0.1.1","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.0","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"99c490606fe31f723efdc88636c617dd06dc126b","_id":"bow@1.0.5","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-cB4Fkgtj730avnGEJ8Z+CvcA0ZUJSU7qriQMfvYgRPpdiDACtih2quZnpEzNFFakyWg1Uf4FAX5DJX1aRNJyTw==","shasum":"f3a29735944ef20a60026f87b08b4e2f54cb7544","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.5.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDW+ztDXFJ32p/rcIfxIxBUE0/wTybrGqALS8k89SgeVgIhAMMG2XFhtlh6gNY1U4ihGPP00rIKzW57r2IgMcW+n6a2"}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.5.tgz_1508091236757_0.8002023904118687"},"directories":{}},"1.0.6":{"name":"bow","version":"1.0.6","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.0","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"29e6372011abdb27a34bef93d67774f6d5f9fe96","_id":"bow@1.0.6","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-/I7fWz0N1WU8ZdZCnM9XTyQ6hksTawGnw/QVjUpT3K1e6F4jcluQWr6IgyBFJMOlJ+Ta4OUHg0vSy1JKimwd0g==","shasum":"6906464a66c9e3cf3af840d5eac3626d543510d3","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.6.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD/i46SyIcH8q9lMoUY8qckeJGeXOzk5G+IAYJBDY9HHwIgQIYQqscU6tGeXXunwTusImuAKgnVMYlRMuUXIoPfapI="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.6.tgz_1508172848701_0.6708949212916195"},"directories":{}},"1.0.7":{"name":"bow","version":"1.0.7","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.0","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"021e1ee8ee47ccd5a8888fbdbf3af77c10cc1e44","_id":"bow@1.0.7","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-W2SIdNeda7noLHFj9VG2EYdv54doNW0woReQ3ZEkz0O6ksH1P1LnBtbz/R8Po0cY6uwTZJ1oC3FWsSR4hFCyQQ==","shasum":"8cf9384f9ac0acf2582ec203090cfb9dee3476a1","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.7.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDxR/le83GQD84XxN07MZxIcPa0NiWma6I8/Gp37O8rkgIhAM1aG12UN22sBd3aIamquB74egu0loWd1dc2HecFp8cB"}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.7.tgz_1508173364797_0.7467001061886549"},"directories":{}},"1.0.8":{"name":"bow","version":"1.0.8","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.2","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"9485236a5ffd97ad68500370cc5cc39a0ef89f1e","_id":"bow@1.0.8","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-F/1hnb4JDAv2gR70HK9STv5YlIyu+/P/DActyaPO+yiNQR2/aol5w13iQE0ICsi0iwKeD9fADWerfyHWVIOW9w==","shasum":"c00937a18d47edc3ba151b8252a560f4eea162b6","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.8.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFKFWXF5S9wquq7+e3LLpXEjW9VqUhkgiU5vA5exQeOxAiEA0Hm4cIhWzGOJpPtTii6t36ok5vmPuOsR/8XP2VPe2G0="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.8.tgz_1508175138168_0.9651326783932745"},"directories":{}},"1.0.9":{"name":"bow","version":"1.0.9","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.2","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"6b0b7f659e61600c91cbe62fd20074fafe5a3594","_id":"bow@1.0.9","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-n6JuUrLA/f9MLx74UoClg064AS6x5j4yhesUyI7EybQ4IW6n0wZdhybL7UQE7Ew/B9i5FRrh5+ewM3zm0LGVlA==","shasum":"a8c91681f5d11c020227e429d7be1b7f5a01d0de","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.9.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCJS8WKx2YM7pvZ1tKatnUCDWs52QBO1Hqa6RiC9cKZwIgE5r9uNhCitNBB7bZE8bkRH0CDTkiBsU+kFd5wDIDh2c="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.9.tgz_1508193971736_0.09957763575948775"},"directories":{}},"1.0.10":{"name":"bow","version":"1.0.10","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.2","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"ed5249200b592c7ee97d55b7dd1ecc6eb3f8ded1","_id":"bow@1.0.10","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-mEanr7DGDVkxaNp6KywmsXA25gujc9Gnf2vEXmWrtvkdNsLZGpvtu4Vjh+Pr+zbkM86CFTpOvBhfdXatZwk3KA==","shasum":"9a205e928e1e100ecb42baa6845a67ad49b26335","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.10.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICayOv8dam0sZr2X1g2qiMfjJH8ONA+0gmwVtepl+jIjAiBYaDtxuU866KFmeaqpOolbgjH2pNmbjxsQh7btDBrvTg=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.10.tgz_1508233040359_0.9783855681307614"},"directories":{}},"1.0.11":{"name":"bow","version":"1.0.11","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.2","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"0f41cd99a6d081748fbda845ce93101e4676d09d","_id":"bow@1.0.11","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-LNaIpPzzz+GEW6xqglmPxVMbfeis1xW4QZ5G92G0vTq0w6PTib5DgCx4I8t/TGynD8VFiGQhcpQT+BltEsVbuw==","shasum":"05fad7cdb76d182271c4b1da69d9271a1ed07f9b","tarball":"https://registry.npmjs.org/bow/-/bow-1.0.11.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDZG4Mxuw94dQ9ljG2ZIjUBn4gXdpMIc2Ysv01SjA92MAiAvqgF4eq9G/S+eIcy79yCpbrOO1mamqFusLDFfd64HdA=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.0.11.tgz_1508236468450_0.49806178268045187"},"directories":{}},"1.1.0":{"name":"bow","version":"1.1.0","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.2","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"48d95bef10f0b811c3b4aaf6f50e6f50aa068425","_id":"bow@1.1.0","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-MLUpUY6VX/vv8HqHS8XKlgtibD4HKc4K3JOZlegx5jWPQQ2sF+01mgGmprsvxjtG91QYG6B5vVbLYw5hZuZstA==","shasum":"61e3120e487cce4e18651033b67f55fe5a7e2fb1","tarball":"https://registry.npmjs.org/bow/-/bow-1.1.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF3h01l2XUzd/XMD45inO2Bg6j9vToqX+GkwOzlCXZgEAiAr1X94x/dhZEVMnFLJojNn4e77E00Hs+12atH/70D9zA=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.1.0.tgz_1508259081948_0.3507687086239457"},"directories":{}},"1.1.1":{"name":"bow","version":"1.1.1","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","redis":"^2.8.0","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.2","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"f828cf72979c5126972ba34edd3c763bb30721e9","_id":"bow@1.1.1","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-Wm1Fn8ugZDDP+9aaOFzxJaGfo0hEJWltbEzfMvhwpth2c6W/HGbkaXOwpFyt83mGLt1CTBDsmffPDlzff39t0g==","shasum":"2794383aa5f56a0f5cfcd9cfcb9f25faee724f7c","tarball":"https://registry.npmjs.org/bow/-/bow-1.1.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA5tJqYLporDcs0gvPnkJoYVMGx47/HHdSaKsm2ynh9mAiAQXakZjBeftDpC2SyaOp1rfnUyW62YBbwOePMyQmqKdg=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.1.1.tgz_1508328499519_0.533619569381699"},"directories":{}},"1.2.0":{"name":"bow","version":"1.2.0","description":"Broadcast Over WebSocket","keywords":["bow","websocket","microservice","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","ioredis":"^3.1.4","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.2","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"80db89564ba96d15e683c499aab16655ca82e46f","_id":"bow@1.2.0","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-lAUn44chg4r9UIcKHGw9TBvOYpgnuwZOqpJSdgN7zlVay4RppiiwvCoq5xrolqANLNDemRyXIKiSSOfwEJaudA==","shasum":"b5db043b80db7ef83b36fff967776a76e6feb969","tarball":"https://registry.npmjs.org/bow/-/bow-1.2.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDi4HvZi3aInAiK2II8nYxqlccBpAvk4vX3BSglO7V3mAiBnip5L35Q9sFLI7yWm9vBF9UP2Q7u5slNtAjDWzXoiUg=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.2.0.tgz_1508435309389_0.963172412943095"},"directories":{}},"1.2.1":{"name":"bow","version":"1.2.1","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","ioredis":"^3.1.4","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.2","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"bc3da0f9d17edd4e2832f4f482f34825413d5e14","_id":"bow@1.2.1","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-9tx9g+MP9BXcTPZbjKSmW15LpmBm9I0j0ZmUHhkHv1LqI6sSTX2Y0+JC7C3XtacnR7PCMYLDY2EM08kg9d33pQ==","shasum":"9c8251eebc40af24b41c144247540974265b7eed","tarball":"https://registry.npmjs.org/bow/-/bow-1.2.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFq54TWn27IX+h70id10jfa5dPqs2dJNKPE9zfGF1FbWAiAd90pY74++k426yTszXL4D6R87AgQS0aZbIhcriS2CZA=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.2.1.tgz_1508445024974_0.2636813702993095"},"directories":{}},"1.2.2":{"name":"bow","version":"1.2.2","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":[{"node":">=7.6.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"^7.3.0","clone":"^2.1.1","debug":"^3.1.0","deep-equal":"^1.0.1","deep-freeze":"0.0.1","http-auth":"^3.2.3","ioredis":"^3.1.4","killable":"^1.0.0","koa":"^2.3.0","koa-bodyparser":"^4.2.0","koa-router":"^7.2.1","socket.io":"^2.0.3","uuid":"^3.1.0"},"devDependencies":{"babel-eslint":"^7.2.3","coveralls":"^2.13.3","eslint":"^3.19.0","eslint-plugin-no-null":"^1.0.2","https-pem":"^1.0.4","husky":"^0.13.3","istanbul":"^1.1.0-alpha.1","mocha":"^3.5.3","should":"^13.1.2","socket.io-client":"^2.0.3","supertest":"^3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"0fa6c8a91a9b56c890d5e056411ab3205c0766fa","_id":"bow@1.2.2","_npmVersion":"5.4.2","_nodeVersion":"7.10.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-JBBwu7LdSE03Xgb+u36hPBWe7If5CKUbynK7kh04QbJfHUQrMAaHcVaQ1s0wrpbeQobA7H2xIUlFGxdELTgEnQ==","shasum":"c40c9835a3970e83b709c2867f61de190851cba8","tarball":"https://registry.npmjs.org/bow/-/bow-1.2.2.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHd4upsq6VSKd3XlDI8egFIwa4sjoGHukzd71bHZs4b/AiEA+aVynGu7nfWU5uvvyq+c0209ZQR8vs4zuJtnkcPgbW0="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow-1.2.2.tgz_1508749458599_0.06183090014383197"},"directories":{}},"2.0.0":{"name":"bow","version":"2.0.0","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":[{"node":">=8.3.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"~7.3.0","clone":"~2.1.2","debug":"~3.1.0","deep-equal":"~1.0.1","deep-freeze":"~0.0.1","http-auth":"~3.2.3","ioredis":"~3.2.2","killable":"~1.0.0","koa":"~2.5.0","koa-bodyparser":"~4.2.0","koa-router":"~7.4.0","socket.io":"~2.1.0","uuid":"~3.2.1"},"devDependencies":{"babel-eslint":"~8.2.2","coveralls":"~3.0.0","eslint":"~4.19.1","eslint-plugin-no-null":"~1.0.2","https-pem":"~2.0.0","husky":"~0.14.3","istanbul":"~1.1.0-alpha.1","mocha":"~5.0.5","should":"~13.2.1","socket.io-client":"~2.1.0","supertest":"~3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --exit --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"b482fa3e18f8735089691f7b6fc1e22742a4ff22","_id":"bow@2.0.0","_npmVersion":"5.3.0","_nodeVersion":"8.3.0","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-Q0E+QFHkTA2Ivvb4e6Ipijs9KegpsAUSvI4LuAchD+i2Qh5ilWyya9bpZdc9rovwXMmU1yPTMzsnF3qzySY8SQ==","shasum":"373fe2e3f7413953c868ab1c5e3352b94598fa7a","tarball":"https://registry.npmjs.org/bow/-/bow-2.0.0.tgz","fileCount":13,"unpackedSize":48168,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa1y6UCRA9TVsSAnZWagAA1JAQAIo1jKkvdKVs09C+ln7C\nOmLFQ2jAM2vcTUrucXJhPpTeyJV1uPcfdqG6hr34NMqiv5bJRo/C5fwN77N0\n3XKolzx6uwWeoyEITyr5/DIcsJPsAuPEVXYKNRSvHW3EAJYqUTZkv3OG9l0U\nUsF6OtTa+L12wQrN4w1BLCo3Li9p8JC1o/6E6ayTVP9KEDh3CILQuHvPkL1+\nu0z3nbv5Lx8vJlERW2Ci8pBfAf/K3FhO87zVyD+XrbqcFLzOvGkWfEegUmCW\ntGtHYrYo4nvjlJYd8ClJ5xfrj31pGbu5VpKp7Iz7yOnKWHJJ74Vu8nUJsc94\nqK4GErzLec+dkhhX+7HRy58ETSY8v1RlE735lw81q27y+SHnTdaNJBTGHl+i\n/kP3K/IThM4Df3MRAriX7ebHVF6f2ZGKHJgd8kpOu6AIV1wi56cIE2tf5PrM\nGEEgHz/q3mH8FtoFIQmKvseXVshXG6LOscZMWdl73gffhOMVYKsrSMXWtoNB\n7Hd6dR6vserXyeUXGtZsmggMj5iLObZeeCaN+g+eb9o2ESF3dR90Y6rr7nG0\nQLUSfGQ02daThubmDKBwvr/0v14UEMwVo6yViWdmkXZ9f1o2WMGUuO4Rlqiq\nIXau+Pt4PMhKMe/icgaePJa068bWpDEAqPjUdMlleNFJDQNl1V6wZitEhKFF\nVTFZ\r\n=hIGi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCYJ97ZPg5InI8TwVt/LyEy1ns55bCGuMwkpRus3kgywwIhANm0nAfhrp0nJzl0B142ovn8chcYODweuXc6nTrz5Qpl"}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow_2.0.0_1524051602928_0.5701631410133177"},"_hasShrinkwrap":false},"2.1.0":{"name":"bow","version":"2.1.0","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":[{"node":">=8.3.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"~7.3.0","clone":"~2.1.2","debug":"~3.1.0","deep-equal":"~1.0.1","deep-freeze":"~0.0.1","http-auth":"~3.2.3","ioredis":"~3.2.2","killable":"~1.0.0","koa":"~2.5.0","koa-bodyparser":"~4.2.0","koa-router":"~7.4.0","socket.io":"~2.1.0","uuid":"~3.2.1"},"devDependencies":{"babel-eslint":"~8.2.2","coveralls":"~3.0.0","eslint":"~4.19.1","eslint-plugin-no-null":"~1.0.2","https-pem":"~2.0.0","husky":"~0.14.3","istanbul":"~1.1.0-alpha.1","mocha":"~5.0.5","should":"~13.2.1","socket.io-client":"~2.1.0","supertest":"~3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --exit --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"364116852868db9e2a45a9485c4f353c7aad13ee","_id":"bow@2.1.0","_npmVersion":"5.3.0","_nodeVersion":"8.3.0","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-kymjMhXpGbUYUYCpxLP83HHlC0BjrKWDZ+CSkGoc7ZLv0ndH0foFyJAPVZofmSA5GarnL8O0/92HZ5nwNZ9rrw==","shasum":"cd89e5ed90b60de8483484aea672ef0654d62d53","tarball":"https://registry.npmjs.org/bow/-/bow-2.1.0.tgz","fileCount":13,"unpackedSize":48841,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa1z34CRA9TVsSAnZWagAAyC4QAJJYrzmzM+eOSeAwXImO\n30jzgTKaxobyk93H3u741SiUFk6Gydy+wzJwqfkyqZwyVHWW6E4AeOQA9UdA\nO8Gb4iW9fVWA9Va0XmGizvrvBuyQomsHTVpkuq+FLqMnxZ3ySqdmjKTB/SDU\nPoRhtQS0tjpuZbAjzLM3PGPPK5GAvIY/1R4JOaiTF236wKd6x2bS8LYcyIVN\nz/crHcDtQh38MJf7ObpRXNF+o9I6mcetLrT8q/2iXlcKY9mNNwCrhBNohD+q\nOksPXImdVDl3tP/GwIwyJslDfYM8qryTFB7lP/csZfNg6uBn6g1ilrc82uuL\nW8muMLxFNzrxQvacmCoDBpHYbzMK/3qa7/fp8mMmKFrfOnkJ1gWfMgIRhg23\nhv6aTJbaUFCTQbHNojEF1WyMsC713lSjQgOFBhRHjE+3xy0eoEhv/V4qeLWs\nXRBy2CPlSPAGtDLs6q3pYCAo7JqmfOndSiWjxg0225ly8qeyUwZf1+2I/N4j\nC3biV0jnw4waLnTJ978DfQvdPckJRTK7X5nXFP4Poq0zXYXzrY/2EikFjgof\na19pW2qDWUMo8kDg/eEiB4xEoj2lSZR30P3z4ue6LSuvwI9fmZjpiof0ocXr\nKoGh97V8NefITpYHARNMUipq8D5fDDAedKFCGZQ4Xeci3HlrK0BEaAIJWGqs\nyVkJ\r\n=+/9N\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDz2Bh60RtfID7EpAc5GJGvP2wHnkz57vgJE0iErds3yAiBBwsC5cpiFNRT2LhzMayHS095mjyWTWW2hV2N0Q66HJg=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow_2.1.0_1524055543415_0.11374712748256854"},"_hasShrinkwrap":false},"2.2.0":{"name":"bow","version":"2.2.0","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":[{"node":">=8.3.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"~7.3.0","clone":"~2.1.2","debug":"~3.1.0","deep-equal":"~1.0.1","deep-freeze":"~0.0.1","http-auth":"~3.2.3","ioredis":"~3.2.2","killable":"~1.0.0","koa":"~2.5.1","koa-bodyparser":"~4.2.0","koa-router":"~7.4.0","socket.io":"~2.1.0","uuid":"~3.2.1"},"devDependencies":{"babel-eslint":"~8.2.2","coveralls":"~3.0.1","eslint":"~4.19.1","eslint-plugin-no-null":"~1.0.2","https-pem":"~2.0.0","husky":"~0.14.3","istanbul":"~1.1.0-alpha.1","mocha":"~5.1.1","should":"~13.2.1","socket.io-client":"~2.1.0","supertest":"~3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --exit --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"eb093ee609507376fe557817abb23a8b039552ec","_id":"bow@2.2.0","_npmVersion":"5.6.0","_nodeVersion":"8.11.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-kMfyLKN9ifCUkQ7d+NhC20RrZs11dOTc8PUd+vj9ziynitcvrZfa/hyYZEXr75qyOrkGd6vrJfiKOyPBcXrLSQ==","shasum":"1e2f000cb0c851f8b8e14f023ec5e22a1a13606f","tarball":"https://registry.npmjs.org/bow/-/bow-2.2.0.tgz","fileCount":13,"unpackedSize":50623,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa61XQCRA9TVsSAnZWagAALpEQAKKu9SN2QIzU6dho+FyU\nFP1jHO8krST9zw57drw2Hh1KeBth5k39dg/gmhvINuH+oPMHNtiLsEPBtSGu\na2ajREmkjFo/kDcvN1uJDy8gqt4u/JhhSerCZjljUzeNiS3luXH6u8MLOXOk\nh9NEQBGXJfc0gPYImIPRHvvcPngqvUYXMs659zYKx/yxAWfzG1jJnS8aNU0s\nweUQmEC3f6c+CevBVi53jLczLz4AchIkpBdXR8OHm0g7ph1wX3qRuZByQd0y\nMws3iYN3+W9j+pQcvHf2Oll16QpiVQTkzsLN9Lxy2hApE96zzSQEk8b3tdbH\neOz0eo3ueLySqTZ8INq0CEC3jy9P9tFET5v8yMtgPMeQHZ64U8M9tTU9Qb/C\nGS2u5wmQl51UjTC//fowK3dnnVjvnK0OcIHSCMcbHyYyAoQvgldWQwGdwasp\nQGD0W5NmzPonNeCLRudFbZwDiRJbo9joBuwBOSbvyNePRzJLIOQs9kTG8Gxf\nEiUnQayvT64RHT8J9EyITV6mCApLb7HI0me7I8n3/CXu7CQP645FAJcVaoqU\nRLymCo8mP+JSRbIZpufY6XgZ1L+KdiwczRvaGPe/u1mD9o13cekKN5lSiLov\njzGnVJpkF02G4iUeDbgZhh5zaIrwu7dM13BBj6WoI6D60EEJMfGhB8qgFk8p\nsR5S\r\n=0ZhJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC58IZCL63q908PFeUt9FFCbjpYut5/x05Rk392Yni/kgIgTE0vads8s2XoMo0pc/WuP90eOSplRIRISVn/EPflyV8="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow_2.2.0_1525372366893_0.97318848962977"},"_hasShrinkwrap":false},"2.3.0":{"name":"bow","version":"2.3.0","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":[{"node":">=8.3.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"~7.3.0","clone":"~2.1.2","debug":"~3.1.0","deep-equal":"~1.0.1","deep-freeze":"~0.0.1","http-auth":"~3.2.3","ioredis":"~3.2.2","killable":"~1.0.0","koa":"~2.5.1","koa-bodyparser":"~4.2.0","koa-router":"~7.4.0","socket.io":"~2.1.0","uuid":"~3.2.1"},"devDependencies":{"babel-eslint":"~8.2.2","coveralls":"~3.0.1","eslint":"~4.19.1","eslint-plugin-no-null":"~1.0.2","https-pem":"~2.0.0","husky":"~0.14.3","istanbul":"~1.1.0-alpha.1","mocha":"~5.1.1","should":"~13.2.1","socket.io-client":"~2.1.0","supertest":"~3.0.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:*,dbow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --exit --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"af1a4bc3a67232981f6e09d6dc70b300eb704e5d","_id":"bow@2.3.0","_npmVersion":"6.0.1","_nodeVersion":"8.11.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-v7ikmnn9dfScIbOn0Jd9vFx+HKKKRyIquaGbIiaIztFhMKwkZ30siQRJpbL1EasuXe87PslqNjK4GBr7z3F2eA==","shasum":"07c8a9499eaff826c662d81c60670a8565e321ac","tarball":"https://registry.npmjs.org/bow/-/bow-2.3.0.tgz","fileCount":13,"unpackedSize":51680,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbBA5aCRA9TVsSAnZWagAAnjYQAIXhWJC6JR5a74A37OXk\n2CPOnKJvlsjYniBSIQC6Z+zVE3cx5VePZrSajDXEEFv01pssI/4V7yf/eshh\nnpgk8AFNVW0seyBtRzROe4E/guN1Bn8NVIIo1VSuIoXWKhUDc/Z07X+P8GGj\nfI1ukYqi+RCas6DuOuZTpXkh3JZoixz2Yy2vTwdilzUvj8LmiJn5XCWzJTuA\nL10VVcFuOwi5kajAEJYu0Vdkj6eJXQpW9sLdNyRvHMiuG9yGW+yIT2TgchFy\nRFZQWh7LRL2FftsDAZr352eICqlcFEQ5mWbz7bjZGxOORw8kW18zp1VIEFoT\nlgIdT7gCh4Qu15QQae9/wRzU9trroM6uHwVJAwgtuVV4ACADYh4OX1oixFQw\nPRH4Wk3nEcwzJpIJIzBrkCAlUgVwUXUuSMw8ZFei9a9UnBHmAvv32ojGbAr4\n4yCE8eqJEneYoSSzes7RLEQdYeH9VCxArZUZ8R99xhyASE79EjFIiivD8taO\niD8qOKvx4ggox5UYxf8/Ljo4FfuPXegMLUVci3qImd1ulgp1aHmkEsVK0PQL\nh6pV3FygngKA4sWP3uvUuoLliVYUSIntaJlR8I44Q2J75hzetXdwCLO2YjWy\ntsYlU2I7uzhJt7tq4BoCh2fgKAWOXSFWDZ2tmy0Psp3J7dTRd6iZOyPRPpX8\npO4w\r\n=r5R+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHtQuoE9gY7hboY5tlKWjQixUHs6L6cn+XOYXlH/YleEAiEA5KncchMeJazNvsPJZx7SO6c0jVhFFjKzf6+bVTpiJV8="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow_2.3.0_1526992472291_0.17430139131393974"},"_hasShrinkwrap":false},"2.3.1":{"name":"bow","version":"2.3.1","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":[{"node":">=8.3.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"7.3.0","clone":"2.1.1","debug":"3.1.0","deep-equal":"1.0.1","deep-freeze":"0.0.1","http-auth":"3.2.3","ioredis":"3.2.2","killable":"1.0.0","koa":"2.5.1","koa-bodyparser":"4.2.1","koa-router":"7.4.0","socket.io":"2.1.1","uuid":"3.2.1"},"devDependencies":{"babel-eslint":"8.2.3","coveralls":"3.0.1","eslint":"4.19.1","eslint-plugin-no-null":"1.0.2","https-pem":"2.0.0","husky":"0.14.3","istanbul":"1.1.0-alpha.1","mocha":"5.2.0","should":"13.2.1","socket.io-client":"2.1.1","supertest":"3.1.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:*,dbow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --exit --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"937800c7156c03b0470485d254ccf37c91465e60","_id":"bow@2.3.1","_npmVersion":"6.0.1","_nodeVersion":"8.11.1","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-RcpreYPdWjoAK9zFgfGz6WOj4RvFsNR6M30mFhyWXIYI8xq6d72UW6k6fweHInEdseeKNWIgFyW/P64afq4WbQ==","shasum":"2b3d502e837906af5d868ef94db1cbc39a47ce58","tarball":"https://registry.npmjs.org/bow/-/bow-2.3.1.tgz","fileCount":13,"unpackedSize":51657,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbBoaoCRA9TVsSAnZWagAAXMoP/RTgcQpwaU2WqcMkkMwR\nkn089eFYoxIW6dFb2HfwJgNTnLDjc4CvEKVKcPdHRAaAQiCBZlAmI5HbWBmG\nDT/BCJ0qYvWMRoqt4SMO4egiidIzTp8sHGbyGpwHroJmodXTcUZ0RzMgu6T3\nDSJmzuXf2fH4R6i/g4UMUD+8FXiQfZMvAqirNbZdvtVphJk82G6Z2pee9EAs\nFdfgkXEgm05fQ4Xlr3UkUaKSPKXxUO+ZaSIjKDAXlaDkRk/datDyTzhC+rM6\nIU6PF6gX1/Qac4cMeUVRZQqTafVFltwITXiOubSuPvrkTudeVo5DqCk4qOcf\nV3uF5i2XFUyKdQBtmIOqPPdBO4Un8oC8E/Mfln/DOt4MMp4i98OAnUcSV8ty\n0G6xKjge0LebI61Wp/szFEIbSKFnCAYZZwaD0LPV7l/bVjNW+Pq9I1CKdJW2\njz5VBjBSaD5KfCtVLuhl/gKkElfKCEJsaQoswveFVW2XQktyUp4IslICFhqb\neVl17XeeIpfhtVFwU94SQvobLektbL1O84KqKyX5H4xkJC34DXb8L6bt0A/N\nfMDi5op6IBqIOfrmK4Q4e8fue1je6gfLCAcL7a21w3T0Y4X3iVBvG5+wBoF9\nohjUREkv02HJEuV+kKMsYOxUVQ5xJXBCz1p0bgaZI3V4a8/qd4zvUtu5tVfs\nUYml\r\n=3K3k\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHLGF/RB0c77HzjYaAmxK7wB3CEaJyAAPP+5txFKPi8vAiALI9AlCgA84QGOaj0+tqGNS9mQ4/0K0mqh45wRogM17Q=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow_2.3.1_1527154343553_0.23908626525944543"},"_hasShrinkwrap":false},"2.3.2":{"name":"bow","version":"2.3.2","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":[{"node":">=8.3.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"check-types":"7.4.0","clone":"2.1.1","debug":"3.1.0","deep-equal":"1.0.1","deep-freeze":"0.0.1","http-auth":"3.2.3","ioredis":"3.2.2","killable":"1.0.0","koa":"2.5.2","koa-bodyparser":"4.2.1","koa-router":"7.4.0","socket.io":"2.1.1","uuid":"3.3.2"},"devDependencies":{"babel-eslint":"8.2.6","coveralls":"3.0.2","eslint":"5.2.0","eslint-plugin-no-null":"1.0.2","https-pem":"2.0.0","husky":"0.14.3","istanbul":"1.1.0-alpha.1","mocha":"5.2.0","should":"13.2.1","socket.io-client":"2.1.1","supertest":"3.1.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:*,dbow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --exit --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"18e9dc3386adc5696b2b4500a56f070c3cc945dc","_id":"bow@2.3.2","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-soYI6yzzF5WLawuW2ShNhSGagm8LM+PBGNS5bCpF6tZBk9f/NaidvSqwW52aNeSEYlzutsErZ9nwk//AxUWj2Q==","shasum":"6563e9b5d369fdce7541106378ffa7de2644f064","tarball":"https://registry.npmjs.org/bow/-/bow-2.3.2.tgz","fileCount":13,"unpackedSize":52371,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbWdNKCRA9TVsSAnZWagAA0FkP/RJrNLh66Hug3h6tYhBK\nf1cH4HkrZ7Ap5RhES8DoVfAh/YqVT97FDbKkgZxESJCEsg+gBHP/G34EW0Mr\nhNC3iXZp0i97sqZWre+jF8b24IWqjHt4d9/9C2izI6Jfsp96aTPgkCnXHjnD\nc2vNJuLCfKfAS5qWf9JOfIqGYYzPWqcLRlKJxFlExuA2iFd2mW9EsvQ7hJO4\nqv3LoPAPY0SvZBGUnrzfRc2pCLl57h84pkPq18XPKuI0SLpVtjb5zpgQ1L/q\nYtGouJBNsKIo5lXUqLbpgVvocOuNdB2aQNWgXr+AUBJVbpEBroBUosbFhZrh\n7WLpJWZfwacauzxmRabq33WPLuGzLGPvNOMXdivpwlXzQ5C3cGZRzqDaRJQR\nDTbJqOEhSCnkd05GlFVOWx7WKXPR5Kh/8wGsGRa3WPD+3HODW5clJ/hMwlQc\nDqTkHotZHk5RzxUzhipFOoMpvPhyf+PU5thB5bCbKDuWTWoSpO9YY8YmOLgn\nLWJk1B9FCEJ+uoQunAku9BoBbf6Xbk710fP9PETuvzU/PZt5Jzz5k3SZdwPj\n1HuJIynoDZBfZYPLpM/L6jVM4Smswp+SIsDY6Nn24iyorWnoZDN2Q5730bVJ\nsKp1QEzK98LcbjznBxdGHQpZqEFq5XtwkeYcNfKvoiqVCxTRi1ocj4kKdKZ6\nOnBh\r\n=6O12\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCCFB60E3yr4KQCUiaMrZr8GwaL/eIopEDBEG3/qk8xCAIhAKaOL7kdTFOCjHmG+SEZu+EVf/WuGUYcA5rMG7RYu+Rm"}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow_2.3.2_1532613450397_0.4820096157310656"},"_hasShrinkwrap":false},"2.3.3":{"name":"bow","version":"2.3.3","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":[{"node":">=8.3.0"}],"main":"index.js","files":["lib/"],"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"basic-auth":"2.0.0","check-types":"7.4.0","clone":"2.1.1","debug":"3.1.0","deep-equal":"1.0.1","deep-freeze":"0.0.1","ioredis":"3.2.2","killable":"1.0.0","koa":"2.5.2","koa-bodyparser":"4.2.1","koa-router":"7.4.0","socket.io":"2.1.1","uuid":"3.3.2"},"devDependencies":{"babel-eslint":"8.2.6","coveralls":"3.0.2","eslint":"5.2.0","eslint-plugin-no-null":"1.0.2","https-pem":"2.0.0","husky":"0.14.3","istanbul":"1.1.0-alpha.1","mocha":"5.2.0","should":"13.2.1","socket.io-client":"2.1.1","supertest":"3.1.0"},"scripts":{"commitmsg":"node ./.hooks/commit-msg","prepush":"eslint . && npm test","test":"DEBUG=bow:*,dbow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --exit --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"gitHead":"5db48b5e278f7e53d9d4cc00f9202e4bd4ad1590","_id":"bow@2.3.3","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"dist":{"integrity":"sha512-kN+tJz6cU4xk/9otv7ozJ99xOJYPK9S6oHm/SNLk8YBFvqwdt9EKef48Ox8vLNrb86/3nicn/oVHZX4KLf13MQ==","shasum":"4f3c02fbb0d18ca360216ca84e990678918507e7","tarball":"https://registry.npmjs.org/bow/-/bow-2.3.3.tgz","fileCount":13,"unpackedSize":52389,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbWfmeCRA9TVsSAnZWagAACVEQAIn6UTafy7+giXNVuPrn\n8YRgWSN6JGhuBnDmd7hRn5troVLbDcsXhw+XIFps8AU9KFllR27kYbv/AAwI\nijiXATqJPkw+VlozhQ51BALT12QuaFFR+cpHS1Eacvf0+NGhz2h+EeZSVcf8\noLCTpHGW1gwQFtQCQFEQRAOlWolDCMX0FrgmY8XL5/UQFmb8jlpsUxYOTvCB\nWnSJVgv+Yt0vOXgRboDAQD50OmMmnNsR7mQ7cd04Y1vpMAKYF1cYb4/cfhT8\nStTs49HauQJ2HD2E7LcJPVynJAQ6f+TFyiKxrp84RhAHHAC9hOSLqdEr59VQ\npnK1V1BL8PAsbDwpzLuPtrf2rECyBygELYShul52UdHUISdqsHr+HJIPQq4F\nKUaYVQC7cocK8dOPaafg4Yb7AXHVDlM9B16+Wn636SIHUkDmYW0JYYAFUaVw\nMsSLSgG4lQkdgyRrRQcuMONUKe2GJVt8kPvtfBIrxJjIFnDqTCBDGo61BMw+\nUb0Lb6MuWTAvTa2WzjgKgTTl03XU78pNOEjvhaNKMb9+WFEkNVnGDdY31o1g\nLLjdWHjZAKWAhW/NCj2p1CIpYS3uKfuIvpoKqwZ7tpYAfvljBVFoqr1mTzQm\nUht3R8A7GLtSgY/dN3F1K7HPFYqWLkGzTqyUIsI2BzThR55z+Y5q3aQi4sm/\n7Zae\r\n=2PKt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDE/FnelFmjcZ0xLw3QmF7E1zNvZ3zhTbFXpGhG0tifIgIgcl5DZYbO/L/kWElQ2sz25Eg269VSYJQOM9iP4NBBJzs="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow_2.3.3_1532623262355_0.007942390586698655"},"_hasShrinkwrap":false},"2.3.4":{"name":"bow","version":"2.3.4","description":"Broadcast Over WebSocket","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"engines":{"node":">=8.3.0"},"main":"index.js","author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","bugs":{"url":"https://github.com/bowjs/bow/issues"},"dependencies":{"basic-auth":"2.0.1","check-types":"8.0.2","clone":"2.1.2","debug":"4.1.0","deep-equal":"1.0.1","deep-freeze":"0.0.1","ioredis":"4.9.3","killable":"1.0.1","koa":"2.7.0","koa-bodyparser":"4.2.1","koa-router":"7.4.0","socket.io":"2.2.0","uuid":"3.3.2"},"devDependencies":{"babel-eslint":"10.0.1","coveralls":"3.0.3","eslint":"5.16.0","eslint-plugin-no-null":"1.0.2","https-pem":"2.0.0","husky":"2.3.0","istanbul":"1.1.0-alpha.1","mocha":"6.1.4","should":"13.2.3","socket.io-client":"2.2.0","supertest":"4.0.2"},"scripts":{"test":"DEBUG=bow:*,dbow:* istanbul cover -x \"./test/**/*.js\" node_modules/mocha/bin/_mocha -- --exit --recursive ./test/**/*.test.js","coverage":"cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"},"husky":{"hooks":{"commit-msg":"node ./.hooks/commit-msg","pre-push":"eslint . && npm test"}},"gitHead":"62851bea27529c0b61a9302d3fcefeb63269f372","_id":"bow@2.3.4","_nodeVersion":"8.11.2","_npmVersion":"6.7.0","dist":{"integrity":"sha512-VU5C2q+CHPZjywSYE0YdiABhkfetWkebUfpsgy3KLW7S3CaXZ4BBR6iTZKvHA1/J/kIPjPCKBfrs3L7Zmcoy4w==","shasum":"01d88e573fb0fbbb627a94095db8f1fd70a596ec","tarball":"https://registry.npmjs.org/bow/-/bow-2.3.4.tgz","fileCount":13,"unpackedSize":55084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc5nJvCRA9TVsSAnZWagAAS4cQAJZ65xfCwg6nHn6BaUUl\n9oGkD4wH2GjjMI9wOY9iEgUwurByEGYD07+0JzpgbZTaK2yVdhI/SKK4yWtI\n8UIxwWS3ds1rcRi9Khl4z1wz11KwyBrMU5W3iN6WwSykuod0ispTKkiM+Wab\ntmOCGBLhHWjl1pnpINRZc+i1jNTBBtEp2y8AjzVdeDtL3gFByc8o4BM3EZO/\nGFD0D3nIhSUuPf5muixk95QNZCxwDK8+sBNLrgWjm+Q/yZUm5yWk1/3oLVH8\nX3Q+1Rk9ZGFZxhGvRySk3u+AvFlmO1kzz5aZHllueAVIGi1Fi93JTOqJRiNi\nLLOLW9jI9DoRNHaw1W9L0mOKrFSi10D959szbVENtP5phI2UNxS3JQskjgoq\n5ArZ+PS3C+Ve+ZFGHkkQfxoWpwN1y7Gm47hMbarOG5WyB4FNm+N2cwkSI6ma\npXtrvshpPpewS0iCA3eaE2/QE8Jp2zDF5VTTknDYXaKpoPyJ/gjsMwLf2bhL\nnQuD97HvycqGU5wGuJfGD8x6YwYw+O6Dqk8PTk7Is+ZxIA7mW+6sA+EeYIWO\nNI+BjB5csd0buEqFC2b2Qr4VJPycYdPGIsT6C1fdsyAcksl4zOEyXYKYS1je\nsWzc3l5W1qncCkD9sfu578Ks8qe9wW7JZG+OidWYOsvUpPVQ+yYAhbjKOPDR\nsq+N\r\n=1oFu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFjofWk0pYeAtD87XxH5yRj+QHlNqghuPsNRwGjmJNUNAiB083sOI/oGlib04ZG+dxj6A3bjEzg077p7no2FpAMg5Q=="}]},"maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"_npmUser":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bow_2.3.4_1558606447137_0.049458081503617635"},"_hasShrinkwrap":false}},"readme":"# Bow - Broadcast Over WebSocket\n\n[![NPM](https://nodei.co/npm/bow.png?compact=true)](https://nodei.co/npm/bow/)\n\nBow helps you building a multitenant WebSocket server that fits into a microservice architecture.\n\n## State\n\n[![Build](https://api.travis-ci.org/bowjs/bow.svg?branch=master)](https://travis-ci.org/bowjs/bow)  \n[![Coverage](https://coveralls.io/repos/github/bowjs/bow/badge.svg?branch=master)](https://coveralls.io/github/bowjs/bow?branch=master)  \n[![Maintainability](https://img.shields.io/codeclimate/maintainability/bowjs/bow.svg?style=flat)](https://codeclimate.com/github/bowjs/bow/maintainability)  \n[![Dependencies](https://david-dm.org/bowjs/bow/status.svg)](https://david-dm.org/bowjs/bow)  \n[![Vulnerabilities](https://snyk.io/test/github/bowjs/bow/badge.svg)](https://snyk.io/test/github/bowjs/bow)  \n[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://opensource.org/licenses/MIT)  \n\n## Specs\n\nBow exposes two main JSON-based APIs to third party:\n\n- **an HTTP API to push messages**, built on top of [Koa](http://koajs.com/);\n- and **a WebSocket API to receive messages**, built on top of [Socket.IO](https://socket.io/).\n\nTo ease horizontal scalability, each Bow instance can connect to a [Redis message broker](https://redis.io/topics/pubsub) thanks to [ioredis](https://www.npmjs.com/package/ioredis).\n\nBow is built upon these four main concepts:\n\n- **messages**, that must hold the audience to which they must be dispatched to;\n- **middlewares**, that know how to resolve the messages audiences;\n- **inbounds**, which create new HTTP API endpoints;\n- and **outbounds**, which create new WebSocket API endpoints.\n\n### Message\n\nA message is composed by:\n\n- a *name*, that will be used for the WebSocket event name;\n- a *payload*, that will be used for the WebSocket event content;\n- and an *audience*, i.e. the tenants the WebSocket event must be dispatched to.\n\nAn audience is composed by *queries*, themselves composed by *predicates*.\n\n#### Predicate\n\nA predicate is a key-value pair, where keys are strings and **values only one of the following JSON literals**:\n\n- Boolean (`true` or `false`);\n- Number (e.g. `42` or `3.14159`);\n- String, non-empty (e.g. `\"foobar\"`).\n\n#### Query\n\nA query is a conjunction (logical `AND`) of predicates as a JSON object, for example:\n\n```json\n{ \"role\": \"author\", \"blogId\": 42 }\n```\n\nThe above query is composed by two predicates: `\"role\": \"author\"` and `\"blogId\": 42`. Such a query will thus select only authors of the blog 42, i.e. both predicates must be fulfilled.\n\n#### Audience\n\nAn audience is a disjunction (logical `OR`) of queries as a JSON array, for example:\n\n```json\n[\n  { \"role\": \"admin\" },\n  { \"role\": \"author\", \"blogId\": 42 }\n]\n```\n\nThe above audience is composed by two queries: one selecting admins, and another one selecting the authors of the blog 42. The message holding this audience will thus be dispatched to either admins, or authors of the blog 42.\n\n#### Example\n\nHere is an example of what could be a message:\n\n```json\n{\n  \"name\": \"NEW_ARTICLE\",\n  \"title\": \"This article has just been created\",\n  \"content\": \"The article content...\",\n  \"audience\": [\n    { \"role\": \"admin\" },\n    { \"role\": \"author\", \"blogId\": 42 }\n  ]\n}\n```\n\n#### `__disconnect`\n\nIf you push a message named `__disconnect`, then instead of dispatching the message to the matched tenants, **their socket will be disconnected**, for example:\n\n```json\n{\n  \"name\": \"__disconnect\",\n  \"audience\": [\n    { \"role\": \"admin\" },\n    { \"role\": \"author\", \"blogId\": 42 }\n  ]\n}\n```\n\nThe above message will disconnect all the sockets of either admins, or authors of the blog 42.\n\n### Middleware\n\nThe purpose of middlewares is to resolve an audience so that holding message can be dispatched to the right tenants.\n\nA middleware is composed by:\n\n- a *version* (String, non-empty);\n- and a *function*, that creates *criteria* given a *listener's details*, possibly via a promise.\n\n#### Criterion\n\nJust like predicates, criteria are key-value pairs, where keys are strings and **values only one of the following JSON literals**:\n\n- Boolean (`true` or `false`);\n- Number (e.g. `42` or `3.14159`);\n- String, non-empty (e.g. `\"foobar\"`);\n- Array (e.g. `[42, 418]`), which values must be only one of the following JSON literals:\n  - Boolean (`true` or `false`);\n  - Number (e.g. `42` or `3.14159`);\n  - String, non-empty (e.g. `\"foobar\"`).\n\nFor example:\n\n```json\n{\n  \"role\": \"author\",\n  \"blogId\": [42, 418]\n}\n```\n\nThe above criteria mean that the listener is an author of the blogs 42 and 418.\n\n#### `__id`\n\nCriteria will automatically hold the listener's id in a property named `__id`. This allows messages audiences to target specific listeners.\n\n#### Resolution\n\nThe message resolver will first try to match the audiences predicates keys with the listeners criteria keys, then the audiences predicates values with the listeners criteria values.\n\nFor example, given the following listener criteria:\n\n```json\n{\n  \"role\": \"author\",\n  \"blogId\": [42, 418]\n}\n```\n\nAnd the following audience:\n\n```json\n[\n  { \"role\": \"admin\" },\n  { \"role\": \"author\", \"blogId\": 42 }\n]\n```\n\nThe first query in the audience (`{ \"role\": \"admin\" }`) won't match, because listener's `role` criterion value is `\"author\"`.\n\nBut the second query in the audience (`{ \"role\": \"author\", \"blogId\": 42 }`) will match, because listener's `role` criterion value is `\"author\"` and they are linked to blog 42.\n\nThe message holding this audience will thus be forwarded to the listener.\n\n### Inbound\n\nMessages are pushed via inbounds, which are basically HTTP endpoints built thanks to [Koa](http://koajs.com/). Inbounds are protected by [Basic Auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#Basic_authentication_scheme), which makes it easily compatible with [Amazon SNS](http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.html) for example (if you plan to use Amazon SNS, [sns-validator](https://www.npmjs.com/package/sns-validator) could be useful).\n\nAn inbound is composed by:\n\n- a *path* (String, non-empty), **mapped to the HTTP method `POST`**;\n- and a *function*, that creates a *message* given a *request body*, possibly via a promise.\n\nFor example, given the following message:\n\n```json\n{\n  \"name\": \"NEW_ARTICLE\",\n  \"title\": \"This article has just been created\",\n  \"content\": \"The article content...\",\n  \"audience\": [\n    { \"role\": \"admin\" },\n    { \"role\": \"author\", \"blogId\": 42 }\n  ]\n}\n```\n\nThe function could be:\n\n```js\nconst createMessageFromRequestBody = async (body) => {\n  await validateRequestBody(body);\n  return {\n    name: body.name,\n    payload: body,\n    audience: body.audience\n  };\n};\n```\n\n#### Possible HTTP response statuses\n\n- `404` if the URL is not handled;\n- `405` if the verb is not handled (paths are mapped to `POST`);\n- `401` if no auth is provided or if the provided auth is wrong;\n- `422` if no body is provided in the HTTP request or if the provided body cannot be parsed into a message;\n- `204` otherwise.\n\n### Outbound\n\n*Outbounds* handle WebSocket connections thanks to [Socket.IO](https://socket.io/), and are composed by:\n\n- a *version* (String, non-empty);\n- and a *function* that creates a *listener's details* given a *token*, possibly via a promise.\n\nA listener's details should be an object that has at least one `id` property, holding a value of **only one of the following JSON literals**:\n\n- Number (e.g. `42` or `3.14159`);\n- String, non-empty (e.g. `\"foobar\"`).\n\nThis `id` must uniquely identify the listening entity. The same `id` can connect multiple times (for example a user connected via their browser and their phone), in which case both listeners will be notified when a message is dispatched.\n\n**Be careful not to make two distinct entities share the same `id`** (for example a *user* and a *live signage*, which may share the same database `id` value as not of the same type). In this case, one solution can be to prefix the `id` by the type (e.g. `USER/{id}` and `SIGNAGE/{id}`).\n\n#### Handshake\n\nWhen connecting to an outbound, the client must provide the outbound version it wants to use in [the Socket.IO handshake query](https://socket.io/docs/client-api/#with-query-option), thanks to a parameter named `v`. Once successfully connected, it must send an `authenticate` event holding the token needed by the outbound to authenticate the connection, along with [an acknowledgement function](https://socket.io/docs/#sending-and-getting-data-(acknowledgements)) that will be called if the client has been successfully authenticated.\n\nIf an error occurred in the authentication process, Bow will first send an `alert` event with an explanation, **and will then disconnect the client**.\n\nFor example, client-side:\n\n```js\nconst io = require(\"socket.io-client\");\n\nconst url = \"...\";\nconst version = \"...\";\nconst token = \"...\";\n\nconst socket = io(url, { query: { v: version } })\n  .on(\"error\", (error) => {\n    console.error(\"Oops, something's gone wrong:\", error);\n  })\n  .on(\"alert\", (alert) => {\n    console.error(\"Oops, something's gone wrong:\", alert);\n  })\n  .on(\"connect\", () => {\n    console.log(\"Connected!\");\n    socket.emit(\"authenticate\", token, () => {\n      console.log(\"Authenticated!\");\n    });\n  });\n```\n\n#### Possible received WebSocket events\n\n- `error` if a namespace has been provided, or if no version has been provided in the handshake query parameters, or if the provided version if not handled;\n- `alert` if the authentication timeout has been reached, or if a listener id could not be found given the provided token, or if no criteria could get built given the listener id.\n\nAny of the above events **will disconnect the client**.\n\nSee also the [Socket.IO Client API Documentation](https://socket.io/docs/client-api/).\n\n## Architecture\n\n### Handshake\n\n![Handshake](docs/handshake.png?raw=true \"Handshake\")\n\n1. The client used by \"user #1\" establishes the WebSocket connection. The load balancer attaches it to \"Bow instance #1\".\n\n2. The client asks \"your app\" a token, so that it can authenticate to the WebSocket server.\n\n3. \"Your app\" generates a token and returns it. If using a JWT token, the claims could look like:\n\n```js\n{\n  \"id\": \"USER/1\",\n  \"criteria\": {\n    \"role\": \"author\",\n    \"blogId\": 42\n  }\n}\n```\n\n4. The client sends the token it received to the instance it is connected to, via the established WebSocket connection. The instance validates the token, stores the WebSocket connection object in its memory, and call the client-provided acknowledgement function. In memory, the listener will be scattered this way:\n\n```js\nMap {\n  // ...,\n  \"__id\": Map {\n    // ...,\n    \"USER/1\": Set [ ..., webSocketConnection, ... ],\n    // ...,\n  },\n  \"role\": Map {\n    // ...,\n    \"author\": Set [ ..., webSocketConnection, ... ],\n    // ...,\n  },\n  \"blogId\": Map {\n    // ...,\n    42: Set [ ..., webSocketConnection ... ],\n    // ...,\n  }\n  // ...\n}\n```\n\n5. The instance tells Redis that it just got a new listener registered, while attaching the corresponding criteria.\n\n6. Redis broadcasts this message to all instances, so that they can update their current version of this user's criteria, if any (a same user can be connected with both their laptop and their smartphone to different instances for example).\n\n### Push\n\n![Push](docs/push.png?raw=true \"Push\")\n\n0. The clients used by \"user #1\" and \"user #2\" both have an authenticated WebSocket connection.\n\n1. \"User #2\" creates a new article by calling \"your app\"'s API.\n\n2. \"Your app\" pushes \"NEW_ARTICLE\" to the WebSocket server. The load balancer forwards it to \"Bow instance #3\". The message looks like:\n\n```js\n{\n  \"name\": \"NEW_ARTICLE\",\n  \"article\": {\n    \"title\": \"New article title\",\n    \"content\": \"New article content\"\n  },\n  \"audience\": [\n    { \"role\": \"admin\" },\n    { \"role\": \"author\", \"blogId\": 42 }\n  ]\n}\n```\n\n3. The instance tells Redis that it just got a new message to forward while attaching it. At this point, the instance does nothing more.\n\n4. Redis broadcasts this message to all instances, including \"Bow instance #3\" that triggered this message's process, so that they can all forward it to the targeted listeners, by resolving the audience attached to the message against the listeners they currently hold in memory.\n\n5. Both \"Bow instance #1\" and \"Bow instance #3\" found listeners they must push the message to, respectively \"user #1\" and \"user #2\". These two clients then receive the message over the established WebSocket connection.\n\n## Usage\n\n### Installation\n\nBow requires **Node.js v8.3.0 or higher** for ES2015 and async function support, plus the spreading syntax.\n\n```text\nnpm install --save bow\n```\n\n### Environment variables\n\nIf used in production environment, it is recommended to set the `NODE_ENV` environment variable to `production`.\n\nBecause Bow uses [debug](https://www.npmjs.com/package/debug), you should set [the `DEBUG` environment variable](https://www.npmjs.com/package/debug#environment-variables) to `bow:*`. You can have more verbose logs by adding `dbow:*` as well (mostly for debugging purposes), i.e. `bow:*,dbow:.*`.\n\nThese variables can be easily set thanks to [cross-env](https://www.npmjs.com/package/cross-env).\n\n### new Bow(config)\n\nCreates a new `Bow` instance, expects one `config` object argument:\n\n#### config.port\n\n**Required**, the port the server will be listening to.\n\n#### config.https\n\nOptional, the `options` object to pass to [Node.js `https.createServer(...)` function](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). If this option is not provided, then an [HTTP server will be created](https://nodejs.org/api/http.html#http_http_createserver_requestlistener) instead.\n\n#### config.redis\n\nOptional, the Redis config.\n\nIf this is an object, then it will be passed to [ioredis `new Redis(...)`](https://www.npmjs.com/package/ioredis#connect-to-redis).\n\nIf this is an array of object, then it will be passed to [ioredis `new Redis.Cluster(...)`](https://www.npmjs.com/package/ioredis#cluster).\n\n**Any other value will fail** (e.g. only the port).\n\n#### config.middleware.logInterval\n\nOptional, the interval in seconds that should be used to log the number of currently connected WebSocket clients. If negative or null, nothing will be logged.\n\n#### config.inbound.realm\n\n**Required**, the realm for the Basic Auth protecting the HTTP API.\n\n#### config.inbound.username\n\n**Required**, the username for the Basic Auth protecting the HTTP API.\n\n#### config.inbound.password\n\n**Required**, the password for the Basic Auth protecting the HTTP API.\n\n#### config.outbound.timeout\n\n**Required**, the timeout for WebSocket connections to authenticate, in seconds.\n\n### bow.middleware(config)\n\nRegisters a new middleware, expects one `config` object argument:\n\n#### config.version\n\n**Required**, the version of this middleware, must be unique between all middlewares.\n\n#### config.createCriteriaFromListenerDetails\n\n**Required**, a function that takes listener's details, and returns the corresponding listener criteria, possibly via a promise.\n\n### bow.inbound(config)\n\nRegisters a new inbound, expects one `config` object argument:\n\n#### config.path\n\n**Required**, the path of this inbound, must be unique between all inbounds. This path will then be passed to Koa router, **mapped to the HTTP method `POST`**. **The path cannot be `/health`**, as it is reserved for the health check.\n\n#### config.createMessageFromRequestBody\n\n**Required**, a function that takes one single `body` argument as found in the HTTP request body, and returns a *message* object, possibly via a promise, defined by:\n\n- a `name` property, that will be the `eventName` parameter passed to [Socket.IO `socket.emit(...)`](https://socket.io/docs/emit-cheatsheet/);\n- a `payload` property, that will be the `eventPayload`parameter passed to [Socket.IO `socket.emit(...)`](https://socket.io/docs/emit-cheatsheet/);\n- and an `audience` property, that will passed to the chosen middleware so that it can dispatch the event as expected.\n\n#### config.middlewareVersion\n\n**Required**, the middleware version to use to resolve the audiences found in pushed messages.\n\n### bow.outbound(config)\n\nRegisters a new outbound, expects one `config` object argument:\n\n#### config.version\n\n**Required**, the version of this outbound, must be unique between all outbounds.\n\n#### config.createListenerDetailsFromToken\n\n**Required**, a function that takes one single `token` argument (the one provided when authenticating a WebSocket connection), and returns the corresponding listener details, possibly via a promise.\n\n#### config.middlewareVersion\n\n**Required**, the middleware version to use to resolve the listener from the id retrieved thanks to the token.\n\n### bow.healthCheck(healthCheckDecorator)\n\nBy default, `GET /health` will simply return an empty 200, but this allows you to improve this response. The given `healthCheckDecorator` must be a function that takes a [Koa `context`](https://github.com/koajs/koa/blob/master/docs/api/context.md).\n\n## Examples\n\nThe following examples use [JWT](https://jwt.io/). Note that while JWT fits great here, you can use any other token system of your choice.\n\n### Server with simple JWTs and a database access to create the criteria\n\nThe following server example uses a relational database holding the users (i.e. the *listeners*) that will be used to create the criteria by your Bow server.\n\n#### Database\n\nTable `listener`:\n\n```text\n+----+----------+--------+---------+\n| id |   name   |  role  | blog_id |\n+----+----------+--------+---------+\n|  1 | Admin 1  | admin  |      42 |\n|  2 | Author 1 | author |      42 |\n|  3 | Author 2 | author |     418 |\n+----+----------+--------+---------+\n```\n\n#### Server\n\n```js\nconst Bow = require(\"bow\");\n\n/*\n * middleware configuration:\n */\n\nconst createCriteriaFromListenerDetails = async (listenerDetails) => {\n  const results = await dbConnection.query(\"SELECT * FROM listener WHERE id = ?\", listenerDetails.id);\n  if (1 === results.length) {\n    const listener = result[0];\n    return {\n      role: listener[\"role\"],\n      blogId: listener[\"blog_id\"]\n    };\n  } else {\n    throw new Error(`Expected one result for listener id '${listenerDetails.id}', but got ${results.length}`);\n  }\n};\n\n/*\n * inbound configuration:\n */\n\nconst createMessageFromRequestBody = (body) => ({\n  name: body.name,\n  payload: body,\n  audience: body.audience\n});\n\n/*\n * outbound configuration:\n */\n\n// shared with auth server that created the token:\nconst PRIVATE_KEY = \"thisisatopsecretkey\";\n\nconst createListenerDetailsFromToken = (token) => {\n  const payload = jwt.decrypt(token, PRIVATE_KEY);\n  return {\n    id: payload.listenerId\n  };\n};\n\n/*\n * create server:\n */\n\n const config = {\n   port: 443,\n   https: { ... },\n   redis: { ... },\n   inbound: {\n     realm: \"My blogging platform\",\n     username: \"messagepusher\",\n     password: \"thisisasecret\"\n   },\n   outbound: {\n     timeout: 5 // seconds\n   }\n };\n\nconst bow = new Bow(config)\n  .middleware({\n    version: \"v1.1\",\n    createCriteriaFromListenerDetails\n  })\n  .inbound({\n    path: \"/v1.2/messages\",\n    createMessageFromRequestBody,\n    middlewareVersion: \"v1.1\"\n  })\n  .outbound({\n    version: \"v1.3\",\n    createListenerDetailsFromToken,\n    middlewareVersion: \"v1.1\"\n  });\n\nbow.start().then(() => {\n  console.log(\"Ready!\");\n});\n```\n\n### Server with complex JWTs that hold the criteria directly\n\n```js\nconst Bow = require(\"bow\");\n\n/*\n * middleware configuration:\n */\n\nconst createCriteriaFromListenerDetails = (listenerDetails) =>\n  // criteria already available in the listener details,\n  // prepared by createListenerDetailsFromToken(...) (see below):\n  listenerDetails.criteria;\n\n/*\n * inbound configuration:\n */\n\nconst createMessageFromRequestBody = (body) => ({\n  name: body.name,\n  payload: body,\n  audience: body.audience\n});\n\n/*\n * outbound configuration:\n */\n\n// shared with auth server that created the token:\nconst PRIVATE_KEY = \"thisisatopsecretkey\";\n\nconst createListenerDetailsFromToken = (token) => {\n  const payload = jwt.decrypt(token, PRIVATE_KEY);\n  return {\n    id: payload.listenerId,\n    // generated by the auth server,\n    // say based on the same database as in the previous example:\n    criteria: payload.criteria\n  };\n};\n\n/*\n * create server:\n */\n\n const config = {\n   port: 443,\n   https: { ... },\n   redis: { ... },\n   inbound: {\n     realm: \"My blogging platform\",\n     username: \"messagepusher\",\n     password: \"thisisasecret\"\n   },\n   outbound: {\n     timeout: 5 // seconds\n   }\n };\n\nconst bow = new Bow(config)\n  .middleware({\n    version: \"v1.1\",\n    createCriteriaFromListenerDetails\n  })\n  .inbound({\n    path: \"/v1.2/messages\",\n    createMessageFromRequestBody,\n    middlewareVersion: \"v1.1\"\n  })\n  .outbound({\n    version: \"v1.3\",\n    createListenerDetailsFromToken,\n    middlewareVersion: \"v1.1\"\n  });\n\nbow.start().then(() => {\n  console.log(\"Ready!\");\n});\n```\n\n### Client\n\nThe following client applies to both servers above.\n\n```js\nconst io = require(\"socket.io-client\");\n\nconst onError = (error) => console.error(\"Oops, something's gone wrong:\", error);\n\nconst onNewArticle = (article) => {\n  // ...\n};\n\nconst socket = io(url, { query: { v: \"v1.3\" } })\n  .on(\"NEW_ARTICLE\", onNewArticle)\n  .on(\"alert\", onError)\n  .on(\"error\", onError)\n  .on(\"connect\", async () => {\n    console.log(\"Connected!\");\n    const token = await AuthService.getToken();\n    socket.emit(\"authenticate\", token, () => {\n      console.log(\"Authenticated!\");\n    });\n  });\n```\n\n### Push new message\n\nThe following push applies to both servers above.\n\n```text\nPOST /v1.2/messages\n\n{\n  \"name\": \"NEW_ARTICLE\",\n  \"title\": \"This article has just been created\",\n  \"content\": \"The article content\",\n  \"audience\": [\n    { \"role\": \"admin\" },\n    { \"role\": \"author\", \"blogId\": 42 }\n  ]\n}\n```\n\nThe following users will receive this message:\n\n- Admin 1: `role` is `\"admin\"`;\n- Author 1: `role` is `\"author\"` and `blogId` is `42`.\n\nThe following users will **not** receive this message:\n\n- Author 2: `role` is `\"author\"` but `blogId` is `418`.\n","maintainers":[{"email":"christophe.maillard@rocketmail.com","name":"sp00m"}],"time":{"modified":"2022-06-13T05:00:35.957Z","created":"2013-01-10T11:12:55.308Z","0.0.1":"2013-01-10T11:12:58.463Z","1.0.0":"2017-09-26T15:41:54.128Z","1.0.1":"2017-09-26T15:46:45.612Z","1.0.2":"2017-09-29T19:09:11.349Z","1.0.3":"2017-09-29T19:25:38.937Z","1.0.4":"2017-09-29T19:45:42.570Z","1.0.5":"2017-10-15T18:13:57.922Z","1.0.6":"2017-10-16T16:54:09.680Z","1.0.7":"2017-10-16T17:02:45.819Z","1.0.8":"2017-10-16T17:32:19.936Z","1.0.9":"2017-10-16T22:46:12.726Z","1.0.10":"2017-10-17T09:37:21.345Z","1.0.11":"2017-10-17T10:34:31.907Z","1.1.0":"2017-10-17T16:51:23.035Z","1.1.1":"2017-10-18T12:08:20.547Z","1.2.0":"2017-10-19T17:48:30.425Z","1.2.1":"2017-10-19T20:30:25.981Z","1.2.2":"2017-10-23T09:04:19.588Z","2.0.0":"2018-04-18T11:40:02.989Z","2.1.0":"2018-04-18T12:45:43.573Z","2.2.0":"2018-05-03T18:32:46.987Z","2.3.0":"2018-05-22T12:34:32.386Z","2.3.1":"2018-05-24T09:32:23.659Z","2.3.2":"2018-07-26T13:57:30.493Z","2.3.3":"2018-07-26T16:41:02.480Z","2.3.4":"2019-05-23T10:14:07.260Z"},"author":{"name":"sp00m","email":"christophe.maillard@rocketmail.com"},"repository":{"type":"git","url":"git+https://github.com/bowjs/bow.git"},"homepage":"https://github.com/bowjs/bow#readme","readmeFilename":"README.md","keywords":["bow","server","http","websocket","microservice","multitenant","scalable","redis"],"bugs":{"url":"https://github.com/bowjs/bow/issues"},"license":"MIT"}